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