1
2
3
4
5
6
7
8
9 """
10 MAIN CLASS FOR TLS LITE (START HERE!).
11 """
12
13 import socket
14 from .utils.compat import formatExceptionTrace
15 from .tlsrecordlayer import TLSRecordLayer
16 from .session import Session
17 from .constants import *
18 from .utils.cryptomath import getRandomBytes
19 from .errors import *
20 from .messages import *
21 from .mathtls import *
22 from .handshakesettings import HandshakeSettings
23 from .utils.tackwrapper import *
24
25
27 """
28 This class wraps a socket and provides TLS handshaking and data
29 transfer.
30
31 To use this class, create a new instance, passing a connected
32 socket into the constructor. Then call some handshake function.
33 If the handshake completes without raising an exception, then a TLS
34 connection has been negotiated. You can transfer data over this
35 connection as if it were a socket.
36
37 This class provides both synchronous and asynchronous versions of
38 its key functions. The synchronous versions should be used when
39 writing single-or multi-threaded code using blocking sockets. The
40 asynchronous versions should be used when performing asynchronous,
41 event-based I/O with non-blocking sockets.
42
43 Asynchronous I/O is a complicated subject; typically, you should
44 not use the asynchronous functions directly, but should use some
45 framework like asyncore or Twisted which TLS Lite integrates with
46 (see
47 L{tlslite.integration.tlsasyncdispatchermixin.TLSAsyncDispatcherMixIn}).
48 """
49
51 """Create a new TLSConnection instance.
52
53 @param sock: The socket data will be transmitted on. The
54 socket should already be connected. It may be in blocking or
55 non-blocking mode.
56
57 @type sock: L{socket.socket}
58 """
59 TLSRecordLayer.__init__(self, sock)
60
61
62
63
64
68 """Perform an anonymous handshake in the role of client.
69
70 This function performs an SSL or TLS handshake using an
71 anonymous Diffie Hellman ciphersuite.
72
73 Like any handshake function, this can be called on a closed
74 TLS connection, or on a TLS connection that is already open.
75 If called on an open connection it performs a re-handshake.
76
77 If the function completes without raising an exception, the
78 TLS connection will be open and available for data transfer.
79
80 If an exception is raised, the connection will have been
81 automatically closed (if it was ever open).
82
83 @type session: L{tlslite.Session.Session}
84 @param session: A TLS session to attempt to resume. If the
85 resumption does not succeed, a full handshake will be
86 performed.
87
88 @type settings: L{tlslite.HandshakeSettings.HandshakeSettings}
89 @param settings: Various settings which can be used to control
90 the ciphersuites, certificate types, and SSL/TLS versions
91 offered by the client.
92
93 @type checker: L{tlslite.Checker.Checker}
94 @param checker: A Checker instance. This instance will be
95 invoked to examine the other party's authentication
96 credentials, if the handshake completes succesfully.
97
98 @type serverName: string
99 @param serverName: The ServerNameIndication TLS Extension.
100
101 @type async: bool
102 @param async: If False, this function will block until the
103 handshake is completed. If True, this function will return a
104 generator. Successive invocations of the generator will
105 return 0 if it is waiting to read from the socket, 1 if it is
106 waiting to write to the socket, or will raise StopIteration if
107 the handshake operation is completed.
108
109 @rtype: None or an iterable
110 @return: If 'async' is True, a generator object will be
111 returned.
112
113 @raise socket.error: If a socket error occurs.
114 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
115 without a preceding alert.
116 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
117 @raise tlslite.errors.TLSAuthenticationError: If the checker
118 doesn't like the other party's authentication credentials.
119 """
120 handshaker = self._handshakeClientAsync(anonParams=(True),
121 session=session,
122 settings=settings,
123 checker=checker,
124 serverName=serverName)
125 if async:
126 return handshaker
127 for result in handshaker:
128 pass
129
130 - def handshakeClientSRP(self, username, password, session=None,
131 settings=None, checker=None,
132 reqTack=True, serverName="",
133 async=False):
134 """Perform an SRP handshake in the role of client.
135
136 This function performs a TLS/SRP handshake. SRP mutually
137 authenticates both parties to each other using only a
138 username and password. This function may also perform a
139 combined SRP and server-certificate handshake, if the server
140 chooses to authenticate itself with a certificate chain in
141 addition to doing SRP.
142
143 If the function completes without raising an exception, the
144 TLS connection will be open and available for data transfer.
145
146 If an exception is raised, the connection will have been
147 automatically closed (if it was ever open).
148
149 @type username: str
150 @param username: The SRP username.
151
152 @type password: str
153 @param password: The SRP password.
154
155 @type session: L{tlslite.session.Session}
156 @param session: A TLS session to attempt to resume. This
157 session must be an SRP session performed with the same username
158 and password as were passed in. If the resumption does not
159 succeed, a full SRP handshake will be performed.
160
161 @type settings: L{tlslite.handshakesettings.HandshakeSettings}
162 @param settings: Various settings which can be used to control
163 the ciphersuites, certificate types, and SSL/TLS versions
164 offered by the client.
165
166 @type checker: L{tlslite.checker.Checker}
167 @param checker: A Checker instance. This instance will be
168 invoked to examine the other party's authentication
169 credentials, if the handshake completes succesfully.
170
171 @type reqTack: bool
172 @param reqTack: Whether or not to send a "tack" TLS Extension,
173 requesting the server return a TackExtension if it has one.
174
175 @type serverName: string
176 @param serverName: The ServerNameIndication TLS Extension.
177
178 @type async: bool
179 @param async: If False, this function will block until the
180 handshake is completed. If True, this function will return a
181 generator. Successive invocations of the generator will
182 return 0 if it is waiting to read from the socket, 1 if it is
183 waiting to write to the socket, or will raise StopIteration if
184 the handshake operation is completed.
185
186 @rtype: None or an iterable
187 @return: If 'async' is True, a generator object will be
188 returned.
189
190 @raise socket.error: If a socket error occurs.
191 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
192 without a preceding alert.
193 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
194 @raise tlslite.errors.TLSAuthenticationError: If the checker
195 doesn't like the other party's authentication credentials.
196 """
197 handshaker = self._handshakeClientAsync(srpParams=(username, password),
198 session=session, settings=settings, checker=checker,
199 reqTack=reqTack, serverName=serverName)
200
201
202
203
204
205
206
207 if async:
208 return handshaker
209 for result in handshaker:
210 pass
211
212 - def handshakeClientCert(self, certChain=None, privateKey=None,
213 session=None, settings=None, checker=None,
214 reqTack=True, serverName="", async=False):
215 """Perform a certificate-based handshake in the role of client.
216
217 This function performs an SSL or TLS handshake. The server
218 will authenticate itself using an X.509 certificate
219 chain. If the handshake succeeds, the server's certificate
220 chain will be stored in the session's serverCertChain attribute.
221 Unless a checker object is passed in, this function does no
222 validation or checking of the server's certificate chain.
223
224 If the server requests client authentication, the
225 client will send the passed-in certificate chain, and use the
226 passed-in private key to authenticate itself. If no
227 certificate chain and private key were passed in, the client
228 will attempt to proceed without client authentication. The
229 server may or may not allow this.
230
231 If the function completes without raising an exception, the
232 TLS connection will be open and available for data transfer.
233
234 If an exception is raised, the connection will have been
235 automatically closed (if it was ever open).
236
237 @type certChain: L{tlslite.x509certchain.X509CertChain}
238 @param certChain: The certificate chain to be used if the
239 server requests client authentication.
240
241 @type privateKey: L{tlslite.utils.rsakey.RSAKey}
242 @param privateKey: The private key to be used if the server
243 requests client authentication.
244
245 @type session: L{tlslite.session.Session}
246 @param session: A TLS session to attempt to resume. If the
247 resumption does not succeed, a full handshake will be
248 performed.
249
250 @type settings: L{tlslite.handshakesettings.HandshakeSettings}
251 @param settings: Various settings which can be used to control
252 the ciphersuites, certificate types, and SSL/TLS versions
253 offered by the client.
254
255 @type checker: L{tlslite.checker.Checker}
256 @param checker: A Checker instance. This instance will be
257 invoked to examine the other party's authentication
258 credentials, if the handshake completes succesfully.
259
260 @type reqTack: bool
261 @param reqTack: Whether or not to send a "tack" TLS Extension,
262 requesting the server return a TackExtension if it has one.
263
264 @type serverName: string
265 @param serverName: The ServerNameIndication TLS Extension.
266
267 @type async: bool
268 @param async: If False, this function will block until the
269 handshake is completed. If True, this function will return a
270 generator. Successive invocations of the generator will
271 return 0 if it is waiting to read from the socket, 1 if it is
272 waiting to write to the socket, or will raise StopIteration if
273 the handshake operation is completed.
274
275 @rtype: None or an iterable
276 @return: If 'async' is True, a generator object will be
277 returned.
278
279 @raise socket.error: If a socket error occurs.
280 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
281 without a preceding alert.
282 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
283 @raise tlslite.errors.TLSAuthenticationError: If the checker
284 doesn't like the other party's authentication credentials.
285 """
286 handshaker = self._handshakeClientAsync(certParams=(certChain,
287 privateKey), session=session, settings=settings,
288 checker=checker, serverName=serverName,
289 reqTack=reqTack)
290
291
292
293
294
295
296
297 if async:
298 return handshaker
299 for result in handshaker:
300 pass
301
302
303 - def _handshakeClientAsync(self, srpParams=(), certParams=(), anonParams=(),
304 session=None, settings=None, checker=None,
305 serverName="", reqTack=True):
316
317
320
321 self._handshakeStart(client=True)
322
323
324 srpUsername = None
325 password = None
326 clientCertChain = None
327 privateKey = None
328
329
330 if srpParams:
331 assert(not certParams)
332 assert(not anonParams)
333 srpUsername, password = srpParams
334 if certParams:
335 assert(not srpParams)
336 assert(not anonParams)
337 clientCertChain, privateKey = certParams
338 if anonParams:
339 assert(not srpParams)
340 assert(not certParams)
341
342
343 if srpUsername and not password:
344 raise ValueError("Caller passed a username but no password")
345 if password and not srpUsername:
346 raise ValueError("Caller passed a password but no username")
347 if clientCertChain and not privateKey:
348 raise ValueError("Caller passed a certChain but no privateKey")
349 if privateKey and not clientCertChain:
350 raise ValueError("Caller passed a privateKey but no certChain")
351 if reqTack:
352 if not tackpyLoaded:
353 reqTack = False
354 if not settings or not settings.useExperimentalTackExtension:
355 reqTack = False
356
357
358
359 if not settings:
360 settings = HandshakeSettings()
361 settings = settings._filter()
362
363 if clientCertChain:
364 if not isinstance(clientCertChain, X509CertChain):
365 raise ValueError("Unrecognized certificate type")
366 if "x509" not in settings.certificateTypes:
367 raise ValueError("Client certificate doesn't match "\
368 "Handshake Settings")
369
370 if session:
371
372
373 if not session.valid():
374 session = None
375 elif session.resumable:
376 if session.srpUsername != srpUsername:
377 raise ValueError("Session username doesn't match")
378 if session.serverName != serverName:
379 raise ValueError("Session servername doesn't match")
380
381
382 if srpUsername and self.fault == Fault.badUsername:
383 srpUsername += "GARBAGE"
384 if password and self.fault == Fault.badPassword:
385 password += "GARBAGE"
386
387
388
389
390 self.version = settings.maxVersion
391
392
393
394
395
396 for result in self._clientSendClientHello(settings, session,
397 srpUsername, srpParams, certParams,
398 anonParams, serverName, reqTack):
399 if result in (0,1): yield result
400 else: break
401 clientHello = result
402
403
404 for result in self._clientGetServerHello(settings, clientHello):
405 if result in (0,1): yield result
406 else: break
407 serverHello = result
408 cipherSuite = serverHello.cipher_suite
409
410
411 for result in self._clientResume(session, serverHello,
412 clientHello.random,
413 settings.cipherImplementations):
414 if result in (0,1): yield result
415 else: break
416 if result == "resumed_and_finished":
417 self._handshakeDone(resumed=True)
418 return
419
420
421
422
423 if cipherSuite in CipherSuite.srpAllSuites:
424 for result in self._clientSRPKeyExchange(\
425 settings, cipherSuite, serverHello.certificate_type,
426 srpUsername, password,
427 clientHello.random, serverHello.random,
428 serverHello.tackExt):
429 if result in (0,1): yield result
430 else: break
431 (premasterSecret, serverCertChain, tackExt) = result
432
433
434 elif cipherSuite in CipherSuite.anonSuites:
435 for result in self._clientAnonKeyExchange(settings, cipherSuite,
436 clientHello.random, serverHello.random):
437 if result in (0,1): yield result
438 else: break
439 (premasterSecret, serverCertChain, tackExt) = result
440
441
442
443
444
445
446
447 else:
448 for result in self._clientRSAKeyExchange(settings, cipherSuite,
449 clientCertChain, privateKey,
450 serverHello.certificate_type,
451 clientHello.random, serverHello.random,
452 serverHello.tackExt):
453 if result in (0,1): yield result
454 else: break
455 (premasterSecret, serverCertChain, clientCertChain,
456 tackExt) = result
457
458
459
460 for result in self._clientFinished(premasterSecret,
461 clientHello.random,
462 serverHello.random,
463 cipherSuite, settings.cipherImplementations):
464 if result in (0,1): yield result
465 else: break
466 masterSecret = result
467
468
469 self.session = Session()
470 self.session.create(masterSecret, serverHello.session_id, cipherSuite,
471 srpUsername, clientCertChain, serverCertChain,
472 tackExt, serverHello.tackExt!=None, clientHello.server_name)
473 self._handshakeDone(resumed=False)
474
475
476 - def _clientSendClientHello(self, settings, session, srpUsername,
477 srpParams, certParams, anonParams,
478 serverName, reqTack):
479
480 cipherSuites = [CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
481 if srpParams:
482 cipherSuites += CipherSuite.getSrpAllSuites(settings.cipherNames)
483 elif certParams:
484 cipherSuites += CipherSuite.getCertSuites(settings.cipherNames)
485 elif anonParams:
486 cipherSuites += CipherSuite.getAnonSuites(settings.cipherNames)
487 else:
488 assert(False)
489
490
491 certificateTypes = settings._getCertificateTypes()
492
493
494 if session and session.sessionID:
495
496
497 if session.cipherSuite not in cipherSuites:
498 raise ValueError("Session's cipher suite not consistent "\
499 "with parameters")
500 else:
501 clientHello = ClientHello()
502 clientHello.create(settings.maxVersion, getRandomBytes(32),
503 session.sessionID, cipherSuites,
504 certificateTypes, session.srpUsername,
505 reqTack, False, session.serverName)
506
507
508 else:
509 clientHello = ClientHello()
510 clientHello.create(settings.maxVersion, getRandomBytes(32),
511 createByteArraySequence([]), cipherSuites,
512 certificateTypes, srpUsername,
513 reqTack, False, serverName)
514 for result in self._sendMsg(clientHello):
515 yield result
516 yield clientHello
517
518
571
572 - def _clientResume(self, session, serverHello, clientRandom,
573 cipherImplementations):
599
600 - def _clientSRPKeyExchange(self, settings, cipherSuite, certificateType,
601 srpUsername, password,
602 clientRandom, serverRandom, tackExt):
603
604
605 if cipherSuite in CipherSuite.srpCertSuites:
606
607 for result in self._getMsg(ContentType.handshake,
608 HandshakeType.certificate, certificateType):
609 if result in (0,1): yield result
610 else: break
611 serverCertificate = result
612 else:
613 serverCertificate = None
614
615 for result in self._getMsg(ContentType.handshake,
616 HandshakeType.server_key_exchange, cipherSuite):
617 if result in (0,1): yield result
618 else: break
619 serverKeyExchange = result
620
621 for result in self._getMsg(ContentType.handshake,
622 HandshakeType.server_hello_done):
623 if result in (0,1): yield result
624 else: break
625 serverHelloDone = result
626
627
628
629 N = serverKeyExchange.srp_N
630 g = serverKeyExchange.srp_g
631 s = serverKeyExchange.srp_s
632 B = serverKeyExchange.srp_B
633
634 if (g,N) not in goodGroupParameters:
635 for result in self._sendError(\
636 AlertDescription.insufficient_security,
637 "Unknown group parameters"):
638 yield result
639 if numBits(N) < settings.minKeySize:
640 for result in self._sendError(\
641 AlertDescription.insufficient_security,
642 "N value is too small: %d" % numBits(N)):
643 yield result
644 if numBits(N) > settings.maxKeySize:
645 for result in self._sendError(\
646 AlertDescription.insufficient_security,
647 "N value is too large: %d" % numBits(N)):
648 yield result
649 if B % N == 0:
650 for result in self._sendError(\
651 AlertDescription.illegal_parameter,
652 "Suspicious B value"):
653 yield result
654
655
656
657 serverCertChain = None
658 if cipherSuite in CipherSuite.srpCertSuites:
659
660 hashBytes = serverKeyExchange.hash(clientRandom, serverRandom)
661
662
663 sigBytes = serverKeyExchange.signature
664 if len(sigBytes) == 0:
665 for result in self._sendError(\
666 AlertDescription.illegal_parameter,
667 "Server sent an SRP ServerKeyExchange "\
668 "message without a signature"):
669 yield result
670
671
672
673
674 for result in self._clientGetKeyFromChain(serverCertificate,
675 settings, tackExt):
676 if result in (0,1): yield result
677 else: break
678 publicKey, serverCertChain, tackExt = result
679
680
681 if not publicKey.verify(sigBytes, hashBytes):
682 for result in self._sendError(\
683 AlertDescription.decrypt_error,
684 "Signature failed to verify"):
685 yield result
686
687
688 a = bytesToNumber(getRandomBytes(32))
689 A = powMod(g, a, N)
690
691
692 x = makeX(bytesToString(s), srpUsername, password)
693 v = powMod(g, x, N)
694
695
696 u = makeU(N, A, B)
697
698
699 k = makeK(N, g)
700 S = powMod((B - (k*v)) % N, a+(u*x), N)
701
702 if self.fault == Fault.badA:
703 A = N
704 S = 0
705
706 premasterSecret = numberToBytes(S)
707
708
709 for result in self._sendMsg(\
710 ClientKeyExchange(cipherSuite).createSRP(A)):
711 yield result
712 yield (premasterSecret, serverCertChain, tackExt)
713
714
715 - def _clientRSAKeyExchange(self, settings, cipherSuite,
716 clientCertChain, privateKey,
717 certificateType,
718 clientRandom, serverRandom,
719 tackExt):
720
721
722 for result in self._getMsg(ContentType.handshake,
723 HandshakeType.certificate, certificateType):
724 if result in (0,1): yield result
725 else: break
726 serverCertificate = result
727
728
729 for result in self._getMsg(ContentType.handshake,
730 (HandshakeType.server_hello_done,
731 HandshakeType.certificate_request)):
732 if result in (0,1): yield result
733 else: break
734 msg = result
735 certificateRequest = None
736 if isinstance(msg, CertificateRequest):
737 certificateRequest = msg
738
739 for result in self._getMsg(ContentType.handshake,
740 HandshakeType.server_hello_done):
741 if result in (0,1): yield result
742 else: break
743 serverHelloDone = result
744 elif isinstance(msg, ServerHelloDone):
745 serverHelloDone = msg
746
747
748
749
750 for result in self._clientGetKeyFromChain(serverCertificate,
751 settings, tackExt):
752 if result in (0,1): yield result
753 else: break
754 publicKey, serverCertChain, tackExt = result
755
756
757 premasterSecret = getRandomBytes(48)
758 premasterSecret[0] = settings.maxVersion[0]
759 premasterSecret[1] = settings.maxVersion[1]
760
761 if self.fault == Fault.badPremasterPadding:
762 premasterSecret[0] = 5
763 if self.fault == Fault.shortPremasterSecret:
764 premasterSecret = premasterSecret[:-1]
765
766
767 encryptedPreMasterSecret = publicKey.encrypt(premasterSecret)
768
769
770
771 if certificateRequest:
772 clientCertificate = Certificate(certificateType)
773
774 if clientCertChain:
775
776
777 wrongType = False
778 if certificateType == CertificateType.x509:
779 if not isinstance(clientCertChain, X509CertChain):
780 wrongType = True
781 if wrongType:
782 for result in self._sendError(\
783 AlertDescription.handshake_failure,
784 "Client certificate is of wrong type"):
785 yield result
786
787 clientCertificate.create(clientCertChain)
788 for result in self._sendMsg(clientCertificate):
789 yield result
790 else:
791
792
793
794 privateKey = None
795 clientCertChain = None
796
797
798 clientKeyExchange = ClientKeyExchange(cipherSuite,
799 self.version)
800 clientKeyExchange.createRSA(encryptedPreMasterSecret)
801 for result in self._sendMsg(clientKeyExchange):
802 yield result
803
804
805
806 if certificateRequest and privateKey:
807 if self.version == (3,0):
808 masterSecret = calcMasterSecret(self.version,
809 premasterSecret,
810 clientRandom,
811 serverRandom)
812 verifyBytes = self._calcSSLHandshakeHash(masterSecret, "")
813 elif self.version in ((3,1), (3,2)):
814 verifyBytes = stringToBytes(\
815 self._handshake_md5.digest() + \
816 self._handshake_sha.digest())
817 if self.fault == Fault.badVerifyMessage:
818 verifyBytes[0] = ((verifyBytes[0]+1) % 256)
819 signedBytes = privateKey.sign(verifyBytes)
820 certificateVerify = CertificateVerify()
821 certificateVerify.create(signedBytes)
822 for result in self._sendMsg(certificateVerify):
823 yield result
824 yield (premasterSecret, serverCertChain, clientCertChain, tackExt)
825
828 for result in self._getMsg(ContentType.handshake,
829 HandshakeType.server_key_exchange, cipherSuite):
830 if result in (0,1): yield result
831 else: break
832 serverKeyExchange = result
833
834 for result in self._getMsg(ContentType.handshake,
835 HandshakeType.server_hello_done):
836 if result in (0,1): yield result
837 else: break
838 serverHelloDone = result
839
840
841 dh_p = serverKeyExchange.dh_p
842 dh_g = serverKeyExchange.dh_g
843 dh_Xc = bytesToNumber(getRandomBytes(32))
844 dh_Ys = serverKeyExchange.dh_Ys
845 dh_Yc = powMod(dh_g, dh_Xc, dh_p)
846
847
848 for result in self._sendMsg(\
849 ClientKeyExchange(cipherSuite, self.version).createDH(dh_Yc)):
850 yield result
851
852
853 S = powMod(dh_Ys, dh_Xc, dh_p)
854 premasterSecret = numberToBytes(S)
855
856 yield (premasterSecret, None, None)
857
858 - def _clientFinished(self, premasterSecret, clientRandom, serverRandom,
859 cipherSuite, cipherImplementations):
860 masterSecret = calcMasterSecret(self.version, premasterSecret,
861 clientRandom, serverRandom)
862 self._calcPendingStates(cipherSuite, masterSecret,
863 clientRandom, serverRandom,
864 cipherImplementations)
865
866
867 for result in self._sendFinished(masterSecret):
868 yield result
869 for result in self._getFinished(masterSecret):
870 yield result
871 yield masterSecret
872
908
909
910
911
912
913
914
915 - def handshakeServer(self, verifierDB=None,
916 certChain=None, privateKey=None, reqCert=False,
917 sessionCache=None, settings=None, checker=None,
918 reqCAs = None,
919 tack=None, breakSigs=None, pinActivation=False,
920 nextProtos=None, anon=False):
921 """Perform a handshake in the role of server.
922
923 This function performs an SSL or TLS handshake. Depending on
924 the arguments and the behavior of the client, this function can
925 perform an SRP, or certificate-based handshake. It
926 can also perform a combined SRP and server-certificate
927 handshake.
928
929 Like any handshake function, this can be called on a closed
930 TLS connection, or on a TLS connection that is already open.
931 If called on an open connection it performs a re-handshake.
932 This function does not send a Hello Request message before
933 performing the handshake, so if re-handshaking is required,
934 the server must signal the client to begin the re-handshake
935 through some other means.
936
937 If the function completes without raising an exception, the
938 TLS connection will be open and available for data transfer.
939
940 If an exception is raised, the connection will have been
941 automatically closed (if it was ever open).
942
943 @type verifierDB: L{tlslite.verifierdb.VerifierDB}
944 @param verifierDB: A database of SRP password verifiers
945 associated with usernames. If the client performs an SRP
946 handshake, the session's srpUsername attribute will be set.
947
948 @type certChain: L{tlslite.x509certchain.X509CertChain}
949 @param certChain: The certificate chain to be used if the
950 client requests server certificate authentication.
951
952 @type privateKey: L{tlslite.utils.rsakey.RSAKey}
953 @param privateKey: The private key to be used if the client
954 requests server certificate authentication.
955
956 @type reqCert: bool
957 @param reqCert: Whether to request client certificate
958 authentication. This only applies if the client chooses server
959 certificate authentication; if the client chooses SRP
960 authentication, this will be ignored. If the client
961 performs a client certificate authentication, the sessions's
962 clientCertChain attribute will be set.
963
964 @type sessionCache: L{tlslite.sessioncache.SessionCache}
965 @param sessionCache: An in-memory cache of resumable sessions.
966 The client can resume sessions from this cache. Alternatively,
967 if the client performs a full handshake, a new session will be
968 added to the cache.
969
970 @type settings: L{tlslite.handshakesettings.HandshakeSettings}
971 @param settings: Various settings which can be used to control
972 the ciphersuites and SSL/TLS version chosen by the server.
973
974 @type checker: L{tlslite.checker.Checker}
975 @param checker: A Checker instance. This instance will be
976 invoked to examine the other party's authentication
977 credentials, if the handshake completes succesfully.
978
979 @type reqCAs: list of L{bytearray} of unsigned bytes
980 @param reqCAs: A collection of DER-encoded DistinguishedNames that
981 will be sent along with a certificate request. This does not affect
982 verification.
983
984 @raise socket.error: If a socket error occurs.
985 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
986 without a preceding alert.
987 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
988 @raise tlslite.errors.TLSAuthenticationError: If the checker
989 doesn't like the other party's authentication credentials.
990 """
991 for result in self.handshakeServerAsync(verifierDB,
992 certChain, privateKey, reqCert, sessionCache, settings,
993 checker, reqCAs,
994 tack=tack, breakSigs=breakSigs, pinActivation=pinActivation,
995 nextProtos=nextProtos, anon=anon):
996 pass
997
998
999 - def handshakeServerAsync(self, verifierDB=None,
1000 certChain=None, privateKey=None, reqCert=False,
1001 sessionCache=None, settings=None, checker=None,
1002 reqCAs=None,
1003 tack=None, breakSigs=None, pinActivation=False,
1004 nextProtos=None, anon=False
1005 ):
1006 """Start a server handshake operation on the TLS connection.
1007
1008 This function returns a generator which behaves similarly to
1009 handshakeServer(). Successive invocations of the generator
1010 will return 0 if it is waiting to read from the socket, 1 if it is
1011 waiting to write to the socket, or it will raise StopIteration
1012 if the handshake operation is complete.
1013
1014 @rtype: iterable
1015 @return: A generator; see above for details.
1016 """
1017 handshaker = self._handshakeServerAsyncHelper(\
1018 verifierDB=verifierDB, certChain=certChain,
1019 privateKey=privateKey, reqCert=reqCert,
1020 sessionCache=sessionCache, settings=settings,
1021 reqCAs=reqCAs,
1022 tack=tack, breakSigs=breakSigs, pinActivation=pinActivation,
1023 nextProtos=nextProtos, anon=anon)
1024 for result in self._handshakeWrapperAsync(handshaker, checker):
1025 yield result
1026
1027
1028 - def _handshakeServerAsyncHelper(self, verifierDB,
1029 certChain, privateKey, reqCert, sessionCache,
1030 settings, reqCAs,
1031 tack, breakSigs, pinActivation,
1032 nextProtos, anon):
1033
1034 self._handshakeStart(client=False)
1035
1036 if (not verifierDB) and (not certChain) and not anon:
1037 raise ValueError("Caller passed no authentication credentials")
1038 if certChain and not privateKey:
1039 raise ValueError("Caller passed a certChain but no privateKey")
1040 if privateKey and not certChain:
1041 raise ValueError("Caller passed a privateKey but no certChain")
1042 if reqCAs and not reqCert:
1043 raise ValueError("Caller passed reqCAs but not reqCert")
1044 if certChain and not isinstance(certChain, X509CertChain):
1045 raise ValueError("Unrecognized certificate type")
1046 if (tack or breakSigs or pinActivation):
1047 if not tackpyLoaded:
1048 raise ValueError("tackpy is not loaded")
1049 if not settings or not settings.useExperimentalTackExtension:
1050 raise ValueError("useExperimentalTackExtension not enabled")
1051
1052 if not settings:
1053 settings = HandshakeSettings()
1054 settings = settings._filter()
1055
1056
1057
1058
1059
1060 for result in self._serverGetClientHello(settings, certChain,\
1061 verifierDB, sessionCache,
1062 anon):
1063 if result in (0,1): yield result
1064 elif result == None:
1065 self._handshakeDone(resumed=True)
1066 return
1067 else: break
1068 (clientHello, cipherSuite) = result
1069
1070
1071
1072
1073 if sessionCache:
1074 sessionID = getRandomBytes(32)
1075 else:
1076 sessionID = createByteArraySequence([])
1077
1078 if not clientHello.supports_npn:
1079 nextProtos = None
1080
1081
1082 if not cipherSuite in CipherSuite.certAllSuites:
1083 tack = None
1084
1085
1086 if clientHello.tack:
1087 tackExt = TackExtension.create(tack, breakSigs, pinActivation)
1088 else:
1089 tackExt = None
1090 serverHello = ServerHello()
1091 serverHello.create(self.version, getRandomBytes(32), sessionID, \
1092 cipherSuite, CertificateType.x509, tackExt,
1093 nextProtos)
1094
1095
1096 clientCertChain = None
1097 if cipherSuite in CipherSuite.srpAllSuites:
1098 for result in self._serverSRPKeyExchange(clientHello, serverHello,
1099 verifierDB, cipherSuite,
1100 privateKey, certChain):
1101 if result in (0,1): yield result
1102 else: break
1103 premasterSecret = result
1104
1105
1106 elif cipherSuite in CipherSuite.certSuites:
1107 for result in self._serverCertKeyExchange(clientHello, serverHello,
1108 certChain, privateKey,
1109 reqCert, reqCAs, cipherSuite,
1110 settings):
1111 if result in (0,1): yield result
1112 else: break
1113 (premasterSecret, clientCertChain) = result
1114
1115
1116 elif cipherSuite in CipherSuite.anonSuites:
1117 for result in self._serverAnonKeyExchange(clientHello, serverHello,
1118 cipherSuite, settings):
1119 if result in (0,1): yield result
1120 else: break
1121 premasterSecret = result
1122
1123 else:
1124 assert(False)
1125
1126
1127 for result in self._serverFinished(premasterSecret,
1128 clientHello.random, serverHello.random,
1129 cipherSuite, settings.cipherImplementations,
1130 nextProtos):
1131 if result in (0,1): yield result
1132 else: break
1133 masterSecret = result
1134
1135
1136 self.session = Session()
1137 if cipherSuite in CipherSuite.certAllSuites:
1138 serverCertChain = certChain
1139 else:
1140 serverCertChain = None
1141 self.session.create(masterSecret, serverHello.session_id, cipherSuite,
1142 clientHello.srp_username, clientCertChain, serverCertChain,
1143 tackExt, serverHello.tackExt!=None, clientHello.server_name)
1144
1145
1146 if sessionCache and sessionID:
1147 sessionCache[bytesToString(sessionID)] = self.session
1148
1149 self._handshakeDone(resumed=False)
1150
1151
1154
1155 cipherSuites = []
1156 if verifierDB:
1157 if certChain:
1158 cipherSuites += \
1159 CipherSuite.getSrpCertSuites(settings.cipherNames)
1160 cipherSuites += CipherSuite.getSrpSuites(settings.cipherNames)
1161 elif certChain:
1162 cipherSuites += CipherSuite.getCertSuites(settings.cipherNames)
1163 elif anon:
1164 cipherSuites += CipherSuite.getAnonSuites(settings.cipherNames)
1165 else:
1166 assert(False)
1167
1168
1169
1170
1171 self.version = settings.maxVersion
1172
1173
1174 for result in self._getMsg(ContentType.handshake,
1175 HandshakeType.client_hello):
1176 if result in (0,1): yield result
1177 else: break
1178 clientHello = result
1179
1180
1181 if clientHello.client_version < settings.minVersion:
1182 self.version = settings.minVersion
1183 for result in self._sendError(\
1184 AlertDescription.protocol_version,
1185 "Too old version: %s" % str(clientHello.client_version)):
1186 yield result
1187
1188
1189 elif clientHello.client_version > settings.maxVersion:
1190 self.version = settings.maxVersion
1191
1192 else:
1193
1194 self.version = clientHello.client_version
1195
1196
1197 if clientHello.session_id and sessionCache:
1198 session = None
1199
1200
1201 if sessionCache and not session:
1202 try:
1203 session = sessionCache[bytesToString(\
1204 clientHello.session_id)]
1205 if not session.resumable:
1206 raise AssertionError()
1207
1208 if session.cipherSuite not in cipherSuites:
1209 for result in self._sendError(\
1210 AlertDescription.handshake_failure):
1211 yield result
1212 if session.cipherSuite not in clientHello.cipher_suites:
1213 for result in self._sendError(\
1214 AlertDescription.handshake_failure):
1215 yield result
1216 if clientHello.srp_username:
1217 if clientHello.srp_username != session.srpUsername:
1218 for result in self._sendError(\
1219 AlertDescription.handshake_failure):
1220 yield result
1221 if clientHello.server_name:
1222 if clientHello.server_name != session.serverName:
1223 for result in self._sendError(\
1224 AlertDescription.handshake_failure):
1225 yield result
1226 except KeyError:
1227 pass
1228
1229
1230 if session:
1231
1232 serverHello = ServerHello()
1233 serverHello.create(self.version, getRandomBytes(32),
1234 session.sessionID, session.cipherSuite,
1235 CertificateType.x509, None, None)
1236 for result in self._sendMsg(serverHello):
1237 yield result
1238
1239
1240 self._versionCheck = True
1241
1242
1243 self._calcPendingStates(session.cipherSuite,
1244 session.masterSecret,
1245 clientHello.random,
1246 serverHello.random,
1247 settings.cipherImplementations)
1248
1249
1250 for result in self._sendFinished(session.masterSecret):
1251 yield result
1252 for result in self._getFinished(session.masterSecret):
1253 yield result
1254
1255
1256 self.session = session
1257
1258 yield None
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268 for cipherSuite in cipherSuites:
1269 if cipherSuite in clientHello.cipher_suites:
1270 break
1271 else:
1272 for result in self._sendError(\
1273 AlertDescription.handshake_failure,
1274 "No mutual ciphersuite"):
1275 yield result
1276 if cipherSuite in CipherSuite.srpAllSuites and \
1277 not clientHello.srp_username:
1278 for result in self._sendError(\
1279 AlertDescription.unknown_psk_identity,
1280 "Client sent a hello, but without the SRP username"):
1281 yield result
1282
1283
1284 if cipherSuite in CipherSuite.certAllSuites and CertificateType.x509 \
1285 not in clientHello.certificate_types:
1286 for result in self._sendError(\
1287 AlertDescription.handshake_failure,
1288 "the client doesn't support my certificate type"):
1289 yield result
1290
1291
1292
1293
1294 yield (clientHello, cipherSuite)
1295
1296 - def _serverSRPKeyExchange(self, clientHello, serverHello, verifierDB,
1297 cipherSuite, privateKey, serverCertChain):
1298
1299 self.allegedSrpUsername = clientHello.srp_username
1300
1301 try:
1302 entry = verifierDB[clientHello.srp_username]
1303 except KeyError:
1304 for result in self._sendError(\
1305 AlertDescription.unknown_psk_identity):
1306 yield result
1307 (N, g, s, v) = entry
1308
1309
1310 b = bytesToNumber(getRandomBytes(32))
1311 k = makeK(N, g)
1312 B = (powMod(g, b, N) + (k*v)) % N
1313
1314
1315 serverKeyExchange = ServerKeyExchange(cipherSuite)
1316 serverKeyExchange.createSRP(N, g, stringToBytes(s), B)
1317 if cipherSuite in CipherSuite.srpCertSuites:
1318 hashBytes = serverKeyExchange.hash(clientHello.random,
1319 serverHello.random)
1320 serverKeyExchange.signature = privateKey.sign(hashBytes)
1321
1322
1323
1324 msgs = []
1325 msgs.append(serverHello)
1326 if cipherSuite in CipherSuite.srpCertSuites:
1327 certificateMsg = Certificate(CertificateType.x509)
1328 certificateMsg.create(serverCertChain)
1329 msgs.append(certificateMsg)
1330 msgs.append(serverKeyExchange)
1331 msgs.append(ServerHelloDone())
1332 for result in self._sendMsgs(msgs):
1333 yield result
1334
1335
1336 self._versionCheck = True
1337
1338
1339 for result in self._getMsg(ContentType.handshake,
1340 HandshakeType.client_key_exchange,
1341 cipherSuite):
1342 if result in (0,1): yield result
1343 else: break
1344 clientKeyExchange = result
1345 A = clientKeyExchange.srp_A
1346 if A % N == 0:
1347 for result in self._sendError(AlertDescription.illegal_parameter,
1348 "Suspicious A value"):
1349 yield result
1350 assert(False)
1351
1352
1353 u = makeU(N, A, B)
1354
1355
1356 S = powMod((A * powMod(v,u,N)) % N, b, N)
1357 premasterSecret = numberToBytes(S)
1358
1359 yield premasterSecret
1360
1361
1362 - def _serverCertKeyExchange(self, clientHello, serverHello,
1363 serverCertChain, privateKey,
1364 reqCert, reqCAs, cipherSuite,
1365 settings):
1366
1367
1368 msgs = []
1369
1370
1371 clientCertChain = None
1372
1373 msgs.append(serverHello)
1374 msgs.append(Certificate(CertificateType.x509).create(serverCertChain))
1375 if reqCert and reqCAs:
1376 msgs.append(CertificateRequest().create(\
1377 [ClientCertificateType.rsa_sign], reqCAs))
1378 elif reqCert:
1379 msgs.append(CertificateRequest())
1380 msgs.append(ServerHelloDone())
1381 for result in self._sendMsgs(msgs):
1382 yield result
1383
1384
1385 self._versionCheck = True
1386
1387
1388 if reqCert:
1389 if self.version == (3,0):
1390 for result in self._getMsg((ContentType.handshake,
1391 ContentType.alert),
1392 HandshakeType.certificate,
1393 CertificateType.x509):
1394 if result in (0,1): yield result
1395 else: break
1396 msg = result
1397
1398 if isinstance(msg, Alert):
1399
1400 alert = msg
1401 if alert.description != \
1402 AlertDescription.no_certificate:
1403 self._shutdown(False)
1404 raise TLSRemoteAlert(alert)
1405 elif isinstance(msg, Certificate):
1406 clientCertificate = msg
1407 if clientCertificate.certChain and \
1408 clientCertificate.certChain.getNumCerts()!=0:
1409 clientCertChain = clientCertificate.certChain
1410 else:
1411 raise AssertionError()
1412 elif self.version in ((3,1), (3,2)):
1413 for result in self._getMsg(ContentType.handshake,
1414 HandshakeType.certificate,
1415 CertificateType.x509):
1416 if result in (0,1): yield result
1417 else: break
1418 clientCertificate = result
1419 if clientCertificate.certChain and \
1420 clientCertificate.certChain.getNumCerts()!=0:
1421 clientCertChain = clientCertificate.certChain
1422 else:
1423 raise AssertionError()
1424
1425
1426 for result in self._getMsg(ContentType.handshake,
1427 HandshakeType.client_key_exchange,
1428 cipherSuite):
1429 if result in (0,1): yield result
1430 else: break
1431 clientKeyExchange = result
1432
1433
1434 premasterSecret = privateKey.decrypt(\
1435 clientKeyExchange.encryptedPreMasterSecret)
1436
1437
1438
1439 randomPreMasterSecret = getRandomBytes(48)
1440 versionCheck = (premasterSecret[0], premasterSecret[1])
1441 if not premasterSecret:
1442 premasterSecret = randomPreMasterSecret
1443 elif len(premasterSecret)!=48:
1444 premasterSecret = randomPreMasterSecret
1445 elif versionCheck != clientHello.client_version:
1446 if versionCheck != self.version:
1447 premasterSecret = randomPreMasterSecret
1448
1449
1450 if clientCertChain:
1451 if self.version == (3,0):
1452 masterSecret = calcMasterSecret(self.version, premasterSecret,
1453 clientHello.random, serverHello.random)
1454 verifyBytes = self._calcSSLHandshakeHash(masterSecret, "")
1455 elif self.version in ((3,1), (3,2)):
1456 verifyBytes = stringToBytes(self._handshake_md5.digest() +\
1457 self._handshake_sha.digest())
1458 for result in self._getMsg(ContentType.handshake,
1459 HandshakeType.certificate_verify):
1460 if result in (0,1): yield result
1461 else: break
1462 certificateVerify = result
1463 publicKey = clientCertChain.getEndEntityPublicKey()
1464 if len(publicKey) < settings.minKeySize:
1465 for result in self._sendError(\
1466 AlertDescription.handshake_failure,
1467 "Client's public key too small: %d" % len(publicKey)):
1468 yield result
1469
1470 if len(publicKey) > settings.maxKeySize:
1471 for result in self._sendError(\
1472 AlertDescription.handshake_failure,
1473 "Client's public key too large: %d" % len(publicKey)):
1474 yield result
1475
1476 if not publicKey.verify(certificateVerify.signature, verifyBytes):
1477 for result in self._sendError(\
1478 AlertDescription.decrypt_error,
1479 "Signature failed to verify"):
1480 yield result
1481 yield (premasterSecret, clientCertChain)
1482
1483
1486
1487 dh_p = getRandomSafePrime(32, False)
1488 dh_g = getRandomNumber(2, dh_p)
1489 dh_Xs = bytesToNumber(getRandomBytes(32))
1490 dh_Ys = powMod(dh_g, dh_Xs, dh_p)
1491
1492
1493 serverKeyExchange = ServerKeyExchange(cipherSuite)
1494 serverKeyExchange.createDH(dh_p, dh_g, dh_Ys)
1495
1496
1497
1498 msgs = []
1499 msgs.append(serverHello)
1500 msgs.append(serverKeyExchange)
1501 msgs.append(ServerHelloDone())
1502 for result in self._sendMsgs(msgs):
1503 yield result
1504
1505
1506 self._versionCheck = True
1507
1508
1509 for result in self._getMsg(ContentType.handshake,
1510 HandshakeType.client_key_exchange,
1511 cipherSuite):
1512 if result in (0,1):
1513 yield result
1514 else:
1515 break
1516 clientKeyExchange = result
1517 dh_Yc = clientKeyExchange.dh_Yc
1518
1519 if dh_Yc % dh_p == 0:
1520 for result in self._sendError(AlertDescription.illegal_parameter,
1521 "Suspicious dh_Yc value"):
1522 yield result
1523 assert(False)
1524
1525
1526 S = powMod(dh_Yc,dh_Xs,dh_p)
1527 premasterSecret = numberToBytes(S)
1528
1529 yield premasterSecret
1530
1531
1532 - def _serverFinished(self, premasterSecret, clientRandom, serverRandom,
1533 cipherSuite, cipherImplementations, nextProtos):
1534 masterSecret = calcMasterSecret(self.version, premasterSecret,
1535 clientRandom, serverRandom)
1536
1537
1538 self._calcPendingStates(cipherSuite, masterSecret,
1539 clientRandom, serverRandom,
1540 cipherImplementations)
1541
1542
1543 for result in self._getFinished(masterSecret,
1544 expect_next_protocol=nextProtos is not None):
1545 yield result
1546
1547 for result in self._sendFinished(masterSecret):
1548 yield result
1549
1550 yield masterSecret
1551
1552
1553
1554
1555
1556
1557
1575
1576 - def _getFinished(self, masterSecret, expect_next_protocol=False):
1617
1619 if self.version == (3,0):
1620 if (self._client and send) or (not self._client and not send):
1621 senderStr = "\x43\x4C\x4E\x54"
1622 else:
1623 senderStr = "\x53\x52\x56\x52"
1624
1625 verifyData = self._calcSSLHandshakeHash(masterSecret, senderStr)
1626 return verifyData
1627
1628 elif self.version in ((3,1), (3,2)):
1629 if (self._client and send) or (not self._client and not send):
1630 label = "client finished"
1631 else:
1632 label = "server finished"
1633
1634 handshakeHashes = stringToBytes(self._handshake_md5.digest() + \
1635 self._handshake_sha.digest())
1636 verifyData = PRF(masterSecret, label, handshakeHashes, 12)
1637 return verifyData
1638 else:
1639 raise AssertionError()
1640
1641
1668