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