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