1
2
3
4
5
6
7
8
9
10
11
12 """
13 MAIN CLASS FOR TLS LITE (START HERE!).
14 """
15
16 from __future__ import division
17 import socket
18 from .utils.compat import formatExceptionTrace
19 from .tlsrecordlayer import TLSRecordLayer
20 from .session import Session
21 from .constants import *
22 from .utils.cryptomath import getRandomBytes
23 from .errors import *
24 from .messages import *
25 from .mathtls import *
26 from .handshakesettings import HandshakeSettings
27 from .utils.tackwrapper import *
28 from .utils.rsakey import RSAKey
29
31
32 """
33 Common API for calculating Premaster secret
34
35 NOT stable, will get moved from this file
36 """
37
38 - def __init__(self, cipherSuite, clientHello, serverHello, privateKey):
39 """
40 Initializes the KeyExchange. privateKey is the signing private key.
41 """
42 self.cipherSuite = cipherSuite
43 self.clientHello = clientHello
44 self.serverHello = serverHello
45 self.privateKey = privateKey
46
48 """
49 Returns a ServerKeyExchange object for the server's initial leg in the
50 handshake. If the key exchange method does not send ServerKeyExchange
51 (e.g. RSA), it returns None.
52 """
53 raise NotImplementedError()
54
56 """
57 Processes the client's ClientKeyExchange message and returns the
58 premaster secret. Raises TLSLocalAlert on error.
59 """
60 raise NotImplementedError()
61
63
64 """
65 Handling of RSA key exchange
66
67 NOT stable API, do NOT use
68 """
69
72
74 premasterSecret = self.privateKey.decrypt(\
75 clientKeyExchange.encryptedPreMasterSecret)
76
77
78
79 randomPreMasterSecret = getRandomBytes(48)
80 if not premasterSecret:
81 premasterSecret = randomPreMasterSecret
82 elif len(premasterSecret) != 48:
83 premasterSecret = randomPreMasterSecret
84 else:
85 versionCheck = (premasterSecret[0], premasterSecret[1])
86 if versionCheck != self.clientHello.client_version:
87
88 if versionCheck != self.serverHello.server_version:
89 premasterSecret = randomPreMasterSecret
90 return premasterSecret
91
93
94 """
95 Handling of ephemeral Diffe-Hellman Key exchange
96
97 NOT stable API, do NOT use
98 """
99
100 - def __init__(self, cipherSuite, clientHello, serverHello, privateKey):
104
105
106 dh_g, dh_p = goodGroupParameters[2]
107
108
109 strength = 160
110
129
141
143 """
144 This class wraps a socket and provides TLS handshaking and data
145 transfer.
146
147 To use this class, create a new instance, passing a connected
148 socket into the constructor. Then call some handshake function.
149 If the handshake completes without raising an exception, then a TLS
150 connection has been negotiated. You can transfer data over this
151 connection as if it were a socket.
152
153 This class provides both synchronous and asynchronous versions of
154 its key functions. The synchronous versions should be used when
155 writing single-or multi-threaded code using blocking sockets. The
156 asynchronous versions should be used when performing asynchronous,
157 event-based I/O with non-blocking sockets.
158
159 Asynchronous I/O is a complicated subject; typically, you should
160 not use the asynchronous functions directly, but should use some
161 framework like asyncore or Twisted which TLS Lite integrates with
162 (see
163 L{tlslite.integration.tlsasyncdispatchermixin.TLSAsyncDispatcherMixIn}).
164 """
165
167 """Create a new TLSConnection instance.
168
169 @param sock: The socket data will be transmitted on. The
170 socket should already be connected. It may be in blocking or
171 non-blocking mode.
172
173 @type sock: L{socket.socket}
174 """
175 TLSRecordLayer.__init__(self, sock)
176
177
178
179
180
184 """Perform an anonymous handshake in the role of client.
185
186 This function performs an SSL or TLS handshake using an
187 anonymous Diffie Hellman ciphersuite.
188
189 Like any handshake function, this can be called on a closed
190 TLS connection, or on a TLS connection that is already open.
191 If called on an open connection it performs a re-handshake.
192
193 If the function completes without raising an exception, the
194 TLS connection will be open and available for data transfer.
195
196 If an exception is raised, the connection will have been
197 automatically closed (if it was ever open).
198
199 @type session: L{tlslite.Session.Session}
200 @param session: A TLS session to attempt to resume. If the
201 resumption does not succeed, a full handshake will be
202 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 serverName: string
215 @param serverName: The ServerNameIndication TLS Extension.
216
217 @type async: bool
218 @param async: If False, this function will block until the
219 handshake is completed. If True, this function will return a
220 generator. Successive invocations of the generator will
221 return 0 if it is waiting to read from the socket, 1 if it is
222 waiting to write to the socket, or will raise StopIteration if
223 the handshake operation is completed.
224
225 @rtype: None or an iterable
226 @return: If 'async' is True, a generator object will be
227 returned.
228
229 @raise socket.error: If a socket error occurs.
230 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
231 without a preceding alert.
232 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
233 @raise tlslite.errors.TLSAuthenticationError: If the checker
234 doesn't like the other party's authentication credentials.
235 """
236 handshaker = self._handshakeClientAsync(anonParams=(True),
237 session=session,
238 settings=settings,
239 checker=checker,
240 serverName=serverName)
241 if async:
242 return handshaker
243 for result in handshaker:
244 pass
245
246 - def handshakeClientSRP(self, username, password, session=None,
247 settings=None, checker=None,
248 reqTack=True, serverName=None,
249 async=False):
250 """Perform an SRP handshake in the role of client.
251
252 This function performs a TLS/SRP handshake. SRP mutually
253 authenticates both parties to each other using only a
254 username and password. This function may also perform a
255 combined SRP and server-certificate handshake, if the server
256 chooses to authenticate itself with a certificate chain in
257 addition to doing SRP.
258
259 If the function completes without raising an exception, the
260 TLS connection will be open and available for data transfer.
261
262 If an exception is raised, the connection will have been
263 automatically closed (if it was ever open).
264
265 @type username: str
266 @param username: The SRP username.
267
268 @type password: str
269 @param password: The SRP password.
270
271 @type session: L{tlslite.session.Session}
272 @param session: A TLS session to attempt to resume. This
273 session must be an SRP session performed with the same username
274 and password as were passed in. If the resumption does not
275 succeed, a full SRP handshake will be performed.
276
277 @type settings: L{tlslite.handshakesettings.HandshakeSettings}
278 @param settings: Various settings which can be used to control
279 the ciphersuites, certificate types, and SSL/TLS versions
280 offered by the client.
281
282 @type checker: L{tlslite.checker.Checker}
283 @param checker: A Checker instance. This instance will be
284 invoked to examine the other party's authentication
285 credentials, if the handshake completes succesfully.
286
287 @type reqTack: bool
288 @param reqTack: Whether or not to send a "tack" TLS Extension,
289 requesting the server return a TackExtension if it has one.
290
291 @type serverName: string
292 @param serverName: The ServerNameIndication TLS Extension.
293
294 @type async: bool
295 @param async: If False, this function will block until the
296 handshake is completed. If True, this function will return a
297 generator. Successive invocations of the generator will
298 return 0 if it is waiting to read from the socket, 1 if it is
299 waiting to write to the socket, or will raise StopIteration if
300 the handshake operation is completed.
301
302 @rtype: None or an iterable
303 @return: If 'async' is True, a generator object will be
304 returned.
305
306 @raise socket.error: If a socket error occurs.
307 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
308 without a preceding alert.
309 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
310 @raise tlslite.errors.TLSAuthenticationError: If the checker
311 doesn't like the other party's authentication credentials.
312 """
313 handshaker = self._handshakeClientAsync(srpParams=(username, password),
314 session=session, settings=settings, checker=checker,
315 reqTack=reqTack, serverName=serverName)
316
317
318
319
320
321
322
323 if async:
324 return handshaker
325 for result in handshaker:
326 pass
327
328 - def handshakeClientCert(self, certChain=None, privateKey=None,
329 session=None, settings=None, checker=None,
330 nextProtos=None, reqTack=True, serverName=None,
331 async=False):
332 """Perform a certificate-based handshake in the role of client.
333
334 This function performs an SSL or TLS handshake. The server
335 will authenticate itself using an X.509 certificate
336 chain. If the handshake succeeds, the server's certificate
337 chain will be stored in the session's serverCertChain attribute.
338 Unless a checker object is passed in, this function does no
339 validation or checking of the server's certificate chain.
340
341 If the server requests client authentication, the
342 client will send the passed-in certificate chain, and use the
343 passed-in private key to authenticate itself. If no
344 certificate chain and private key were passed in, the client
345 will attempt to proceed without client authentication. The
346 server may or may not allow this.
347
348 If the function completes without raising an exception, the
349 TLS connection will be open and available for data transfer.
350
351 If an exception is raised, the connection will have been
352 automatically closed (if it was ever open).
353
354 @type certChain: L{tlslite.x509certchain.X509CertChain}
355 @param certChain: The certificate chain to be used if the
356 server requests client authentication.
357
358 @type privateKey: L{tlslite.utils.rsakey.RSAKey}
359 @param privateKey: The private key to be used if the server
360 requests client authentication.
361
362 @type session: L{tlslite.session.Session}
363 @param session: A TLS session to attempt to resume. If the
364 resumption does not succeed, a full handshake will be
365 performed.
366
367 @type settings: L{tlslite.handshakesettings.HandshakeSettings}
368 @param settings: Various settings which can be used to control
369 the ciphersuites, certificate types, and SSL/TLS versions
370 offered by the client.
371
372 @type checker: L{tlslite.checker.Checker}
373 @param checker: A Checker instance. This instance will be
374 invoked to examine the other party's authentication
375 credentials, if the handshake completes succesfully.
376
377 @type nextProtos: list of strings.
378 @param nextProtos: A list of upper layer protocols ordered by
379 preference, to use in the Next-Protocol Negotiation Extension.
380
381 @type reqTack: bool
382 @param reqTack: Whether or not to send a "tack" TLS Extension,
383 requesting the server return a TackExtension if it has one.
384
385 @type serverName: string
386 @param serverName: The ServerNameIndication TLS Extension.
387
388 @type async: bool
389 @param async: If False, this function will block until the
390 handshake is completed. If True, this function will return a
391 generator. Successive invocations of the generator will
392 return 0 if it is waiting to read from the socket, 1 if it is
393 waiting to write to the socket, or will raise StopIteration if
394 the handshake operation is completed.
395
396 @rtype: None or an iterable
397 @return: If 'async' is True, a generator object will be
398 returned.
399
400 @raise socket.error: If a socket error occurs.
401 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
402 without a preceding alert.
403 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
404 @raise tlslite.errors.TLSAuthenticationError: If the checker
405 doesn't like the other party's authentication credentials.
406 """
407 handshaker = \
408 self._handshakeClientAsync(certParams=(certChain, privateKey),
409 session=session, settings=settings,
410 checker=checker,
411 serverName=serverName,
412 nextProtos=nextProtos,
413 reqTack=reqTack)
414
415
416
417
418
419
420
421 if async:
422 return handshaker
423 for result in handshaker:
424 pass
425
426
427 - def _handshakeClientAsync(self, srpParams=(), certParams=(), anonParams=(),
428 session=None, settings=None, checker=None,
429 nextProtos=None, serverName=None, reqTack=True):
441
442
445
446 self._handshakeStart(client=True)
447
448
449 srpUsername = None
450 password = None
451 clientCertChain = None
452 privateKey = None
453
454
455 if srpParams:
456 assert(not certParams)
457 assert(not anonParams)
458 srpUsername, password = srpParams
459 if certParams:
460 assert(not srpParams)
461 assert(not anonParams)
462 clientCertChain, privateKey = certParams
463 if anonParams:
464 assert(not srpParams)
465 assert(not certParams)
466
467
468 if srpUsername and not password:
469 raise ValueError("Caller passed a username but no password")
470 if password and not srpUsername:
471 raise ValueError("Caller passed a password but no username")
472 if clientCertChain and not privateKey:
473 raise ValueError("Caller passed a certChain but no privateKey")
474 if privateKey and not clientCertChain:
475 raise ValueError("Caller passed a privateKey but no certChain")
476 if reqTack:
477 if not tackpyLoaded:
478 reqTack = False
479 if not settings or not settings.useExperimentalTackExtension:
480 reqTack = False
481 if nextProtos is not None:
482 if len(nextProtos) == 0:
483 raise ValueError("Caller passed no nextProtos")
484
485
486
487 if not settings:
488 settings = HandshakeSettings()
489 settings = settings.validate()
490
491 if clientCertChain:
492 if not isinstance(clientCertChain, X509CertChain):
493 raise ValueError("Unrecognized certificate type")
494 if "x509" not in settings.certificateTypes:
495 raise ValueError("Client certificate doesn't match "\
496 "Handshake Settings")
497
498 if session:
499
500
501 if not session.valid():
502 session = None
503 elif session.resumable:
504 if session.srpUsername != srpUsername:
505 raise ValueError("Session username doesn't match")
506 if session.serverName != serverName:
507 raise ValueError("Session servername doesn't match")
508
509
510 if srpUsername and self.fault == Fault.badUsername:
511 srpUsername += "GARBAGE"
512 if password and self.fault == Fault.badPassword:
513 password += "GARBAGE"
514
515
516
517
518 self.version = settings.maxVersion
519
520
521
522
523
524 for result in self._clientSendClientHello(settings, session,
525 srpUsername, srpParams, certParams,
526 anonParams, serverName, nextProtos,
527 reqTack):
528 if result in (0,1): yield result
529 else: break
530 clientHello = result
531
532
533 for result in self._clientGetServerHello(settings, clientHello):
534 if result in (0,1): yield result
535 else: break
536 serverHello = result
537 cipherSuite = serverHello.cipher_suite
538
539
540
541 nextProto = self._clientSelectNextProto(nextProtos, serverHello)
542
543
544 if serverHello.getExtension(ExtensionType.encrypt_then_mac):
545 self._recordLayer.encryptThenMAC = True
546
547
548 for result in self._clientResume(session, serverHello,
549 clientHello.random,
550 settings.cipherImplementations,
551 nextProto):
552 if result in (0,1): yield result
553 else: break
554 if result == "resumed_and_finished":
555 self._handshakeDone(resumed=True)
556 return
557
558
559
560
561 if cipherSuite in CipherSuite.srpAllSuites:
562 for result in self._clientSRPKeyExchange(\
563 settings, cipherSuite, serverHello.certificate_type,
564 srpUsername, password,
565 clientHello.random, serverHello.random,
566 serverHello.tackExt):
567 if result in (0,1): yield result
568 else: break
569 (premasterSecret, serverCertChain, tackExt) = result
570
571
572
573 elif cipherSuite in CipherSuite.dhAllSuites:
574 for result in self._clientDHEKeyExchange(settings, cipherSuite,
575 clientCertChain, privateKey,
576 serverHello.certificate_type,
577 serverHello.tackExt,
578 clientHello.random, serverHello.random):
579 if result in (0,1): yield result
580 else: break
581 (premasterSecret, serverCertChain, clientCertChain,
582 tackExt) = result
583
584
585
586
587
588
589
590 else:
591 for result in self._clientRSAKeyExchange(settings, cipherSuite,
592 clientCertChain, privateKey,
593 serverHello.certificate_type,
594 clientHello.random, serverHello.random,
595 serverHello.tackExt):
596 if result in (0,1): yield result
597 else: break
598 (premasterSecret, serverCertChain, clientCertChain,
599 tackExt) = result
600
601
602
603 for result in self._clientFinished(premasterSecret,
604 clientHello.random,
605 serverHello.random,
606 cipherSuite, settings.cipherImplementations,
607 nextProto):
608 if result in (0,1): yield result
609 else: break
610 masterSecret = result
611
612
613 self.session = Session()
614 self.session.create(masterSecret, serverHello.session_id, cipherSuite,
615 srpUsername, clientCertChain, serverCertChain,
616 tackExt, (serverHello.tackExt is not None),
617 serverName,
618 encryptThenMAC=self._recordLayer.encryptThenMAC)
619 self._handshakeDone(resumed=False)
620
621
622 - def _clientSendClientHello(self, settings, session, srpUsername,
623 srpParams, certParams, anonParams,
624 serverName, nextProtos, reqTack):
625
626 cipherSuites = [CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
627 if srpParams:
628 cipherSuites += CipherSuite.getSrpAllSuites(settings)
629 elif certParams:
630 cipherSuites += CipherSuite.getDheCertSuites(settings)
631 cipherSuites += CipherSuite.getCertSuites(settings)
632 elif anonParams:
633 cipherSuites += CipherSuite.getAnonSuites(settings)
634 else:
635 assert(False)
636
637
638
639 wireCipherSuites = list(cipherSuites)
640 if settings.sendFallbackSCSV:
641 wireCipherSuites.append(CipherSuite.TLS_FALLBACK_SCSV)
642
643
644 certificateTypes = settings.getCertificateTypes()
645
646
647 if settings.useEncryptThenMAC:
648 extensions = [TLSExtension().create(ExtensionType.encrypt_then_mac,
649 bytearray(0))]
650 else:
651 extensions = None
652
653
654 if session and session.sessionID:
655
656
657 if session.cipherSuite not in cipherSuites:
658 raise ValueError("Session's cipher suite not consistent "\
659 "with parameters")
660 else:
661 clientHello = ClientHello()
662 clientHello.create(settings.maxVersion, getRandomBytes(32),
663 session.sessionID, wireCipherSuites,
664 certificateTypes,
665 session.srpUsername,
666 reqTack, nextProtos is not None,
667 session.serverName,
668 extensions=extensions)
669
670
671 else:
672 clientHello = ClientHello()
673 clientHello.create(settings.maxVersion, getRandomBytes(32),
674 bytearray(0), wireCipherSuites,
675 certificateTypes,
676 srpUsername,
677 reqTack, nextProtos is not None,
678 serverName,
679 extensions=extensions)
680 for result in self._sendMsg(clientHello):
681 yield result
682 yield clientHello
683
684
686 for result in self._getMsg(ContentType.handshake,
687 HandshakeType.server_hello):
688 if result in (0,1): yield result
689 else: break
690 serverHello = result
691
692
693
694 self.version = serverHello.server_version
695
696
697 if serverHello.server_version < settings.minVersion:
698 for result in self._sendError(\
699 AlertDescription.protocol_version,
700 "Too old version: %s" % str(serverHello.server_version)):
701 yield result
702 if serverHello.server_version > settings.maxVersion:
703 for result in self._sendError(\
704 AlertDescription.protocol_version,
705 "Too new version: %s" % str(serverHello.server_version)):
706 yield result
707 serverVer = serverHello.server_version
708 cipherSuites = CipherSuite.filterForVersion(clientHello.cipher_suites,
709 minVersion=serverVer,
710 maxVersion=serverVer)
711 if serverHello.cipher_suite not in cipherSuites:
712 for result in self._sendError(\
713 AlertDescription.illegal_parameter,
714 "Server responded with incorrect ciphersuite"):
715 yield result
716 if serverHello.certificate_type not in clientHello.certificate_types:
717 for result in self._sendError(\
718 AlertDescription.illegal_parameter,
719 "Server responded with incorrect certificate type"):
720 yield result
721 if serverHello.compression_method != 0:
722 for result in self._sendError(\
723 AlertDescription.illegal_parameter,
724 "Server responded with incorrect compression method"):
725 yield result
726 if serverHello.tackExt:
727 if not clientHello.tack:
728 for result in self._sendError(\
729 AlertDescription.illegal_parameter,
730 "Server responded with unrequested Tack Extension"):
731 yield result
732 if not serverHello.tackExt.verifySignatures():
733 for result in self._sendError(\
734 AlertDescription.decrypt_error,
735 "TackExtension contains an invalid signature"):
736 yield result
737 if serverHello.next_protos and not clientHello.supports_npn:
738 for result in self._sendError(\
739 AlertDescription.illegal_parameter,
740 "Server responded with unrequested NPN Extension"):
741 yield result
742 yield serverHello
743
745
746
747
748
749
750
751
752 if nextProtos is not None and serverHello.next_protos is not None:
753 for p in nextProtos:
754 if bytearray(p) in serverHello.next_protos:
755 return bytearray(p)
756 else:
757
758
759
760 return bytearray(nextProtos[0])
761 return None
762
763 - def _clientResume(self, session, serverHello, clientRandom,
764 cipherImplementations, nextProto):
793
794 - def _clientSRPKeyExchange(self, settings, cipherSuite, certificateType,
795 srpUsername, password,
796 clientRandom, serverRandom, tackExt):
797
798
799 if cipherSuite in CipherSuite.srpCertSuites:
800
801 for result in self._getMsg(ContentType.handshake,
802 HandshakeType.certificate, certificateType):
803 if result in (0,1): yield result
804 else: break
805 serverCertificate = result
806 else:
807 serverCertificate = None
808
809 for result in self._getMsg(ContentType.handshake,
810 HandshakeType.server_key_exchange, cipherSuite):
811 if result in (0,1): yield result
812 else: break
813 serverKeyExchange = result
814
815 for result in self._getMsg(ContentType.handshake,
816 HandshakeType.server_hello_done):
817 if result in (0,1): yield result
818 else: break
819 serverHelloDone = result
820
821
822
823 N = serverKeyExchange.srp_N
824 g = serverKeyExchange.srp_g
825 s = serverKeyExchange.srp_s
826 B = serverKeyExchange.srp_B
827
828 if (g,N) not in goodGroupParameters:
829 for result in self._sendError(\
830 AlertDescription.insufficient_security,
831 "Unknown group parameters"):
832 yield result
833 if numBits(N) < settings.minKeySize:
834 for result in self._sendError(\
835 AlertDescription.insufficient_security,
836 "N value is too small: %d" % numBits(N)):
837 yield result
838 if numBits(N) > settings.maxKeySize:
839 for result in self._sendError(\
840 AlertDescription.insufficient_security,
841 "N value is too large: %d" % numBits(N)):
842 yield result
843 if B % N == 0:
844 for result in self._sendError(\
845 AlertDescription.illegal_parameter,
846 "Suspicious B value"):
847 yield result
848
849
850
851 serverCertChain = None
852 if cipherSuite in CipherSuite.srpCertSuites:
853
854 hashBytes = serverKeyExchange.hash(clientRandom, serverRandom)
855 if self.version == (3, 3):
856 hashBytes = RSAKey.addPKCS1SHA1Prefix(hashBytes)
857
858
859 sigBytes = serverKeyExchange.signature
860 if len(sigBytes) == 0:
861 for result in self._sendError(\
862 AlertDescription.illegal_parameter,
863 "Server sent an SRP ServerKeyExchange "\
864 "message without a signature"):
865 yield result
866
867
868
869
870 for result in self._clientGetKeyFromChain(serverCertificate,
871 settings, tackExt):
872 if result in (0,1): yield result
873 else: break
874 publicKey, serverCertChain, tackExt = result
875
876
877 if not publicKey.verify(sigBytes, hashBytes):
878 for result in self._sendError(\
879 AlertDescription.decrypt_error,
880 "Signature failed to verify"):
881 yield result
882
883
884 a = bytesToNumber(getRandomBytes(32))
885 A = powMod(g, a, N)
886
887
888 x = makeX(s, bytearray(srpUsername, "utf-8"),
889 bytearray(password, "utf-8"))
890 v = powMod(g, x, N)
891
892
893 u = makeU(N, A, B)
894
895
896 k = makeK(N, g)
897 S = powMod((B - (k*v)) % N, a+(u*x), N)
898
899 if self.fault == Fault.badA:
900 A = N
901 S = 0
902
903 premasterSecret = numberToByteArray(S)
904
905
906 for result in self._sendMsg(\
907 ClientKeyExchange(cipherSuite, self.version).createSRP(A)):
908 yield result
909 yield (premasterSecret, serverCertChain, tackExt)
910
911
912 - def _clientRSAKeyExchange(self, settings, cipherSuite,
913 clientCertChain, privateKey,
914 certificateType,
915 clientRandom, serverRandom,
916 tackExt):
917
918
919 for result in self._getMsg(ContentType.handshake,
920 HandshakeType.certificate, certificateType):
921 if result in (0,1): yield result
922 else: break
923 serverCertificate = result
924
925
926 for result in self._getMsg(ContentType.handshake,
927 (HandshakeType.server_hello_done,
928 HandshakeType.certificate_request)):
929 if result in (0,1): yield result
930 else: break
931 msg = result
932 certificateRequest = None
933 if isinstance(msg, CertificateRequest):
934 certificateRequest = msg
935
936 for result in self._getMsg(ContentType.handshake,
937 HandshakeType.server_hello_done):
938 if result in (0,1): yield result
939 else: break
940 serverHelloDone = result
941 elif isinstance(msg, ServerHelloDone):
942 serverHelloDone = msg
943
944
945
946
947 for result in self._clientGetKeyFromChain(serverCertificate,
948 settings, tackExt):
949 if result in (0,1): yield result
950 else: break
951 publicKey, serverCertChain, tackExt = result
952
953
954 premasterSecret = getRandomBytes(48)
955 premasterSecret[0] = settings.maxVersion[0]
956 premasterSecret[1] = settings.maxVersion[1]
957
958 if self.fault == Fault.badPremasterPadding:
959 premasterSecret[0] = 5
960 if self.fault == Fault.shortPremasterSecret:
961 premasterSecret = premasterSecret[:-1]
962
963
964 encryptedPreMasterSecret = publicKey.encrypt(premasterSecret)
965
966
967
968 if certificateRequest:
969 clientCertificate = Certificate(certificateType)
970
971 if clientCertChain:
972
973
974 wrongType = False
975 if certificateType == CertificateType.x509:
976 if not isinstance(clientCertChain, X509CertChain):
977 wrongType = True
978 if wrongType:
979 for result in self._sendError(\
980 AlertDescription.handshake_failure,
981 "Client certificate is of wrong type"):
982 yield result
983
984 clientCertificate.create(clientCertChain)
985 for result in self._sendMsg(clientCertificate):
986 yield result
987 else:
988
989
990
991 privateKey = None
992 clientCertChain = None
993
994
995 clientKeyExchange = ClientKeyExchange(cipherSuite,
996 self.version)
997 clientKeyExchange.createRSA(encryptedPreMasterSecret)
998 for result in self._sendMsg(clientKeyExchange):
999 yield result
1000
1001
1002
1003 if certificateRequest and privateKey:
1004 signatureAlgorithm = None
1005 if self.version == (3,0):
1006 masterSecret = calcMasterSecret(self.version,
1007 cipherSuite,
1008 premasterSecret,
1009 clientRandom,
1010 serverRandom)
1011 verifyBytes = self._handshake_hash.digestSSL(masterSecret, b"")
1012 elif self.version in ((3,1), (3,2)):
1013 verifyBytes = self._handshake_hash.digest()
1014 elif self.version == (3,3):
1015
1016 signatureAlgorithm = (HashAlgorithm.sha1, SignatureAlgorithm.rsa)
1017 verifyBytes = self._handshake_hash.digest('sha1')
1018 verifyBytes = RSAKey.addPKCS1SHA1Prefix(verifyBytes)
1019 if self.fault == Fault.badVerifyMessage:
1020 verifyBytes[0] = ((verifyBytes[0]+1) % 256)
1021 signedBytes = privateKey.sign(verifyBytes)
1022 certificateVerify = CertificateVerify(self.version)
1023 certificateVerify.create(signedBytes, signatureAlgorithm)
1024 for result in self._sendMsg(certificateVerify):
1025 yield result
1026 yield (premasterSecret, serverCertChain, clientCertChain, tackExt)
1027
1028 - def _clientDHEKeyExchange(self, settings, cipherSuite,
1029 clientCertChain, privateKey,
1030 certificateType,
1031 tackExt, clientRandom, serverRandom):
1032
1033
1034
1035
1036 if cipherSuite in CipherSuite.dheCertSuites:
1037 for result in self._getMsg(ContentType.handshake,
1038 HandshakeType.certificate,
1039 certificateType):
1040 if result in (0, 1):
1041 yield result
1042 else: break
1043 serverCertificate = result
1044
1045 for result in self._getMsg(ContentType.handshake,
1046 HandshakeType.server_key_exchange, cipherSuite):
1047 if result in (0,1): yield result
1048 else: break
1049 serverKeyExchange = result
1050
1051 for result in self._getMsg(ContentType.handshake,
1052 (HandshakeType.certificate_request,
1053 HandshakeType.server_hello_done)):
1054 if result in (0,1): yield result
1055 else: break
1056
1057 certificateRequest = None
1058 if isinstance(result, CertificateRequest):
1059 certificateRequest = result
1060
1061 for result in self._getMsg(ContentType.handshake,
1062 HandshakeType.server_hello_done):
1063 if result in (0, 1):
1064 yield result
1065 else: break
1066 serverHelloDone = result
1067
1068
1069 serverCertChain = None
1070 if cipherSuite in CipherSuite.dheCertSuites:
1071
1072 if self.version == (3, 3):
1073 if serverKeyExchange.hashAlg != HashAlgorithm.sha1 or \
1074 serverKeyExchange.signAlg != SignatureAlgorithm.rsa:
1075 for result in self._sendError(\
1076 AlertDescription.illegal_parameter,
1077 "Server selected not advertised "
1078 "signature algorithm"):
1079 yield result
1080
1081 hashBytes = serverKeyExchange.hash(clientRandom, serverRandom)
1082
1083 sigBytes = serverKeyExchange.signature
1084 if len(sigBytes) == 0:
1085 for result in self._sendError(\
1086 AlertDescription.illegal_parameter,
1087 "Server sent DHE ServerKeyExchange message "
1088 "without a signature"):
1089 yield result
1090
1091 for result in self._clientGetKeyFromChain(serverCertificate,
1092 settings,
1093 tackExt):
1094 if result in (0, 1):
1095 yield result
1096 else:
1097 break
1098 publicKey, serverCertChain, tackExt = result
1099
1100
1101 if self.version == (3, 3):
1102 hashBytes = publicKey.addPKCS1SHA1Prefix(hashBytes)
1103
1104 if not publicKey.verify(sigBytes, hashBytes):
1105 for result in self._sendError(
1106 AlertDescription.decrypt_error,
1107 "signature failed to verify"):
1108 yield result
1109
1110
1111 if 2**1023 > serverKeyExchange.dh_p:
1112 for result in self._sendError(
1113 AlertDescription.insufficient_security,
1114 "Server sent a DHE key exchange with very small prime"):
1115 yield result
1116
1117
1118 if certificateRequest:
1119
1120
1121
1122 if self.version == (3, 3) and \
1123 (HashAlgorithm.sha1, SignatureAlgorithm.rsa) \
1124 not in certificateRequest.supported_signature_algs and\
1125 len(certificateRequest.supported_signature_algs) > 0:
1126 for result in self._sendError(\
1127 AlertDescription.handshake_failure,
1128 "Server doesn't accept any sigalgs we support: " +
1129 str(certificateRequest.supported_signature_algs)):
1130 yield result
1131 clientCertificate = Certificate(certificateType)
1132
1133 if clientCertChain:
1134
1135
1136 wrongType = False
1137 if certificateType == CertificateType.x509:
1138 if not isinstance(clientCertChain, X509CertChain):
1139 wrongType = True
1140 if wrongType:
1141 for result in self._sendError(\
1142 AlertDescription.handshake_failure,
1143 "Client certificate is of wrong type"):
1144 yield result
1145
1146 clientCertificate.create(clientCertChain)
1147
1148 for result in self._sendMsg(clientCertificate):
1149 yield result
1150 else:
1151
1152 privateKey = None
1153 clientCertChain = None
1154
1155
1156 dh_p = serverKeyExchange.dh_p
1157 dh_g = serverKeyExchange.dh_g
1158 dh_Xc = bytesToNumber(getRandomBytes(32))
1159 dh_Ys = serverKeyExchange.dh_Ys
1160 dh_Yc = powMod(dh_g, dh_Xc, dh_p)
1161
1162
1163 for result in self._sendMsg(\
1164 ClientKeyExchange(cipherSuite, self.version).createDH(dh_Yc)):
1165 yield result
1166
1167
1168 S = powMod(dh_Ys, dh_Xc, dh_p)
1169 premasterSecret = numberToByteArray(S)
1170
1171
1172
1173 if certificateRequest and privateKey:
1174 signatureAlgorithm = None
1175 if self.version == (3,0):
1176 masterSecret = calcMasterSecret(self.version,
1177 cipherSuite,
1178 premasterSecret,
1179 clientRandom,
1180 serverRandom)
1181 verifyBytes = self._handshake_hash.digestSSL(masterSecret, b"")
1182 elif self.version in ((3,1), (3,2)):
1183 verifyBytes = self._handshake_hash.digest()
1184 else:
1185
1186 signatureAlgorithm = (HashAlgorithm.sha1, SignatureAlgorithm.rsa)
1187 verifyBytes = self._handshake_hash.digest('sha1')
1188 verifyBytes = RSAKey.addPKCS1SHA1Prefix(verifyBytes)
1189 if self.fault == Fault.badVerifyMessage:
1190 verifyBytes[0] = ((verifyBytes[0]+1) % 256)
1191 signedBytes = privateKey.sign(verifyBytes)
1192 certificateVerify = CertificateVerify(self.version)
1193 certificateVerify.create(signedBytes, signatureAlgorithm)
1194 for result in self._sendMsg(certificateVerify):
1195 yield result
1196
1197 yield (premasterSecret, serverCertChain, clientCertChain, tackExt)
1198
1199 - def _clientFinished(self, premasterSecret, clientRandom, serverRandom,
1200 cipherSuite, cipherImplementations, nextProto):
1201
1202 masterSecret = calcMasterSecret(self.version,
1203 cipherSuite,
1204 premasterSecret,
1205 clientRandom,
1206 serverRandom)
1207 self._calcPendingStates(cipherSuite, masterSecret,
1208 clientRandom, serverRandom,
1209 cipherImplementations)
1210
1211
1212 for result in self._sendFinished(masterSecret, cipherSuite, nextProto):
1213 yield result
1214 for result in self._getFinished(masterSecret,
1215 cipherSuite,
1216 nextProto=nextProto):
1217 yield result
1218 yield masterSecret
1219
1256
1257
1258
1259
1260
1261
1262
1263 - def handshakeServer(self, verifierDB=None,
1264 certChain=None, privateKey=None, reqCert=False,
1265 sessionCache=None, settings=None, checker=None,
1266 reqCAs = None,
1267 tacks=None, activationFlags=0,
1268 nextProtos=None, anon=False):
1269 """Perform a handshake in the role of server.
1270
1271 This function performs an SSL or TLS handshake. Depending on
1272 the arguments and the behavior of the client, this function can
1273 perform an SRP, or certificate-based handshake. It
1274 can also perform a combined SRP and server-certificate
1275 handshake.
1276
1277 Like any handshake function, this can be called on a closed
1278 TLS connection, or on a TLS connection that is already open.
1279 If called on an open connection it performs a re-handshake.
1280 This function does not send a Hello Request message before
1281 performing the handshake, so if re-handshaking is required,
1282 the server must signal the client to begin the re-handshake
1283 through some other means.
1284
1285 If the function completes without raising an exception, the
1286 TLS connection will be open and available for data transfer.
1287
1288 If an exception is raised, the connection will have been
1289 automatically closed (if it was ever open).
1290
1291 @type verifierDB: L{tlslite.verifierdb.VerifierDB}
1292 @param verifierDB: A database of SRP password verifiers
1293 associated with usernames. If the client performs an SRP
1294 handshake, the session's srpUsername attribute will be set.
1295
1296 @type certChain: L{tlslite.x509certchain.X509CertChain}
1297 @param certChain: The certificate chain to be used if the
1298 client requests server certificate authentication.
1299
1300 @type privateKey: L{tlslite.utils.rsakey.RSAKey}
1301 @param privateKey: The private key to be used if the client
1302 requests server certificate authentication.
1303
1304 @type reqCert: bool
1305 @param reqCert: Whether to request client certificate
1306 authentication. This only applies if the client chooses server
1307 certificate authentication; if the client chooses SRP
1308 authentication, this will be ignored. If the client
1309 performs a client certificate authentication, the sessions's
1310 clientCertChain attribute will be set.
1311
1312 @type sessionCache: L{tlslite.sessioncache.SessionCache}
1313 @param sessionCache: An in-memory cache of resumable sessions.
1314 The client can resume sessions from this cache. Alternatively,
1315 if the client performs a full handshake, a new session will be
1316 added to the cache.
1317
1318 @type settings: L{tlslite.handshakesettings.HandshakeSettings}
1319 @param settings: Various settings which can be used to control
1320 the ciphersuites and SSL/TLS version chosen by the server.
1321
1322 @type checker: L{tlslite.checker.Checker}
1323 @param checker: A Checker instance. This instance will be
1324 invoked to examine the other party's authentication
1325 credentials, if the handshake completes succesfully.
1326
1327 @type reqCAs: list of L{bytearray} of unsigned bytes
1328 @param reqCAs: A collection of DER-encoded DistinguishedNames that
1329 will be sent along with a certificate request. This does not affect
1330 verification.
1331
1332 @type nextProtos: list of strings.
1333 @param nextProtos: A list of upper layer protocols to expose to the
1334 clients through the Next-Protocol Negotiation Extension,
1335 if they support it.
1336
1337 @raise socket.error: If a socket error occurs.
1338 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
1339 without a preceding alert.
1340 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
1341 @raise tlslite.errors.TLSAuthenticationError: If the checker
1342 doesn't like the other party's authentication credentials.
1343 """
1344 for result in self.handshakeServerAsync(verifierDB,
1345 certChain, privateKey, reqCert, sessionCache, settings,
1346 checker, reqCAs,
1347 tacks=tacks, activationFlags=activationFlags,
1348 nextProtos=nextProtos, anon=anon):
1349 pass
1350
1351
1352 - def handshakeServerAsync(self, verifierDB=None,
1353 certChain=None, privateKey=None, reqCert=False,
1354 sessionCache=None, settings=None, checker=None,
1355 reqCAs=None,
1356 tacks=None, activationFlags=0,
1357 nextProtos=None, anon=False
1358 ):
1359 """Start a server handshake operation on the TLS connection.
1360
1361 This function returns a generator which behaves similarly to
1362 handshakeServer(). Successive invocations of the generator
1363 will return 0 if it is waiting to read from the socket, 1 if it is
1364 waiting to write to the socket, or it will raise StopIteration
1365 if the handshake operation is complete.
1366
1367 @rtype: iterable
1368 @return: A generator; see above for details.
1369 """
1370 handshaker = self._handshakeServerAsyncHelper(\
1371 verifierDB=verifierDB, certChain=certChain,
1372 privateKey=privateKey, reqCert=reqCert,
1373 sessionCache=sessionCache, settings=settings,
1374 reqCAs=reqCAs,
1375 tacks=tacks, activationFlags=activationFlags,
1376 nextProtos=nextProtos, anon=anon)
1377 for result in self._handshakeWrapperAsync(handshaker, checker):
1378 yield result
1379
1380
1381 - def _handshakeServerAsyncHelper(self, verifierDB,
1382 certChain, privateKey, reqCert, sessionCache,
1383 settings, reqCAs,
1384 tacks, activationFlags,
1385 nextProtos, anon):
1386
1387 self._handshakeStart(client=False)
1388
1389 if (not verifierDB) and (not certChain) and not anon:
1390 raise ValueError("Caller passed no authentication credentials")
1391 if certChain and not privateKey:
1392 raise ValueError("Caller passed a certChain but no privateKey")
1393 if privateKey and not certChain:
1394 raise ValueError("Caller passed a privateKey but no certChain")
1395 if reqCAs and not reqCert:
1396 raise ValueError("Caller passed reqCAs but not reqCert")
1397 if certChain and not isinstance(certChain, X509CertChain):
1398 raise ValueError("Unrecognized certificate type")
1399 if activationFlags and not tacks:
1400 raise ValueError("Nonzero activationFlags requires tacks")
1401 if tacks:
1402 if not tackpyLoaded:
1403 raise ValueError("tackpy is not loaded")
1404 if not settings or not settings.useExperimentalTackExtension:
1405 raise ValueError("useExperimentalTackExtension not enabled")
1406
1407 if not settings:
1408 settings = HandshakeSettings()
1409 settings = settings.validate()
1410
1411
1412
1413
1414
1415 for result in self._serverGetClientHello(settings, certChain,\
1416 verifierDB, sessionCache,
1417 anon):
1418 if result in (0,1): yield result
1419 elif result == None:
1420 self._handshakeDone(resumed=True)
1421 return
1422 else: break
1423 (clientHello, cipherSuite) = result
1424
1425
1426
1427
1428 if sessionCache:
1429 sessionID = getRandomBytes(32)
1430 else:
1431 sessionID = bytearray(0)
1432
1433 if not clientHello.supports_npn:
1434 nextProtos = None
1435
1436
1437 if not cipherSuite in CipherSuite.certAllSuites:
1438 tacks = None
1439
1440
1441 if clientHello.tack:
1442 tackExt = TackExtension.create(tacks, activationFlags)
1443 else:
1444 tackExt = None
1445
1446
1447 if settings.useEncryptThenMAC and \
1448 clientHello.getExtension(ExtensionType.encrypt_then_mac) and \
1449 cipherSuite not in CipherSuite.streamSuites and \
1450 cipherSuite not in CipherSuite.aeadSuites:
1451 extensions = [TLSExtension().create(ExtensionType.encrypt_then_mac,
1452 bytearray(0))]
1453 self._recordLayer.encryptThenMAC = True
1454 else:
1455 extensions = None
1456
1457 serverHello = ServerHello()
1458 serverHello.create(self.version, getRandomBytes(32), sessionID, \
1459 cipherSuite, CertificateType.x509, tackExt,
1460 nextProtos, extensions=extensions)
1461
1462
1463 clientCertChain = None
1464 if cipherSuite in CipherSuite.srpAllSuites:
1465 for result in self._serverSRPKeyExchange(clientHello, serverHello,
1466 verifierDB, cipherSuite,
1467 privateKey, certChain):
1468 if result in (0,1): yield result
1469 else: break
1470 premasterSecret = result
1471
1472
1473 elif (cipherSuite in CipherSuite.certSuites or
1474 cipherSuite in CipherSuite.dheCertSuites):
1475 if cipherSuite in CipherSuite.certSuites:
1476 keyExchange = RSAKeyExchange(cipherSuite,
1477 clientHello,
1478 serverHello,
1479 privateKey)
1480 elif cipherSuite in CipherSuite.dheCertSuites:
1481 keyExchange = DHE_RSAKeyExchange(cipherSuite,
1482 clientHello,
1483 serverHello,
1484 privateKey)
1485 else:
1486 assert(False)
1487 for result in self._serverCertKeyExchange(clientHello, serverHello,
1488 certChain, keyExchange,
1489 reqCert, reqCAs, cipherSuite,
1490 settings):
1491 if result in (0,1): yield result
1492 else: break
1493 (premasterSecret, clientCertChain) = result
1494
1495
1496 elif cipherSuite in CipherSuite.anonSuites:
1497 for result in self._serverAnonKeyExchange(clientHello, serverHello,
1498 cipherSuite, settings):
1499 if result in (0,1): yield result
1500 else: break
1501 premasterSecret = result
1502
1503 else:
1504 assert(False)
1505
1506
1507 for result in self._serverFinished(premasterSecret,
1508 clientHello.random, serverHello.random,
1509 cipherSuite, settings.cipherImplementations,
1510 nextProtos):
1511 if result in (0,1): yield result
1512 else: break
1513 masterSecret = result
1514
1515
1516 self.session = Session()
1517 if cipherSuite in CipherSuite.certAllSuites:
1518 serverCertChain = certChain
1519 else:
1520 serverCertChain = None
1521 srpUsername = None
1522 serverName = None
1523 if clientHello.srp_username:
1524 srpUsername = clientHello.srp_username.decode("utf-8")
1525 if clientHello.server_name:
1526 serverName = clientHello.server_name.decode("utf-8")
1527 self.session.create(masterSecret, serverHello.session_id, cipherSuite,
1528 srpUsername, clientCertChain, serverCertChain,
1529 tackExt, (serverHello.tackExt is not None),
1530 serverName,
1531 encryptThenMAC=self._recordLayer.encryptThenMAC)
1532
1533
1534 if sessionCache and sessionID:
1535 sessionCache[sessionID] = self.session
1536
1537 self._handshakeDone(resumed=False)
1538
1539
1542
1543
1544
1545 self.version = settings.maxVersion
1546
1547
1548 for result in self._getMsg(ContentType.handshake,
1549 HandshakeType.client_hello):
1550 if result in (0,1): yield result
1551 else: break
1552 clientHello = result
1553
1554
1555 if clientHello.client_version < settings.minVersion:
1556 self.version = settings.minVersion
1557 for result in self._sendError(\
1558 AlertDescription.protocol_version,
1559 "Too old version: %s" % str(clientHello.client_version)):
1560 yield result
1561
1562
1563 elif clientHello.client_version > settings.maxVersion:
1564 self.version = settings.maxVersion
1565
1566 else:
1567
1568 self.version = clientHello.client_version
1569
1570
1571 if clientHello.client_version < settings.maxVersion and \
1572 CipherSuite.TLS_FALLBACK_SCSV in clientHello.cipher_suites:
1573 for result in self._sendError(\
1574 AlertDescription.inappropriate_fallback):
1575 yield result
1576
1577
1578
1579 cipherSuites = []
1580 if verifierDB:
1581 if certChain:
1582 cipherSuites += \
1583 CipherSuite.getSrpCertSuites(settings, self.version)
1584 cipherSuites += CipherSuite.getSrpSuites(settings, self.version)
1585 elif certChain:
1586 cipherSuites += CipherSuite.getDheCertSuites(settings, self.version)
1587 cipherSuites += CipherSuite.getCertSuites(settings, self.version)
1588 elif anon:
1589 cipherSuites += CipherSuite.getAnonSuites(settings, self.version)
1590 else:
1591 assert(False)
1592 cipherSuites = CipherSuite.filterForVersion(cipherSuites,
1593 minVersion=self.version,
1594 maxVersion=self.version)
1595
1596
1597 if clientHello.session_id and sessionCache:
1598 session = None
1599
1600
1601 if sessionCache and not session:
1602 try:
1603 session = sessionCache[clientHello.session_id]
1604 if not session.resumable:
1605 raise AssertionError()
1606
1607 if session.cipherSuite not in cipherSuites:
1608 for result in self._sendError(\
1609 AlertDescription.handshake_failure):
1610 yield result
1611 if session.cipherSuite not in clientHello.cipher_suites:
1612 for result in self._sendError(\
1613 AlertDescription.handshake_failure):
1614 yield result
1615 if clientHello.srp_username:
1616 if not session.srpUsername or \
1617 clientHello.srp_username != bytearray(session.srpUsername, "utf-8"):
1618 for result in self._sendError(\
1619 AlertDescription.handshake_failure):
1620 yield result
1621 if clientHello.server_name:
1622 if not session.serverName or \
1623 clientHello.server_name != bytearray(session.serverName, "utf-8"):
1624 for result in self._sendError(\
1625 AlertDescription.handshake_failure):
1626 yield result
1627 if session.encryptThenMAC and \
1628 not clientHello.getExtension(
1629 ExtensionType.encrypt_then_mac):
1630 for result in self._sendError(\
1631 AlertDescription.handshake_failure):
1632 yield result
1633 except KeyError:
1634 pass
1635
1636
1637 if session:
1638
1639 if session.encryptThenMAC:
1640 self._recordLayer.encryptThenMAC = True
1641 mte = TLSExtension().create(ExtensionType.encrypt_then_mac,
1642 bytearray(0))
1643 extensions = [mte]
1644 else:
1645 extensions = None
1646 serverHello = ServerHello()
1647 serverHello.create(self.version, getRandomBytes(32),
1648 session.sessionID, session.cipherSuite,
1649 CertificateType.x509, None, None,
1650 extensions=extensions)
1651 for result in self._sendMsg(serverHello):
1652 yield result
1653
1654
1655 self._calcPendingStates(session.cipherSuite,
1656 session.masterSecret,
1657 clientHello.random,
1658 serverHello.random,
1659 settings.cipherImplementations)
1660
1661
1662 for result in self._sendFinished(session.masterSecret,
1663 session.cipherSuite):
1664 yield result
1665 for result in self._getFinished(session.masterSecret,
1666 session.cipherSuite):
1667 yield result
1668
1669
1670 self.session = session
1671
1672 yield None
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682 for cipherSuite in cipherSuites:
1683 if cipherSuite in clientHello.cipher_suites:
1684 break
1685 else:
1686 for result in self._sendError(\
1687 AlertDescription.handshake_failure,
1688 "No mutual ciphersuite"):
1689 yield result
1690 if cipherSuite in CipherSuite.srpAllSuites and \
1691 not clientHello.srp_username:
1692 for result in self._sendError(\
1693 AlertDescription.unknown_psk_identity,
1694 "Client sent a hello, but without the SRP username"):
1695 yield result
1696
1697
1698 if cipherSuite in CipherSuite.certAllSuites and CertificateType.x509 \
1699 not in clientHello.certificate_types:
1700 for result in self._sendError(\
1701 AlertDescription.handshake_failure,
1702 "the client doesn't support my certificate type"):
1703 yield result
1704
1705
1706
1707
1708 yield (clientHello, cipherSuite)
1709
1710 - def _serverSRPKeyExchange(self, clientHello, serverHello, verifierDB,
1711 cipherSuite, privateKey, serverCertChain):
1712
1713 srpUsername = clientHello.srp_username.decode("utf-8")
1714 self.allegedSrpUsername = srpUsername
1715
1716 try:
1717 entry = verifierDB[srpUsername]
1718 except KeyError:
1719 for result in self._sendError(\
1720 AlertDescription.unknown_psk_identity):
1721 yield result
1722 (N, g, s, v) = entry
1723
1724
1725 b = bytesToNumber(getRandomBytes(32))
1726 k = makeK(N, g)
1727 B = (powMod(g, b, N) + (k*v)) % N
1728
1729
1730 serverKeyExchange = ServerKeyExchange(cipherSuite, self.version)
1731 serverKeyExchange.createSRP(N, g, s, B)
1732 if cipherSuite in CipherSuite.srpCertSuites:
1733 hashBytes = serverKeyExchange.hash(clientHello.random,
1734 serverHello.random)
1735 if self.version == (3, 3):
1736 hashBytes = RSAKey.addPKCS1SHA1Prefix(hashBytes)
1737 serverKeyExchange.signature = privateKey.sign(hashBytes)
1738 if self.version == (3, 3):
1739
1740 serverKeyExchange.signAlg = SignatureAlgorithm.rsa
1741 serverKeyExchange.hashAlg = HashAlgorithm.sha1
1742
1743
1744
1745 msgs = []
1746 msgs.append(serverHello)
1747 if cipherSuite in CipherSuite.srpCertSuites:
1748 certificateMsg = Certificate(CertificateType.x509)
1749 certificateMsg.create(serverCertChain)
1750 msgs.append(certificateMsg)
1751 msgs.append(serverKeyExchange)
1752 msgs.append(ServerHelloDone())
1753 for result in self._sendMsgs(msgs):
1754 yield result
1755
1756
1757 for result in self._getMsg(ContentType.handshake,
1758 HandshakeType.client_key_exchange,
1759 cipherSuite):
1760 if result in (0,1): yield result
1761 else: break
1762 clientKeyExchange = result
1763 A = clientKeyExchange.srp_A
1764 if A % N == 0:
1765 for result in self._sendError(AlertDescription.illegal_parameter,
1766 "Suspicious A value"):
1767 yield result
1768 assert(False)
1769
1770
1771 u = makeU(N, A, B)
1772
1773
1774 S = powMod((A * powMod(v,u,N)) % N, b, N)
1775 premasterSecret = numberToByteArray(S)
1776
1777 yield premasterSecret
1778
1779
1780 - def _serverCertKeyExchange(self, clientHello, serverHello,
1781 serverCertChain, keyExchange,
1782 reqCert, reqCAs, cipherSuite,
1783 settings):
1784
1785
1786 msgs = []
1787
1788
1789 clientCertChain = None
1790
1791 msgs.append(serverHello)
1792 msgs.append(Certificate(CertificateType.x509).create(serverCertChain))
1793 serverKeyExchange = keyExchange.makeServerKeyExchange()
1794 if serverKeyExchange is not None:
1795 msgs.append(serverKeyExchange)
1796 if reqCert:
1797 certificateRequest = CertificateRequest(self.version)
1798 if not reqCAs:
1799 reqCAs = []
1800
1801 certificateRequest.create([ClientCertificateType.rsa_sign],
1802 reqCAs,
1803 [(HashAlgorithm.sha1,
1804 SignatureAlgorithm.rsa)])
1805 msgs.append(certificateRequest)
1806 msgs.append(ServerHelloDone())
1807 for result in self._sendMsgs(msgs):
1808 yield result
1809
1810
1811 if reqCert:
1812 if self.version == (3,0):
1813 for result in self._getMsg((ContentType.handshake,
1814 ContentType.alert),
1815 HandshakeType.certificate,
1816 CertificateType.x509):
1817 if result in (0,1): yield result
1818 else: break
1819 msg = result
1820
1821 if isinstance(msg, Alert):
1822
1823 alert = msg
1824 if alert.description != \
1825 AlertDescription.no_certificate:
1826 self._shutdown(False)
1827 raise TLSRemoteAlert(alert)
1828 elif isinstance(msg, Certificate):
1829 clientCertificate = msg
1830 if clientCertificate.certChain and \
1831 clientCertificate.certChain.getNumCerts()!=0:
1832 clientCertChain = clientCertificate.certChain
1833 else:
1834 raise AssertionError()
1835 elif self.version in ((3,1), (3,2), (3,3)):
1836 for result in self._getMsg(ContentType.handshake,
1837 HandshakeType.certificate,
1838 CertificateType.x509):
1839 if result in (0,1): yield result
1840 else: break
1841 clientCertificate = result
1842 if clientCertificate.certChain and \
1843 clientCertificate.certChain.getNumCerts()!=0:
1844 clientCertChain = clientCertificate.certChain
1845 else:
1846 raise AssertionError()
1847
1848
1849 for result in self._getMsg(ContentType.handshake,
1850 HandshakeType.client_key_exchange,
1851 cipherSuite):
1852 if result in (0,1): yield result
1853 else: break
1854 clientKeyExchange = result
1855
1856
1857 try:
1858 premasterSecret = \
1859 keyExchange.processClientKeyExchange(clientKeyExchange)
1860 except TLSLocalAlert as alert:
1861 for result in self._sendError(alert.description, alert.message):
1862 yield result
1863
1864
1865 if clientCertChain:
1866 if self.version == (3,0):
1867 masterSecret = calcMasterSecret(self.version,
1868 cipherSuite,
1869 premasterSecret,
1870 clientHello.random,
1871 serverHello.random)
1872 verifyBytes = self._handshake_hash.digestSSL(masterSecret, b"")
1873 elif self.version in ((3,1), (3,2)):
1874 verifyBytes = self._handshake_hash.digest()
1875 elif self.version == (3,3):
1876 verifyBytes = self._handshake_hash.digest('sha1')
1877 verifyBytes = RSAKey.addPKCS1SHA1Prefix(verifyBytes)
1878 for result in self._getMsg(ContentType.handshake,
1879 HandshakeType.certificate_verify):
1880 if result in (0,1): yield result
1881 else: break
1882 certificateVerify = result
1883 publicKey = clientCertChain.getEndEntityPublicKey()
1884 if len(publicKey) < settings.minKeySize:
1885 for result in self._sendError(\
1886 AlertDescription.handshake_failure,
1887 "Client's public key too small: %d" % len(publicKey)):
1888 yield result
1889
1890 if len(publicKey) > settings.maxKeySize:
1891 for result in self._sendError(\
1892 AlertDescription.handshake_failure,
1893 "Client's public key too large: %d" % len(publicKey)):
1894 yield result
1895
1896 if not publicKey.verify(certificateVerify.signature, verifyBytes):
1897 for result in self._sendError(\
1898 AlertDescription.decrypt_error,
1899 "Signature failed to verify"):
1900 yield result
1901 yield (premasterSecret, clientCertChain)
1902
1903
1906
1907
1908 dh_g, dh_p = goodGroupParameters[2]
1909 dh_Xs = bytesToNumber(getRandomBytes(32))
1910 dh_Ys = powMod(dh_g, dh_Xs, dh_p)
1911
1912
1913 serverKeyExchange = ServerKeyExchange(cipherSuite, self.version)
1914 serverKeyExchange.createDH(dh_p, dh_g, dh_Ys)
1915
1916
1917
1918 msgs = []
1919 msgs.append(serverHello)
1920 msgs.append(serverKeyExchange)
1921 msgs.append(ServerHelloDone())
1922 for result in self._sendMsgs(msgs):
1923 yield result
1924
1925
1926 for result in self._getMsg(ContentType.handshake,
1927 HandshakeType.client_key_exchange,
1928 cipherSuite):
1929 if result in (0,1):
1930 yield result
1931 else:
1932 break
1933 clientKeyExchange = result
1934 dh_Yc = clientKeyExchange.dh_Yc
1935
1936 if dh_Yc % dh_p == 0:
1937 for result in self._sendError(AlertDescription.illegal_parameter,
1938 "Suspicious dh_Yc value"):
1939 yield result
1940 assert(False)
1941
1942
1943 S = powMod(dh_Yc,dh_Xs,dh_p)
1944 premasterSecret = numberToByteArray(S)
1945
1946 yield premasterSecret
1947
1948
1949 - def _serverFinished(self, premasterSecret, clientRandom, serverRandom,
1950 cipherSuite, cipherImplementations, nextProtos):
1951 masterSecret = calcMasterSecret(self.version,
1952 cipherSuite,
1953 premasterSecret,
1954 clientRandom,
1955 serverRandom)
1956
1957
1958 self._calcPendingStates(cipherSuite, masterSecret,
1959 clientRandom, serverRandom,
1960 cipherImplementations)
1961
1962
1963 for result in self._getFinished(masterSecret,
1964 cipherSuite,
1965 expect_next_protocol=nextProtos is not None):
1966 yield result
1967
1968 for result in self._sendFinished(masterSecret, cipherSuite):
1969 yield result
1970
1971 yield masterSecret
1972
1973
1974
1975
1976
1977
1978
1979 - def _sendFinished(self, masterSecret, cipherSuite=None, nextProto=None):
2005
2006 - def _getFinished(self, masterSecret, cipherSuite=None,
2007 expect_next_protocol=False, nextProto=None):
2008
2009 for result in self._getMsg(ContentType.change_cipher_spec):
2010 if result in (0,1):
2011 yield result
2012 changeCipherSpec = result
2013
2014 if changeCipherSpec.type != 1:
2015 for result in self._sendError(AlertDescription.illegal_parameter,
2016 "ChangeCipherSpec type incorrect"):
2017 yield result
2018
2019
2020 self._changeReadState()
2021
2022
2023 if expect_next_protocol:
2024 for result in self._getMsg(ContentType.handshake, HandshakeType.next_protocol):
2025 if result in (0,1):
2026 yield result
2027 if result is None:
2028 for result in self._sendError(AlertDescription.unexpected_message,
2029 "Didn't get NextProtocol message"):
2030 yield result
2031
2032 self.next_proto = result.next_proto
2033 else:
2034 self.next_proto = None
2035
2036
2037 if nextProto:
2038 self.next_proto = nextProto
2039
2040
2041 verifyData = calcFinished(self.version,
2042 masterSecret,
2043 cipherSuite,
2044 self._handshake_hash,
2045 not self._client)
2046
2047
2048 for result in self._getMsg(ContentType.handshake,
2049 HandshakeType.finished):
2050 if result in (0,1):
2051 yield result
2052 finished = result
2053 if finished.verify_data != verifyData:
2054 for result in self._sendError(AlertDescription.decrypt_error,
2055 "Finished message is incorrect"):
2056 yield result
2057
2083