1
2
3
4
5
6
7 """
8 MAIN CLASS FOR TLS LITE (START HERE!).
9 """
10
11 import socket
12 from .utils.compat import formatExceptionTrace
13 from .tlsrecordlayer import TLSRecordLayer
14 from .session import Session
15 from .constants import *
16 from .utils.cryptomath import getRandomBytes
17 from .errors import *
18 from .messages import *
19 from .mathtls import *
20 from .handshakesettings import HandshakeSettings
21 from .utils.tackwrapper import *
22
23
25 """
26 This class wraps a socket and provides TLS handshaking and data
27 transfer.
28
29 To use this class, create a new instance, passing a connected
30 socket into the constructor. Then call some handshake function.
31 If the handshake completes without raising an exception, then a TLS
32 connection has been negotiated. You can transfer data over this
33 connection as if it were a socket.
34
35 This class provides both synchronous and asynchronous versions of
36 its key functions. The synchronous versions should be used when
37 writing single-or multi-threaded code using blocking sockets. The
38 asynchronous versions should be used when performing asynchronous,
39 event-based I/O with non-blocking sockets.
40
41 Asynchronous I/O is a complicated subject; typically, you should
42 not use the asynchronous functions directly, but should use some
43 framework like asyncore or Twisted which TLS Lite integrates with
44 (see
45 L{tlslite.integration.tlsasyncdispatchermixin.TLSAsyncDispatcherMixIn}).
46 """
47
49 """Create a new TLSConnection instance.
50
51 @param sock: The socket data will be transmitted on. The
52 socket should already be connected. It may be in blocking or
53 non-blocking mode.
54
55 @type sock: L{socket.socket}
56 """
57 TLSRecordLayer.__init__(self, sock)
58
59
60
61
62
63 - def handshakeClientSRP(self, username, password, session=None,
64 settings=None, checker=None,
65 reqTack=False, async=False):
66 """Perform an SRP handshake in the role of client.
67
68 This function performs a TLS/SRP handshake. SRP mutually
69 authenticates both parties to each other using only a
70 username and password. This function may also perform a
71 combined SRP and server-certificate handshake, if the server
72 chooses to authenticate itself with a certificate chain in
73 addition to doing SRP.
74
75 If the function completes without raising an exception, the
76 TLS connection will be open and available for data transfer.
77
78 If an exception is raised, the connection will have been
79 automatically closed (if it was ever open).
80
81 @type username: str
82 @param username: The SRP username.
83
84 @type password: str
85 @param password: The SRP password.
86
87 @type session: L{tlslite.session.Session}
88 @param session: A TLS session to attempt to resume. This
89 session must be an SRP session performed with the same username
90 and password as were passed in. If the resumption does not
91 succeed, a full SRP handshake will be performed.
92
93 @type settings: L{tlslite.handshakesettings.HandshakeSettings}
94 @param settings: Various settings which can be used to control
95 the ciphersuites, certificate types, and SSL/TLS versions
96 offered by the client.
97
98 @type checker: L{tlslite.checker.Checker}
99 @param checker: A Checker instance. This instance will be
100 invoked to examine the other party's authentication
101 credentials, if the handshake completes succesfully.
102
103 @type reqTack: bool
104 @param reqTack: Whether or not to send a "tack" TLS Extension,
105 requesting the server return a TACK_Extension if it has one.
106
107 @type async: bool
108 @param async: If False, this function will block until the
109 handshake is completed. If True, this function will return a
110 generator. Successive invocations of the generator will
111 return 0 if it is waiting to read from the socket, 1 if it is
112 waiting to write to the socket, or will raise StopIteration if
113 the handshake operation is completed.
114
115 @rtype: None or an iterable
116 @return: If 'async' is True, a generator object will be
117 returned.
118
119 @raise socket.error: If a socket error occurs.
120 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
121 without a preceding alert.
122 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
123 @raise tlslite.errors.TLSAuthenticationError: If the checker
124 doesn't like the other party's authentication credentials.
125 """
126 handshaker = self._handshakeClientAsync(srpParams=(username, password),
127 session=session, settings=settings, checker=checker,
128 reqTack=reqTack)
129
130
131
132
133
134
135
136 if async:
137 return handshaker
138 for result in handshaker:
139 pass
140
141 - def handshakeClientCert(self, certChain=None, privateKey=None,
142 session=None, settings=None, checker=None,
143 reqTack=False, async=False):
144 """Perform a certificate-based handshake in the role of client.
145
146 This function performs an SSL or TLS handshake. The server
147 will authenticate itself using an X.509 certificate
148 chain. If the handshake succeeds, the server's certificate
149 chain will be stored in the session's serverCertChain attribute.
150 Unless a checker object is passed in, this function does no
151 validation or checking of the server's certificate chain.
152
153 If the server requests client authentication, the
154 client will send the passed-in certificate chain, and use the
155 passed-in private key to authenticate itself. If no
156 certificate chain and private key were passed in, the client
157 will attempt to proceed without client authentication. The
158 server may or may not allow this.
159
160 If the function completes without raising an exception, the
161 TLS connection will be open and available for data transfer.
162
163 If an exception is raised, the connection will have been
164 automatically closed (if it was ever open).
165
166 @type certChain: L{tlslite.x509certchain.X509CertChain}
167 @param certChain: The certificate chain to be used if the
168 server requests client authentication.
169
170 @type privateKey: L{tlslite.utils.rsakey.RSAKey}
171 @param privateKey: The private key to be used if the server
172 requests client authentication.
173
174 @type session: L{tlslite.session.Session}
175 @param session: A TLS session to attempt to resume. If the
176 resumption does not succeed, a full handshake will be
177 performed.
178
179 @type settings: L{tlslite.handshakesettings.HandshakeSettings}
180 @param settings: Various settings which can be used to control
181 the ciphersuites, certificate types, and SSL/TLS versions
182 offered by the client.
183
184 @type checker: L{tlslite.checker.Checker}
185 @param checker: A Checker instance. This instance will be
186 invoked to examine the other party's authentication
187 credentials, if the handshake completes succesfully.
188
189 @type reqTack: bool
190 @param reqTack: Whether or not to send a "tack" TLS Extension,
191 requesting the server return a TACK_Extension if it has one.
192
193 @type async: bool
194 @param async: If False, this function will block until the
195 handshake is completed. If True, this function will return a
196 generator. Successive invocations of the generator will
197 return 0 if it is waiting to read from the socket, 1 if it is
198 waiting to write to the socket, or will raise StopIteration if
199 the handshake operation is completed.
200
201 @rtype: None or an iterable
202 @return: If 'async' is True, a generator object will be
203 returned.
204
205 @raise socket.error: If a socket error occurs.
206 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
207 without a preceding alert.
208 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
209 @raise tlslite.errors.TLSAuthenticationError: If the checker
210 doesn't like the other party's authentication credentials.
211 """
212 handshaker = self._handshakeClientAsync(certParams=(certChain,
213 privateKey), session=session, settings=settings,
214 checker=checker, reqTack=reqTack)
215
216
217
218
219
220
221
222 if async:
223 return handshaker
224 for result in handshaker:
225 pass
226
227
228 - def _handshakeClientAsync(self, srpParams=(), certParams=(),
229 session=None, settings=None, checker=None,
230 reqTack=False):
239
240
243
244 self._handshakeStart(client=True)
245
246
247 srpUsername = None
248 password = None
249 clientCertChain = None
250 privateKey = None
251
252
253 if srpParams:
254 assert(not certParams)
255 srpUsername, password = srpParams
256 if certParams:
257 assert(not srpParams)
258 clientCertChain, privateKey = certParams
259
260
261 if srpUsername and not password:
262 raise ValueError("Caller passed a username but no password")
263 if password and not srpUsername:
264 raise ValueError("Caller passed a password but no username")
265 if clientCertChain and not privateKey:
266 raise ValueError("Caller passed a certChain but no privateKey")
267 if privateKey and not clientCertChain:
268 raise ValueError("Caller passed a privateKey but no certChain")
269 if reqTack and not tackpyLoaded:
270 raise ValueError("TACKpy is not loaded")
271
272
273
274 if not settings:
275 settings = HandshakeSettings()
276 settings = settings._filter()
277
278 if clientCertChain:
279 if not isinstance(clientCertChain, X509CertChain):
280 raise ValueError("Unrecognized certificate type")
281 if "x509" not in settings.certificateTypes:
282 raise ValueError("Client certificate doesn't match "\
283 "Handshake Settings")
284
285 if session:
286
287
288 if not session.valid():
289 session = None
290 elif session.resumable and \
291 (session.srpUsername != srpUsername):
292 raise ValueError("Session username doesn't match")
293
294
295 if srpUsername and self.fault == Fault.badUsername:
296 srpUsername += "GARBAGE"
297 if password and self.fault == Fault.badPassword:
298 password += "GARBAGE"
299
300
301
302
303 self.version = settings.maxVersion
304
305
306
307
308
309 for result in self._clientSendClientHello(settings, session,
310 srpUsername, srpParams, certParams,
311 reqTack):
312 if result in (0,1): yield result
313 else: break
314 clientHello = result
315
316
317 for result in self._clientGetServerHello(settings, clientHello):
318 if result in (0,1): yield result
319 else: break
320 serverHello = result
321 cipherSuite = serverHello.cipher_suite
322
323
324 for result in self._clientResume(session, serverHello,
325 clientHello.random,
326 settings.cipherImplementations):
327 if result in (0,1): yield result
328 else: break
329 if result == "resumed_and_finished":
330 self._handshakeDone(resumed=True)
331 return
332
333
334
335
336 if cipherSuite in CipherSuite.srpAllSuites:
337 for result in self._clientSRPKeyExchange(\
338 settings, cipherSuite, serverHello.certificate_type,
339 srpUsername, password,
340 clientHello.random, serverHello.random,
341 serverHello.tackExt):
342 if result in (0,1): yield result
343 else: break
344 (premasterSecret, serverCertChain, tackExt) = result
345
346
347
348
349
350
351
352 else:
353 for result in self._clientRSAKeyExchange(settings, cipherSuite,
354 clientCertChain, privateKey,
355 serverHello.certificate_type,
356 clientHello.random, serverHello.random,
357 serverHello.tackExt):
358 if result in (0,1): yield result
359 else: break
360 (premasterSecret, serverCertChain, clientCertChain,
361 tackExt) = result
362
363
364
365 for result in self._clientFinished(premasterSecret,
366 clientHello.random,
367 serverHello.random,
368 cipherSuite, settings.cipherImplementations):
369 if result in (0,1): yield result
370 else: break
371 masterSecret = result
372
373
374 self.session = Session()
375 self.session.create(masterSecret, serverHello.session_id, cipherSuite,
376 srpUsername, clientCertChain, serverCertChain,
377 tackExt)
378 self._handshakeDone(resumed=False)
379
380
383
384 cipherSuites = [CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
385 if srpParams:
386 cipherSuites += CipherSuite.getSrpAllSuites(settings.cipherNames)
387 elif certParams:
388 cipherSuites += CipherSuite.getCertSuites(settings.cipherNames)
389 else:
390 cipherSuites += CipherSuite.getCertSuites(settings.cipherNames)
391
392
393 certificateTypes = settings._getCertificateTypes()
394
395
396 if session and session.sessionID:
397
398
399 if session.cipherSuite not in cipherSuites:
400 raise ValueError("Session's cipher suite not consistent "\
401 "with parameters")
402 else:
403 clientHello = ClientHello()
404 clientHello.create(settings.maxVersion, getRandomBytes(32),
405 session.sessionID, cipherSuites,
406 certificateTypes, session.srpUsername,
407 reqTack)
408
409
410 else:
411 clientHello = ClientHello()
412 clientHello.create(settings.maxVersion, getRandomBytes(32),
413 createByteArraySequence([]), cipherSuites,
414 certificateTypes, srpUsername,
415 reqTack)
416 for result in self._sendMsg(clientHello):
417 yield result
418 yield clientHello
419
420
467
468 - def _clientResume(self, session, serverHello, clientRandom,
469 cipherImplementations):
495
496 - def _clientSRPKeyExchange(self, settings, cipherSuite, certificateType,
497 srpUsername, password,
498 clientRandom, serverRandom, tackExt):
499
500
501 if cipherSuite in CipherSuite.srpCertSuites:
502
503 for result in self._getMsg(ContentType.handshake,
504 HandshakeType.certificate, certificateType):
505 if result in (0,1): yield result
506 else: break
507 serverCertificate = result
508 else:
509 serverCertificate = None
510
511 for result in self._getMsg(ContentType.handshake,
512 HandshakeType.server_key_exchange, cipherSuite):
513 if result in (0,1): yield result
514 else: break
515 serverKeyExchange = result
516
517 for result in self._getMsg(ContentType.handshake,
518 HandshakeType.server_hello_done):
519 if result in (0,1): yield result
520 else: break
521 serverHelloDone = result
522
523
524
525 N = serverKeyExchange.srp_N
526 g = serverKeyExchange.srp_g
527 s = serverKeyExchange.srp_s
528 B = serverKeyExchange.srp_B
529
530 if (g,N) not in goodGroupParameters:
531 for result in self._sendError(\
532 AlertDescription.insufficient_security,
533 "Unknown group parameters"):
534 yield result
535 if numBits(N) < settings.minKeySize:
536 for result in self._sendError(\
537 AlertDescription.insufficient_security,
538 "N value is too small: %d" % numBits(N)):
539 yield result
540 if numBits(N) > settings.maxKeySize:
541 for result in self._sendError(\
542 AlertDescription.insufficient_security,
543 "N value is too large: %d" % numBits(N)):
544 yield result
545 if B % N == 0:
546 for result in self._sendError(\
547 AlertDescription.illegal_parameter,
548 "Suspicious B value"):
549 yield result
550
551
552
553 serverCertChain = None
554 if cipherSuite in CipherSuite.srpCertSuites:
555
556 hashBytes = serverKeyExchange.hash(clientRandom, serverRandom)
557
558
559 sigBytes = serverKeyExchange.signature
560 if len(sigBytes) == 0:
561 for result in self._sendError(\
562 AlertDescription.illegal_parameter,
563 "Server sent an SRP ServerKeyExchange "\
564 "message without a signature"):
565 yield result
566
567
568
569
570 for result in self._clientGetKeyFromChain(serverCertificate,
571 settings, tackExt):
572 if result in (0,1): yield result
573 else: break
574 publicKey, serverCertChain, tackExt = result
575
576
577 if not publicKey.verify(sigBytes, hashBytes):
578 for result in self._sendError(\
579 AlertDescription.decrypt_error,
580 "Signature failed to verify"):
581 yield result
582
583
584 a = bytesToNumber(getRandomBytes(32))
585 A = powMod(g, a, N)
586
587
588 x = makeX(bytesToString(s), srpUsername, password)
589 v = powMod(g, x, N)
590
591
592 u = makeU(N, A, B)
593
594
595 k = makeK(N, g)
596 S = powMod((B - (k*v)) % N, a+(u*x), N)
597
598 if self.fault == Fault.badA:
599 A = N
600 S = 0
601
602 premasterSecret = numberToBytes(S)
603
604
605 for result in self._sendMsg(\
606 ClientKeyExchange(cipherSuite).createSRP(A)):
607 yield result
608 yield (premasterSecret, serverCertChain, tackExt)
609
610
611 - def _clientRSAKeyExchange(self, settings, cipherSuite,
612 clientCertChain, privateKey,
613 certificateType,
614 clientRandom, serverRandom,
615 tackExt):
616
617
618 for result in self._getMsg(ContentType.handshake,
619 HandshakeType.certificate, certificateType):
620 if result in (0,1): yield result
621 else: break
622 serverCertificate = result
623
624
625 for result in self._getMsg(ContentType.handshake,
626 (HandshakeType.server_hello_done,
627 HandshakeType.certificate_request)):
628 if result in (0,1): yield result
629 else: break
630 msg = result
631 certificateRequest = None
632 if isinstance(msg, CertificateRequest):
633 certificateRequest = msg
634
635 for result in self._getMsg(ContentType.handshake,
636 HandshakeType.server_hello_done):
637 if result in (0,1): yield result
638 else: break
639 serverHelloDone = result
640 elif isinstance(msg, ServerHelloDone):
641 serverHelloDone = msg
642
643
644
645
646 for result in self._clientGetKeyFromChain(serverCertificate,
647 settings, tackExt):
648 if result in (0,1): yield result
649 else: break
650 publicKey, serverCertChain, tackExt = result
651
652
653 premasterSecret = getRandomBytes(48)
654 premasterSecret[0] = settings.maxVersion[0]
655 premasterSecret[1] = settings.maxVersion[1]
656
657 if self.fault == Fault.badPremasterPadding:
658 premasterSecret[0] = 5
659 if self.fault == Fault.shortPremasterSecret:
660 premasterSecret = premasterSecret[:-1]
661
662
663 encryptedPreMasterSecret = publicKey.encrypt(premasterSecret)
664
665
666
667 if certificateRequest:
668 clientCertificate = Certificate(certificateType)
669
670 if clientCertChain:
671
672
673 wrongType = False
674 if certificateType == CertificateType.x509:
675 if not isinstance(clientCertChain, X509CertChain):
676 wrongType = True
677 if wrongType:
678 for result in self._sendError(\
679 AlertDescription.handshake_failure,
680 "Client certificate is of wrong type"):
681 yield result
682
683 clientCertificate.create(clientCertChain)
684 for result in self._sendMsg(clientCertificate):
685 yield result
686 else:
687
688
689
690 privateKey = None
691 clientCertChain = None
692
693
694 clientKeyExchange = ClientKeyExchange(cipherSuite,
695 self.version)
696 clientKeyExchange.createRSA(encryptedPreMasterSecret)
697 for result in self._sendMsg(clientKeyExchange):
698 yield result
699
700
701
702 if certificateRequest and privateKey:
703 if self.version == (3,0):
704 masterSecret = calcMasterSecret(self.version,
705 premasterSecret,
706 clientRandom,
707 serverRandom)
708 verifyBytes = self._calcSSLHandshakeHash(masterSecret, "")
709 elif self.version in ((3,1), (3,2)):
710 verifyBytes = stringToBytes(\
711 self._handshake_md5.digest() + \
712 self._handshake_sha.digest())
713 if self.fault == Fault.badVerifyMessage:
714 verifyBytes[0] = ((verifyBytes[0]+1) % 256)
715 signedBytes = privateKey.sign(verifyBytes)
716 certificateVerify = CertificateVerify()
717 certificateVerify.create(signedBytes)
718 for result in self._sendMsg(certificateVerify):
719 yield result
720 yield (premasterSecret, serverCertChain, clientCertChain, tackExt)
721
722 - def _clientFinished(self, premasterSecret, clientRandom, serverRandom,
723 cipherSuite, cipherImplementations):
724
725 masterSecret = calcMasterSecret(self.version, premasterSecret,
726 clientRandom, serverRandom)
727 self._calcPendingStates(cipherSuite, masterSecret,
728 clientRandom, serverRandom,
729 cipherImplementations)
730
731
732 for result in self._sendFinished(masterSecret):
733 yield result
734 for result in self._getFinished(masterSecret):
735 yield result
736 yield masterSecret
737
772
773
774
775
776
777
778
779 - def handshakeServer(self, verifierDB=None,
780 certChain=None, privateKey=None, reqCert=False,
781 sessionCache=None, settings=None, checker=None,
782 reqCAs = None, tack=None, breakSigs=None):
783 """Perform a handshake in the role of server.
784
785 This function performs an SSL or TLS handshake. Depending on
786 the arguments and the behavior of the client, this function can
787 perform an SRP, or certificate-based handshake. It
788 can also perform a combined SRP and server-certificate
789 handshake.
790
791 Like any handshake function, this can be called on a closed
792 TLS connection, or on a TLS connection that is already open.
793 If called on an open connection it performs a re-handshake.
794 This function does not send a Hello Request message before
795 performing the handshake, so if re-handshaking is required,
796 the server must signal the client to begin the re-handshake
797 through some other means.
798
799 If the function completes without raising an exception, the
800 TLS connection will be open and available for data transfer.
801
802 If an exception is raised, the connection will have been
803 automatically closed (if it was ever open).
804
805 @type verifierDB: L{tlslite.verifierdb.VerifierDB}
806 @param verifierDB: A database of SRP password verifiers
807 associated with usernames. If the client performs an SRP
808 handshake, the session's srpUsername attribute will be set.
809
810 @type certChain: L{tlslite.x509certchain.X509CertChain}
811 @param certChain: The certificate chain to be used if the
812 client requests server certificate authentication.
813
814 @type privateKey: L{tlslite.utils.rsakey.RSAKey}
815 @param privateKey: The private key to be used if the client
816 requests server certificate authentication.
817
818 @type reqCert: bool
819 @param reqCert: Whether to request client certificate
820 authentication. This only applies if the client chooses server
821 certificate authentication; if the client chooses SRP
822 authentication, this will be ignored. If the client
823 performs a client certificate authentication, the sessions's
824 clientCertChain attribute will be set.
825
826 @type sessionCache: L{tlslite.sessioncache.SessionCache}
827 @param sessionCache: An in-memory cache of resumable sessions.
828 The client can resume sessions from this cache. Alternatively,
829 if the client performs a full handshake, a new session will be
830 added to the cache.
831
832 @type settings: L{tlslite.handshakesettings.HandshakeSettings}
833 @param settings: Various settings which can be used to control
834 the ciphersuites and SSL/TLS version chosen by the server.
835
836 @type checker: L{tlslite.checker.Checker}
837 @param checker: A Checker instance. This instance will be
838 invoked to examine the other party's authentication
839 credentials, if the handshake completes succesfully.
840
841 @type reqCAs: list of L{bytearray} of unsigned bytes
842 @param reqCAs: A collection of DER-encoded DistinguishedNames that
843 will be sent along with a certificate request. This does not affect
844 verification.
845
846 @raise socket.error: If a socket error occurs.
847 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
848 without a preceding alert.
849 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
850 @raise tlslite.errors.TLSAuthenticationError: If the checker
851 doesn't like the other party's authentication credentials.
852 """
853 for result in self.handshakeServerAsync(verifierDB,
854 certChain, privateKey, reqCert, sessionCache, settings,
855 checker, reqCAs, tack=tack, breakSigs=breakSigs):
856 pass
857
858
859 - def handshakeServerAsync(self, verifierDB=None,
860 certChain=None, privateKey=None, reqCert=False,
861 sessionCache=None, settings=None, checker=None,
862 reqCAs=None, tack=None, breakSigs=None):
863 """Start a server handshake operation on the TLS connection.
864
865 This function returns a generator which behaves similarly to
866 handshakeServer(). Successive invocations of the generator
867 will return 0 if it is waiting to read from the socket, 1 if it is
868 waiting to write to the socket, or it will raise StopIteration
869 if the handshake operation is complete.
870
871 @rtype: iterable
872 @return: A generator; see above for details.
873 """
874 handshaker = self._handshakeServerAsyncHelper(\
875 verifierDB=verifierDB, certChain=certChain,
876 privateKey=privateKey, reqCert=reqCert,
877 sessionCache=sessionCache, settings=settings,
878 reqCAs=reqCAs, tack=tack, breakSigs=breakSigs)
879 for result in self._handshakeWrapperAsync(handshaker, checker):
880 yield result
881
882
883 - def _handshakeServerAsyncHelper(self, verifierDB,
884 certChain, privateKey, reqCert, sessionCache,
885 settings, reqCAs, tack, breakSigs):
886
887 self._handshakeStart(client=False)
888
889 if (not verifierDB) and (not certChain):
890 raise ValueError("Caller passed no authentication credentials")
891 if certChain and not privateKey:
892 raise ValueError("Caller passed a certChain but no privateKey")
893 if privateKey and not certChain:
894 raise ValueError("Caller passed a privateKey but no certChain")
895 if reqCAs and not reqCert:
896 raise ValueError("Caller passed reqCAs but not reqCert")
897 if certChain and not isinstance(certChain, X509CertChain):
898 raise ValueError("Unrecognized certificate type")
899 if (tack or breakSigs) and not tackpyLoaded:
900 raise ValueError("TACKpy is not loaded")
901
902 if not settings:
903 settings = HandshakeSettings()
904 settings = settings._filter()
905
906
907
908
909
910 for result in self._serverGetClientHello(settings, certChain,\
911 verifierDB, sessionCache):
912 if result in (0,1): yield result
913 elif result == None:
914 self._handshakeDone(resumed=True)
915 return
916 else: break
917 (clientHello, cipherSuite) = result
918
919
920
921
922 if sessionCache:
923 sessionID = getRandomBytes(32)
924 else:
925 sessionID = createByteArraySequence([])
926
927
928 if not cipherSuite in CipherSuite.certAllSuites:
929 tack = None
930
931
932 if clientHello.tack:
933 tackExt = TACK_Extension()
934 tackExt.create(tack, breakSigs)
935 else:
936 tackExt = None
937 serverHello = ServerHello()
938 serverHello.create(self.version, getRandomBytes(32), sessionID, \
939 cipherSuite, CertificateType.x509, tackExt)
940
941
942 clientCertChain = None
943 if cipherSuite in CipherSuite.srpAllSuites:
944 for result in self._serverSRPKeyExchange(clientHello, serverHello,
945 verifierDB, cipherSuite,
946 privateKey, certChain):
947 if result in (0,1): yield result
948 else: break
949 premasterSecret = result
950
951
952
953 elif cipherSuite in CipherSuite.certSuites:
954 for result in self._serverCertKeyExchange(clientHello, serverHello,
955 certChain, privateKey,
956 reqCert, reqCAs, cipherSuite,
957 settings):
958 if result in (0,1): yield result
959 else: break
960 (premasterSecret, clientCertChain) = result
961
962
963 for result in self._serverFinished(premasterSecret,
964 clientHello.random, serverHello.random,
965 cipherSuite, settings.cipherImplementations):
966 if result in (0,1): yield result
967 else: break
968 masterSecret = result
969
970
971 self.session = Session()
972 if cipherSuite in CipherSuite.certAllSuites:
973 serverCertChain = certChain
974 else:
975 serverCertChain = None
976 self.session.create(masterSecret, serverHello.session_id, cipherSuite,
977 clientHello.srp_username, clientCertChain, serverCertChain,
978 tackExt)
979
980
981 if sessionCache and sessionID:
982 sessionCache[bytesToString(sessionID)] = self.session
983
984 self._handshakeDone(resumed=False)
985
986
989
990 cipherSuites = []
991 if verifierDB:
992 if certChain:
993 cipherSuites += \
994 CipherSuite.getSrpCertSuites(settings.cipherNames)
995 cipherSuites += CipherSuite.getSrpSuites(settings.cipherNames)
996 elif certChain:
997 cipherSuites += CipherSuite.getCertSuites(settings.cipherNames)
998 else:
999 assert(False)
1000
1001
1002
1003
1004 self.version = settings.maxVersion
1005
1006
1007 for result in self._getMsg(ContentType.handshake,
1008 HandshakeType.client_hello):
1009 if result in (0,1): yield result
1010 else: break
1011 clientHello = result
1012
1013
1014 if clientHello.client_version < settings.minVersion:
1015 self.version = settings.minVersion
1016 for result in self._sendError(\
1017 AlertDescription.protocol_version,
1018 "Too old version: %s" % str(clientHello.client_version)):
1019 yield result
1020
1021
1022 elif clientHello.client_version > settings.maxVersion:
1023 self.version = settings.maxVersion
1024
1025 else:
1026
1027 self.version = clientHello.client_version
1028
1029
1030 if clientHello.session_id and sessionCache:
1031 session = None
1032
1033
1034 if sessionCache and not session:
1035 try:
1036 session = sessionCache[bytesToString(\
1037 clientHello.session_id)]
1038 if not session.resumable:
1039 raise AssertionError()
1040
1041 if session.cipherSuite not in cipherSuites:
1042 for result in self._sendError(\
1043 AlertDescription.handshake_failure):
1044 yield result
1045 if session.cipherSuite not in clientHello.cipher_suites:
1046 for result in self._sendError(\
1047 AlertDescription.handshake_failure):
1048 yield result
1049 if clientHello.srp_username:
1050 if clientHello.srp_username != session.srpUsername:
1051 for result in self._sendError(\
1052 AlertDescription.handshake_failure):
1053 yield result
1054 except KeyError:
1055 pass
1056
1057
1058 if session:
1059
1060 serverHello = ServerHello()
1061 serverHello.create(self.version, getRandomBytes(32),
1062 session.sessionID, session.cipherSuite,
1063 CertificateType.x509, None)
1064 for result in self._sendMsg(serverHello):
1065 yield result
1066
1067
1068 self._versionCheck = True
1069
1070
1071 self._calcPendingStates(session.cipherSuite,
1072 session.masterSecret,
1073 clientHello.random,
1074 serverHello.random,
1075 settings.cipherImplementations)
1076
1077
1078 for result in self._sendFinished(session.masterSecret):
1079 yield result
1080 for result in self._getFinished(session.masterSecret):
1081 yield result
1082
1083
1084 self.session = session
1085
1086 yield None
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096 for cipherSuite in cipherSuites:
1097 if cipherSuite in clientHello.cipher_suites:
1098 break
1099 else:
1100 for result in self._sendError(\
1101 AlertDescription.handshake_failure,
1102 "No mutual ciphersuite"):
1103 yield result
1104
1105 if cipherSuite in CipherSuite.srpAllSuites and \
1106 not clientHello.srp_username:
1107 for result in self._sendError(\
1108 AlertDescription.unknown_psk_identity,
1109 "Client sent a hello, but without the SRP username"):
1110 yield result
1111
1112
1113 if cipherSuite in CipherSuite.certAllSuites and CertificateType.x509 \
1114 not in clientHello.certificate_types:
1115 for result in self._sendError(\
1116 AlertDescription.handshake_failure,
1117 "the client doesn't support my certificate type"):
1118 yield result
1119
1120
1121
1122
1123 yield (clientHello, cipherSuite)
1124
1125 - def _serverSRPKeyExchange(self, clientHello, serverHello, verifierDB,
1126 cipherSuite, privateKey, serverCertChain):
1127
1128 self.allegedSrpUsername = clientHello.srp_username
1129
1130 try:
1131 entry = verifierDB[clientHello.srp_username]
1132 except KeyError:
1133 for result in self._sendError(\
1134 AlertDescription.unknown_psk_identity):
1135 yield result
1136 (N, g, s, v) = entry
1137
1138
1139 b = bytesToNumber(getRandomBytes(32))
1140 k = makeK(N, g)
1141 B = (powMod(g, b, N) + (k*v)) % N
1142
1143
1144 serverKeyExchange = ServerKeyExchange(cipherSuite)
1145 serverKeyExchange.createSRP(N, g, stringToBytes(s), B)
1146 if cipherSuite in CipherSuite.srpCertSuites:
1147 hashBytes = serverKeyExchange.hash(clientHello.random,
1148 serverHello.random)
1149 serverKeyExchange.signature = privateKey.sign(hashBytes)
1150
1151
1152
1153 msgs = []
1154 msgs.append(serverHello)
1155 if cipherSuite in CipherSuite.srpCertSuites:
1156 certificateMsg = Certificate(CertificateType.x509)
1157 certificateMsg.create(serverCertChain)
1158 msgs.append(certificateMsg)
1159 msgs.append(serverKeyExchange)
1160 msgs.append(ServerHelloDone())
1161 for result in self._sendMsgs(msgs):
1162 yield result
1163
1164
1165 self._versionCheck = True
1166
1167
1168 for result in self._getMsg(ContentType.handshake,
1169 HandshakeType.client_key_exchange,
1170 cipherSuite):
1171 if result in (0,1): yield result
1172 else: break
1173 clientKeyExchange = result
1174 A = clientKeyExchange.srp_A
1175 if A % N == 0:
1176 for result in self._sendError(AlertDescription.illegal_parameter,
1177 "Suspicious A value"):
1178 yield result
1179 assert(False)
1180
1181
1182 u = makeU(N, A, B)
1183
1184
1185 S = powMod((A * powMod(v,u,N)) % N, b, N)
1186 premasterSecret = numberToBytes(S)
1187
1188 yield premasterSecret
1189
1190
1191 - def _serverCertKeyExchange(self, clientHello, serverHello,
1192 serverCertChain, privateKey,
1193 reqCert, reqCAs, cipherSuite,
1194 settings):
1195
1196
1197 msgs = []
1198
1199
1200 clientCertChain = None
1201
1202 msgs.append(serverHello)
1203 msgs.append(Certificate(CertificateType.x509).create(serverCertChain))
1204 if reqCert and reqCAs:
1205 msgs.append(CertificateRequest().create(\
1206 [ClientCertificateType.rsa_sign], reqCAs))
1207 elif reqCert:
1208 msgs.append(CertificateRequest())
1209 msgs.append(ServerHelloDone())
1210 for result in self._sendMsgs(msgs):
1211 yield result
1212
1213
1214 self._versionCheck = True
1215
1216
1217 if reqCert:
1218 if self.version == (3,0):
1219 for result in self._getMsg((ContentType.handshake,
1220 ContentType.alert),
1221 HandshakeType.certificate,
1222 CertificateType.x509):
1223 if result in (0,1): yield result
1224 else: break
1225 msg = result
1226
1227 if isinstance(msg, Alert):
1228
1229 alert = msg
1230 if alert.description != \
1231 AlertDescription.no_certificate:
1232 self._shutdown(False)
1233 raise TLSRemoteAlert(alert)
1234 elif isinstance(msg, Certificate):
1235 clientCertificate = msg
1236 if clientCertificate.certChain and \
1237 clientCertificate.certChain.getNumCerts()!=0:
1238 clientCertChain = clientCertificate.certChain
1239 else:
1240 raise AssertionError()
1241 elif self.version in ((3,1), (3,2)):
1242 for result in self._getMsg(ContentType.handshake,
1243 HandshakeType.certificate,
1244 CertificateType.x509):
1245 if result in (0,1): yield result
1246 else: break
1247 clientCertificate = result
1248 if clientCertificate.certChain and \
1249 clientCertificate.certChain.getNumCerts()!=0:
1250 clientCertChain = clientCertificate.certChain
1251 else:
1252 raise AssertionError()
1253
1254
1255 for result in self._getMsg(ContentType.handshake,
1256 HandshakeType.client_key_exchange,
1257 cipherSuite):
1258 if result in (0,1): yield result
1259 else: break
1260 clientKeyExchange = result
1261
1262
1263 premasterSecret = privateKey.decrypt(\
1264 clientKeyExchange.encryptedPreMasterSecret)
1265
1266 randomPreMasterSecret = getRandomBytes(48)
1267 versionCheck = (premasterSecret[0], premasterSecret[1])
1268 if not premasterSecret:
1269 premasterSecret = randomPreMasterSecret
1270 elif len(premasterSecret)!=48:
1271 premasterSecret = randomPreMasterSecret
1272 elif versionCheck != clientHello.client_version:
1273 if versionCheck != self.version:
1274 premasterSecret = randomPreMasterSecret
1275
1276
1277 if clientCertChain:
1278 if self.version == (3,0):
1279 masterSecret = calcMasterSecret(self.version, premasterSecret,
1280 clientHello.random, serverHello.random)
1281 verifyBytes = self._calcSSLHandshakeHash(masterSecret, "")
1282 elif self.version in ((3,1), (3,2)):
1283 verifyBytes = stringToBytes(self._handshake_md5.digest() +\
1284 self._handshake_sha.digest())
1285 for result in self._getMsg(ContentType.handshake,
1286 HandshakeType.certificate_verify):
1287 if result in (0,1): yield result
1288 else: break
1289 certificateVerify = result
1290 publicKey = clientCertChain.getEndEntityPublicKey()
1291 if len(publicKey) < settings.minKeySize:
1292 for result in self._sendError(\
1293 AlertDescription.handshake_failure,
1294 "Client's public key too small: %d" % len(publicKey)):
1295 yield result
1296
1297 if len(publicKey) > settings.maxKeySize:
1298 for result in self._sendError(\
1299 AlertDescription.handshake_failure,
1300 "Client's public key too large: %d" % len(publicKey)):
1301 yield result
1302
1303 if not publicKey.verify(certificateVerify.signature, verifyBytes):
1304 for result in self._sendError(\
1305 AlertDescription.decrypt_error,
1306 "Signature failed to verify"):
1307 yield result
1308 yield (premasterSecret, clientCertChain)
1309
1310
1311
1312 - def _serverFinished(self, premasterSecret, clientRandom, serverRandom,
1313 cipherSuite, cipherImplementations):
1314
1315 masterSecret = calcMasterSecret(self.version, premasterSecret,
1316 clientRandom, serverRandom)
1317
1318
1319 self._calcPendingStates(cipherSuite, masterSecret,
1320 clientRandom, serverRandom,
1321 cipherImplementations)
1322
1323
1324 for result in self._getFinished(masterSecret):
1325 yield result
1326
1327 for result in self._sendFinished(masterSecret):
1328 yield result
1329
1330 yield masterSecret
1331
1332
1333
1334
1335
1336
1337
1355
1384
1386 if self.version == (3,0):
1387 if (self._client and send) or (not self._client and not send):
1388 senderStr = "\x43\x4C\x4E\x54"
1389 else:
1390 senderStr = "\x53\x52\x56\x52"
1391
1392 verifyData = self._calcSSLHandshakeHash(masterSecret, senderStr)
1393 return verifyData
1394
1395 elif self.version in ((3,1), (3,2)):
1396 if (self._client and send) or (not self._client and not send):
1397 label = "client finished"
1398 else:
1399 label = "server finished"
1400
1401 handshakeHashes = stringToBytes(self._handshake_md5.digest() + \
1402 self._handshake_sha.digest())
1403 verifyData = PRF(masterSecret, label, handshakeHashes, 12)
1404 return verifyData
1405 else:
1406 raise AssertionError()
1407
1408
1435