1a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch# Authors:
2a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#   Trevor Perrin
3a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#   Dimitris Moraitis - Anon ciphersuites
4a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#
5a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch# See the LICENSE file for legal information regarding use of this file.
6a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)A helper class for using TLS Lite with stdlib clients
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)(httplib, xmlrpclib, imaplib, poplib).
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochfrom tlslite.checker import Checker
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochclass ClientHelper(object):
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """This is a helper class used to integrate TLS Lite with various
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TLS clients (e.g. poplib, smtplib, httplib, etc.)"""
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def __init__(self,
19a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch              username=None, password=None,
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              certChain=None, privateKey=None,
21a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch              checker=None,
22a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch              settings = None,
23a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch              anon = False):
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        """
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        For client authentication, use one of these argument
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        combinations:
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         - username, password (SRP)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         - certChain, privateKey (certificate)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        For server authentication, you can either rely on the
31a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        implicit mutual authentication performed by SRP,
32a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        or you can do certificate-based server
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        authentication with one of these argument combinations:
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         - x509Fingerprint
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Certificate-based server authentication is compatible with
37a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        SRP or certificate-based client authentication.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        The constructor does not perform the TLS handshake itself, but
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        simply stores these arguments for later.  The handshake is
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        performed only when this class needs to connect with the
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        server.  Then you should be prepared to handle TLS-specific
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        exceptions.  See the client handshake functions in
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        L{tlslite.TLSConnection.TLSConnection} for details on which
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        exceptions might be raised.
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        @type username: str
48a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        @param username: SRP username.  Requires the
49a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        'password' argument.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        @type password: str
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        @param password: SRP password for mutual authentication.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Requires the 'username' argument.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        @type certChain: L{tlslite.x509certchain.X509CertChain}
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        @param certChain: Certificate chain for client authentication.
57a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        Requires the 'privateKey' argument.  Excludes the SRP arguments.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        @type privateKey: L{tlslite.utils.rsakey.RSAKey}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        @param privateKey: Private key for client authentication.
61a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        Requires the 'certChain' argument.  Excludes the SRP arguments.
62a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
63a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        @type checker: L{tlslite.checker.Checker}
64a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        @param checker: Callable object called after handshaking to
65a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        evaluate the connection and raise an Exception if necessary.
66a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
67a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        @type settings: L{tlslite.handshakesettings.HandshakeSettings}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        @param settings: Various settings which can be used to control
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        the ciphersuites, certificate types, and SSL/TLS versions
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        offered by the client.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        """
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self.username = None
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self.password = None
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self.certChain = None
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self.privateKey = None
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self.checker = None
78a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        self.anon = anon
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        #SRP Authentication
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if username and password and not \
82a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                (certChain or privateKey):
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self.username = username
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self.password = password
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        #Certificate Chain Authentication
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        elif certChain and privateKey and not \
88a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                (username or password):
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self.certChain = certChain
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self.privateKey = privateKey
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        #No Authentication
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        elif not password and not username and not \
94a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                certChain and not privateKey:
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            pass
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else:
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            raise ValueError("Bad parameters")
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        self.checker = checker
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self.settings = settings
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self.tlsSession = None
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def _handshake(self, tlsConnection):
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if self.username and self.password:
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            tlsConnection.handshakeClientSRP(username=self.username,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             password=self.password,
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             checker=self.checker,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             settings=self.settings,
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             session=self.tlsSession)
112a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        elif self.anon:
113a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            tlsConnection.handshakeClientAnonymous(session=self.tlsSession,
114a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                                settings=self.settings,
115a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                                checker=self.checker)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else:
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            tlsConnection.handshakeClientCert(certChain=self.certChain,
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              privateKey=self.privateKey,
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              checker=self.checker,
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              settings=self.settings,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              session=self.tlsSession)
122a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        self.tlsSession = tlsConnection.session