1
2
3
4
5
6
7
8
9
10
11
12
13
14 """
15 MAIN CLASS FOR TLS LITE (START HERE!).
16 """
17
18 from __future__ import division
19 import socket
20 from .utils.compat import formatExceptionTrace
21 from .tlsrecordlayer import TLSRecordLayer
22 from .session import Session
23 from .constants import *
24 from .utils.cryptomath import getRandomBytes
25 from .errors import *
26 from .messages import *
27 from .mathtls import *
28 from .handshakesettings import HandshakeSettings
29 from .utils.tackwrapper import *
30 from .keyexchange import KeyExchange, RSAKeyExchange, DHE_RSAKeyExchange, \
31 ECDHE_RSAKeyExchange, SRPKeyExchange
34 """
35 This class wraps a socket and provides TLS handshaking and data transfer.
36
37 To use this class, create a new instance, passing a connected
38 socket into the constructor. Then call some handshake function.
39 If the handshake completes without raising an exception, then a TLS
40 connection has been negotiated. You can transfer data over this
41 connection as if it were a socket.
42
43 This class provides both synchronous and asynchronous versions of
44 its key functions. The synchronous versions should be used when
45 writing single-or multi-threaded code using blocking sockets. The
46 asynchronous versions should be used when performing asynchronous,
47 event-based I/O with non-blocking sockets.
48
49 Asynchronous I/O is a complicated subject; typically, you should
50 not use the asynchronous functions directly, but should use some
51 framework like asyncore or Twisted which TLS Lite integrates with
52 (see
53 L{tlslite.integration.tlsasyncdispatchermixin.TLSAsyncDispatcherMixIn}).
54 """
55
57 """Create a new TLSConnection instance.
58
59 @param sock: The socket data will be transmitted on. The
60 socket should already be connected. It may be in blocking or
61 non-blocking mode.
62
63 @type sock: L{socket.socket}
64 """
65 TLSRecordLayer.__init__(self, sock)
66 self.serverSigAlg = None
67 self.ecdhCurve = None
68 self.dhGroupSize = None
69
70
71
72
73
77 """Perform an anonymous handshake in the role of client.
78
79 This function performs an SSL or TLS handshake using an
80 anonymous Diffie Hellman ciphersuite.
81
82 Like any handshake function, this can be called on a closed
83 TLS connection, or on a TLS connection that is already open.
84 If called on an open connection it performs a re-handshake.
85
86 If the function completes without raising an exception, the
87 TLS connection will be open and available for data transfer.
88
89 If an exception is raised, the connection will have been
90 automatically closed (if it was ever open).
91
92 @type session: L{tlslite.Session.Session}
93 @param session: A TLS session to attempt to resume. If the
94 resumption does not succeed, a full handshake will be
95 performed.
96
97 @type settings: L{tlslite.HandshakeSettings.HandshakeSettings}
98 @param settings: Various settings which can be used to control
99 the ciphersuites, certificate types, and SSL/TLS versions
100 offered by the client.
101
102 @type checker: L{tlslite.Checker.Checker}
103 @param checker: A Checker instance. This instance will be
104 invoked to examine the other party's authentication
105 credentials, if the handshake completes succesfully.
106
107 @type serverName: string
108 @param serverName: The ServerNameIndication TLS Extension.
109
110 @type async: bool
111 @param async: If False, this function will block until the
112 handshake is completed. If True, this function will return a
113 generator. Successive invocations of the generator will
114 return 0 if it is waiting to read from the socket, 1 if it is
115 waiting to write to the socket, or will raise StopIteration if
116 the handshake operation is completed.
117
118 @rtype: None or an iterable
119 @return: If 'async' is True, a generator object will be
120 returned.
121
122 @raise socket.error: If a socket error occurs.
123 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
124 without a preceding alert.
125 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
126 @raise tlslite.errors.TLSAuthenticationError: If the checker
127 doesn't like the other party's authentication credentials.
128 """
129 handshaker = self._handshakeClientAsync(anonParams=(True),
130 session=session,
131 settings=settings,
132 checker=checker,
133 serverName=serverName)
134 if async:
135 return handshaker
136 for result in handshaker:
137 pass
138
139 - def handshakeClientSRP(self, username, password, session=None,
140 settings=None, checker=None,
141 reqTack=True, serverName=None,
142 async=False):
143 """Perform an SRP handshake in the role of client.
144
145 This function performs a TLS/SRP handshake. SRP mutually
146 authenticates both parties to each other using only a
147 username and password. This function may also perform a
148 combined SRP and server-certificate handshake, if the server
149 chooses to authenticate itself with a certificate chain in
150 addition to doing SRP.
151
152 If the function completes without raising an exception, the
153 TLS connection will be open and available for data transfer.
154
155 If an exception is raised, the connection will have been
156 automatically closed (if it was ever open).
157
158 @type username: str
159 @param username: The SRP username.
160
161 @type password: str
162 @param password: The SRP password.
163
164 @type session: L{tlslite.session.Session}
165 @param session: A TLS session to attempt to resume. This
166 session must be an SRP session performed with the same username
167 and password as were passed in. If the resumption does not
168 succeed, a full SRP handshake will be performed.
169
170 @type settings: L{tlslite.handshakesettings.HandshakeSettings}
171 @param settings: Various settings which can be used to control
172 the ciphersuites, certificate types, and SSL/TLS versions
173 offered by the client.
174
175 @type checker: L{tlslite.checker.Checker}
176 @param checker: A Checker instance. This instance will be
177 invoked to examine the other party's authentication
178 credentials, if the handshake completes succesfully.
179
180 @type reqTack: bool
181 @param reqTack: Whether or not to send a "tack" TLS Extension,
182 requesting the server return a TackExtension if it has one.
183
184 @type serverName: string
185 @param serverName: The ServerNameIndication TLS Extension.
186
187 @type async: bool
188 @param async: If False, this function will block until the
189 handshake is completed. If True, this function will return a
190 generator. Successive invocations of the generator will
191 return 0 if it is waiting to read from the socket, 1 if it is
192 waiting to write to the socket, or will raise StopIteration if
193 the handshake operation is completed.
194
195 @rtype: None or an iterable
196 @return: If 'async' is True, a generator object will be
197 returned.
198
199 @raise socket.error: If a socket error occurs.
200 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
201 without a preceding alert.
202 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
203 @raise tlslite.errors.TLSAuthenticationError: If the checker
204 doesn't like the other party's authentication credentials.
205 """
206 handshaker = self._handshakeClientAsync(srpParams=(username, password),
207 session=session, settings=settings, checker=checker,
208 reqTack=reqTack, serverName=serverName)
209
210
211
212
213
214
215
216 if async:
217 return handshaker
218 for result in handshaker:
219 pass
220
221 - def handshakeClientCert(self, certChain=None, privateKey=None,
222 session=None, settings=None, checker=None,
223 nextProtos=None, reqTack=True, serverName=None,
224 async=False):
225 """Perform a certificate-based handshake in the role of client.
226
227 This function performs an SSL or TLS handshake. The server
228 will authenticate itself using an X.509 certificate
229 chain. If the handshake succeeds, the server's certificate
230 chain will be stored in the session's serverCertChain attribute.
231 Unless a checker object is passed in, this function does no
232 validation or checking of the server's certificate chain.
233
234 If the server requests client authentication, the
235 client will send the passed-in certificate chain, and use the
236 passed-in private key to authenticate itself. If no
237 certificate chain and private key were passed in, the client
238 will attempt to proceed without client authentication. The
239 server may or may not allow this.
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 certChain: L{tlslite.x509certchain.X509CertChain}
248 @param certChain: The certificate chain to be used if the
249 server requests client authentication.
250
251 @type privateKey: L{tlslite.utils.rsakey.RSAKey}
252 @param privateKey: The private key to be used if the server
253 requests client authentication.
254
255 @type session: L{tlslite.session.Session}
256 @param session: A TLS session to attempt to resume. If the
257 resumption does not succeed, a full handshake will be
258 performed.
259
260 @type settings: L{tlslite.handshakesettings.HandshakeSettings}
261 @param settings: Various settings which can be used to control
262 the ciphersuites, certificate types, and SSL/TLS versions
263 offered by the client.
264
265 @type checker: L{tlslite.checker.Checker}
266 @param checker: A Checker instance. This instance will be
267 invoked to examine the other party's authentication
268 credentials, if the handshake completes succesfully.
269
270 @type nextProtos: list of strings.
271 @param nextProtos: A list of upper layer protocols ordered by
272 preference, to use in the Next-Protocol Negotiation Extension.
273
274 @type reqTack: bool
275 @param reqTack: Whether or not to send a "tack" TLS Extension,
276 requesting the server return a TackExtension if it has one.
277
278 @type serverName: string
279 @param serverName: The ServerNameIndication TLS Extension.
280
281 @type async: bool
282 @param async: If False, this function will block until the
283 handshake is completed. If True, this function will return a
284 generator. Successive invocations of the generator will
285 return 0 if it is waiting to read from the socket, 1 if it is
286 waiting to write to the socket, or will raise StopIteration if
287 the handshake operation is completed.
288
289 @rtype: None or an iterable
290 @return: If 'async' is True, a generator object will be
291 returned.
292
293 @raise socket.error: If a socket error occurs.
294 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
295 without a preceding alert.
296 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
297 @raise tlslite.errors.TLSAuthenticationError: If the checker
298 doesn't like the other party's authentication credentials.
299 """
300 handshaker = \
301 self._handshakeClientAsync(certParams=(certChain, privateKey),
302 session=session, settings=settings,
303 checker=checker,
304 serverName=serverName,
305 nextProtos=nextProtos,
306 reqTack=reqTack)
307
308
309
310
311
312
313
314 if async:
315 return handshaker
316 for result in handshaker:
317 pass
318
319
320 - def _handshakeClientAsync(self, srpParams=(), certParams=(), anonParams=(),
321 session=None, settings=None, checker=None,
322 nextProtos=None, serverName=None, reqTack=True):
334
335
338
339 self._handshakeStart(client=True)
340
341
342 srpUsername = None
343 password = None
344 clientCertChain = None
345 privateKey = None
346
347
348 if srpParams:
349 assert(not certParams)
350 assert(not anonParams)
351 srpUsername, password = srpParams
352 if certParams:
353 assert(not srpParams)
354 assert(not anonParams)
355 clientCertChain, privateKey = certParams
356 if anonParams:
357 assert(not srpParams)
358 assert(not certParams)
359
360
361 if srpUsername and not password:
362 raise ValueError("Caller passed a username but no password")
363 if password and not srpUsername:
364 raise ValueError("Caller passed a password but no username")
365 if clientCertChain and not privateKey:
366 raise ValueError("Caller passed a certChain but no privateKey")
367 if privateKey and not clientCertChain:
368 raise ValueError("Caller passed a privateKey but no certChain")
369 if reqTack:
370 if not tackpyLoaded:
371 reqTack = False
372 if not settings or not settings.useExperimentalTackExtension:
373 reqTack = False
374 if nextProtos is not None:
375 if len(nextProtos) == 0:
376 raise ValueError("Caller passed no nextProtos")
377
378
379
380 if not settings:
381 settings = HandshakeSettings()
382 settings = settings.validate()
383
384 if clientCertChain:
385 if not isinstance(clientCertChain, X509CertChain):
386 raise ValueError("Unrecognized certificate type")
387 if "x509" not in settings.certificateTypes:
388 raise ValueError("Client certificate doesn't match "\
389 "Handshake Settings")
390
391 if session:
392
393
394 if not session.valid():
395 session = None
396 elif session.resumable:
397 if session.srpUsername != srpUsername:
398 raise ValueError("Session username doesn't match")
399 if session.serverName != serverName:
400 raise ValueError("Session servername doesn't match")
401
402
403 if srpUsername and self.fault == Fault.badUsername:
404 srpUsername += "GARBAGE"
405 if password and self.fault == Fault.badPassword:
406 password += "GARBAGE"
407
408
409
410
411 self.version = settings.maxVersion
412
413
414
415
416
417 for result in self._clientSendClientHello(settings, session,
418 srpUsername, srpParams, certParams,
419 anonParams, serverName, nextProtos,
420 reqTack):
421 if result in (0,1): yield result
422 else: break
423 clientHello = result
424
425
426 for result in self._clientGetServerHello(settings, clientHello):
427 if result in (0,1): yield result
428 else: break
429 serverHello = result
430 cipherSuite = serverHello.cipher_suite
431
432
433
434 nextProto = self._clientSelectNextProto(nextProtos, serverHello)
435
436
437 if serverHello.getExtension(ExtensionType.encrypt_then_mac):
438 self._recordLayer.encryptThenMAC = True
439
440
441 for result in self._clientResume(session, serverHello,
442 clientHello.random,
443 settings.cipherImplementations,
444 nextProto):
445 if result in (0,1): yield result
446 else: break
447 if result == "resumed_and_finished":
448 self._handshakeDone(resumed=True)
449 return
450
451
452
453
454 if cipherSuite in CipherSuite.srpAllSuites:
455 keyExchange = SRPKeyExchange(cipherSuite, clientHello,
456 serverHello, None, None,
457 srpUsername=srpUsername,
458 password=password,
459 settings=settings)
460
461
462
463 elif cipherSuite in CipherSuite.dhAllSuites:
464 keyExchange = DHE_RSAKeyExchange(cipherSuite, clientHello,
465 serverHello, None)
466
467 elif cipherSuite in CipherSuite.ecdhAllSuites:
468 acceptedCurves = self._curveNamesToList(settings)
469 keyExchange = ECDHE_RSAKeyExchange(cipherSuite, clientHello,
470 serverHello, None,
471 acceptedCurves)
472
473
474
475
476
477
478
479 else:
480 keyExchange = RSAKeyExchange(cipherSuite, clientHello,
481 serverHello, None)
482
483 for result in self._clientKeyExchange(settings, cipherSuite,
484 clientCertChain,
485 privateKey,
486 serverHello.certificate_type,
487 serverHello.tackExt,
488 clientHello.random,
489 serverHello.random,
490 keyExchange):
491 if result in (0, 1):
492 yield result
493 else: break
494 (premasterSecret, serverCertChain, clientCertChain,
495 tackExt) = result
496
497
498
499 for result in self._clientFinished(premasterSecret,
500 clientHello.random,
501 serverHello.random,
502 cipherSuite, settings.cipherImplementations,
503 nextProto):
504 if result in (0,1): yield result
505 else: break
506 masterSecret = result
507
508
509 self.session = Session()
510 self.session.create(masterSecret, serverHello.session_id, cipherSuite,
511 srpUsername, clientCertChain, serverCertChain,
512 tackExt, (serverHello.tackExt is not None),
513 serverName,
514 encryptThenMAC=self._recordLayer.encryptThenMAC)
515 self._handshakeDone(resumed=False)
516
517
518 - def _clientSendClientHello(self, settings, session, srpUsername,
519 srpParams, certParams, anonParams,
520 serverName, nextProtos, reqTack):
521
522 cipherSuites = [CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
523 if srpParams:
524 cipherSuites += CipherSuite.getSrpAllSuites(settings)
525 elif certParams:
526 cipherSuites += CipherSuite.getEcdheCertSuites(settings)
527 cipherSuites += CipherSuite.getDheCertSuites(settings)
528 cipherSuites += CipherSuite.getCertSuites(settings)
529 elif anonParams:
530 cipherSuites += CipherSuite.getEcdhAnonSuites(settings)
531 cipherSuites += CipherSuite.getAnonSuites(settings)
532 else:
533 assert False
534
535
536
537 wireCipherSuites = list(cipherSuites)
538 if settings.sendFallbackSCSV:
539 wireCipherSuites.append(CipherSuite.TLS_FALLBACK_SCSV)
540
541
542 certificateTypes = settings.getCertificateTypes()
543
544 extensions = []
545
546
547 if settings.useEncryptThenMAC:
548 extensions.append(TLSExtension().\
549 create(ExtensionType.encrypt_then_mac,
550 bytearray(0)))
551
552 if next((cipher for cipher in cipherSuites \
553 if cipher in CipherSuite.ecdhAllSuites), None) is not None:
554 extensions.append(SupportedGroupsExtension().\
555 create(self._curveNamesToList(settings)))
556 extensions.append(ECPointFormatsExtension().\
557 create([ECPointFormat.uncompressed]))
558
559 if settings.maxVersion >= (3, 3):
560 sigList = self._sigHashesToList(settings)
561 assert len(sigList) > 0
562 extensions.append(SignatureAlgorithmsExtension().\
563 create(sigList))
564
565 if not extensions:
566 extensions = None
567
568
569 if session and session.sessionID:
570
571
572 if session.cipherSuite not in cipherSuites:
573 raise ValueError("Session's cipher suite not consistent "\
574 "with parameters")
575 else:
576 clientHello = ClientHello()
577 clientHello.create(settings.maxVersion, getRandomBytes(32),
578 session.sessionID, wireCipherSuites,
579 certificateTypes,
580 session.srpUsername,
581 reqTack, nextProtos is not None,
582 session.serverName,
583 extensions=extensions)
584
585
586 else:
587 clientHello = ClientHello()
588 clientHello.create(settings.maxVersion, getRandomBytes(32),
589 bytearray(0), wireCipherSuites,
590 certificateTypes,
591 srpUsername,
592 reqTack, nextProtos is not None,
593 serverName,
594 extensions=extensions)
595 for result in self._sendMsg(clientHello):
596 yield result
597 yield clientHello
598
599
601 for result in self._getMsg(ContentType.handshake,
602 HandshakeType.server_hello):
603 if result in (0,1): yield result
604 else: break
605 serverHello = result
606
607
608
609 self.version = serverHello.server_version
610
611
612 if serverHello.server_version < settings.minVersion:
613 for result in self._sendError(\
614 AlertDescription.protocol_version,
615 "Too old version: %s" % str(serverHello.server_version)):
616 yield result
617 if serverHello.server_version > settings.maxVersion:
618 for result in self._sendError(\
619 AlertDescription.protocol_version,
620 "Too new version: %s" % str(serverHello.server_version)):
621 yield result
622 serverVer = serverHello.server_version
623 cipherSuites = CipherSuite.filterForVersion(clientHello.cipher_suites,
624 minVersion=serverVer,
625 maxVersion=serverVer)
626 if serverHello.cipher_suite not in cipherSuites:
627 for result in self._sendError(\
628 AlertDescription.illegal_parameter,
629 "Server responded with incorrect ciphersuite"):
630 yield result
631 if serverHello.certificate_type not in clientHello.certificate_types:
632 for result in self._sendError(\
633 AlertDescription.illegal_parameter,
634 "Server responded with incorrect certificate type"):
635 yield result
636 if serverHello.compression_method != 0:
637 for result in self._sendError(\
638 AlertDescription.illegal_parameter,
639 "Server responded with incorrect compression method"):
640 yield result
641 if serverHello.tackExt:
642 if not clientHello.tack:
643 for result in self._sendError(\
644 AlertDescription.illegal_parameter,
645 "Server responded with unrequested Tack Extension"):
646 yield result
647 if not serverHello.tackExt.verifySignatures():
648 for result in self._sendError(\
649 AlertDescription.decrypt_error,
650 "TackExtension contains an invalid signature"):
651 yield result
652 if serverHello.next_protos and not clientHello.supports_npn:
653 for result in self._sendError(\
654 AlertDescription.illegal_parameter,
655 "Server responded with unrequested NPN Extension"):
656 yield result
657 yield serverHello
658
660
661
662
663
664
665
666
667 if nextProtos is not None and serverHello.next_protos is not None:
668 for p in nextProtos:
669 if bytearray(p) in serverHello.next_protos:
670 return bytearray(p)
671 else:
672
673
674
675 return bytearray(nextProtos[0])
676 return None
677
678 - def _clientResume(self, session, serverHello, clientRandom,
679 cipherImplementations, nextProto):
708
709 - def _clientKeyExchange(self, settings, cipherSuite,
710 clientCertChain, privateKey,
711 certificateType,
712 tackExt, clientRandom, serverRandom,
713 keyExchange):
714 """Perform the client side of key exchange"""
715
716 if cipherSuite in CipherSuite.certAllSuites:
717 for result in self._getMsg(ContentType.handshake,
718 HandshakeType.certificate,
719 certificateType):
720 if result in (0, 1):
721 yield result
722 else: break
723 serverCertificate = result
724 else:
725 serverCertificate = None
726
727 if cipherSuite not in CipherSuite.certSuites:
728 for result in self._getMsg(ContentType.handshake,
729 HandshakeType.server_key_exchange,
730 cipherSuite):
731 if result in (0, 1):
732 yield result
733 else: break
734 serverKeyExchange = result
735 else:
736 serverKeyExchange = None
737
738 for result in self._getMsg(ContentType.handshake,
739 (HandshakeType.certificate_request,
740 HandshakeType.server_hello_done)):
741 if result in (0, 1):
742 yield result
743 else: break
744
745 certificateRequest = None
746 if isinstance(result, CertificateRequest):
747 certificateRequest = result
748
749
750 if cipherSuite not in CipherSuite.certAllSuites \
751 or cipherSuite in CipherSuite.srpAllSuites:
752 for result in self._sendError(\
753 AlertDescription.unexpected_message,
754 "Certificate Request with incompatible cipher suite"):
755 yield result
756
757
758 for result in self._getMsg(ContentType.handshake,
759 HandshakeType.server_hello_done):
760 if result in (0, 1):
761 yield result
762 else: break
763 serverHelloDone = result
764
765 serverCertChain = None
766 publicKey = None
767 if cipherSuite in CipherSuite.certAllSuites:
768
769 for result in self._clientGetKeyFromChain(serverCertificate,
770 settings,
771 tackExt):
772 if result in (0, 1):
773 yield result
774 else: break
775 publicKey, serverCertChain, tackExt = result
776
777
778
779 if serverKeyExchange:
780 validSigAlgs = self._sigHashesToList(settings)
781 try:
782 KeyExchange.verifyServerKeyExchange(serverKeyExchange,
783 publicKey,
784 clientRandom,
785 serverRandom,
786 validSigAlgs)
787 except TLSIllegalParameterException:
788 for result in self._sendError(AlertDescription.\
789 illegal_parameter):
790 yield result
791 except TLSDecryptionFailed:
792 for result in self._sendError(\
793 AlertDescription.decrypt_error):
794 yield result
795
796 if serverKeyExchange:
797
798 if self.version >= (3, 3) \
799 and cipherSuite in CipherSuite.certAllSuites \
800 and cipherSuite not in CipherSuite.certSuites:
801 self.serverSigAlg = (serverKeyExchange.hashAlg,
802 serverKeyExchange.signAlg)
803
804 if cipherSuite in CipherSuite.dhAllSuites:
805 self.dhGroupSize = numBits(serverKeyExchange.dh_p)
806 if cipherSuite in CipherSuite.ecdhAllSuites:
807 self.ecdhCurve = serverKeyExchange.named_curve
808
809
810 if certificateRequest:
811
812
813
814 if self.version == (3, 3)\
815 and not [sig for sig in \
816 certificateRequest.supported_signature_algs\
817 if sig[1] == SignatureAlgorithm.rsa]:
818 for result in self._sendError(\
819 AlertDescription.handshake_failure,
820 "Server doesn't accept any sigalgs we support: " +
821 str(certificateRequest.supported_signature_algs)):
822 yield result
823 clientCertificate = Certificate(certificateType)
824
825 if clientCertChain:
826
827
828 if certificateType == CertificateType.x509 \
829 and not isinstance(clientCertChain, X509CertChain):
830 for result in self._sendError(\
831 AlertDescription.handshake_failure,
832 "Client certificate is of wrong type"):
833 yield result
834
835 clientCertificate.create(clientCertChain)
836
837 for result in self._sendMsg(clientCertificate):
838 yield result
839 else:
840
841 privateKey = None
842 clientCertChain = None
843
844 try:
845 ske = serverKeyExchange
846 premasterSecret = keyExchange.processServerKeyExchange(publicKey,
847 ske)
848 except TLSInsufficientSecurity as e:
849 for result in self._sendError(\
850 AlertDescription.insufficient_security, e):
851 yield result
852 except TLSIllegalParameterException as e:
853 for result in self._sendError(\
854 AlertDescription.illegal_parameter, e):
855 yield result
856
857 clientKeyExchange = keyExchange.makeClientKeyExchange()
858
859
860 for result in self._sendMsg(clientKeyExchange):
861 yield result
862
863
864
865 if certificateRequest and privateKey:
866 validSigAlgs = self._sigHashesToList(settings)
867 certificateVerify = KeyExchange.makeCertificateVerify(\
868 self.version,
869 self._handshake_hash,
870 validSigAlgs,
871 privateKey,
872 certificateRequest,
873 premasterSecret,
874 clientRandom,
875 serverRandom)
876 for result in self._sendMsg(certificateVerify):
877 yield result
878
879 yield (premasterSecret, serverCertChain, clientCertChain, tackExt)
880
881 - def _clientFinished(self, premasterSecret, clientRandom, serverRandom,
882 cipherSuite, cipherImplementations, nextProto):
883
884 masterSecret = calcMasterSecret(self.version,
885 cipherSuite,
886 premasterSecret,
887 clientRandom,
888 serverRandom)
889 self._calcPendingStates(cipherSuite, masterSecret,
890 clientRandom, serverRandom,
891 cipherImplementations)
892
893
894 for result in self._sendFinished(masterSecret, cipherSuite, nextProto):
895 yield result
896 for result in self._getFinished(masterSecret,
897 cipherSuite,
898 nextProto=nextProto):
899 yield result
900 yield masterSecret
901
938
939
940
941
942
943
944
945 - def handshakeServer(self, verifierDB=None,
946 certChain=None, privateKey=None, reqCert=False,
947 sessionCache=None, settings=None, checker=None,
948 reqCAs = None,
949 tacks=None, activationFlags=0,
950 nextProtos=None, anon=False):
951 """Perform a handshake in the role of server.
952
953 This function performs an SSL or TLS handshake. Depending on
954 the arguments and the behavior of the client, this function can
955 perform an SRP, or certificate-based handshake. It
956 can also perform a combined SRP and server-certificate
957 handshake.
958
959 Like any handshake function, this can be called on a closed
960 TLS connection, or on a TLS connection that is already open.
961 If called on an open connection it performs a re-handshake.
962 This function does not send a Hello Request message before
963 performing the handshake, so if re-handshaking is required,
964 the server must signal the client to begin the re-handshake
965 through some other means.
966
967 If the function completes without raising an exception, the
968 TLS connection will be open and available for data transfer.
969
970 If an exception is raised, the connection will have been
971 automatically closed (if it was ever open).
972
973 @type verifierDB: L{tlslite.verifierdb.VerifierDB}
974 @param verifierDB: A database of SRP password verifiers
975 associated with usernames. If the client performs an SRP
976 handshake, the session's srpUsername attribute will be set.
977
978 @type certChain: L{tlslite.x509certchain.X509CertChain}
979 @param certChain: The certificate chain to be used if the
980 client requests server certificate authentication.
981
982 @type privateKey: L{tlslite.utils.rsakey.RSAKey}
983 @param privateKey: The private key to be used if the client
984 requests server certificate authentication.
985
986 @type reqCert: bool
987 @param reqCert: Whether to request client certificate
988 authentication. This only applies if the client chooses server
989 certificate authentication; if the client chooses SRP
990 authentication, this will be ignored. If the client
991 performs a client certificate authentication, the sessions's
992 clientCertChain attribute will be set.
993
994 @type sessionCache: L{tlslite.sessioncache.SessionCache}
995 @param sessionCache: An in-memory cache of resumable sessions.
996 The client can resume sessions from this cache. Alternatively,
997 if the client performs a full handshake, a new session will be
998 added to the cache.
999
1000 @type settings: L{tlslite.handshakesettings.HandshakeSettings}
1001 @param settings: Various settings which can be used to control
1002 the ciphersuites and SSL/TLS version chosen by the server.
1003
1004 @type checker: L{tlslite.checker.Checker}
1005 @param checker: A Checker instance. This instance will be
1006 invoked to examine the other party's authentication
1007 credentials, if the handshake completes succesfully.
1008
1009 @type reqCAs: list of L{bytearray} of unsigned bytes
1010 @param reqCAs: A collection of DER-encoded DistinguishedNames that
1011 will be sent along with a certificate request. This does not affect
1012 verification.
1013
1014 @type nextProtos: list of strings.
1015 @param nextProtos: A list of upper layer protocols to expose to the
1016 clients through the Next-Protocol Negotiation Extension,
1017 if they support it.
1018
1019 @raise socket.error: If a socket error occurs.
1020 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
1021 without a preceding alert.
1022 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
1023 @raise tlslite.errors.TLSAuthenticationError: If the checker
1024 doesn't like the other party's authentication credentials.
1025 """
1026 for result in self.handshakeServerAsync(verifierDB,
1027 certChain, privateKey, reqCert, sessionCache, settings,
1028 checker, reqCAs,
1029 tacks=tacks, activationFlags=activationFlags,
1030 nextProtos=nextProtos, anon=anon):
1031 pass
1032
1033
1034 - def handshakeServerAsync(self, verifierDB=None,
1035 certChain=None, privateKey=None, reqCert=False,
1036 sessionCache=None, settings=None, checker=None,
1037 reqCAs=None,
1038 tacks=None, activationFlags=0,
1039 nextProtos=None, anon=False
1040 ):
1041 """Start a server handshake operation on the TLS connection.
1042
1043 This function returns a generator which behaves similarly to
1044 handshakeServer(). Successive invocations of the generator
1045 will return 0 if it is waiting to read from the socket, 1 if it is
1046 waiting to write to the socket, or it will raise StopIteration
1047 if the handshake operation is complete.
1048
1049 @rtype: iterable
1050 @return: A generator; see above for details.
1051 """
1052 handshaker = self._handshakeServerAsyncHelper(\
1053 verifierDB=verifierDB, certChain=certChain,
1054 privateKey=privateKey, reqCert=reqCert,
1055 sessionCache=sessionCache, settings=settings,
1056 reqCAs=reqCAs,
1057 tacks=tacks, activationFlags=activationFlags,
1058 nextProtos=nextProtos, anon=anon)
1059 for result in self._handshakeWrapperAsync(handshaker, checker):
1060 yield result
1061
1062
1063 - def _handshakeServerAsyncHelper(self, verifierDB,
1064 certChain, privateKey, reqCert, sessionCache,
1065 settings, reqCAs,
1066 tacks, activationFlags,
1067 nextProtos, anon):
1068
1069 self._handshakeStart(client=False)
1070
1071 if (not verifierDB) and (not certChain) and not anon:
1072 raise ValueError("Caller passed no authentication credentials")
1073 if certChain and not privateKey:
1074 raise ValueError("Caller passed a certChain but no privateKey")
1075 if privateKey and not certChain:
1076 raise ValueError("Caller passed a privateKey but no certChain")
1077 if reqCAs and not reqCert:
1078 raise ValueError("Caller passed reqCAs but not reqCert")
1079 if certChain and not isinstance(certChain, X509CertChain):
1080 raise ValueError("Unrecognized certificate type")
1081 if activationFlags and not tacks:
1082 raise ValueError("Nonzero activationFlags requires tacks")
1083 if tacks:
1084 if not tackpyLoaded:
1085 raise ValueError("tackpy is not loaded")
1086 if not settings or not settings.useExperimentalTackExtension:
1087 raise ValueError("useExperimentalTackExtension not enabled")
1088
1089 if not settings:
1090 settings = HandshakeSettings()
1091 settings = settings.validate()
1092
1093
1094
1095
1096
1097 for result in self._serverGetClientHello(settings, certChain,\
1098 verifierDB, sessionCache,
1099 anon):
1100 if result in (0,1): yield result
1101 elif result == None:
1102 self._handshakeDone(resumed=True)
1103 return
1104 else: break
1105 (clientHello, cipherSuite) = result
1106
1107
1108
1109
1110 if sessionCache:
1111 sessionID = getRandomBytes(32)
1112 else:
1113 sessionID = bytearray(0)
1114
1115 if not clientHello.supports_npn:
1116 nextProtos = None
1117
1118
1119 if not cipherSuite in CipherSuite.certAllSuites:
1120 tacks = None
1121
1122
1123 if clientHello.tack:
1124 tackExt = TackExtension.create(tacks, activationFlags)
1125 else:
1126 tackExt = None
1127
1128
1129 if settings.useEncryptThenMAC and \
1130 clientHello.getExtension(ExtensionType.encrypt_then_mac) and \
1131 cipherSuite not in CipherSuite.streamSuites and \
1132 cipherSuite not in CipherSuite.aeadSuites:
1133 extensions = [TLSExtension().create(ExtensionType.encrypt_then_mac,
1134 bytearray(0))]
1135 self._recordLayer.encryptThenMAC = True
1136 else:
1137 extensions = None
1138
1139 serverHello = ServerHello()
1140 serverHello.create(self.version, getRandomBytes(32), sessionID, \
1141 cipherSuite, CertificateType.x509, tackExt,
1142 nextProtos, extensions=extensions)
1143
1144
1145 clientCertChain = None
1146 if cipherSuite in CipherSuite.srpAllSuites:
1147 for result in self._serverSRPKeyExchange(clientHello, serverHello,
1148 verifierDB, cipherSuite,
1149 privateKey, certChain,
1150 settings):
1151 if result in (0, 1):
1152 yield result
1153 else: break
1154 premasterSecret = result
1155
1156
1157 elif (cipherSuite in CipherSuite.certSuites or
1158 cipherSuite in CipherSuite.dheCertSuites or
1159 cipherSuite in CipherSuite.ecdheCertSuites):
1160 if cipherSuite in CipherSuite.certSuites:
1161 keyExchange = RSAKeyExchange(cipherSuite,
1162 clientHello,
1163 serverHello,
1164 privateKey)
1165 elif cipherSuite in CipherSuite.dheCertSuites:
1166 keyExchange = DHE_RSAKeyExchange(cipherSuite,
1167 clientHello,
1168 serverHello,
1169 privateKey)
1170 elif cipherSuite in CipherSuite.ecdheCertSuites:
1171 acceptedCurves = self._curveNamesToList(settings)
1172 keyExchange = ECDHE_RSAKeyExchange(cipherSuite,
1173 clientHello,
1174 serverHello,
1175 privateKey,
1176 acceptedCurves)
1177 else:
1178 assert(False)
1179 for result in self._serverCertKeyExchange(clientHello, serverHello,
1180 certChain, keyExchange,
1181 reqCert, reqCAs, cipherSuite,
1182 settings):
1183 if result in (0,1): yield result
1184 else: break
1185 (premasterSecret, clientCertChain) = result
1186
1187
1188 elif cipherSuite in CipherSuite.anonSuites:
1189 for result in self._serverAnonKeyExchange(clientHello, serverHello,
1190 cipherSuite, settings):
1191 if result in (0,1): yield result
1192 else: break
1193 premasterSecret = result
1194
1195 else:
1196 assert(False)
1197
1198
1199 for result in self._serverFinished(premasterSecret,
1200 clientHello.random, serverHello.random,
1201 cipherSuite, settings.cipherImplementations,
1202 nextProtos):
1203 if result in (0,1): yield result
1204 else: break
1205 masterSecret = result
1206
1207
1208 self.session = Session()
1209 if cipherSuite in CipherSuite.certAllSuites:
1210 serverCertChain = certChain
1211 else:
1212 serverCertChain = None
1213 srpUsername = None
1214 serverName = None
1215 if clientHello.srp_username:
1216 srpUsername = clientHello.srp_username.decode("utf-8")
1217 if clientHello.server_name:
1218 serverName = clientHello.server_name.decode("utf-8")
1219 self.session.create(masterSecret, serverHello.session_id, cipherSuite,
1220 srpUsername, clientCertChain, serverCertChain,
1221 tackExt, (serverHello.tackExt is not None),
1222 serverName,
1223 encryptThenMAC=self._recordLayer.encryptThenMAC)
1224
1225
1226 if sessionCache and sessionID:
1227 sessionCache[sessionID] = self.session
1228
1229 self._handshakeDone(resumed=False)
1230
1231
1234
1235
1236
1237 self.version = settings.maxVersion
1238
1239
1240 for result in self._getMsg(ContentType.handshake,
1241 HandshakeType.client_hello):
1242 if result in (0,1): yield result
1243 else: break
1244 clientHello = result
1245
1246
1247 if clientHello.client_version < settings.minVersion:
1248 self.version = settings.minVersion
1249 for result in self._sendError(\
1250 AlertDescription.protocol_version,
1251 "Too old version: %s" % str(clientHello.client_version)):
1252 yield result
1253
1254
1255 elif clientHello.client_version > settings.maxVersion:
1256 self.version = settings.maxVersion
1257
1258 else:
1259
1260 self.version = clientHello.client_version
1261
1262
1263 if clientHello.client_version < settings.maxVersion and \
1264 CipherSuite.TLS_FALLBACK_SCSV in clientHello.cipher_suites:
1265 for result in self._sendError(\
1266 AlertDescription.inappropriate_fallback):
1267 yield result
1268
1269
1270
1271 client_groups = clientHello.getExtension(ExtensionType.supported_groups)
1272 group_intersect = []
1273 if client_groups is not None:
1274 client_groups = client_groups.groups
1275 if client_groups is None:
1276 client_groups = []
1277 server_groups = self._curveNamesToList(settings)
1278 group_intersect = [x for x in client_groups if x in server_groups]
1279
1280
1281
1282 cipherSuites = []
1283 if verifierDB:
1284 if certChain:
1285 cipherSuites += \
1286 CipherSuite.getSrpCertSuites(settings, self.version)
1287 cipherSuites += CipherSuite.getSrpSuites(settings, self.version)
1288 elif certChain:
1289 if group_intersect:
1290 cipherSuites += CipherSuite.getEcdheCertSuites(settings,
1291 self.version)
1292 cipherSuites += CipherSuite.getDheCertSuites(settings, self.version)
1293 cipherSuites += CipherSuite.getCertSuites(settings, self.version)
1294 elif anon:
1295 cipherSuites += CipherSuite.getAnonSuites(settings, self.version)
1296 else:
1297 assert(False)
1298 cipherSuites = CipherSuite.filterForVersion(cipherSuites,
1299 minVersion=self.version,
1300 maxVersion=self.version)
1301
1302
1303 if clientHello.session_id and sessionCache:
1304 session = None
1305
1306
1307 if sessionCache and not session:
1308 try:
1309 session = sessionCache[clientHello.session_id]
1310 if not session.resumable:
1311 raise AssertionError()
1312
1313 if session.cipherSuite not in cipherSuites:
1314 for result in self._sendError(\
1315 AlertDescription.handshake_failure):
1316 yield result
1317 if session.cipherSuite not in clientHello.cipher_suites:
1318 for result in self._sendError(\
1319 AlertDescription.handshake_failure):
1320 yield result
1321 if clientHello.srp_username:
1322 if not session.srpUsername or \
1323 clientHello.srp_username != bytearray(session.srpUsername, "utf-8"):
1324 for result in self._sendError(\
1325 AlertDescription.handshake_failure):
1326 yield result
1327 if clientHello.server_name:
1328 if not session.serverName or \
1329 clientHello.server_name != bytearray(session.serverName, "utf-8"):
1330 for result in self._sendError(\
1331 AlertDescription.handshake_failure):
1332 yield result
1333 if session.encryptThenMAC and \
1334 not clientHello.getExtension(
1335 ExtensionType.encrypt_then_mac):
1336 for result in self._sendError(\
1337 AlertDescription.handshake_failure):
1338 yield result
1339 except KeyError:
1340 pass
1341
1342
1343 if session:
1344
1345 if session.encryptThenMAC:
1346 self._recordLayer.encryptThenMAC = True
1347 mte = TLSExtension().create(ExtensionType.encrypt_then_mac,
1348 bytearray(0))
1349 extensions = [mte]
1350 else:
1351 extensions = None
1352 serverHello = ServerHello()
1353 serverHello.create(self.version, getRandomBytes(32),
1354 session.sessionID, session.cipherSuite,
1355 CertificateType.x509, None, None,
1356 extensions=extensions)
1357 for result in self._sendMsg(serverHello):
1358 yield result
1359
1360
1361 self._calcPendingStates(session.cipherSuite,
1362 session.masterSecret,
1363 clientHello.random,
1364 serverHello.random,
1365 settings.cipherImplementations)
1366
1367
1368 for result in self._sendFinished(session.masterSecret,
1369 session.cipherSuite):
1370 yield result
1371 for result in self._getFinished(session.masterSecret,
1372 session.cipherSuite):
1373 yield result
1374
1375
1376 self.session = session
1377
1378 yield None
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388 for cipherSuite in cipherSuites:
1389 if cipherSuite in clientHello.cipher_suites:
1390 break
1391 else:
1392 for result in self._sendError(\
1393 AlertDescription.handshake_failure,
1394 "No mutual ciphersuite"):
1395 yield result
1396 if cipherSuite in CipherSuite.srpAllSuites and \
1397 not clientHello.srp_username:
1398 for result in self._sendError(\
1399 AlertDescription.unknown_psk_identity,
1400 "Client sent a hello, but without the SRP username"):
1401 yield result
1402
1403
1404 if cipherSuite in CipherSuite.certAllSuites and CertificateType.x509 \
1405 not in clientHello.certificate_types:
1406 for result in self._sendError(\
1407 AlertDescription.handshake_failure,
1408 "the client doesn't support my certificate type"):
1409 yield result
1410
1411
1412
1413
1414 yield (clientHello, cipherSuite)
1415
1416 - def _serverSRPKeyExchange(self, clientHello, serverHello, verifierDB,
1417 cipherSuite, privateKey, serverCertChain,
1418 settings):
1463
1464 - def _serverCertKeyExchange(self, clientHello, serverHello,
1465 serverCertChain, keyExchange,
1466 reqCert, reqCAs, cipherSuite,
1467 settings):
1468
1469
1470 msgs = []
1471
1472
1473 clientCertChain = None
1474
1475 msgs.append(serverHello)
1476 msgs.append(Certificate(CertificateType.x509).create(serverCertChain))
1477 sigHashAlg = self._pickServerKeyExchangeSig(settings, clientHello)
1478 serverKeyExchange = keyExchange.makeServerKeyExchange(sigHashAlg)
1479 if serverKeyExchange is not None:
1480 msgs.append(serverKeyExchange)
1481 if reqCert:
1482 certificateRequest = CertificateRequest(self.version)
1483 if not reqCAs:
1484 reqCAs = []
1485 validSigAlgs = self._sigHashesToList(settings)
1486 certificateRequest.create([ClientCertificateType.rsa_sign],
1487 reqCAs,
1488 validSigAlgs)
1489 msgs.append(certificateRequest)
1490 msgs.append(ServerHelloDone())
1491 for result in self._sendMsgs(msgs):
1492 yield result
1493
1494
1495 if reqCert:
1496 if self.version == (3,0):
1497 for result in self._getMsg((ContentType.handshake,
1498 ContentType.alert),
1499 HandshakeType.certificate,
1500 CertificateType.x509):
1501 if result in (0,1): yield result
1502 else: break
1503 msg = result
1504
1505 if isinstance(msg, Alert):
1506
1507 alert = msg
1508 if alert.description != \
1509 AlertDescription.no_certificate:
1510 self._shutdown(False)
1511 raise TLSRemoteAlert(alert)
1512 elif isinstance(msg, Certificate):
1513 clientCertificate = msg
1514 if clientCertificate.certChain and \
1515 clientCertificate.certChain.getNumCerts()!=0:
1516 clientCertChain = clientCertificate.certChain
1517 else:
1518 raise AssertionError()
1519 elif self.version in ((3,1), (3,2), (3,3)):
1520 for result in self._getMsg(ContentType.handshake,
1521 HandshakeType.certificate,
1522 CertificateType.x509):
1523 if result in (0,1): yield result
1524 else: break
1525 clientCertificate = result
1526 if clientCertificate.certChain and \
1527 clientCertificate.certChain.getNumCerts()!=0:
1528 clientCertChain = clientCertificate.certChain
1529 else:
1530 raise AssertionError()
1531
1532
1533 for result in self._getMsg(ContentType.handshake,
1534 HandshakeType.client_key_exchange,
1535 cipherSuite):
1536 if result in (0,1): yield result
1537 else: break
1538 clientKeyExchange = result
1539
1540
1541 try:
1542 premasterSecret = \
1543 keyExchange.processClientKeyExchange(clientKeyExchange)
1544 except TLSLocalAlert as alert:
1545 for result in self._sendError(alert.description, alert.message):
1546 yield result
1547
1548
1549 if clientCertChain:
1550 handshakeHash = self._handshake_hash.copy()
1551 for result in self._getMsg(ContentType.handshake,
1552 HandshakeType.certificate_verify):
1553 if result in (0, 1):
1554 yield result
1555 else: break
1556 certificateVerify = result
1557 signatureAlgorithm = None
1558 if self.version == (3, 3):
1559 validSigAlgs = self._sigHashesToList(settings)
1560 if certificateVerify.signatureAlgorithm not in validSigAlgs:
1561 for result in self._sendError(\
1562 AlertDescription.decryption_failed,
1563 "Invalid signature on Certificate Verify"):
1564 yield result
1565 signatureAlgorithm = certificateVerify.signatureAlgorithm
1566
1567 verifyBytes = KeyExchange.calcVerifyBytes(self.version,
1568 handshakeHash,
1569 signatureAlgorithm,
1570 premasterSecret,
1571 clientHello.random,
1572 serverHello.random)
1573 publicKey = clientCertChain.getEndEntityPublicKey()
1574 if len(publicKey) < settings.minKeySize:
1575 for result in self._sendError(\
1576 AlertDescription.handshake_failure,
1577 "Client's public key too small: %d" % len(publicKey)):
1578 yield result
1579
1580 if len(publicKey) > settings.maxKeySize:
1581 for result in self._sendError(\
1582 AlertDescription.handshake_failure,
1583 "Client's public key too large: %d" % len(publicKey)):
1584 yield result
1585
1586 if not publicKey.verify(certificateVerify.signature, verifyBytes):
1587 for result in self._sendError(\
1588 AlertDescription.decrypt_error,
1589 "Signature failed to verify"):
1590 yield result
1591 yield (premasterSecret, clientCertChain)
1592
1593
1596
1597
1598 dh_g, dh_p = goodGroupParameters[2]
1599 dh_Xs = bytesToNumber(getRandomBytes(32))
1600 dh_Ys = powMod(dh_g, dh_Xs, dh_p)
1601
1602
1603 serverKeyExchange = ServerKeyExchange(cipherSuite, self.version)
1604 serverKeyExchange.createDH(dh_p, dh_g, dh_Ys)
1605
1606
1607
1608 msgs = []
1609 msgs.append(serverHello)
1610 msgs.append(serverKeyExchange)
1611 msgs.append(ServerHelloDone())
1612 for result in self._sendMsgs(msgs):
1613 yield result
1614
1615
1616 for result in self._getMsg(ContentType.handshake,
1617 HandshakeType.client_key_exchange,
1618 cipherSuite):
1619 if result in (0,1):
1620 yield result
1621 else:
1622 break
1623 clientKeyExchange = result
1624 dh_Yc = clientKeyExchange.dh_Yc
1625
1626 if dh_Yc % dh_p == 0:
1627 for result in self._sendError(AlertDescription.illegal_parameter,
1628 "Suspicious dh_Yc value"):
1629 yield result
1630 assert(False)
1631
1632
1633 S = powMod(dh_Yc,dh_Xs,dh_p)
1634 premasterSecret = numberToByteArray(S)
1635
1636 yield premasterSecret
1637
1638
1639 - def _serverFinished(self, premasterSecret, clientRandom, serverRandom,
1640 cipherSuite, cipherImplementations, nextProtos):
1641 masterSecret = calcMasterSecret(self.version,
1642 cipherSuite,
1643 premasterSecret,
1644 clientRandom,
1645 serverRandom)
1646
1647
1648 self._calcPendingStates(cipherSuite, masterSecret,
1649 clientRandom, serverRandom,
1650 cipherImplementations)
1651
1652
1653 for result in self._getFinished(masterSecret,
1654 cipherSuite,
1655 expect_next_protocol=nextProtos is not None):
1656 yield result
1657
1658 for result in self._sendFinished(masterSecret, cipherSuite):
1659 yield result
1660
1661 yield masterSecret
1662
1663
1664
1665
1666
1667
1668
1669 - def _sendFinished(self, masterSecret, cipherSuite=None, nextProto=None):
1695
1696 - def _getFinished(self, masterSecret, cipherSuite=None,
1697 expect_next_protocol=False, nextProto=None):
1698
1699 for result in self._getMsg(ContentType.change_cipher_spec):
1700 if result in (0,1):
1701 yield result
1702 changeCipherSpec = result
1703
1704 if changeCipherSpec.type != 1:
1705 for result in self._sendError(AlertDescription.illegal_parameter,
1706 "ChangeCipherSpec type incorrect"):
1707 yield result
1708
1709
1710 self._changeReadState()
1711
1712
1713 if expect_next_protocol:
1714 for result in self._getMsg(ContentType.handshake, HandshakeType.next_protocol):
1715 if result in (0,1):
1716 yield result
1717 if result is None:
1718 for result in self._sendError(AlertDescription.unexpected_message,
1719 "Didn't get NextProtocol message"):
1720 yield result
1721
1722 self.next_proto = result.next_proto
1723 else:
1724 self.next_proto = None
1725
1726
1727 if nextProto:
1728 self.next_proto = nextProto
1729
1730
1731 verifyData = calcFinished(self.version,
1732 masterSecret,
1733 cipherSuite,
1734 self._handshake_hash,
1735 not self._client)
1736
1737
1738 for result in self._getMsg(ContentType.handshake,
1739 HandshakeType.finished):
1740 if result in (0,1):
1741 yield result
1742 finished = result
1743 if finished.verify_data != verifyData:
1744 for result in self._sendError(AlertDescription.decrypt_error,
1745 "Finished message is incorrect"):
1746 yield result
1747
1773
1774 @staticmethod
1776 """Pick a hash that matches most closely the supported ones"""
1777 hashAndAlgsExt = clientHello.getExtension(\
1778 ExtensionType.signature_algorithms)
1779
1780 if hashAndAlgsExt is None or hashAndAlgsExt.sigalgs is None:
1781
1782
1783 return "sha1"
1784
1785 rsaHashes = [alg[0] for alg in hashAndAlgsExt.sigalgs
1786 if alg[1] == SignatureAlgorithm.rsa]
1787 for hashName in settings.rsaSigHashes:
1788 hashID = getattr(HashAlgorithm, hashName)
1789 if hashID in rsaHashes:
1790 return hashName
1791
1792
1793 return "sha1"
1794
1795 @staticmethod
1797 """Convert list of valid signature hashes to array of tuples"""
1798 sigAlgs = []
1799 for hashName in settings.rsaSigHashes:
1800 sigAlgs.append((getattr(HashAlgorithm, hashName),
1801 SignatureAlgorithm.rsa))
1802 return sigAlgs
1803
1804 @staticmethod
1806 """Convert list of acceptable curves to array identifiers"""
1807 return [getattr(GroupName, val) for val in settings.eccCurves]
1808