1# Authors:
2#   Trevor Perrin
3#   Google - added reqCAs parameter
4#   Google (adapted by Sam Rushing and Marcelo Fernandez) - NPN support
5#   Dimitris Moraitis - Anon ciphersuites
6#   Martin von Loewis - python 3 port
7#   Yngve Pettersen (ported by Paul Sokolovsky) - TLS 1.2
8#
9# See the LICENSE file for legal information regarding use of this file.
10
11"""
12MAIN CLASS FOR TLS LITE (START HERE!).
13"""
14
15import socket
16from .utils.compat import formatExceptionTrace
17from .tlsrecordlayer import TLSRecordLayer
18from .session import Session
19from .constants import *
20from .utils.cryptomath import getRandomBytes, MD5, SHA1, SHA256
21from .errors import *
22from .messages import *
23from .mathtls import *
24from .handshakesettings import HandshakeSettings
25from .utils.tackwrapper import *
26from .utils.rsakey import RSAKey
27from .utils import p256
28
29class KeyExchange(object):
30    def __init__(self, cipherSuite, clientHello, serverHello, privateKey):
31        """
32        Initializes the KeyExchange. privateKey is the signing private key.
33        """
34        self.cipherSuite = cipherSuite
35        self.clientHello = clientHello
36        self.serverHello = serverHello
37        self.privateKey = privateKey
38
39    def makeServerKeyExchange():
40        """
41        Returns a ServerKeyExchange object for the server's initial leg in the
42        handshake. If the key exchange method does not send ServerKeyExchange
43        (e.g. RSA), it returns None.
44        """
45        raise NotImplementedError()
46
47    def processClientKeyExchange(clientKeyExchange):
48        """
49        Processes the client's ClientKeyExchange message and returns the
50        premaster secret. Raises TLSLocalAlert on error.
51        """
52        raise NotImplementedError()
53
54    def sign(self, inpBytes):
55        algorithm = None
56        if self.serverHello.server_version >= (3, 3):
57            # Negotiate a signature algorithm.
58            peerPrefs = self.clientHello.signature_algorithms
59            if (HashAlgorithm.sha256, SignatureAlgorithm.rsa) in peerPrefs:
60                algorithm = (HashAlgorithm.sha256, SignatureAlgorithm.rsa)
61                inpBytes = RSAKey.addPKCS1SHA256Prefix(SHA256(inpBytes))
62            elif (HashAlgorithm.sha1, SignatureAlgorithm.rsa) in peerPrefs:
63                algorithm = (HashAlgorithm.sha1, SignatureAlgorithm.rsa)
64                inpBytes = RSAKey.addPKCS1SHA1Prefix(SHA1(inpBytes))
65            else:
66                raise TLSLocalAlert(AlertDescription.handshake_failure,
67                                   "no common signature algorithms")
68        else:
69            inpBytes = MD5(inpBytes) + SHA1(inpBytes)
70        return algorithm, self.privateKey.sign(inpBytes)
71
72class RSAKeyExchange(KeyExchange):
73    def makeServerKeyExchange(self):
74        return None
75
76    def processClientKeyExchange(self, clientKeyExchange):
77        premasterSecret = self.privateKey.decrypt(\
78            clientKeyExchange.encryptedPreMasterSecret)
79
80        # On decryption failure randomize premaster secret to avoid
81        # Bleichenbacher's "million message" attack
82        randomPreMasterSecret = getRandomBytes(48)
83        if not premasterSecret:
84            premasterSecret = randomPreMasterSecret
85        elif len(premasterSecret)!=48:
86            premasterSecret = randomPreMasterSecret
87        else:
88            versionCheck = (premasterSecret[0], premasterSecret[1])
89            if versionCheck != self.clientHello.client_version:
90                #Tolerate buggy IE clients
91                if versionCheck != self.serverHello.server_version:
92                    premasterSecret = randomPreMasterSecret
93        return premasterSecret
94
95def _hexStringToNumber(s):
96    s = s.replace(" ", "").replace("\n", "")
97    if len(s) % 2 != 0:
98        raise ValueError("Length is not even")
99    return bytesToNumber(bytearray.fromhex(s))
100
101class DHE_RSAKeyExchange(KeyExchange):
102    # 2048-bit MODP Group (RFC 3526, Section 3)
103    dh_p = _hexStringToNumber("""
104FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1
10529024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD
106EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245
107E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED
108EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D
109C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F
11083655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D
111670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B
112E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9
113DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510
11415728E5A 8AACAA68 FFFFFFFF FFFFFFFF""")
115    dh_g = 2
116
117    # RFC 3526, Section 8.
118    strength = 160
119
120    def makeServerKeyExchange(self):
121        # Per RFC 3526, Section 1, the exponent should have double the entropy
122        # of the strength of the curve.
123        self.dh_Xs = bytesToNumber(getRandomBytes(self.strength * 2 / 8))
124        dh_Ys = powMod(self.dh_g, self.dh_Xs, self.dh_p)
125
126        version = self.serverHello.server_version
127        serverKeyExchange = ServerKeyExchange(self.cipherSuite, version)
128        serverKeyExchange.createDH(self.dh_p, self.dh_g, dh_Ys)
129        serverKeyExchange.signature_algorithm, serverKeyExchange.signature = \
130            self.sign(serverKeyExchange.signingPayload(self.clientHello.random,
131                                                       self.serverHello.random))
132        return serverKeyExchange
133
134    def processClientKeyExchange(self, clientKeyExchange):
135        dh_Yc = clientKeyExchange.dh_Yc
136
137        # First half of RFC 2631, Section 2.1.5. Validate the client's public
138        # key.
139        if not 2 <= dh_Yc <= self.dh_p - 1:
140            raise TLSLocalAlert(AlertDescription.illegal_parameter,
141                                "Invalid dh_Yc value")
142
143        S = powMod(dh_Yc, self.dh_Xs, self.dh_p)
144        return numberToByteArray(S)
145
146class ECDHE_RSAKeyExchange(KeyExchange):
147    def makeServerKeyExchange(self):
148        public, self.private = p256.generatePublicPrivate()
149
150        version = self.serverHello.server_version
151        serverKeyExchange = ServerKeyExchange(self.cipherSuite, version)
152        serverKeyExchange.createECDH(NamedCurve.secp256r1, bytearray(public))
153        serverKeyExchange.signature_algorithm, serverKeyExchange.signature = \
154            self.sign(serverKeyExchange.signingPayload(self.clientHello.random,
155                                                       self.serverHello.random))
156        return serverKeyExchange
157
158    def processClientKeyExchange(self, clientKeyExchange):
159        ecdh_Yc = clientKeyExchange.ecdh_Yc
160        return bytearray(p256.generateSharedValue(bytes(ecdh_Yc), self.private))
161
162class TLSConnection(TLSRecordLayer):
163    """
164    This class wraps a socket and provides TLS handshaking and data
165    transfer.
166
167    To use this class, create a new instance, passing a connected
168    socket into the constructor.  Then call some handshake function.
169    If the handshake completes without raising an exception, then a TLS
170    connection has been negotiated.  You can transfer data over this
171    connection as if it were a socket.
172
173    This class provides both synchronous and asynchronous versions of
174    its key functions.  The synchronous versions should be used when
175    writing single-or multi-threaded code using blocking sockets.  The
176    asynchronous versions should be used when performing asynchronous,
177    event-based I/O with non-blocking sockets.
178
179    Asynchronous I/O is a complicated subject; typically, you should
180    not use the asynchronous functions directly, but should use some
181    framework like asyncore or Twisted which TLS Lite integrates with
182    (see
183    L{tlslite.integration.tlsasyncdispatchermixin.TLSAsyncDispatcherMixIn}).
184    """
185
186    def __init__(self, sock):
187        """Create a new TLSConnection instance.
188
189        @param sock: The socket data will be transmitted on.  The
190        socket should already be connected.  It may be in blocking or
191        non-blocking mode.
192
193        @type sock: L{socket.socket}
194        """
195        TLSRecordLayer.__init__(self, sock)
196        self.clientRandom = b""
197        self.serverRandom = b""
198
199    #*********************************************************
200    # Client Handshake Functions
201    #*********************************************************
202
203    def handshakeClientAnonymous(self, session=None, settings=None,
204                                checker=None, serverName="",
205                                async=False):
206        """Perform an anonymous handshake in the role of client.
207
208        This function performs an SSL or TLS handshake using an
209        anonymous Diffie Hellman ciphersuite.
210
211        Like any handshake function, this can be called on a closed
212        TLS connection, or on a TLS connection that is already open.
213        If called on an open connection it performs a re-handshake.
214
215        If the function completes without raising an exception, the
216        TLS connection will be open and available for data transfer.
217
218        If an exception is raised, the connection will have been
219        automatically closed (if it was ever open).
220
221        @type session: L{tlslite.Session.Session}
222        @param session: A TLS session to attempt to resume.  If the
223        resumption does not succeed, a full handshake will be
224        performed.
225
226        @type settings: L{tlslite.HandshakeSettings.HandshakeSettings}
227        @param settings: Various settings which can be used to control
228        the ciphersuites, certificate types, and SSL/TLS versions
229        offered by the client.
230
231        @type checker: L{tlslite.Checker.Checker}
232        @param checker: A Checker instance.  This instance will be
233        invoked to examine the other party's authentication
234        credentials, if the handshake completes succesfully.
235
236        @type serverName: string
237        @param serverName: The ServerNameIndication TLS Extension.
238
239        @type async: bool
240        @param async: If False, this function will block until the
241        handshake is completed.  If True, this function will return a
242        generator.  Successive invocations of the generator will
243        return 0 if it is waiting to read from the socket, 1 if it is
244        waiting to write to the socket, or will raise StopIteration if
245        the handshake operation is completed.
246
247        @rtype: None or an iterable
248        @return: If 'async' is True, a generator object will be
249        returned.
250
251        @raise socket.error: If a socket error occurs.
252        @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
253        without a preceding alert.
254        @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
255        @raise tlslite.errors.TLSAuthenticationError: If the checker
256        doesn't like the other party's authentication credentials.
257        """
258        handshaker = self._handshakeClientAsync(anonParams=(True),
259                                                session=session,
260                                                settings=settings,
261                                                checker=checker,
262                                                serverName=serverName)
263        if async:
264            return handshaker
265        for result in handshaker:
266            pass
267
268    def handshakeClientSRP(self, username, password, session=None,
269                           settings=None, checker=None,
270                           reqTack=True, serverName="",
271                           async=False):
272        """Perform an SRP handshake in the role of client.
273
274        This function performs a TLS/SRP handshake.  SRP mutually
275        authenticates both parties to each other using only a
276        username and password.  This function may also perform a
277        combined SRP and server-certificate handshake, if the server
278        chooses to authenticate itself with a certificate chain in
279        addition to doing SRP.
280
281        If the function completes without raising an exception, the
282        TLS connection will be open and available for data transfer.
283
284        If an exception is raised, the connection will have been
285        automatically closed (if it was ever open).
286
287        @type username: str
288        @param username: The SRP username.
289
290        @type password: str
291        @param password: The SRP password.
292
293        @type session: L{tlslite.session.Session}
294        @param session: A TLS session to attempt to resume.  This
295        session must be an SRP session performed with the same username
296        and password as were passed in.  If the resumption does not
297        succeed, a full SRP handshake will be performed.
298
299        @type settings: L{tlslite.handshakesettings.HandshakeSettings}
300        @param settings: Various settings which can be used to control
301        the ciphersuites, certificate types, and SSL/TLS versions
302        offered by the client.
303
304        @type checker: L{tlslite.checker.Checker}
305        @param checker: A Checker instance.  This instance will be
306        invoked to examine the other party's authentication
307        credentials, if the handshake completes succesfully.
308
309        @type reqTack: bool
310        @param reqTack: Whether or not to send a "tack" TLS Extension,
311        requesting the server return a TackExtension if it has one.
312
313        @type serverName: string
314        @param serverName: The ServerNameIndication TLS Extension.
315
316        @type async: bool
317        @param async: If False, this function will block until the
318        handshake is completed.  If True, this function will return a
319        generator.  Successive invocations of the generator will
320        return 0 if it is waiting to read from the socket, 1 if it is
321        waiting to write to the socket, or will raise StopIteration if
322        the handshake operation is completed.
323
324        @rtype: None or an iterable
325        @return: If 'async' is True, a generator object will be
326        returned.
327
328        @raise socket.error: If a socket error occurs.
329        @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
330        without a preceding alert.
331        @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
332        @raise tlslite.errors.TLSAuthenticationError: If the checker
333        doesn't like the other party's authentication credentials.
334        """
335        handshaker = self._handshakeClientAsync(srpParams=(username, password),
336                        session=session, settings=settings, checker=checker,
337                        reqTack=reqTack, serverName=serverName)
338        # The handshaker is a Python Generator which executes the handshake.
339        # It allows the handshake to be run in a "piecewise", asynchronous
340        # fashion, returning 1 when it is waiting to able to write, 0 when
341        # it is waiting to read.
342        #
343        # If 'async' is True, the generator is returned to the caller,
344        # otherwise it is executed to completion here.
345        if async:
346            return handshaker
347        for result in handshaker:
348            pass
349
350    def handshakeClientCert(self, certChain=None, privateKey=None,
351                            session=None, settings=None, checker=None,
352                            nextProtos=None, reqTack=True, serverName="",
353                            async=False):
354        """Perform a certificate-based handshake in the role of client.
355
356        This function performs an SSL or TLS handshake.  The server
357        will authenticate itself using an X.509 certificate
358        chain.  If the handshake succeeds, the server's certificate
359        chain will be stored in the session's serverCertChain attribute.
360        Unless a checker object is passed in, this function does no
361        validation or checking of the server's certificate chain.
362
363        If the server requests client authentication, the
364        client will send the passed-in certificate chain, and use the
365        passed-in private key to authenticate itself.  If no
366        certificate chain and private key were passed in, the client
367        will attempt to proceed without client authentication.  The
368        server may or may not allow this.
369
370        If the function completes without raising an exception, the
371        TLS connection will be open and available for data transfer.
372
373        If an exception is raised, the connection will have been
374        automatically closed (if it was ever open).
375
376        @type certChain: L{tlslite.x509certchain.X509CertChain}
377        @param certChain: The certificate chain to be used if the
378        server requests client authentication.
379
380        @type privateKey: L{tlslite.utils.rsakey.RSAKey}
381        @param privateKey: The private key to be used if the server
382        requests client authentication.
383
384        @type session: L{tlslite.session.Session}
385        @param session: A TLS session to attempt to resume.  If the
386        resumption does not succeed, a full handshake will be
387        performed.
388
389        @type settings: L{tlslite.handshakesettings.HandshakeSettings}
390        @param settings: Various settings which can be used to control
391        the ciphersuites, certificate types, and SSL/TLS versions
392        offered by the client.
393
394        @type checker: L{tlslite.checker.Checker}
395        @param checker: A Checker instance.  This instance will be
396        invoked to examine the other party's authentication
397        credentials, if the handshake completes succesfully.
398
399        @type nextProtos: list of strings.
400        @param nextProtos: A list of upper layer protocols ordered by
401        preference, to use in the Next-Protocol Negotiation Extension.
402
403        @type reqTack: bool
404        @param reqTack: Whether or not to send a "tack" TLS Extension,
405        requesting the server return a TackExtension if it has one.
406
407        @type serverName: string
408        @param serverName: The ServerNameIndication TLS Extension.
409
410        @type async: bool
411        @param async: If False, this function will block until the
412        handshake is completed.  If True, this function will return a
413        generator.  Successive invocations of the generator will
414        return 0 if it is waiting to read from the socket, 1 if it is
415        waiting to write to the socket, or will raise StopIteration if
416        the handshake operation is completed.
417
418        @rtype: None or an iterable
419        @return: If 'async' is True, a generator object will be
420        returned.
421
422        @raise socket.error: If a socket error occurs.
423        @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
424        without a preceding alert.
425        @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
426        @raise tlslite.errors.TLSAuthenticationError: If the checker
427        doesn't like the other party's authentication credentials.
428        """
429        handshaker = self._handshakeClientAsync(certParams=(certChain,
430                        privateKey), session=session, settings=settings,
431                        checker=checker, serverName=serverName,
432                        nextProtos=nextProtos, reqTack=reqTack)
433        # The handshaker is a Python Generator which executes the handshake.
434        # It allows the handshake to be run in a "piecewise", asynchronous
435        # fashion, returning 1 when it is waiting to able to write, 0 when
436        # it is waiting to read.
437        #
438        # If 'async' is True, the generator is returned to the caller,
439        # otherwise it is executed to completion here.
440        if async:
441            return handshaker
442        for result in handshaker:
443            pass
444
445
446    def _handshakeClientAsync(self, srpParams=(), certParams=(), anonParams=(),
447                             session=None, settings=None, checker=None,
448                             nextProtos=None, serverName="", reqTack=True):
449
450        handshaker = self._handshakeClientAsyncHelper(srpParams=srpParams,
451                certParams=certParams,
452                anonParams=anonParams,
453                session=session,
454                settings=settings,
455                serverName=serverName,
456                nextProtos=nextProtos,
457                reqTack=reqTack)
458        for result in self._handshakeWrapperAsync(handshaker, checker):
459            yield result
460
461
462    def _handshakeClientAsyncHelper(self, srpParams, certParams, anonParams,
463                               session, settings, serverName, nextProtos, reqTack):
464
465        self._handshakeStart(client=True)
466
467        #Unpack parameters
468        srpUsername = None      # srpParams[0]
469        password = None         # srpParams[1]
470        clientCertChain = None  # certParams[0]
471        privateKey = None       # certParams[1]
472
473        # Allow only one of (srpParams, certParams, anonParams)
474        if srpParams:
475            assert(not certParams)
476            assert(not anonParams)
477            srpUsername, password = srpParams
478        if certParams:
479            assert(not srpParams)
480            assert(not anonParams)
481            clientCertChain, privateKey = certParams
482        if anonParams:
483            assert(not srpParams)
484            assert(not certParams)
485
486        #Validate parameters
487        if srpUsername and not password:
488            raise ValueError("Caller passed a username but no password")
489        if password and not srpUsername:
490            raise ValueError("Caller passed a password but no username")
491        if clientCertChain and not privateKey:
492            raise ValueError("Caller passed a certChain but no privateKey")
493        if privateKey and not clientCertChain:
494            raise ValueError("Caller passed a privateKey but no certChain")
495        if reqTack:
496            if not tackpyLoaded:
497                reqTack = False
498            if not settings or not settings.useExperimentalTackExtension:
499                reqTack = False
500        if nextProtos is not None:
501            if len(nextProtos) == 0:
502                raise ValueError("Caller passed no nextProtos")
503
504        # Validates the settings and filters out any unsupported ciphers
505        # or crypto libraries that were requested
506        if not settings:
507            settings = HandshakeSettings()
508        settings = settings._filter()
509
510        if settings.alpnProtos is not None:
511            if len(settings.alpnProtos) == 0:
512                raise ValueError("Caller passed no alpnProtos")
513
514        if clientCertChain:
515            if not isinstance(clientCertChain, X509CertChain):
516                raise ValueError("Unrecognized certificate type")
517            if "x509" not in settings.certificateTypes:
518                raise ValueError("Client certificate doesn't match "\
519                                 "Handshake Settings")
520
521        if session:
522            # session.valid() ensures session is resumable and has
523            # non-empty sessionID
524            if not session.valid():
525                session = None #ignore non-resumable sessions...
526            elif session.resumable:
527                if session.srpUsername != srpUsername:
528                    raise ValueError("Session username doesn't match")
529                if session.serverName != serverName:
530                    raise ValueError("Session servername doesn't match")
531
532        #Add Faults to parameters
533        if srpUsername and self.fault == Fault.badUsername:
534            srpUsername += "GARBAGE"
535        if password and self.fault == Fault.badPassword:
536            password += "GARBAGE"
537
538        #Tentatively set the version to the client's minimum version.
539        #We'll use this for the ClientHello, and if an error occurs
540        #parsing the Server Hello, we'll use this version for the response
541        self.version = settings.maxVersion
542
543        # OK Start sending messages!
544        # *****************************
545
546        # Send the ClientHello.
547        for result in self._clientSendClientHello(settings, session,
548                                        srpUsername, srpParams, certParams,
549                                        anonParams, serverName, nextProtos,
550                                        reqTack):
551            if result in (0,1): yield result
552            else: break
553        clientHello = result
554
555        #Get the ServerHello.
556        for result in self._clientGetServerHello(settings, clientHello):
557            if result in (0,1): yield result
558            else: break
559        serverHello = result
560        cipherSuite = serverHello.cipher_suite
561
562        # Choose a matching Next Protocol from server list against ours
563        # (string or None)
564        nextProto = self._clientSelectNextProto(nextProtos, serverHello)
565
566        #If the server elected to resume the session, it is handled here.
567        for result in self._clientResume(session, serverHello,
568                        clientHello.random,
569                        settings.cipherImplementations,
570                        nextProto):
571            if result in (0,1): yield result
572            else: break
573        if result == "resumed_and_finished":
574            self._handshakeDone(resumed=True)
575            return
576
577        #If the server selected an SRP ciphersuite, the client finishes
578        #reading the post-ServerHello messages, then derives a
579        #premasterSecret and sends a corresponding ClientKeyExchange.
580        if cipherSuite in CipherSuite.srpAllSuites:
581            for result in self._clientSRPKeyExchange(\
582                    settings, cipherSuite, serverHello.certificate_type,
583                    srpUsername, password,
584                    clientHello.random, serverHello.random,
585                    serverHello.tackExt):
586                if result in (0,1): yield result
587                else: break
588            (premasterSecret, serverCertChain, tackExt) = result
589
590        #If the server selected an anonymous ciphersuite, the client
591        #finishes reading the post-ServerHello messages.
592        elif cipherSuite in CipherSuite.anonSuites:
593            for result in self._clientAnonKeyExchange(settings, cipherSuite,
594                                    clientHello.random, serverHello.random):
595                if result in (0,1): yield result
596                else: break
597            (premasterSecret, serverCertChain, tackExt) = result
598
599        #If the server selected a certificate-based RSA ciphersuite,
600        #the client finishes reading the post-ServerHello messages. If
601        #a CertificateRequest message was sent, the client responds with
602        #a Certificate message containing its certificate chain (if any),
603        #and also produces a CertificateVerify message that signs the
604        #ClientKeyExchange.
605        else:
606            for result in self._clientRSAKeyExchange(settings, cipherSuite,
607                                    clientCertChain, privateKey,
608                                    serverHello.certificate_type,
609                                    clientHello.random, serverHello.random,
610                                    serverHello.tackExt):
611                if result in (0,1): yield result
612                else: break
613            (premasterSecret, serverCertChain, clientCertChain,
614             tackExt) = result
615
616        #After having previously sent a ClientKeyExchange, the client now
617        #initiates an exchange of Finished messages.
618        for result in self._clientFinished(premasterSecret,
619                            clientHello.random,
620                            serverHello.random,
621                            cipherSuite, settings.cipherImplementations,
622                            nextProto):
623                if result in (0,1): yield result
624                else: break
625        masterSecret = result
626
627        self.clientRandom = clientHello.random
628        self.serverRandom = serverHello.random
629
630        # Create the session object which is used for resumptions
631        self.session = Session()
632        self.session.create(masterSecret, serverHello.session_id, cipherSuite,
633            srpUsername, clientCertChain, serverCertChain,
634            tackExt, serverHello.tackExt!=None, serverName)
635        self._handshakeDone(resumed=False)
636
637
638    def _clientSendClientHello(self, settings, session, srpUsername,
639                                srpParams, certParams, anonParams,
640                                serverName, nextProtos, reqTack):
641        #Initialize acceptable ciphersuites
642        cipherSuites = [CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
643        if srpParams:
644            cipherSuites += CipherSuite.getSrpAllSuites(settings)
645        elif certParams:
646            # TODO: Client DHE_RSA not supported.
647            # cipherSuites += CipherSuite.getDheCertSuites(settings)
648            cipherSuites += CipherSuite.getCertSuites(settings)
649        elif anonParams:
650            cipherSuites += CipherSuite.getAnonSuites(settings)
651        else:
652            assert(False)
653
654        #Initialize acceptable certificate types
655        certificateTypes = settings._getCertificateTypes()
656
657        #Either send ClientHello (with a resumable session)...
658        if session and session.sessionID:
659            #If it's resumable, then its
660            #ciphersuite must be one of the acceptable ciphersuites
661            if session.cipherSuite not in cipherSuites:
662                raise ValueError("Session's cipher suite not consistent "\
663                                 "with parameters")
664            else:
665                clientHello = ClientHello()
666                clientHello.create(settings.maxVersion, getRandomBytes(32),
667                                   session.sessionID, cipherSuites,
668                                   certificateTypes,
669                                   session.srpUsername,
670                                   reqTack, settings.alpnProtos,
671                                   nextProtos is not None,
672                                   session.serverName)
673
674        #Or send ClientHello (without)
675        else:
676            clientHello = ClientHello()
677            clientHello.create(settings.maxVersion, getRandomBytes(32),
678                               bytearray(0), cipherSuites,
679                               certificateTypes,
680                               srpUsername,
681                               reqTack, settings.alpnProtos,
682                               nextProtos is not None,
683                               serverName)
684        for result in self._sendMsg(clientHello):
685            yield result
686        yield clientHello
687
688
689    def _clientGetServerHello(self, settings, clientHello):
690        for result in self._getMsg(ContentType.handshake,
691                                  HandshakeType.server_hello):
692            if result in (0,1): yield result
693            else: break
694        serverHello = result
695
696        #Get the server version.  Do this before anything else, so any
697        #error alerts will use the server's version
698        self.version = serverHello.server_version
699
700        #Future responses from server must use this version
701        self._versionCheck = True
702
703        #Check ServerHello
704        if serverHello.server_version < settings.minVersion:
705            for result in self._sendError(\
706                AlertDescription.protocol_version,
707                "Too old version: %s" % str(serverHello.server_version)):
708                yield result
709        if serverHello.server_version > settings.maxVersion:
710            for result in self._sendError(\
711                AlertDescription.protocol_version,
712                "Too new version: %s" % str(serverHello.server_version)):
713                yield result
714        if serverHello.cipher_suite not in clientHello.cipher_suites:
715            for result in self._sendError(\
716                AlertDescription.illegal_parameter,
717                "Server responded with incorrect ciphersuite"):
718                yield result
719        if serverHello.certificate_type not in clientHello.certificate_types:
720            for result in self._sendError(\
721                AlertDescription.illegal_parameter,
722                "Server responded with incorrect certificate type"):
723                yield result
724        if serverHello.compression_method != 0:
725            for result in self._sendError(\
726                AlertDescription.illegal_parameter,
727                "Server responded with incorrect compression method"):
728                yield result
729        if serverHello.tackExt:
730            if not clientHello.tack:
731                for result in self._sendError(\
732                    AlertDescription.illegal_parameter,
733                    "Server responded with unrequested Tack Extension"):
734                    yield result
735        if serverHello.alpn_proto_selected and not clientHello.alpn_protos_advertised:
736            for result in self._sendError(\
737                AlertDescription.illegal_parameter,
738                "Server responded with unrequested ALPN Extension"):
739                yield result
740        if serverHello.alpn_proto_selected and serverHello.next_protos:
741            for result in self._sendError(\
742                AlertDescription.illegal_parameter,
743                "Server responded with both ALPN and NPN extension"):
744                yield result
745        if serverHello.next_protos and not clientHello.supports_npn:
746            for result in self._sendError(\
747                AlertDescription.illegal_parameter,
748                "Server responded with unrequested NPN Extension"):
749                yield result
750            if not serverHello.tackExt.verifySignatures():
751                for result in self._sendError(\
752                    AlertDescription.decrypt_error,
753                    "TackExtension contains an invalid signature"):
754                    yield result
755        yield serverHello
756
757    def _clientSelectNextProto(self, nextProtos, serverHello):
758        # nextProtos is None or non-empty list of strings
759        # serverHello.next_protos is None or possibly-empty list of strings
760        #
761        # !!! We assume the client may have specified nextProtos as a list of
762        # strings so we convert them to bytearrays (it's awkward to require
763        # the user to specify a list of bytearrays or "bytes", and in
764        # Python 2.6 bytes() is just an alias for str() anyways...
765        if nextProtos is not None and serverHello.next_protos is not None:
766            for p in nextProtos:
767                if bytearray(p) in serverHello.next_protos:
768                    return bytearray(p)
769            else:
770                # If the client doesn't support any of server's protocols,
771                # or the server doesn't advertise any (next_protos == [])
772                # the client SHOULD select the first protocol it supports.
773                return bytearray(nextProtos[0])
774        return None
775
776    def _clientResume(self, session, serverHello, clientRandom,
777                      cipherImplementations, nextProto):
778        #If the server agrees to resume
779        if session and session.sessionID and \
780            serverHello.session_id == session.sessionID:
781
782            if serverHello.cipher_suite != session.cipherSuite:
783                for result in self._sendError(\
784                    AlertDescription.illegal_parameter,\
785                    "Server's ciphersuite doesn't match session"):
786                    yield result
787
788            #Calculate pending connection states
789            self._calcPendingStates(session.cipherSuite,
790                                    session.masterSecret,
791                                    clientRandom, serverHello.random,
792                                    cipherImplementations)
793
794            #Exchange ChangeCipherSpec and Finished messages
795            for result in self._getFinished(session.masterSecret):
796                yield result
797            for result in self._sendFinished(session.masterSecret, nextProto):
798                yield result
799
800            #Set the session for this connection
801            self.session = session
802            yield "resumed_and_finished"
803
804    def _clientSRPKeyExchange(self, settings, cipherSuite, certificateType,
805            srpUsername, password,
806            clientRandom, serverRandom, tackExt):
807
808        #If the server chose an SRP+RSA suite...
809        if cipherSuite in CipherSuite.srpCertSuites:
810            #Get Certificate, ServerKeyExchange, ServerHelloDone
811            for result in self._getMsg(ContentType.handshake,
812                    HandshakeType.certificate, certificateType):
813                if result in (0,1): yield result
814                else: break
815            serverCertificate = result
816        else:
817            serverCertificate = None
818
819        for result in self._getMsg(ContentType.handshake,
820                HandshakeType.server_key_exchange, cipherSuite):
821            if result in (0,1): yield result
822            else: break
823        serverKeyExchange = result
824
825        for result in self._getMsg(ContentType.handshake,
826                HandshakeType.server_hello_done):
827            if result in (0,1): yield result
828            else: break
829        serverHelloDone = result
830
831        #Calculate SRP premaster secret
832        #Get and check the server's group parameters and B value
833        N = serverKeyExchange.srp_N
834        g = serverKeyExchange.srp_g
835        s = serverKeyExchange.srp_s
836        B = serverKeyExchange.srp_B
837
838        if (g,N) not in goodGroupParameters:
839            for result in self._sendError(\
840                    AlertDescription.insufficient_security,
841                    "Unknown group parameters"):
842                yield result
843        if numBits(N) < settings.minKeySize:
844            for result in self._sendError(\
845                    AlertDescription.insufficient_security,
846                    "N value is too small: %d" % numBits(N)):
847                yield result
848        if numBits(N) > settings.maxKeySize:
849            for result in self._sendError(\
850                    AlertDescription.insufficient_security,
851                    "N value is too large: %d" % numBits(N)):
852                yield result
853        if B % N == 0:
854            for result in self._sendError(\
855                    AlertDescription.illegal_parameter,
856                    "Suspicious B value"):
857                yield result
858
859        #Check the server's signature, if server chose an
860        #SRP+RSA suite
861        serverCertChain = None
862        if cipherSuite in CipherSuite.srpCertSuites:
863            #Hash ServerKeyExchange/ServerSRPParams
864            hashBytes = serverKeyExchange.hash(clientRandom, serverRandom)
865
866            #Extract signature bytes from ServerKeyExchange
867            sigBytes = serverKeyExchange.signature
868            if len(sigBytes) == 0:
869                for result in self._sendError(\
870                        AlertDescription.illegal_parameter,
871                        "Server sent an SRP ServerKeyExchange "\
872                        "message without a signature"):
873                    yield result
874
875            # Get server's public key from the Certificate message
876            # Also validate the chain against the ServerHello's TACKext (if any)
877            # If none, and a TACK cert is present, return its TACKext
878            for result in self._clientGetKeyFromChain(serverCertificate,
879                                               settings, tackExt):
880                if result in (0,1): yield result
881                else: break
882            publicKey, serverCertChain, tackExt = result
883
884            #Verify signature
885            if not publicKey.verify(sigBytes, hashBytes):
886                for result in self._sendError(\
887                        AlertDescription.decrypt_error,
888                        "Signature failed to verify"):
889                    yield result
890
891        #Calculate client's ephemeral DH values (a, A)
892        a = bytesToNumber(getRandomBytes(32))
893        A = powMod(g, a, N)
894
895        #Calculate client's static DH values (x, v)
896        x = makeX(s, bytearray(srpUsername, "utf-8"),
897                    bytearray(password, "utf-8"))
898        v = powMod(g, x, N)
899
900        #Calculate u
901        u = makeU(N, A, B)
902
903        #Calculate premaster secret
904        k = makeK(N, g)
905        S = powMod((B - (k*v)) % N, a+(u*x), N)
906
907        if self.fault == Fault.badA:
908            A = N
909            S = 0
910
911        premasterSecret = numberToByteArray(S)
912
913        #Send ClientKeyExchange
914        for result in self._sendMsg(\
915                ClientKeyExchange(cipherSuite).createSRP(A)):
916            yield result
917        yield (premasterSecret, serverCertChain, tackExt)
918
919
920    def _clientRSAKeyExchange(self, settings, cipherSuite,
921                                clientCertChain, privateKey,
922                                certificateType,
923                                clientRandom, serverRandom,
924                                tackExt):
925
926        #Get Certificate[, CertificateRequest], ServerHelloDone
927        for result in self._getMsg(ContentType.handshake,
928                HandshakeType.certificate, certificateType):
929            if result in (0,1): yield result
930            else: break
931        serverCertificate = result
932
933        # Get CertificateRequest or ServerHelloDone
934        for result in self._getMsg(ContentType.handshake,
935                (HandshakeType.server_hello_done,
936                HandshakeType.certificate_request)):
937            if result in (0,1): yield result
938            else: break
939        msg = result
940        certificateRequest = None
941        if isinstance(msg, CertificateRequest):
942            certificateRequest = msg
943            # We got CertificateRequest, so this must be ServerHelloDone
944            for result in self._getMsg(ContentType.handshake,
945                    HandshakeType.server_hello_done):
946                if result in (0,1): yield result
947                else: break
948            serverHelloDone = result
949        elif isinstance(msg, ServerHelloDone):
950            serverHelloDone = msg
951
952        # Get server's public key from the Certificate message
953        # Also validate the chain against the ServerHello's TACKext (if any)
954        # If none, and a TACK cert is present, return its TACKext
955        for result in self._clientGetKeyFromChain(serverCertificate,
956                                           settings, tackExt):
957            if result in (0,1): yield result
958            else: break
959        publicKey, serverCertChain, tackExt = result
960
961        #Calculate premaster secret
962        premasterSecret = getRandomBytes(48)
963        premasterSecret[0] = settings.maxVersion[0]
964        premasterSecret[1] = settings.maxVersion[1]
965
966        if self.fault == Fault.badPremasterPadding:
967            premasterSecret[0] = 5
968        if self.fault == Fault.shortPremasterSecret:
969            premasterSecret = premasterSecret[:-1]
970
971        #Encrypt premaster secret to server's public key
972        encryptedPreMasterSecret = publicKey.encrypt(premasterSecret)
973
974        #If client authentication was requested, send Certificate
975        #message, either with certificates or empty
976        if certificateRequest:
977            clientCertificate = Certificate(certificateType)
978
979            if clientCertChain:
980                #Check to make sure we have the same type of
981                #certificates the server requested
982                wrongType = False
983                if certificateType == CertificateType.x509:
984                    if not isinstance(clientCertChain, X509CertChain):
985                        wrongType = True
986                if wrongType:
987                    for result in self._sendError(\
988                            AlertDescription.handshake_failure,
989                            "Client certificate is of wrong type"):
990                        yield result
991
992                clientCertificate.create(clientCertChain)
993            for result in self._sendMsg(clientCertificate):
994                yield result
995        else:
996            #The server didn't request client auth, so we
997            #zeroize these so the clientCertChain won't be
998            #stored in the session.
999            privateKey = None
1000            clientCertChain = None
1001
1002        #Send ClientKeyExchange
1003        clientKeyExchange = ClientKeyExchange(cipherSuite,
1004                                              self.version)
1005        clientKeyExchange.createRSA(encryptedPreMasterSecret)
1006        for result in self._sendMsg(clientKeyExchange):
1007            yield result
1008
1009        #If client authentication was requested and we have a
1010        #private key, send CertificateVerify
1011        if certificateRequest and privateKey:
1012            signatureAlgorithm = None
1013            if self.version == (3,0):
1014                masterSecret = calcMasterSecret(self.version,
1015                                         premasterSecret,
1016                                         clientRandom,
1017                                         serverRandom,
1018                                         b"", False)
1019                verifyBytes = self._calcSSLHandshakeHash(masterSecret, b"")
1020            elif self.version in ((3,1), (3,2)):
1021                verifyBytes = self._handshake_md5.digest() + \
1022                                self._handshake_sha.digest()
1023            elif self.version == (3,3):
1024                # TODO: Signature algorithm negotiation not supported.
1025                signatureAlgorithm = (HashAlgorithm.sha1, SignatureAlgorithm.rsa)
1026                verifyBytes = self._handshake_sha.digest()
1027                verifyBytes = RSAKey.addPKCS1SHA1Prefix(verifyBytes)
1028            if self.fault == Fault.badVerifyMessage:
1029                verifyBytes[0] = ((verifyBytes[0]+1) % 256)
1030            signedBytes = privateKey.sign(verifyBytes)
1031            certificateVerify = CertificateVerify(self.version)
1032            certificateVerify.create(signatureAlgorithm, signedBytes)
1033            for result in self._sendMsg(certificateVerify):
1034                yield result
1035        yield (premasterSecret, serverCertChain, clientCertChain, tackExt)
1036
1037    def _clientAnonKeyExchange(self, settings, cipherSuite, clientRandom,
1038                               serverRandom):
1039        for result in self._getMsg(ContentType.handshake,
1040                HandshakeType.server_key_exchange, cipherSuite):
1041            if result in (0,1): yield result
1042            else: break
1043        serverKeyExchange = result
1044
1045        for result in self._getMsg(ContentType.handshake,
1046                HandshakeType.server_hello_done):
1047            if result in (0,1): yield result
1048            else: break
1049        serverHelloDone = result
1050
1051        #calculate Yc
1052        dh_p = serverKeyExchange.dh_p
1053        dh_g = serverKeyExchange.dh_g
1054        dh_Xc = bytesToNumber(getRandomBytes(32))
1055        dh_Ys = serverKeyExchange.dh_Ys
1056        dh_Yc = powMod(dh_g, dh_Xc, dh_p)
1057
1058        #Send ClientKeyExchange
1059        for result in self._sendMsg(\
1060                ClientKeyExchange(cipherSuite, self.version).createDH(dh_Yc)):
1061            yield result
1062
1063        #Calculate premaster secret
1064        S = powMod(dh_Ys, dh_Xc, dh_p)
1065        premasterSecret = numberToByteArray(S)
1066
1067        yield (premasterSecret, None, None)
1068
1069    def _clientFinished(self, premasterSecret, clientRandom, serverRandom,
1070                        cipherSuite, cipherImplementations, nextProto):
1071
1072        masterSecret = calcMasterSecret(self.version, premasterSecret,
1073                            clientRandom, serverRandom, b"", False)
1074        self._calcPendingStates(cipherSuite, masterSecret,
1075                                clientRandom, serverRandom,
1076                                cipherImplementations)
1077
1078        #Exchange ChangeCipherSpec and Finished messages
1079        for result in self._sendFinished(masterSecret, nextProto):
1080            yield result
1081        for result in self._getFinished(masterSecret, nextProto=nextProto):
1082            yield result
1083        yield masterSecret
1084
1085    def _clientGetKeyFromChain(self, certificate, settings, tackExt=None):
1086        #Get and check cert chain from the Certificate message
1087        certChain = certificate.certChain
1088        if not certChain or certChain.getNumCerts() == 0:
1089            for result in self._sendError(AlertDescription.illegal_parameter,
1090                    "Other party sent a Certificate message without "\
1091                    "certificates"):
1092                yield result
1093
1094        #Get and check public key from the cert chain
1095        publicKey = certChain.getEndEntityPublicKey()
1096        if len(publicKey) < settings.minKeySize:
1097            for result in self._sendError(AlertDescription.handshake_failure,
1098                    "Other party's public key too small: %d" % len(publicKey)):
1099                yield result
1100        if len(publicKey) > settings.maxKeySize:
1101            for result in self._sendError(AlertDescription.handshake_failure,
1102                    "Other party's public key too large: %d" % len(publicKey)):
1103                yield result
1104
1105        # If there's no TLS Extension, look for a TACK cert
1106        if tackpyLoaded:
1107            if not tackExt:
1108                tackExt = certChain.getTackExt()
1109
1110            # If there's a TACK (whether via TLS or TACK Cert), check that it
1111            # matches the cert chain
1112            if tackExt and tackExt.tacks:
1113                for tack in tackExt.tacks:
1114                    if not certChain.checkTack(tack):
1115                        for result in self._sendError(
1116                                AlertDescription.illegal_parameter,
1117                                "Other party's TACK doesn't match their public key"):
1118                                yield result
1119
1120        yield publicKey, certChain, tackExt
1121
1122
1123    #*********************************************************
1124    # Server Handshake Functions
1125    #*********************************************************
1126
1127
1128    def handshakeServer(self, verifierDB=None,
1129                        certChain=None, privateKey=None, reqCert=False,
1130                        sessionCache=None, settings=None, checker=None,
1131                        reqCAs = None, reqCertTypes = None,
1132                        tacks=None, activationFlags=0,
1133                        nextProtos=None, anon=False,
1134                        signedCertTimestamps=None,
1135                        fallbackSCSV=False, ocspResponse=None):
1136        """Perform a handshake in the role of server.
1137
1138        This function performs an SSL or TLS handshake.  Depending on
1139        the arguments and the behavior of the client, this function can
1140        perform an SRP, or certificate-based handshake.  It
1141        can also perform a combined SRP and server-certificate
1142        handshake.
1143
1144        Like any handshake function, this can be called on a closed
1145        TLS connection, or on a TLS connection that is already open.
1146        If called on an open connection it performs a re-handshake.
1147        This function does not send a Hello Request message before
1148        performing the handshake, so if re-handshaking is required,
1149        the server must signal the client to begin the re-handshake
1150        through some other means.
1151
1152        If the function completes without raising an exception, the
1153        TLS connection will be open and available for data transfer.
1154
1155        If an exception is raised, the connection will have been
1156        automatically closed (if it was ever open).
1157
1158        @type verifierDB: L{tlslite.verifierdb.VerifierDB}
1159        @param verifierDB: A database of SRP password verifiers
1160        associated with usernames.  If the client performs an SRP
1161        handshake, the session's srpUsername attribute will be set.
1162
1163        @type certChain: L{tlslite.x509certchain.X509CertChain}
1164        @param certChain: The certificate chain to be used if the
1165        client requests server certificate authentication.
1166
1167        @type privateKey: L{tlslite.utils.rsakey.RSAKey}
1168        @param privateKey: The private key to be used if the client
1169        requests server certificate authentication.
1170
1171        @type reqCert: bool
1172        @param reqCert: Whether to request client certificate
1173        authentication.  This only applies if the client chooses server
1174        certificate authentication; if the client chooses SRP
1175        authentication, this will be ignored.  If the client
1176        performs a client certificate authentication, the sessions's
1177        clientCertChain attribute will be set.
1178
1179        @type sessionCache: L{tlslite.sessioncache.SessionCache}
1180        @param sessionCache: An in-memory cache of resumable sessions.
1181        The client can resume sessions from this cache.  Alternatively,
1182        if the client performs a full handshake, a new session will be
1183        added to the cache.
1184
1185        @type settings: L{tlslite.handshakesettings.HandshakeSettings}
1186        @param settings: Various settings which can be used to control
1187        the ciphersuites and SSL/TLS version chosen by the server.
1188
1189        @type checker: L{tlslite.checker.Checker}
1190        @param checker: A Checker instance.  This instance will be
1191        invoked to examine the other party's authentication
1192        credentials, if the handshake completes succesfully.
1193
1194        @type reqCAs: list of L{bytearray} of unsigned bytes
1195        @param reqCAs: A collection of DER-encoded DistinguishedNames that
1196        will be sent along with a certificate request. This does not affect
1197        verification.
1198
1199        @type reqCertTypes: list of int
1200        @param reqCertTypes: A list of certificate_type values to be sent
1201        along with a certificate request. This does not affect verification.
1202
1203        @type nextProtos: list of strings.
1204        @param nextProtos: A list of upper layer protocols to expose to the
1205        clients through the Next-Protocol Negotiation Extension,
1206        if they support it.
1207
1208        @type signedCertTimestamps: str
1209        @param signedCertTimestamps: A SignedCertificateTimestampList (as a
1210        binary 8-bit string) that will be sent as a TLS extension whenever
1211        the client announces support for the extension.
1212
1213        @type fallbackSCSV: bool
1214        @param fallbackSCSV: if true, the server will implement
1215        TLS_FALLBACK_SCSV and thus reject connections using less than the
1216        server's maximum TLS version that include this cipher suite.
1217
1218        @type ocspResponse: str
1219        @param ocspResponse: An OCSP response (as a binary 8-bit string) that
1220        will be sent stapled in the handshake whenever the client announces
1221        support for the status_request extension.
1222        Note that the response is sent independent of the ClientHello
1223        status_request extension contents, and is thus only meant for testing
1224        environments. Real OCSP stapling is more complicated as it requires
1225        choosing a suitable response based on the ClientHello status_request
1226        extension contents.
1227
1228        @raise socket.error: If a socket error occurs.
1229        @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
1230        without a preceding alert.
1231        @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
1232        @raise tlslite.errors.TLSAuthenticationError: If the checker
1233        doesn't like the other party's authentication credentials.
1234        """
1235        for result in self.handshakeServerAsync(verifierDB,
1236                certChain, privateKey, reqCert, sessionCache, settings,
1237                checker, reqCAs, reqCertTypes,
1238                tacks=tacks, activationFlags=activationFlags,
1239                nextProtos=nextProtos, anon=anon,
1240                signedCertTimestamps=signedCertTimestamps,
1241                fallbackSCSV=fallbackSCSV, ocspResponse=ocspResponse):
1242            pass
1243
1244
1245    def handshakeServerAsync(self, verifierDB=None,
1246                             certChain=None, privateKey=None, reqCert=False,
1247                             sessionCache=None, settings=None, checker=None,
1248                             reqCAs=None, reqCertTypes=None,
1249                             tacks=None, activationFlags=0,
1250                             nextProtos=None, anon=False,
1251                             signedCertTimestamps=None,
1252                             fallbackSCSV=False,
1253                             ocspResponse=None
1254                             ):
1255        """Start a server handshake operation on the TLS connection.
1256
1257        This function returns a generator which behaves similarly to
1258        handshakeServer().  Successive invocations of the generator
1259        will return 0 if it is waiting to read from the socket, 1 if it is
1260        waiting to write to the socket, or it will raise StopIteration
1261        if the handshake operation is complete.
1262
1263        @rtype: iterable
1264        @return: A generator; see above for details.
1265        """
1266        handshaker = self._handshakeServerAsyncHelper(\
1267            verifierDB=verifierDB, certChain=certChain,
1268            privateKey=privateKey, reqCert=reqCert,
1269            sessionCache=sessionCache, settings=settings,
1270            reqCAs=reqCAs, reqCertTypes=reqCertTypes,
1271            tacks=tacks, activationFlags=activationFlags,
1272            nextProtos=nextProtos, anon=anon,
1273            signedCertTimestamps=signedCertTimestamps,
1274            fallbackSCSV=fallbackSCSV,
1275            ocspResponse=ocspResponse)
1276        for result in self._handshakeWrapperAsync(handshaker, checker):
1277            yield result
1278        if settings and settings.alertAfterHandshake:
1279            for result in self._sendError(AlertDescription.internal_error,
1280                                          "Spurious alert"):
1281                yield result
1282
1283
1284    def _handshakeServerAsyncHelper(self, verifierDB,
1285                             certChain, privateKey, reqCert, sessionCache,
1286                             settings, reqCAs, reqCertTypes,
1287                             tacks, activationFlags,
1288                             nextProtos, anon,
1289                             signedCertTimestamps, fallbackSCSV,
1290                             ocspResponse):
1291
1292        self._handshakeStart(client=False)
1293
1294        if (not verifierDB) and (not certChain) and not anon:
1295            raise ValueError("Caller passed no authentication credentials")
1296        if certChain and not privateKey:
1297            raise ValueError("Caller passed a certChain but no privateKey")
1298        if privateKey and not certChain:
1299            raise ValueError("Caller passed a privateKey but no certChain")
1300        if reqCAs and not reqCert:
1301            raise ValueError("Caller passed reqCAs but not reqCert")
1302        if reqCertTypes and not reqCert:
1303            raise ValueError("Caller passed reqCertTypes but not reqCert")
1304        if certChain and not isinstance(certChain, X509CertChain):
1305            raise ValueError("Unrecognized certificate type")
1306        if activationFlags and not tacks:
1307            raise ValueError("Nonzero activationFlags requires tacks")
1308        if tacks:
1309            if not tackpyLoaded:
1310                raise ValueError("tackpy is not loaded")
1311            if not settings or not settings.useExperimentalTackExtension:
1312                raise ValueError("useExperimentalTackExtension not enabled")
1313        if signedCertTimestamps and not certChain:
1314            raise ValueError("Caller passed signedCertTimestamps but no "
1315                             "certChain")
1316
1317        if not settings:
1318            settings = HandshakeSettings()
1319        settings = settings._filter()
1320
1321        # OK Start exchanging messages
1322        # ******************************
1323
1324        # Handle ClientHello and resumption
1325        for result in self._serverGetClientHello(settings, certChain,\
1326                                            verifierDB, sessionCache,
1327                                            anon, fallbackSCSV):
1328            if result in (0,1): yield result
1329            elif result == None:
1330                self._handshakeDone(resumed=True)
1331                return # Handshake was resumed, we're done
1332            else: break
1333        (clientHello, cipherSuite) = result
1334
1335        # Save the ClientHello for external code to query.
1336        self.clientHello = clientHello
1337
1338        #If not a resumption...
1339
1340        # Create the ServerHello message
1341        if sessionCache:
1342            sessionID = getRandomBytes(32)
1343        else:
1344            sessionID = bytearray(0)
1345
1346        alpn_proto_selected = None
1347        if (clientHello.alpn_protos_advertised is not None
1348                and settings.alpnProtos is not None):
1349            for proto in settings.alpnProtos:
1350                if proto in clientHello.alpn_protos_advertised:
1351                    alpn_proto_selected = proto
1352                    nextProtos = None
1353                    break;
1354
1355        if not clientHello.supports_npn:
1356            nextProtos = None
1357
1358        # If not doing a certificate-based suite, discard the TACK
1359        if not cipherSuite in CipherSuite.certAllSuites:
1360            tacks = None
1361
1362        # Prepare a TACK Extension if requested
1363        if clientHello.tack:
1364            tackExt = TackExtension.create(tacks, activationFlags)
1365        else:
1366            tackExt = None
1367        serverRandom = getRandomBytes(32)
1368        # See https://tools.ietf.org/html/rfc8446#section-4.1.3
1369        if settings.simulateTLS13Downgrade:
1370            serverRandom = serverRandom[:24] + \
1371                bytearray("\x44\x4f\x57\x4e\x47\x52\x44\x01")
1372        elif settings.simulateTLS12Downgrade:
1373            serverRandom = serverRandom[:24] + \
1374                bytearray("\x44\x4f\x57\x4e\x47\x52\x44\x00")
1375        serverHello = ServerHello()
1376        serverHello.create(self.version, serverRandom, sessionID, \
1377                            cipherSuite, CertificateType.x509, tackExt,
1378                            alpn_proto_selected,
1379                            nextProtos)
1380        serverHello.channel_id = \
1381            clientHello.channel_id and settings.enableChannelID
1382        serverHello.extended_master_secret = \
1383            clientHello.extended_master_secret and \
1384            settings.enableExtendedMasterSecret
1385        for param in clientHello.tb_client_params:
1386            if param in settings.supportedTokenBindingParams:
1387                serverHello.tb_params = param
1388                break
1389        if clientHello.support_signed_cert_timestamps:
1390            serverHello.signed_cert_timestamps = signedCertTimestamps
1391        if clientHello.status_request:
1392            serverHello.status_request = ocspResponse
1393        if clientHello.ri:
1394            serverHello.send_ri = True
1395
1396        # Perform the SRP key exchange
1397        clientCertChain = None
1398        if cipherSuite in CipherSuite.srpAllSuites:
1399            for result in self._serverSRPKeyExchange(clientHello, serverHello,
1400                                    verifierDB, cipherSuite,
1401                                    privateKey, certChain):
1402                if result in (0,1): yield result
1403                else: break
1404            premasterSecret = result
1405
1406        # Perform a certificate-based key exchange
1407        elif cipherSuite in CipherSuite.certAllSuites:
1408            if cipherSuite in CipherSuite.certSuites:
1409                keyExchange = RSAKeyExchange(cipherSuite,
1410                                             clientHello,
1411                                             serverHello,
1412                                             privateKey)
1413            elif cipherSuite in CipherSuite.dheCertSuites:
1414                keyExchange = DHE_RSAKeyExchange(cipherSuite,
1415                                                 clientHello,
1416                                                 serverHello,
1417                                                 privateKey)
1418            elif cipherSuite in CipherSuite.ecdheCertSuites:
1419                keyExchange = ECDHE_RSAKeyExchange(cipherSuite,
1420                                                   clientHello,
1421                                                   serverHello,
1422                                                   privateKey)
1423            else:
1424                assert(False)
1425            for result in self._serverCertKeyExchange(clientHello, serverHello,
1426                                        certChain, keyExchange,
1427                                        reqCert, reqCAs, reqCertTypes, cipherSuite,
1428                                        settings, ocspResponse):
1429                if result in (0,1): yield result
1430                else: break
1431            (premasterSecret, clientCertChain) = result
1432
1433        # Perform anonymous Diffie Hellman key exchange
1434        elif cipherSuite in CipherSuite.anonSuites:
1435            for result in self._serverAnonKeyExchange(clientHello, serverHello,
1436                                        cipherSuite, settings):
1437                if result in (0,1): yield result
1438                else: break
1439            premasterSecret = result
1440
1441        else:
1442            assert(False)
1443
1444        # Exchange Finished messages
1445        for result in self._serverFinished(premasterSecret,
1446                                clientHello.random, serverHello.random,
1447                                cipherSuite, settings.cipherImplementations,
1448                                nextProtos, serverHello.channel_id,
1449                                serverHello.extended_master_secret):
1450                if result in (0,1): yield result
1451                else: break
1452        masterSecret = result
1453
1454        self.clientRandom = clientHello.random
1455        self.serverRandom = serverHello.random
1456
1457        #Create the session object
1458        self.session = Session()
1459        if cipherSuite in CipherSuite.certAllSuites:
1460            serverCertChain = certChain
1461        else:
1462            serverCertChain = None
1463        srpUsername = None
1464        serverName = None
1465        if clientHello.srp_username:
1466            srpUsername = clientHello.srp_username.decode("utf-8")
1467        if clientHello.server_name:
1468            serverName = clientHello.server_name.decode("utf-8")
1469        self.session.create(masterSecret, serverHello.session_id, cipherSuite,
1470            srpUsername, clientCertChain, serverCertChain,
1471            tackExt, serverHello.tackExt!=None, serverName)
1472
1473        #Add the session object to the session cache
1474        if sessionCache and sessionID:
1475            sessionCache[sessionID] = self.session
1476
1477        self._handshakeDone(resumed=False)
1478
1479
1480    def _isIntolerant(self, settings, clientHello):
1481        if settings.tlsIntolerant is None:
1482            return False
1483        clientVersion = clientHello.client_version
1484        if clientHello.has_supported_versions:
1485            clientVersion = (3, 4)
1486        return clientVersion >= settings.tlsIntolerant
1487
1488
1489    def _serverGetClientHello(self, settings, certChain, verifierDB,
1490                                sessionCache, anon, fallbackSCSV):
1491        #Tentatively set version to most-desirable version, so if an error
1492        #occurs parsing the ClientHello, this is what we'll use for the
1493        #error alert
1494        self.version = settings.maxVersion
1495
1496        #Get ClientHello
1497        for result in self._getMsg(ContentType.handshake,
1498                                   HandshakeType.client_hello):
1499            if result in (0,1): yield result
1500            else: break
1501        clientHello = result
1502
1503        #If client's version is too low, reject it
1504        if clientHello.client_version < settings.minVersion:
1505            self.version = settings.minVersion
1506            for result in self._sendError(\
1507                  AlertDescription.protocol_version,
1508                  "Too old version: %s" % str(clientHello.client_version)):
1509                yield result
1510
1511        #If simulating TLS intolerance, reject certain TLS versions.
1512        elif self._isIntolerant(settings, clientHello):
1513            if settings.tlsIntoleranceType == "alert":
1514                for result in self._sendError(\
1515                    AlertDescription.handshake_failure):
1516                    yield result
1517            elif settings.tlsIntoleranceType == "close":
1518                self._abruptClose()
1519                raise TLSUnsupportedError("Simulating version intolerance")
1520            elif settings.tlsIntoleranceType == "reset":
1521                self._abruptClose(reset=True)
1522                raise TLSUnsupportedError("Simulating version intolerance")
1523            else:
1524                raise ValueError("Unknown intolerance type: '%s'" %
1525                                 settings.tlsIntoleranceType)
1526
1527        #If client's version is too high, propose my highest version
1528        elif clientHello.client_version > settings.maxVersion:
1529            self.version = settings.maxVersion
1530
1531        #Detect if the client performed an inappropriate fallback.
1532        elif fallbackSCSV and clientHello.client_version < settings.maxVersion:
1533            self.version = clientHello.client_version
1534            if CipherSuite.TLS_FALLBACK_SCSV in clientHello.cipher_suites:
1535                for result in self._sendError(\
1536                        AlertDescription.inappropriate_fallback):
1537                    yield result
1538
1539        else:
1540            #Set the version to the client's version
1541            self.version = clientHello.client_version
1542
1543        #Initialize acceptable cipher suites
1544        cipherSuites = []
1545        if verifierDB:
1546            if certChain:
1547                cipherSuites += \
1548                    CipherSuite.getSrpCertSuites(settings, self.version)
1549            cipherSuites += CipherSuite.getSrpSuites(settings, self.version)
1550        elif certChain:
1551            cipherSuites += CipherSuite.getEcdheCertSuites(settings, self.version)
1552            cipherSuites += CipherSuite.getDheCertSuites(settings, self.version)
1553            cipherSuites += CipherSuite.getCertSuites(settings, self.version)
1554        elif anon:
1555            cipherSuites += CipherSuite.getAnonSuites(settings, self.version)
1556        else:
1557            assert(False)
1558
1559        alpn_proto_selected = None
1560        if (clientHello.alpn_protos_advertised is not None
1561                and settings.alpnProtos is not None):
1562            for proto in settings.alpnProtos:
1563                if proto in clientHello.alpn_protos_advertised:
1564                    alpn_proto_selected = proto
1565                    break;
1566
1567        #If resumption was requested and we have a session cache...
1568        if clientHello.session_id and sessionCache:
1569            session = None
1570
1571            #Check in the session cache
1572            if sessionCache and not session:
1573                try:
1574                    session = sessionCache[clientHello.session_id]
1575                    if not session.resumable:
1576                        raise AssertionError()
1577                    #Check for consistency with ClientHello
1578                    if session.cipherSuite not in cipherSuites:
1579                        for result in self._sendError(\
1580                                AlertDescription.handshake_failure):
1581                            yield result
1582                    if session.cipherSuite not in clientHello.cipher_suites:
1583                        for result in self._sendError(\
1584                                AlertDescription.handshake_failure):
1585                            yield result
1586                    if clientHello.srp_username:
1587                        if not session.srpUsername or \
1588                            clientHello.srp_username != bytearray(session.srpUsername, "utf-8"):
1589                            for result in self._sendError(\
1590                                    AlertDescription.handshake_failure):
1591                                yield result
1592                    if clientHello.server_name:
1593                        if not session.serverName or \
1594                            clientHello.server_name != bytearray(session.serverName, "utf-8"):
1595                            for result in self._sendError(\
1596                                    AlertDescription.handshake_failure):
1597                                yield result
1598                except KeyError:
1599                    pass
1600
1601            #If a session is found..
1602            if session:
1603                #Send ServerHello
1604                serverHello = ServerHello()
1605                serverHello.create(self.version, getRandomBytes(32),
1606                                   session.sessionID, session.cipherSuite,
1607                                   CertificateType.x509, None,
1608                                   alpn_proto_selected, None)
1609                serverHello.extended_master_secret = \
1610                    clientHello.extended_master_secret and \
1611                    settings.enableExtendedMasterSecret
1612                for param in clientHello.tb_client_params:
1613                    if param in settings.supportedTokenBindingParams:
1614                          serverHello.tb_params = param
1615                          break
1616                if clientHello.ri:
1617                    serverHello.send_ri = True
1618                for result in self._sendMsg(serverHello):
1619                    yield result
1620
1621                #From here on, the client's messages must have right version
1622                self._versionCheck = True
1623
1624                #Calculate pending connection states
1625                self._calcPendingStates(session.cipherSuite,
1626                                        session.masterSecret,
1627                                        clientHello.random,
1628                                        serverHello.random,
1629                                        settings.cipherImplementations)
1630
1631                #Exchange ChangeCipherSpec and Finished messages
1632                for result in self._sendFinished(session.masterSecret):
1633                    yield result
1634                for result in self._getFinished(session.masterSecret):
1635                    yield result
1636
1637                #Set the session
1638                self.session = session
1639
1640                self.clientRandom = clientHello.random
1641                self.serverRandom = serverHello.random
1642                yield None # Handshake done!
1643
1644        #Calculate the first cipher suite intersection.
1645        #This is the 'privileged' ciphersuite.  We'll use it if we're
1646        #doing a new negotiation.  In fact,
1647        #the only time we won't use it is if we're resuming a
1648        #session, in which case we use the ciphersuite from the session.
1649        #
1650        #Given the current ciphersuite ordering, this means we prefer SRP
1651        #over non-SRP.
1652        for cipherSuite in cipherSuites:
1653            if cipherSuite in clientHello.cipher_suites:
1654                break
1655        else:
1656            for result in self._sendError(\
1657                    AlertDescription.handshake_failure,
1658                    "No mutual ciphersuite"):
1659                yield result
1660        if cipherSuite in CipherSuite.srpAllSuites and \
1661                            not clientHello.srp_username:
1662            for result in self._sendError(\
1663                    AlertDescription.unknown_psk_identity,
1664                    "Client sent a hello, but without the SRP username"):
1665                yield result
1666
1667        #If an RSA suite is chosen, check for certificate type intersection
1668        if cipherSuite in CipherSuite.certAllSuites and CertificateType.x509 \
1669                                not in clientHello.certificate_types:
1670            for result in self._sendError(\
1671                    AlertDescription.handshake_failure,
1672                    "the client doesn't support my certificate type"):
1673                yield result
1674
1675        # If resumption was not requested, or
1676        # we have no session cache, or
1677        # the client's session_id was not found in cache:
1678        yield (clientHello, cipherSuite)
1679
1680    def _serverSRPKeyExchange(self, clientHello, serverHello, verifierDB,
1681                                cipherSuite, privateKey, serverCertChain):
1682
1683        srpUsername = clientHello.srp_username.decode("utf-8")
1684        self.allegedSrpUsername = srpUsername
1685        #Get parameters from username
1686        try:
1687            entry = verifierDB[srpUsername]
1688        except KeyError:
1689            for result in self._sendError(\
1690                    AlertDescription.unknown_psk_identity):
1691                yield result
1692        (N, g, s, v) = entry
1693
1694        #Calculate server's ephemeral DH values (b, B)
1695        b = bytesToNumber(getRandomBytes(32))
1696        k = makeK(N, g)
1697        B = (powMod(g, b, N) + (k*v)) % N
1698
1699        #Create ServerKeyExchange, signing it if necessary
1700        serverKeyExchange = ServerKeyExchange(cipherSuite, self.version)
1701        serverKeyExchange.createSRP(N, g, s, B)
1702        if cipherSuite in CipherSuite.srpCertSuites:
1703            hashBytes = serverKeyExchange.hash(clientHello.random,
1704                                               serverHello.random)
1705            serverKeyExchange.signature = privateKey.sign(hashBytes)
1706
1707        #Send ServerHello[, Certificate], ServerKeyExchange,
1708        #ServerHelloDone
1709        msgs = []
1710        msgs.append(serverHello)
1711        if cipherSuite in CipherSuite.srpCertSuites:
1712            certificateMsg = Certificate(CertificateType.x509)
1713            certificateMsg.create(serverCertChain)
1714            msgs.append(certificateMsg)
1715        msgs.append(serverKeyExchange)
1716        msgs.append(ServerHelloDone())
1717        for result in self._sendMsgs(msgs):
1718            yield result
1719
1720        #From here on, the client's messages must have the right version
1721        self._versionCheck = True
1722
1723        #Get and check ClientKeyExchange
1724        for result in self._getMsg(ContentType.handshake,
1725                                  HandshakeType.client_key_exchange,
1726                                  cipherSuite):
1727            if result in (0,1): yield result
1728            else: break
1729        clientKeyExchange = result
1730        A = clientKeyExchange.srp_A
1731        if A % N == 0:
1732            for result in self._sendError(AlertDescription.illegal_parameter,
1733                    "Suspicious A value"):
1734                yield result
1735            assert(False) # Just to ensure we don't fall through somehow
1736
1737        #Calculate u
1738        u = makeU(N, A, B)
1739
1740        #Calculate premaster secret
1741        S = powMod((A * powMod(v,u,N)) % N, b, N)
1742        premasterSecret = numberToByteArray(S)
1743
1744        yield premasterSecret
1745
1746
1747    def _serverCertKeyExchange(self, clientHello, serverHello,
1748                                serverCertChain, keyExchange,
1749                                reqCert, reqCAs, reqCertTypes, cipherSuite,
1750                                settings, ocspResponse):
1751        #Send ServerHello, Certificate[, ServerKeyExchange]
1752        #[, CertificateRequest], ServerHelloDone
1753        msgs = []
1754
1755        # If we verify a client cert chain, return it
1756        clientCertChain = None
1757
1758        msgs.append(serverHello)
1759        msgs.append(Certificate(CertificateType.x509).create(serverCertChain))
1760        if serverHello.status_request:
1761            msgs.append(CertificateStatus().create(ocspResponse))
1762        serverKeyExchange = keyExchange.makeServerKeyExchange()
1763        if serverKeyExchange is not None:
1764            msgs.append(serverKeyExchange)
1765        if reqCert:
1766            reqCAs = reqCAs or []
1767            #Apple's Secure Transport library rejects empty certificate_types,
1768            #so default to rsa_sign.
1769            reqCertTypes = reqCertTypes or [ClientCertificateType.rsa_sign]
1770            #Only SHA-1 + RSA is supported.
1771            sigAlgs = [(HashAlgorithm.sha1, SignatureAlgorithm.rsa)]
1772            msgs.append(CertificateRequest(self.version).create(reqCertTypes,
1773                                                                reqCAs,
1774                                                                sigAlgs))
1775        msgs.append(ServerHelloDone())
1776        for result in self._sendMsgs(msgs):
1777            yield result
1778
1779        #From here on, the client's messages must have the right version
1780        self._versionCheck = True
1781
1782        #Get [Certificate,] (if was requested)
1783        if reqCert:
1784            if self.version == (3,0):
1785                for result in self._getMsg((ContentType.handshake,
1786                                           ContentType.alert),
1787                                           HandshakeType.certificate,
1788                                           CertificateType.x509):
1789                    if result in (0,1): yield result
1790                    else: break
1791                msg = result
1792
1793                if isinstance(msg, Alert):
1794                    #If it's not a no_certificate alert, re-raise
1795                    alert = msg
1796                    if alert.description != \
1797                            AlertDescription.no_certificate:
1798                        self._shutdown(False)
1799                        raise TLSRemoteAlert(alert)
1800                elif isinstance(msg, Certificate):
1801                    clientCertificate = msg
1802                    if clientCertificate.certChain and \
1803                            clientCertificate.certChain.getNumCerts()!=0:
1804                        clientCertChain = clientCertificate.certChain
1805                else:
1806                    raise AssertionError()
1807            elif self.version in ((3,1), (3,2), (3,3)):
1808                for result in self._getMsg(ContentType.handshake,
1809                                          HandshakeType.certificate,
1810                                          CertificateType.x509):
1811                    if result in (0,1): yield result
1812                    else: break
1813                clientCertificate = result
1814                if clientCertificate.certChain and \
1815                        clientCertificate.certChain.getNumCerts()!=0:
1816                    clientCertChain = clientCertificate.certChain
1817            else:
1818                raise AssertionError()
1819
1820        #Get ClientKeyExchange
1821        for result in self._getMsg(ContentType.handshake,
1822                                  HandshakeType.client_key_exchange,
1823                                  cipherSuite):
1824            if result in (0,1): yield result
1825            else: break
1826        clientKeyExchange = result
1827
1828        #Process ClientKeyExchange
1829        try:
1830            premasterSecret = \
1831                keyExchange.processClientKeyExchange(clientKeyExchange)
1832        except alert as TLSLocalAlert:
1833            for result in self._sendError(alert.description, alert.message):
1834                yield result
1835
1836        #Get and check CertificateVerify, if relevant
1837        if clientCertChain:
1838            if self.version == (3,0):
1839                masterSecret = calcMasterSecret(self.version, premasterSecret,
1840                                         clientHello.random, serverHello.random,
1841                                         b"", False)
1842                verifyBytes = self._calcSSLHandshakeHash(masterSecret, b"")
1843            elif self.version in ((3,1), (3,2)):
1844                verifyBytes = self._handshake_md5.digest() + \
1845                                self._handshake_sha.digest()
1846            elif self.version == (3,3):
1847                verifyBytes = self._handshake_sha.digest()
1848                verifyBytes = RSAKey.addPKCS1SHA1Prefix(verifyBytes)
1849            for result in self._getMsg(ContentType.handshake,
1850                                      HandshakeType.certificate_verify):
1851                if result in (0,1): yield result
1852                else: break
1853            certificateVerify = result
1854            publicKey = clientCertChain.getEndEntityPublicKey()
1855            if len(publicKey) < settings.minKeySize:
1856                for result in self._sendError(\
1857                        AlertDescription.handshake_failure,
1858                        "Client's public key too small: %d" % len(publicKey)):
1859                    yield result
1860
1861            if len(publicKey) > settings.maxKeySize:
1862                for result in self._sendError(\
1863                        AlertDescription.handshake_failure,
1864                        "Client's public key too large: %d" % len(publicKey)):
1865                    yield result
1866
1867            if not publicKey.verify(certificateVerify.signature, verifyBytes):
1868                for result in self._sendError(\
1869                        AlertDescription.decrypt_error,
1870                        "Signature failed to verify"):
1871                    yield result
1872        yield (premasterSecret, clientCertChain)
1873
1874
1875    def _serverAnonKeyExchange(self, clientHello, serverHello, cipherSuite,
1876                               settings):
1877        # Calculate DH p, g, Xs, Ys
1878        dh_p = getRandomSafePrime(32, False)
1879        dh_g = getRandomNumber(2, dh_p)
1880        dh_Xs = bytesToNumber(getRandomBytes(32))
1881        dh_Ys = powMod(dh_g, dh_Xs, dh_p)
1882
1883        #Create ServerKeyExchange
1884        serverKeyExchange = ServerKeyExchange(cipherSuite, self.version)
1885        serverKeyExchange.createDH(dh_p, dh_g, dh_Ys)
1886
1887        #Send ServerHello[, Certificate], ServerKeyExchange,
1888        #ServerHelloDone
1889        msgs = []
1890        msgs.append(serverHello)
1891        msgs.append(serverKeyExchange)
1892        msgs.append(ServerHelloDone())
1893        for result in self._sendMsgs(msgs):
1894            yield result
1895
1896        #From here on, the client's messages must have the right version
1897        self._versionCheck = True
1898
1899        #Get and check ClientKeyExchange
1900        for result in self._getMsg(ContentType.handshake,
1901                                   HandshakeType.client_key_exchange,
1902                                   cipherSuite):
1903            if result in (0,1):
1904                yield result
1905            else:
1906                break
1907        clientKeyExchange = result
1908        dh_Yc = clientKeyExchange.dh_Yc
1909
1910        if dh_Yc % dh_p == 0:
1911            for result in self._sendError(AlertDescription.illegal_parameter,
1912                    "Suspicious dh_Yc value"):
1913                yield result
1914            assert(False) # Just to ensure we don't fall through somehow
1915
1916        #Calculate premaster secre
1917        S = powMod(dh_Yc,dh_Xs,dh_p)
1918        premasterSecret = numberToByteArray(S)
1919
1920        yield premasterSecret
1921
1922
1923    def _serverFinished(self,  premasterSecret, clientRandom, serverRandom,
1924                        cipherSuite, cipherImplementations, nextProtos,
1925                        doingChannelID, useExtendedMasterSecret):
1926        masterSecret = calcMasterSecret(self.version, premasterSecret,
1927                                      clientRandom, serverRandom,
1928                                      self._ems_handshake_hash,
1929                                      useExtendedMasterSecret)
1930
1931        #Calculate pending connection states
1932        self._calcPendingStates(cipherSuite, masterSecret,
1933                                clientRandom, serverRandom,
1934                                cipherImplementations)
1935
1936        #Exchange ChangeCipherSpec and Finished messages
1937        for result in self._getFinished(masterSecret,
1938                        expect_next_protocol=nextProtos is not None,
1939                        expect_channel_id=doingChannelID):
1940            yield result
1941
1942        for result in self._sendFinished(masterSecret):
1943            yield result
1944
1945        yield masterSecret
1946
1947
1948    #*********************************************************
1949    # Shared Handshake Functions
1950    #*********************************************************
1951
1952
1953    def _sendFinished(self, masterSecret, nextProto=None):
1954        #Send ChangeCipherSpec
1955        for result in self._sendMsg(ChangeCipherSpec()):
1956            yield result
1957
1958        #Switch to pending write state
1959        self._changeWriteState()
1960
1961        if nextProto is not None:
1962            nextProtoMsg = NextProtocol().create(nextProto)
1963            for result in self._sendMsg(nextProtoMsg):
1964                yield result
1965
1966        #Calculate verification data
1967        verifyData = self._calcFinished(masterSecret, True)
1968        if self.fault == Fault.badFinished:
1969            verifyData[0] = (verifyData[0]+1)%256
1970
1971        #Send Finished message under new state
1972        finished = Finished(self.version).create(verifyData)
1973        for result in self._sendMsg(finished):
1974            yield result
1975
1976    def _getFinished(self, masterSecret, expect_next_protocol=False, nextProto=None,
1977                     expect_channel_id=False):
1978        #Get and check ChangeCipherSpec
1979        for result in self._getMsg(ContentType.change_cipher_spec):
1980            if result in (0,1):
1981                yield result
1982        changeCipherSpec = result
1983
1984        if changeCipherSpec.type != 1:
1985            for result in self._sendError(AlertDescription.illegal_parameter,
1986                                         "ChangeCipherSpec type incorrect"):
1987                yield result
1988
1989        #Switch to pending read state
1990        self._changeReadState()
1991
1992        #Server Finish - Are we waiting for a next protocol echo?
1993        if expect_next_protocol:
1994            for result in self._getMsg(ContentType.handshake, HandshakeType.next_protocol):
1995                if result in (0,1):
1996                    yield result
1997            if result is None:
1998                for result in self._sendError(AlertDescription.unexpected_message,
1999                                             "Didn't get NextProtocol message"):
2000                    yield result
2001
2002            self.next_proto = result.next_proto
2003        else:
2004            self.next_proto = None
2005
2006        #Client Finish - Only set the next_protocol selected in the connection
2007        if nextProto:
2008            self.next_proto = nextProto
2009
2010        #Server Finish - Are we waiting for a EncryptedExtensions?
2011        if expect_channel_id:
2012            for result in self._getMsg(ContentType.handshake, HandshakeType.encrypted_extensions):
2013                if result in (0,1):
2014                    yield result
2015            if result is None:
2016                for result in self._sendError(AlertDescription.unexpected_message,
2017                                             "Didn't get EncryptedExtensions message"):
2018                    yield result
2019            encrypted_extensions = result
2020            self.channel_id = result.channel_id_key
2021        else:
2022            self.channel_id = None
2023
2024        #Calculate verification data
2025        verifyData = self._calcFinished(masterSecret, False)
2026
2027        #Get and check Finished message under new state
2028        for result in self._getMsg(ContentType.handshake,
2029                                  HandshakeType.finished):
2030            if result in (0,1):
2031                yield result
2032        finished = result
2033        if finished.verify_data != verifyData:
2034            for result in self._sendError(AlertDescription.decrypt_error,
2035                                         "Finished message is incorrect"):
2036                yield result
2037
2038    def _calcFinished(self, masterSecret, send=True):
2039        if self.version == (3,0):
2040            if (self._client and send) or (not self._client and not send):
2041                senderStr = b"\x43\x4C\x4E\x54"
2042            else:
2043                senderStr = b"\x53\x52\x56\x52"
2044
2045            verifyData = self._calcSSLHandshakeHash(masterSecret, senderStr)
2046            return verifyData
2047
2048        elif self.version in ((3,1), (3,2)):
2049            if (self._client and send) or (not self._client and not send):
2050                label = b"client finished"
2051            else:
2052                label = b"server finished"
2053
2054            handshakeHashes = self._handshake_md5.digest() + \
2055                                self._handshake_sha.digest()
2056            verifyData = PRF(masterSecret, label, handshakeHashes, 12)
2057            return verifyData
2058        elif self.version == (3,3):
2059            if (self._client and send) or (not self._client and not send):
2060                label = b"client finished"
2061            else:
2062                label = b"server finished"
2063
2064            handshakeHashes = self._handshake_sha256.digest()
2065            verifyData = PRF_1_2(masterSecret, label, handshakeHashes, 12)
2066            return verifyData
2067        else:
2068            raise AssertionError()
2069
2070
2071    def _handshakeWrapperAsync(self, handshaker, checker):
2072        if not self.fault:
2073            try:
2074                for result in handshaker:
2075                    yield result
2076                if checker:
2077                    try:
2078                        checker(self)
2079                    except TLSAuthenticationError:
2080                        alert = Alert().create(AlertDescription.close_notify,
2081                                               AlertLevel.fatal)
2082                        for result in self._sendMsg(alert):
2083                            yield result
2084                        raise
2085            except GeneratorExit:
2086                raise
2087            except TLSAlert as alert:
2088                if not self.fault:
2089                    raise
2090                if alert.description not in Fault.faultAlerts[self.fault]:
2091                    raise TLSFaultError(str(alert))
2092                else:
2093                    pass
2094            except:
2095                self._shutdown(False)
2096                raise
2097
2098
2099    def exportKeyingMaterial(self, label, context, use_context, length):
2100        """Returns the exported keying material as defined in RFC 5705."""
2101
2102        seed = self.clientRandom + self.serverRandom
2103        if use_context:
2104            if len(context) > 65535:
2105                raise ValueError("Context is too long")
2106            seed += bytearray(2)
2107            seed[len(seed) - 2] = len(context) >> 8
2108            seed[len(seed) - 1] = len(context) & 0xFF
2109            seed += context
2110        if self.version in ((3,1), (3,2)):
2111            return PRF(self.session.masterSecret, label, seed, length)
2112        elif self.version == (3,3):
2113            return PRF_1_2(self.session.masterSecret, label, seed, length)
2114        else:
2115            raise AssertionError()
2116