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