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
489 self.sock.buffer_writes = True
490 for result in self._clientKeyExchange(settings, cipherSuite,
491 clientCertChain,
492 privateKey,
493 serverHello.certificate_type,
494 serverHello.tackExt,
495 clientHello.random,
496 serverHello.random,
497 keyExchange):
498 if result in (0, 1):
499 yield result
500 else: break
501 (premasterSecret, serverCertChain, clientCertChain,
502 tackExt) = result
503
504
505
506
507 for result in self._clientFinished(premasterSecret,
508 clientHello.random,
509 serverHello.random,
510 cipherSuite, settings.cipherImplementations,
511 nextProto):
512 if result in (0,1): yield result
513 else: break
514 masterSecret = result
515
516
517 self.session = Session()
518 self.session.create(masterSecret, serverHello.session_id, cipherSuite,
519 srpUsername, clientCertChain, serverCertChain,
520 tackExt, (serverHello.tackExt is not None),
521 serverName,
522 encryptThenMAC=self._recordLayer.encryptThenMAC,
523 extendedMasterSecret=self.extendedMasterSecret)
524 self._handshakeDone(resumed=False)
525
526
527 - def _clientSendClientHello(self, settings, session, srpUsername,
528 srpParams, certParams, anonParams,
529 serverName, nextProtos, reqTack):
530
531 cipherSuites = [CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
532 if srpParams:
533 cipherSuites += CipherSuite.getSrpAllSuites(settings)
534 elif certParams:
535 cipherSuites += CipherSuite.getEcdheCertSuites(settings)
536 cipherSuites += CipherSuite.getDheCertSuites(settings)
537 cipherSuites += CipherSuite.getCertSuites(settings)
538 elif anonParams:
539 cipherSuites += CipherSuite.getEcdhAnonSuites(settings)
540 cipherSuites += CipherSuite.getAnonSuites(settings)
541 else:
542 assert False
543
544
545
546 wireCipherSuites = list(cipherSuites)
547 if settings.sendFallbackSCSV:
548 wireCipherSuites.append(CipherSuite.TLS_FALLBACK_SCSV)
549
550
551 certificateTypes = settings.getCertificateTypes()
552
553 extensions = []
554
555
556 if settings.useEncryptThenMAC:
557 extensions.append(TLSExtension().\
558 create(ExtensionType.encrypt_then_mac,
559 bytearray(0)))
560 if settings.useExtendedMasterSecret:
561 extensions.append(TLSExtension().create(ExtensionType.
562 extended_master_secret,
563 bytearray(0)))
564
565 if next((cipher for cipher in cipherSuites \
566 if cipher in CipherSuite.ecdhAllSuites), None) is not None:
567 extensions.append(SupportedGroupsExtension().\
568 create(self._curveNamesToList(settings)))
569 extensions.append(ECPointFormatsExtension().\
570 create([ECPointFormat.uncompressed]))
571
572 if settings.maxVersion >= (3, 3):
573 sigList = self._sigHashesToList(settings)
574 assert len(sigList) > 0
575 extensions.append(SignatureAlgorithmsExtension().\
576 create(sigList))
577
578 if not extensions or settings.maxVersion == (3, 0):
579 extensions = None
580
581
582 if session and session.sessionID:
583
584
585 if session.cipherSuite not in cipherSuites:
586 raise ValueError("Session's cipher suite not consistent "\
587 "with parameters")
588 else:
589 clientHello = ClientHello()
590 clientHello.create(settings.maxVersion, getRandomBytes(32),
591 session.sessionID, wireCipherSuites,
592 certificateTypes,
593 session.srpUsername,
594 reqTack, nextProtos is not None,
595 session.serverName,
596 extensions=extensions)
597
598
599 else:
600 clientHello = ClientHello()
601 clientHello.create(settings.maxVersion, getRandomBytes(32),
602 bytearray(0), wireCipherSuites,
603 certificateTypes,
604 srpUsername,
605 reqTack, nextProtos is not None,
606 serverName,
607 extensions=extensions)
608
609
610
611 if settings.usePaddingExtension:
612 HandshakeHelpers.alignClientHelloPadding(clientHello)
613
614 for result in self._sendMsg(clientHello):
615 yield result
616 yield clientHello
617
618
620 for result in self._getMsg(ContentType.handshake,
621 HandshakeType.server_hello):
622 if result in (0,1): yield result
623 else: break
624 serverHello = result
625
626
627
628 self.version = serverHello.server_version
629
630
631 if serverHello.server_version < settings.minVersion:
632 for result in self._sendError(\
633 AlertDescription.protocol_version,
634 "Too old version: %s" % str(serverHello.server_version)):
635 yield result
636 if serverHello.server_version > settings.maxVersion:
637 for result in self._sendError(\
638 AlertDescription.protocol_version,
639 "Too new version: %s" % str(serverHello.server_version)):
640 yield result
641 serverVer = serverHello.server_version
642 cipherSuites = CipherSuite.filterForVersion(clientHello.cipher_suites,
643 minVersion=serverVer,
644 maxVersion=serverVer)
645 if serverHello.cipher_suite not in cipherSuites:
646 for result in self._sendError(\
647 AlertDescription.illegal_parameter,
648 "Server responded with incorrect ciphersuite"):
649 yield result
650 if serverHello.certificate_type not in clientHello.certificate_types:
651 for result in self._sendError(\
652 AlertDescription.illegal_parameter,
653 "Server responded with incorrect certificate type"):
654 yield result
655 if serverHello.compression_method != 0:
656 for result in self._sendError(\
657 AlertDescription.illegal_parameter,
658 "Server responded with incorrect compression method"):
659 yield result
660 if serverHello.tackExt:
661 if not clientHello.tack:
662 for result in self._sendError(\
663 AlertDescription.illegal_parameter,
664 "Server responded with unrequested Tack Extension"):
665 yield result
666 if not serverHello.tackExt.verifySignatures():
667 for result in self._sendError(\
668 AlertDescription.decrypt_error,
669 "TackExtension contains an invalid signature"):
670 yield result
671 if serverHello.next_protos and not clientHello.supports_npn:
672 for result in self._sendError(\
673 AlertDescription.illegal_parameter,
674 "Server responded with unrequested NPN Extension"):
675 yield result
676 if not serverHello.getExtension(ExtensionType.extended_master_secret)\
677 and settings.requireExtendedMasterSecret:
678 for result in self._sendError(
679 AlertDescription.insufficient_security,
680 "Negotiation of Extended master Secret failed"):
681 yield result
682 yield serverHello
683
685
686
687
688
689
690
691
692 if nextProtos is not None and serverHello.next_protos is not None:
693 for p in nextProtos:
694 if bytearray(p) in serverHello.next_protos:
695 return bytearray(p)
696 else:
697
698
699
700 return bytearray(nextProtos[0])
701 return None
702
703 - def _clientResume(self, session, serverHello, clientRandom,
704 cipherImplementations, nextProto):
737
738 - def _clientKeyExchange(self, settings, cipherSuite,
739 clientCertChain, privateKey,
740 certificateType,
741 tackExt, clientRandom, serverRandom,
742 keyExchange):
743 """Perform the client side of key exchange"""
744
745 if cipherSuite in CipherSuite.certAllSuites:
746 for result in self._getMsg(ContentType.handshake,
747 HandshakeType.certificate,
748 certificateType):
749 if result in (0, 1):
750 yield result
751 else: break
752 serverCertificate = result
753 else:
754 serverCertificate = None
755
756 if cipherSuite not in CipherSuite.certSuites:
757 for result in self._getMsg(ContentType.handshake,
758 HandshakeType.server_key_exchange,
759 cipherSuite):
760 if result in (0, 1):
761 yield result
762 else: break
763 serverKeyExchange = result
764 else:
765 serverKeyExchange = None
766
767 for result in self._getMsg(ContentType.handshake,
768 (HandshakeType.certificate_request,
769 HandshakeType.server_hello_done)):
770 if result in (0, 1):
771 yield result
772 else: break
773
774 certificateRequest = None
775 if isinstance(result, CertificateRequest):
776 certificateRequest = result
777
778
779 if cipherSuite not in CipherSuite.certAllSuites \
780 or cipherSuite in CipherSuite.srpAllSuites:
781 for result in self._sendError(\
782 AlertDescription.unexpected_message,
783 "Certificate Request with incompatible cipher suite"):
784 yield result
785
786
787 for result in self._getMsg(ContentType.handshake,
788 HandshakeType.server_hello_done):
789 if result in (0, 1):
790 yield result
791 else: break
792 serverHelloDone = result
793
794 serverCertChain = None
795 publicKey = None
796 if cipherSuite in CipherSuite.certAllSuites:
797
798 for result in self._clientGetKeyFromChain(serverCertificate,
799 settings,
800 tackExt):
801 if result in (0, 1):
802 yield result
803 else: break
804 publicKey, serverCertChain, tackExt = result
805
806
807
808 if serverKeyExchange:
809 validSigAlgs = self._sigHashesToList(settings)
810 try:
811 KeyExchange.verifyServerKeyExchange(serverKeyExchange,
812 publicKey,
813 clientRandom,
814 serverRandom,
815 validSigAlgs)
816 except TLSIllegalParameterException:
817 for result in self._sendError(AlertDescription.\
818 illegal_parameter):
819 yield result
820 except TLSDecryptionFailed:
821 for result in self._sendError(\
822 AlertDescription.decrypt_error):
823 yield result
824
825 if serverKeyExchange:
826
827 if self.version >= (3, 3) \
828 and cipherSuite in CipherSuite.certAllSuites \
829 and cipherSuite not in CipherSuite.certSuites:
830 self.serverSigAlg = (serverKeyExchange.hashAlg,
831 serverKeyExchange.signAlg)
832
833 if cipherSuite in CipherSuite.dhAllSuites:
834 self.dhGroupSize = numBits(serverKeyExchange.dh_p)
835 if cipherSuite in CipherSuite.ecdhAllSuites:
836 self.ecdhCurve = serverKeyExchange.named_curve
837
838
839 if certificateRequest:
840
841
842
843 if self.version == (3, 3)\
844 and not [sig for sig in \
845 certificateRequest.supported_signature_algs\
846 if sig[1] == SignatureAlgorithm.rsa]:
847 for result in self._sendError(\
848 AlertDescription.handshake_failure,
849 "Server doesn't accept any sigalgs we support: " +
850 str(certificateRequest.supported_signature_algs)):
851 yield result
852 clientCertificate = Certificate(certificateType)
853
854 if clientCertChain:
855
856
857 if certificateType == CertificateType.x509 \
858 and not isinstance(clientCertChain, X509CertChain):
859 for result in self._sendError(\
860 AlertDescription.handshake_failure,
861 "Client certificate is of wrong type"):
862 yield result
863
864 clientCertificate.create(clientCertChain)
865
866 for result in self._sendMsg(clientCertificate):
867 yield result
868 else:
869
870 privateKey = None
871 clientCertChain = None
872
873 try:
874 ske = serverKeyExchange
875 premasterSecret = keyExchange.processServerKeyExchange(publicKey,
876 ske)
877 except TLSInsufficientSecurity as e:
878 for result in self._sendError(\
879 AlertDescription.insufficient_security, e):
880 yield result
881 except TLSIllegalParameterException as e:
882 for result in self._sendError(\
883 AlertDescription.illegal_parameter, e):
884 yield result
885
886 clientKeyExchange = keyExchange.makeClientKeyExchange()
887
888
889 for result in self._sendMsg(clientKeyExchange):
890 yield result
891
892
893
894 if certificateRequest and privateKey:
895 validSigAlgs = self._sigHashesToList(settings)
896 certificateVerify = KeyExchange.makeCertificateVerify(\
897 self.version,
898 self._handshake_hash,
899 validSigAlgs,
900 privateKey,
901 certificateRequest,
902 premasterSecret,
903 clientRandom,
904 serverRandom)
905 for result in self._sendMsg(certificateVerify):
906 yield result
907
908 yield (premasterSecret, serverCertChain, clientCertChain, tackExt)
909
910 - def _clientFinished(self, premasterSecret, clientRandom, serverRandom,
911 cipherSuite, cipherImplementations, nextProto):
912 if self.extendedMasterSecret:
913 masterSecret = calcExtendedMasterSecret(self.version,
914 cipherSuite,
915 premasterSecret,
916 self._handshake_hash)
917 else:
918 masterSecret = calcMasterSecret(self.version,
919 cipherSuite,
920 premasterSecret,
921 clientRandom,
922 serverRandom)
923 self._calcPendingStates(cipherSuite, masterSecret,
924 clientRandom, serverRandom,
925 cipherImplementations)
926
927
928 for result in self._sendFinished(masterSecret, cipherSuite, nextProto):
929 yield result
930 self.sock.flush()
931 self.sock.buffer_writes = False
932 for result in self._getFinished(masterSecret,
933 cipherSuite,
934 nextProto=nextProto):
935 yield result
936 yield masterSecret
937
974
975
976
977
978
979
980
981 - def handshakeServer(self, verifierDB=None,
982 certChain=None, privateKey=None, reqCert=False,
983 sessionCache=None, settings=None, checker=None,
984 reqCAs = None,
985 tacks=None, activationFlags=0,
986 nextProtos=None, anon=False):
987 """Perform a handshake in the role of server.
988
989 This function performs an SSL or TLS handshake. Depending on
990 the arguments and the behavior of the client, this function can
991 perform an SRP, or certificate-based handshake. It
992 can also perform a combined SRP and server-certificate
993 handshake.
994
995 Like any handshake function, this can be called on a closed
996 TLS connection, or on a TLS connection that is already open.
997 If called on an open connection it performs a re-handshake.
998 This function does not send a Hello Request message before
999 performing the handshake, so if re-handshaking is required,
1000 the server must signal the client to begin the re-handshake
1001 through some other means.
1002
1003 If the function completes without raising an exception, the
1004 TLS connection will be open and available for data transfer.
1005
1006 If an exception is raised, the connection will have been
1007 automatically closed (if it was ever open).
1008
1009 @type verifierDB: L{tlslite.verifierdb.VerifierDB}
1010 @param verifierDB: A database of SRP password verifiers
1011 associated with usernames. If the client performs an SRP
1012 handshake, the session's srpUsername attribute will be set.
1013
1014 @type certChain: L{tlslite.x509certchain.X509CertChain}
1015 @param certChain: The certificate chain to be used if the
1016 client requests server certificate authentication.
1017
1018 @type privateKey: L{tlslite.utils.rsakey.RSAKey}
1019 @param privateKey: The private key to be used if the client
1020 requests server certificate authentication.
1021
1022 @type reqCert: bool
1023 @param reqCert: Whether to request client certificate
1024 authentication. This only applies if the client chooses server
1025 certificate authentication; if the client chooses SRP
1026 authentication, this will be ignored. If the client
1027 performs a client certificate authentication, the sessions's
1028 clientCertChain attribute will be set.
1029
1030 @type sessionCache: L{tlslite.sessioncache.SessionCache}
1031 @param sessionCache: An in-memory cache of resumable sessions.
1032 The client can resume sessions from this cache. Alternatively,
1033 if the client performs a full handshake, a new session will be
1034 added to the cache.
1035
1036 @type settings: L{tlslite.handshakesettings.HandshakeSettings}
1037 @param settings: Various settings which can be used to control
1038 the ciphersuites and SSL/TLS version chosen by the server.
1039
1040 @type checker: L{tlslite.checker.Checker}
1041 @param checker: A Checker instance. This instance will be
1042 invoked to examine the other party's authentication
1043 credentials, if the handshake completes succesfully.
1044
1045 @type reqCAs: list of L{bytearray} of unsigned bytes
1046 @param reqCAs: A collection of DER-encoded DistinguishedNames that
1047 will be sent along with a certificate request. This does not affect
1048 verification.
1049
1050 @type nextProtos: list of strings.
1051 @param nextProtos: A list of upper layer protocols to expose to the
1052 clients through the Next-Protocol Negotiation Extension,
1053 if they support it.
1054
1055 @raise socket.error: If a socket error occurs.
1056 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
1057 without a preceding alert.
1058 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
1059 @raise tlslite.errors.TLSAuthenticationError: If the checker
1060 doesn't like the other party's authentication credentials.
1061 """
1062 for result in self.handshakeServerAsync(verifierDB,
1063 certChain, privateKey, reqCert, sessionCache, settings,
1064 checker, reqCAs,
1065 tacks=tacks, activationFlags=activationFlags,
1066 nextProtos=nextProtos, anon=anon):
1067 pass
1068
1069
1070 - def handshakeServerAsync(self, verifierDB=None,
1071 certChain=None, privateKey=None, reqCert=False,
1072 sessionCache=None, settings=None, checker=None,
1073 reqCAs=None,
1074 tacks=None, activationFlags=0,
1075 nextProtos=None, anon=False
1076 ):
1077 """Start a server handshake operation on the TLS connection.
1078
1079 This function returns a generator which behaves similarly to
1080 handshakeServer(). Successive invocations of the generator
1081 will return 0 if it is waiting to read from the socket, 1 if it is
1082 waiting to write to the socket, or it will raise StopIteration
1083 if the handshake operation is complete.
1084
1085 @rtype: iterable
1086 @return: A generator; see above for details.
1087 """
1088 handshaker = self._handshakeServerAsyncHelper(\
1089 verifierDB=verifierDB, certChain=certChain,
1090 privateKey=privateKey, reqCert=reqCert,
1091 sessionCache=sessionCache, settings=settings,
1092 reqCAs=reqCAs,
1093 tacks=tacks, activationFlags=activationFlags,
1094 nextProtos=nextProtos, anon=anon)
1095 for result in self._handshakeWrapperAsync(handshaker, checker):
1096 yield result
1097
1098
1099 - def _handshakeServerAsyncHelper(self, verifierDB,
1100 certChain, privateKey, reqCert, sessionCache,
1101 settings, reqCAs,
1102 tacks, activationFlags,
1103 nextProtos, anon):
1104
1105 self._handshakeStart(client=False)
1106
1107 if (not verifierDB) and (not certChain) and not anon:
1108 raise ValueError("Caller passed no authentication credentials")
1109 if certChain and not privateKey:
1110 raise ValueError("Caller passed a certChain but no privateKey")
1111 if privateKey and not certChain:
1112 raise ValueError("Caller passed a privateKey but no certChain")
1113 if reqCAs and not reqCert:
1114 raise ValueError("Caller passed reqCAs but not reqCert")
1115 if certChain and not isinstance(certChain, X509CertChain):
1116 raise ValueError("Unrecognized certificate type")
1117 if activationFlags and not tacks:
1118 raise ValueError("Nonzero activationFlags requires tacks")
1119 if tacks:
1120 if not tackpyLoaded:
1121 raise ValueError("tackpy is not loaded")
1122 if not settings or not settings.useExperimentalTackExtension:
1123 raise ValueError("useExperimentalTackExtension not enabled")
1124
1125 if not settings:
1126 settings = HandshakeSettings()
1127 settings = settings.validate()
1128
1129
1130
1131
1132
1133 for result in self._serverGetClientHello(settings, certChain,\
1134 verifierDB, sessionCache,
1135 anon):
1136 if result in (0,1): yield result
1137 elif result == None:
1138 self._handshakeDone(resumed=True)
1139 return
1140 else: break
1141 (clientHello, cipherSuite) = result
1142
1143
1144
1145
1146 if sessionCache:
1147 sessionID = getRandomBytes(32)
1148 else:
1149 sessionID = bytearray(0)
1150
1151 if not clientHello.supports_npn:
1152 nextProtos = None
1153
1154
1155 if not cipherSuite in CipherSuite.certAllSuites:
1156 tacks = None
1157
1158
1159 if clientHello.tack:
1160 tackExt = TackExtension.create(tacks, activationFlags)
1161 else:
1162 tackExt = None
1163
1164 extensions = []
1165
1166 if settings.useEncryptThenMAC and \
1167 clientHello.getExtension(ExtensionType.encrypt_then_mac) and \
1168 cipherSuite not in CipherSuite.streamSuites and \
1169 cipherSuite not in CipherSuite.aeadSuites:
1170 extensions.append(TLSExtension().create(ExtensionType.
1171 encrypt_then_mac,
1172 bytearray(0)))
1173 self._recordLayer.encryptThenMAC = True
1174
1175 if settings.useExtendedMasterSecret:
1176 if clientHello.getExtension(ExtensionType.extended_master_secret):
1177 extensions.append(TLSExtension().create(ExtensionType.
1178 extended_master_secret,
1179 bytearray(0)))
1180 self.extendedMasterSecret = True
1181 elif settings.requireExtendedMasterSecret:
1182 for result in self._sendError(
1183 AlertDescription.insufficient_security,
1184 "Failed to negotiate Extended Master Secret"):
1185 yield result
1186
1187
1188 if not extensions:
1189 extensions = None
1190
1191 serverHello = ServerHello()
1192 serverHello.create(self.version, getRandomBytes(32), sessionID, \
1193 cipherSuite, CertificateType.x509, tackExt,
1194 nextProtos, extensions=extensions)
1195
1196
1197 clientCertChain = None
1198 if cipherSuite in CipherSuite.srpAllSuites:
1199 for result in self._serverSRPKeyExchange(clientHello, serverHello,
1200 verifierDB, cipherSuite,
1201 privateKey, certChain,
1202 settings):
1203 if result in (0, 1):
1204 yield result
1205 else: break
1206 premasterSecret = result
1207
1208
1209 elif (cipherSuite in CipherSuite.certSuites or
1210 cipherSuite in CipherSuite.dheCertSuites or
1211 cipherSuite in CipherSuite.ecdheCertSuites):
1212 if cipherSuite in CipherSuite.certSuites:
1213 keyExchange = RSAKeyExchange(cipherSuite,
1214 clientHello,
1215 serverHello,
1216 privateKey)
1217 elif cipherSuite in CipherSuite.dheCertSuites:
1218 keyExchange = DHE_RSAKeyExchange(cipherSuite,
1219 clientHello,
1220 serverHello,
1221 privateKey)
1222 elif cipherSuite in CipherSuite.ecdheCertSuites:
1223 acceptedCurves = self._curveNamesToList(settings)
1224 keyExchange = ECDHE_RSAKeyExchange(cipherSuite,
1225 clientHello,
1226 serverHello,
1227 privateKey,
1228 acceptedCurves)
1229 else:
1230 assert(False)
1231 for result in self._serverCertKeyExchange(clientHello, serverHello,
1232 certChain, keyExchange,
1233 reqCert, reqCAs, cipherSuite,
1234 settings):
1235 if result in (0,1): yield result
1236 else: break
1237 (premasterSecret, clientCertChain) = result
1238
1239
1240 elif cipherSuite in CipherSuite.anonSuites:
1241 for result in self._serverAnonKeyExchange(clientHello, serverHello,
1242 cipherSuite, settings):
1243 if result in (0,1): yield result
1244 else: break
1245 premasterSecret = result
1246
1247 else:
1248 assert(False)
1249
1250
1251 for result in self._serverFinished(premasterSecret,
1252 clientHello.random, serverHello.random,
1253 cipherSuite, settings.cipherImplementations,
1254 nextProtos):
1255 if result in (0,1): yield result
1256 else: break
1257 masterSecret = result
1258
1259
1260 self.session = Session()
1261 if cipherSuite in CipherSuite.certAllSuites:
1262 serverCertChain = certChain
1263 else:
1264 serverCertChain = None
1265 srpUsername = None
1266 serverName = None
1267 if clientHello.srp_username:
1268 srpUsername = clientHello.srp_username.decode("utf-8")
1269 if clientHello.server_name:
1270 serverName = clientHello.server_name.decode("utf-8")
1271 self.session.create(masterSecret, serverHello.session_id, cipherSuite,
1272 srpUsername, clientCertChain, serverCertChain,
1273 tackExt, (serverHello.tackExt is not None),
1274 serverName,
1275 encryptThenMAC=self._recordLayer.encryptThenMAC)
1276
1277
1278 if sessionCache and sessionID:
1279 sessionCache[sessionID] = self.session
1280
1281 self._handshakeDone(resumed=False)
1282
1283
1286
1287
1288
1289 self.version = settings.maxVersion
1290
1291
1292 for result in self._getMsg(ContentType.handshake,
1293 HandshakeType.client_hello):
1294 if result in (0,1): yield result
1295 else: break
1296 clientHello = result
1297
1298
1299 if clientHello.client_version < settings.minVersion:
1300 self.version = settings.minVersion
1301 for result in self._sendError(\
1302 AlertDescription.protocol_version,
1303 "Too old version: %s" % str(clientHello.client_version)):
1304 yield result
1305
1306
1307 elif clientHello.client_version > settings.maxVersion:
1308 self.version = settings.maxVersion
1309
1310 else:
1311
1312 self.version = clientHello.client_version
1313
1314
1315 if clientHello.client_version < settings.maxVersion and \
1316 CipherSuite.TLS_FALLBACK_SCSV in clientHello.cipher_suites:
1317 for result in self._sendError(\
1318 AlertDescription.inappropriate_fallback):
1319 yield result
1320
1321
1322
1323 client_groups = clientHello.getExtension(ExtensionType.supported_groups)
1324 group_intersect = []
1325 if client_groups is not None:
1326 client_groups = client_groups.groups
1327 if client_groups is None:
1328 client_groups = []
1329 server_groups = self._curveNamesToList(settings)
1330 group_intersect = [x for x in client_groups if x in server_groups]
1331
1332
1333
1334 cipherSuites = []
1335 if verifierDB:
1336 if certChain:
1337 cipherSuites += \
1338 CipherSuite.getSrpCertSuites(settings, self.version)
1339 cipherSuites += CipherSuite.getSrpSuites(settings, self.version)
1340 elif certChain:
1341 if group_intersect:
1342 cipherSuites += CipherSuite.getEcdheCertSuites(settings,
1343 self.version)
1344 cipherSuites += CipherSuite.getDheCertSuites(settings, self.version)
1345 cipherSuites += CipherSuite.getCertSuites(settings, self.version)
1346 elif anon:
1347 cipherSuites += CipherSuite.getAnonSuites(settings, self.version)
1348 else:
1349 assert(False)
1350 cipherSuites = CipherSuite.filterForVersion(cipherSuites,
1351 minVersion=self.version,
1352 maxVersion=self.version)
1353
1354
1355 if clientHello.session_id and sessionCache:
1356 session = None
1357
1358
1359 if sessionCache and not session:
1360 try:
1361 session = sessionCache[clientHello.session_id]
1362 if not session.resumable:
1363 raise AssertionError()
1364
1365 if session.cipherSuite not in cipherSuites:
1366 for result in self._sendError(\
1367 AlertDescription.handshake_failure):
1368 yield result
1369 if session.cipherSuite not in clientHello.cipher_suites:
1370 for result in self._sendError(\
1371 AlertDescription.handshake_failure):
1372 yield result
1373 if clientHello.srp_username:
1374 if not session.srpUsername or \
1375 clientHello.srp_username != bytearray(session.srpUsername, "utf-8"):
1376 for result in self._sendError(\
1377 AlertDescription.handshake_failure):
1378 yield result
1379 if clientHello.server_name:
1380 if not session.serverName or \
1381 clientHello.server_name != bytearray(session.serverName, "utf-8"):
1382 for result in self._sendError(\
1383 AlertDescription.handshake_failure):
1384 yield result
1385 if session.encryptThenMAC and \
1386 not clientHello.getExtension(
1387 ExtensionType.encrypt_then_mac):
1388 for result in self._sendError(\
1389 AlertDescription.handshake_failure):
1390 yield result
1391 if session.extendedMasterSecret and \
1392 not clientHello.getExtension(
1393 ExtensionType.extended_master_secret):
1394 for result in self._sendError(\
1395 AlertDescription.handshake_failure):
1396 yield result
1397 except KeyError:
1398 pass
1399
1400
1401 if session:
1402
1403 extensions = []
1404 if session.encryptThenMAC:
1405 self._recordLayer.encryptThenMAC = True
1406 mte = TLSExtension().create(ExtensionType.encrypt_then_mac,
1407 bytearray(0))
1408 extensions.append(mte)
1409 if session.extendedMasterSecret:
1410 ems = TLSExtension().create(ExtensionType.
1411 extended_master_secret,
1412 bytearray(0))
1413 extensions.append(ems)
1414
1415 if not extensions:
1416 extensions = None
1417 serverHello = ServerHello()
1418 serverHello.create(self.version, getRandomBytes(32),
1419 session.sessionID, session.cipherSuite,
1420 CertificateType.x509, None, None,
1421 extensions=extensions)
1422 for result in self._sendMsg(serverHello):
1423 yield result
1424
1425
1426 self._calcPendingStates(session.cipherSuite,
1427 session.masterSecret,
1428 clientHello.random,
1429 serverHello.random,
1430 settings.cipherImplementations)
1431
1432
1433 for result in self._sendFinished(session.masterSecret,
1434 session.cipherSuite):
1435 yield result
1436 for result in self._getFinished(session.masterSecret,
1437 session.cipherSuite):
1438 yield result
1439
1440
1441 self.session = session
1442
1443 yield None
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453 for cipherSuite in cipherSuites:
1454 if cipherSuite in clientHello.cipher_suites:
1455 break
1456 else:
1457 for result in self._sendError(\
1458 AlertDescription.handshake_failure,
1459 "No mutual ciphersuite"):
1460 yield result
1461 if cipherSuite in CipherSuite.srpAllSuites and \
1462 not clientHello.srp_username:
1463 for result in self._sendError(\
1464 AlertDescription.unknown_psk_identity,
1465 "Client sent a hello, but without the SRP username"):
1466 yield result
1467
1468
1469 if cipherSuite in CipherSuite.certAllSuites and CertificateType.x509 \
1470 not in clientHello.certificate_types:
1471 for result in self._sendError(\
1472 AlertDescription.handshake_failure,
1473 "the client doesn't support my certificate type"):
1474 yield result
1475
1476
1477
1478
1479 yield (clientHello, cipherSuite)
1480
1481 - def _serverSRPKeyExchange(self, clientHello, serverHello, verifierDB,
1482 cipherSuite, privateKey, serverCertChain,
1483 settings):
1528
1529 - def _serverCertKeyExchange(self, clientHello, serverHello,
1530 serverCertChain, keyExchange,
1531 reqCert, reqCAs, cipherSuite,
1532 settings):
1533
1534
1535 msgs = []
1536
1537
1538 clientCertChain = None
1539
1540 msgs.append(serverHello)
1541 msgs.append(Certificate(CertificateType.x509).create(serverCertChain))
1542 sigHashAlg = self._pickServerKeyExchangeSig(settings, clientHello)
1543 serverKeyExchange = keyExchange.makeServerKeyExchange(sigHashAlg)
1544 if serverKeyExchange is not None:
1545 msgs.append(serverKeyExchange)
1546 if reqCert:
1547 certificateRequest = CertificateRequest(self.version)
1548 if not reqCAs:
1549 reqCAs = []
1550 validSigAlgs = self._sigHashesToList(settings)
1551 certificateRequest.create([ClientCertificateType.rsa_sign],
1552 reqCAs,
1553 validSigAlgs)
1554 msgs.append(certificateRequest)
1555 msgs.append(ServerHelloDone())
1556 for result in self._sendMsgs(msgs):
1557 yield result
1558
1559
1560 if reqCert:
1561 if self.version == (3,0):
1562 for result in self._getMsg((ContentType.handshake,
1563 ContentType.alert),
1564 HandshakeType.certificate,
1565 CertificateType.x509):
1566 if result in (0,1): yield result
1567 else: break
1568 msg = result
1569
1570 if isinstance(msg, Alert):
1571
1572 alert = msg
1573 if alert.description != \
1574 AlertDescription.no_certificate:
1575 self._shutdown(False)
1576 raise TLSRemoteAlert(alert)
1577 elif isinstance(msg, Certificate):
1578 clientCertificate = msg
1579 if clientCertificate.certChain and \
1580 clientCertificate.certChain.getNumCerts()!=0:
1581 clientCertChain = clientCertificate.certChain
1582 else:
1583 raise AssertionError()
1584 elif self.version in ((3,1), (3,2), (3,3)):
1585 for result in self._getMsg(ContentType.handshake,
1586 HandshakeType.certificate,
1587 CertificateType.x509):
1588 if result in (0,1): yield result
1589 else: break
1590 clientCertificate = result
1591 if clientCertificate.certChain and \
1592 clientCertificate.certChain.getNumCerts()!=0:
1593 clientCertChain = clientCertificate.certChain
1594 else:
1595 raise AssertionError()
1596
1597
1598 for result in self._getMsg(ContentType.handshake,
1599 HandshakeType.client_key_exchange,
1600 cipherSuite):
1601 if result in (0,1): yield result
1602 else: break
1603 clientKeyExchange = result
1604
1605
1606 try:
1607 premasterSecret = \
1608 keyExchange.processClientKeyExchange(clientKeyExchange)
1609 except TLSLocalAlert as alert:
1610 for result in self._sendError(alert.description, alert.message):
1611 yield result
1612
1613
1614 if clientCertChain:
1615 handshakeHash = self._handshake_hash.copy()
1616 for result in self._getMsg(ContentType.handshake,
1617 HandshakeType.certificate_verify):
1618 if result in (0, 1):
1619 yield result
1620 else: break
1621 certificateVerify = result
1622 signatureAlgorithm = None
1623 if self.version == (3, 3):
1624 validSigAlgs = self._sigHashesToList(settings)
1625 if certificateVerify.signatureAlgorithm not in validSigAlgs:
1626 for result in self._sendError(\
1627 AlertDescription.decryption_failed,
1628 "Invalid signature on Certificate Verify"):
1629 yield result
1630 signatureAlgorithm = certificateVerify.signatureAlgorithm
1631
1632 verifyBytes = KeyExchange.calcVerifyBytes(self.version,
1633 handshakeHash,
1634 signatureAlgorithm,
1635 premasterSecret,
1636 clientHello.random,
1637 serverHello.random)
1638 publicKey = clientCertChain.getEndEntityPublicKey()
1639 if len(publicKey) < settings.minKeySize:
1640 for result in self._sendError(\
1641 AlertDescription.handshake_failure,
1642 "Client's public key too small: %d" % len(publicKey)):
1643 yield result
1644
1645 if len(publicKey) > settings.maxKeySize:
1646 for result in self._sendError(\
1647 AlertDescription.handshake_failure,
1648 "Client's public key too large: %d" % len(publicKey)):
1649 yield result
1650
1651 if not publicKey.verify(certificateVerify.signature, verifyBytes):
1652 for result in self._sendError(\
1653 AlertDescription.decrypt_error,
1654 "Signature failed to verify"):
1655 yield result
1656 yield (premasterSecret, clientCertChain)
1657
1658
1661
1662
1663 dh_g, dh_p = goodGroupParameters[2]
1664 dh_Xs = bytesToNumber(getRandomBytes(32))
1665 dh_Ys = powMod(dh_g, dh_Xs, dh_p)
1666
1667
1668 serverKeyExchange = ServerKeyExchange(cipherSuite, self.version)
1669 serverKeyExchange.createDH(dh_p, dh_g, dh_Ys)
1670
1671
1672
1673 msgs = []
1674 msgs.append(serverHello)
1675 msgs.append(serverKeyExchange)
1676 msgs.append(ServerHelloDone())
1677 for result in self._sendMsgs(msgs):
1678 yield result
1679
1680
1681 for result in self._getMsg(ContentType.handshake,
1682 HandshakeType.client_key_exchange,
1683 cipherSuite):
1684 if result in (0,1):
1685 yield result
1686 else:
1687 break
1688 clientKeyExchange = result
1689 dh_Yc = clientKeyExchange.dh_Yc
1690
1691 if dh_Yc % dh_p == 0:
1692 for result in self._sendError(AlertDescription.illegal_parameter,
1693 "Suspicious dh_Yc value"):
1694 yield result
1695 assert(False)
1696
1697
1698 S = powMod(dh_Yc,dh_Xs,dh_p)
1699 premasterSecret = numberToByteArray(S)
1700
1701 yield premasterSecret
1702
1703
1704 - def _serverFinished(self, premasterSecret, clientRandom, serverRandom,
1705 cipherSuite, cipherImplementations, nextProtos):
1706 if self.extendedMasterSecret:
1707 masterSecret = calcExtendedMasterSecret(self.version,
1708 cipherSuite,
1709 premasterSecret,
1710 self._handshake_hash)
1711 else:
1712 masterSecret = calcMasterSecret(self.version,
1713 cipherSuite,
1714 premasterSecret,
1715 clientRandom,
1716 serverRandom)
1717
1718
1719 self._calcPendingStates(cipherSuite, masterSecret,
1720 clientRandom, serverRandom,
1721 cipherImplementations)
1722
1723
1724 for result in self._getFinished(masterSecret,
1725 cipherSuite,
1726 expect_next_protocol=nextProtos is not None):
1727 yield result
1728
1729 for result in self._sendFinished(masterSecret, cipherSuite):
1730 yield result
1731
1732 yield masterSecret
1733
1734
1735
1736
1737
1738
1739
1740 - def _sendFinished(self, masterSecret, cipherSuite=None, nextProto=None):
1770
1771 - def _getFinished(self, masterSecret, cipherSuite=None,
1772 expect_next_protocol=False, nextProto=None):
1773
1774 for result in self._getMsg(ContentType.change_cipher_spec):
1775 if result in (0,1):
1776 yield result
1777 changeCipherSpec = result
1778
1779 if changeCipherSpec.type != 1:
1780 for result in self._sendError(AlertDescription.illegal_parameter,
1781 "ChangeCipherSpec type incorrect"):
1782 yield result
1783
1784
1785 self._changeReadState()
1786
1787
1788 if expect_next_protocol:
1789 for result in self._getMsg(ContentType.handshake, HandshakeType.next_protocol):
1790 if result in (0,1):
1791 yield result
1792 if result is None:
1793 for result in self._sendError(AlertDescription.unexpected_message,
1794 "Didn't get NextProtocol message"):
1795 yield result
1796
1797 self.next_proto = result.next_proto
1798 else:
1799 self.next_proto = None
1800
1801
1802 if nextProto:
1803 self.next_proto = nextProto
1804
1805
1806 verifyData = calcFinished(self.version,
1807 masterSecret,
1808 cipherSuite,
1809 self._handshake_hash,
1810 not self._client)
1811
1812
1813 for result in self._getMsg(ContentType.handshake,
1814 HandshakeType.finished):
1815 if result in (0,1):
1816 yield result
1817 finished = result
1818 if finished.verify_data != verifyData:
1819 for result in self._sendError(AlertDescription.decrypt_error,
1820 "Finished message is incorrect"):
1821 yield result
1822
1848
1849 @staticmethod
1851 """Pick a hash that matches most closely the supported ones"""
1852 hashAndAlgsExt = clientHello.getExtension(\
1853 ExtensionType.signature_algorithms)
1854
1855 if hashAndAlgsExt is None or hashAndAlgsExt.sigalgs is None:
1856
1857
1858 return "sha1"
1859
1860 rsaHashes = [alg[0] for alg in hashAndAlgsExt.sigalgs
1861 if alg[1] == SignatureAlgorithm.rsa]
1862 for hashName in settings.rsaSigHashes:
1863 hashID = getattr(HashAlgorithm, hashName)
1864 if hashID in rsaHashes:
1865 return hashName
1866
1867
1868 return "sha1"
1869
1870 @staticmethod
1872 """Convert list of valid signature hashes to array of tuples"""
1873 sigAlgs = []
1874 for hashName in settings.rsaSigHashes:
1875 sigAlgs.append((getattr(HashAlgorithm, hashName),
1876 SignatureAlgorithm.rsa))
1877 return sigAlgs
1878
1879 @staticmethod
1881 """Convert list of acceptable curves to array identifiers"""
1882 return [getattr(GroupName, val) for val in settings.eccCurves]
1883