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.streamSuites and \
1422 cipherSuite not in CipherSuite.aeadSuites:
1423 extensions = [TLSExtension().create(ExtensionType.encrypt_then_mac,
1424 bytearray(0))]
1425 self._recordLayer.encryptThenMAC = True
1426 else:
1427 extensions = None
1428
1429 serverHello = ServerHello()
1430 serverHello.create(self.version, getRandomBytes(32), sessionID, \
1431 cipherSuite, CertificateType.x509, tackExt,
1432 nextProtos, extensions=extensions)
1433
1434
1435 clientCertChain = None
1436 if cipherSuite in CipherSuite.srpAllSuites:
1437 for result in self._serverSRPKeyExchange(clientHello, serverHello,
1438 verifierDB, cipherSuite,
1439 privateKey, certChain):
1440 if result in (0,1): yield result
1441 else: break
1442 premasterSecret = result
1443
1444
1445 elif (cipherSuite in CipherSuite.certSuites or
1446 cipherSuite in CipherSuite.dheCertSuites):
1447 if cipherSuite in CipherSuite.certSuites:
1448 keyExchange = RSAKeyExchange(cipherSuite,
1449 clientHello,
1450 serverHello,
1451 privateKey)
1452 elif cipherSuite in CipherSuite.dheCertSuites:
1453 keyExchange = DHE_RSAKeyExchange(cipherSuite,
1454 clientHello,
1455 serverHello,
1456 privateKey)
1457 else:
1458 assert(False)
1459 for result in self._serverCertKeyExchange(clientHello, serverHello,
1460 certChain, keyExchange,
1461 reqCert, reqCAs, cipherSuite,
1462 settings):
1463 if result in (0,1): yield result
1464 else: break
1465 (premasterSecret, clientCertChain) = result
1466
1467
1468 elif cipherSuite in CipherSuite.anonSuites:
1469 for result in self._serverAnonKeyExchange(clientHello, serverHello,
1470 cipherSuite, settings):
1471 if result in (0,1): yield result
1472 else: break
1473 premasterSecret = result
1474
1475 else:
1476 assert(False)
1477
1478
1479 for result in self._serverFinished(premasterSecret,
1480 clientHello.random, serverHello.random,
1481 cipherSuite, settings.cipherImplementations,
1482 nextProtos):
1483 if result in (0,1): yield result
1484 else: break
1485 masterSecret = result
1486
1487
1488 self.session = Session()
1489 if cipherSuite in CipherSuite.certAllSuites:
1490 serverCertChain = certChain
1491 else:
1492 serverCertChain = None
1493 srpUsername = None
1494 serverName = None
1495 if clientHello.srp_username:
1496 srpUsername = clientHello.srp_username.decode("utf-8")
1497 if clientHello.server_name:
1498 serverName = clientHello.server_name.decode("utf-8")
1499 self.session.create(masterSecret, serverHello.session_id, cipherSuite,
1500 srpUsername, clientCertChain, serverCertChain,
1501 tackExt, (serverHello.tackExt is not None),
1502 serverName,
1503 encryptThenMAC=self._recordLayer.encryptThenMAC)
1504
1505
1506 if sessionCache and sessionID:
1507 sessionCache[sessionID] = self.session
1508
1509 self._handshakeDone(resumed=False)
1510
1511
1514
1515
1516
1517 self.version = settings.maxVersion
1518
1519
1520 for result in self._getMsg(ContentType.handshake,
1521 HandshakeType.client_hello):
1522 if result in (0,1): yield result
1523 else: break
1524 clientHello = result
1525
1526
1527 if clientHello.client_version < settings.minVersion:
1528 self.version = settings.minVersion
1529 for result in self._sendError(\
1530 AlertDescription.protocol_version,
1531 "Too old version: %s" % str(clientHello.client_version)):
1532 yield result
1533
1534
1535 elif clientHello.client_version > settings.maxVersion:
1536 self.version = settings.maxVersion
1537
1538 else:
1539
1540 self.version = clientHello.client_version
1541
1542
1543 if clientHello.client_version < settings.maxVersion and \
1544 CipherSuite.TLS_FALLBACK_SCSV in clientHello.cipher_suites:
1545 for result in self._sendError(\
1546 AlertDescription.inappropriate_fallback):
1547 yield result
1548
1549
1550
1551 cipherSuites = []
1552 if verifierDB:
1553 if certChain:
1554 cipherSuites += \
1555 CipherSuite.getSrpCertSuites(settings, self.version)
1556 cipherSuites += CipherSuite.getSrpSuites(settings, self.version)
1557 elif certChain:
1558 cipherSuites += CipherSuite.getDheCertSuites(settings, self.version)
1559 cipherSuites += CipherSuite.getCertSuites(settings, self.version)
1560 elif anon:
1561 cipherSuites += CipherSuite.getAnonSuites(settings, self.version)
1562 else:
1563 assert(False)
1564 cipherSuites = CipherSuite.filterForVersion(cipherSuites,
1565 minVersion=self.version,
1566 maxVersion=self.version)
1567
1568
1569 if clientHello.session_id and sessionCache:
1570 session = None
1571
1572
1573 if sessionCache and not session:
1574 try:
1575 session = sessionCache[clientHello.session_id]
1576 if not session.resumable:
1577 raise AssertionError()
1578
1579 if session.cipherSuite not in cipherSuites:
1580 for result in self._sendError(\
1581 AlertDescription.handshake_failure):
1582 yield result
1583 if session.cipherSuite not in clientHello.cipher_suites:
1584 for result in self._sendError(\
1585 AlertDescription.handshake_failure):
1586 yield result
1587 if clientHello.srp_username:
1588 if not session.srpUsername or \
1589 clientHello.srp_username != bytearray(session.srpUsername, "utf-8"):
1590 for result in self._sendError(\
1591 AlertDescription.handshake_failure):
1592 yield result
1593 if clientHello.server_name:
1594 if not session.serverName or \
1595 clientHello.server_name != bytearray(session.serverName, "utf-8"):
1596 for result in self._sendError(\
1597 AlertDescription.handshake_failure):
1598 yield result
1599 if session.encryptThenMAC and \
1600 not clientHello.getExtension(
1601 ExtensionType.encrypt_then_mac):
1602 for result in self._sendError(\
1603 AlertDescription.handshake_failure):
1604 yield result
1605 except KeyError:
1606 pass
1607
1608
1609 if session:
1610
1611 if session.encryptThenMAC:
1612 self._recordLayer.encryptThenMAC = True
1613 mte = TLSExtension().create(ExtensionType.encrypt_then_mac,
1614 bytearray(0))
1615 extensions = [mte]
1616 else:
1617 extensions = None
1618 serverHello = ServerHello()
1619 serverHello.create(self.version, getRandomBytes(32),
1620 session.sessionID, session.cipherSuite,
1621 CertificateType.x509, None, None,
1622 extensions=extensions)
1623 for result in self._sendMsg(serverHello):
1624 yield result
1625
1626
1627 self._calcPendingStates(session.cipherSuite,
1628 session.masterSecret,
1629 clientHello.random,
1630 serverHello.random,
1631 settings.cipherImplementations)
1632
1633
1634 for result in self._sendFinished(session.masterSecret,
1635 session.cipherSuite):
1636 yield result
1637 for result in self._getFinished(session.masterSecret,
1638 session.cipherSuite):
1639 yield result
1640
1641
1642 self.session = session
1643
1644 yield None
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654 for cipherSuite in cipherSuites:
1655 if cipherSuite in clientHello.cipher_suites:
1656 break
1657 else:
1658 for result in self._sendError(\
1659 AlertDescription.handshake_failure,
1660 "No mutual ciphersuite"):
1661 yield result
1662 if cipherSuite in CipherSuite.srpAllSuites and \
1663 not clientHello.srp_username:
1664 for result in self._sendError(\
1665 AlertDescription.unknown_psk_identity,
1666 "Client sent a hello, but without the SRP username"):
1667 yield result
1668
1669
1670 if cipherSuite in CipherSuite.certAllSuites and CertificateType.x509 \
1671 not in clientHello.certificate_types:
1672 for result in self._sendError(\
1673 AlertDescription.handshake_failure,
1674 "the client doesn't support my certificate type"):
1675 yield result
1676
1677
1678
1679
1680 yield (clientHello, cipherSuite)
1681
1682 - def _serverSRPKeyExchange(self, clientHello, serverHello, verifierDB,
1683 cipherSuite, privateKey, serverCertChain):
1684
1685 srpUsername = clientHello.srp_username.decode("utf-8")
1686 self.allegedSrpUsername = srpUsername
1687
1688 try:
1689 entry = verifierDB[srpUsername]
1690 except KeyError:
1691 for result in self._sendError(\
1692 AlertDescription.unknown_psk_identity):
1693 yield result
1694 (N, g, s, v) = entry
1695
1696
1697 b = bytesToNumber(getRandomBytes(32))
1698 k = makeK(N, g)
1699 B = (powMod(g, b, N) + (k*v)) % N
1700
1701
1702 serverKeyExchange = ServerKeyExchange(cipherSuite, self.version)
1703 serverKeyExchange.createSRP(N, g, s, B)
1704 if cipherSuite in CipherSuite.srpCertSuites:
1705 hashBytes = serverKeyExchange.hash(clientHello.random,
1706 serverHello.random)
1707 serverKeyExchange.signature = privateKey.sign(hashBytes)
1708 if self.version == (3, 3):
1709
1710 serverKeyExchange.signAlg = SignatureAlgorithm.rsa
1711 serverKeyExchange.hashAlg = HashAlgorithm.sha1
1712
1713
1714
1715 msgs = []
1716 msgs.append(serverHello)
1717 if cipherSuite in CipherSuite.srpCertSuites:
1718 certificateMsg = Certificate(CertificateType.x509)
1719 certificateMsg.create(serverCertChain)
1720 msgs.append(certificateMsg)
1721 msgs.append(serverKeyExchange)
1722 msgs.append(ServerHelloDone())
1723 for result in self._sendMsgs(msgs):
1724 yield result
1725
1726
1727 for result in self._getMsg(ContentType.handshake,
1728 HandshakeType.client_key_exchange,
1729 cipherSuite):
1730 if result in (0,1): yield result
1731 else: break
1732 clientKeyExchange = result
1733 A = clientKeyExchange.srp_A
1734 if A % N == 0:
1735 for result in self._sendError(AlertDescription.illegal_parameter,
1736 "Suspicious A value"):
1737 yield result
1738 assert(False)
1739
1740
1741 u = makeU(N, A, B)
1742
1743
1744 S = powMod((A * powMod(v,u,N)) % N, b, N)
1745 premasterSecret = numberToByteArray(S)
1746
1747 yield premasterSecret
1748
1749
1750 - def _serverCertKeyExchange(self, clientHello, serverHello,
1751 serverCertChain, keyExchange,
1752 reqCert, reqCAs, cipherSuite,
1753 settings):
1754
1755
1756 msgs = []
1757
1758
1759 clientCertChain = None
1760
1761 msgs.append(serverHello)
1762 msgs.append(Certificate(CertificateType.x509).create(serverCertChain))
1763 serverKeyExchange = keyExchange.makeServerKeyExchange()
1764 if serverKeyExchange is not None:
1765 msgs.append(serverKeyExchange)
1766 if reqCert:
1767 certificateRequest = CertificateRequest(self.version)
1768 if not reqCAs:
1769 reqCAs = []
1770
1771 certificateRequest.create([ClientCertificateType.rsa_sign],
1772 reqCAs,
1773 [(HashAlgorithm.sha1,
1774 SignatureAlgorithm.rsa)])
1775 msgs.append(certificateRequest)
1776 msgs.append(ServerHelloDone())
1777 for result in self._sendMsgs(msgs):
1778 yield result
1779
1780
1781 if reqCert:
1782 if self.version == (3,0):
1783 for result in self._getMsg((ContentType.handshake,
1784 ContentType.alert),
1785 HandshakeType.certificate,
1786 CertificateType.x509):
1787 if result in (0,1): yield result
1788 else: break
1789 msg = result
1790
1791 if isinstance(msg, Alert):
1792
1793 alert = msg
1794 if alert.description != \
1795 AlertDescription.no_certificate:
1796 self._shutdown(False)
1797 raise TLSRemoteAlert(alert)
1798 elif isinstance(msg, Certificate):
1799 clientCertificate = msg
1800 if clientCertificate.certChain and \
1801 clientCertificate.certChain.getNumCerts()!=0:
1802 clientCertChain = clientCertificate.certChain
1803 else:
1804 raise AssertionError()
1805 elif self.version in ((3,1), (3,2), (3,3)):
1806 for result in self._getMsg(ContentType.handshake,
1807 HandshakeType.certificate,
1808 CertificateType.x509):
1809 if result in (0,1): yield result
1810 else: break
1811 clientCertificate = result
1812 if clientCertificate.certChain and \
1813 clientCertificate.certChain.getNumCerts()!=0:
1814 clientCertChain = clientCertificate.certChain
1815 else:
1816 raise AssertionError()
1817
1818
1819 for result in self._getMsg(ContentType.handshake,
1820 HandshakeType.client_key_exchange,
1821 cipherSuite):
1822 if result in (0,1): yield result
1823 else: break
1824 clientKeyExchange = result
1825
1826
1827 try:
1828 premasterSecret = \
1829 keyExchange.processClientKeyExchange(clientKeyExchange)
1830 except TLSLocalAlert as alert:
1831 for result in self._sendError(alert.description, alert.message):
1832 yield result
1833
1834
1835 if clientCertChain:
1836 if self.version == (3,0):
1837 masterSecret = calcMasterSecret(self.version,
1838 cipherSuite,
1839 premasterSecret,
1840 clientHello.random,
1841 serverHello.random)
1842 verifyBytes = self._handshake_hash.digestSSL(masterSecret, b"")
1843 elif self.version in ((3,1), (3,2)):
1844 verifyBytes = self._handshake_hash.digest()
1845 elif self.version == (3,3):
1846 verifyBytes = self._handshake_hash.digest('sha1')
1847 verifyBytes = RSAKey.addPKCS1SHA1Prefix(verifyBytes)
1848 for result in self._getMsg(ContentType.handshake,
1849 HandshakeType.certificate_verify):
1850 if result in (0,1): yield result
1851 else: break
1852 certificateVerify = result
1853 publicKey = clientCertChain.getEndEntityPublicKey()
1854 if len(publicKey) < settings.minKeySize:
1855 for result in self._sendError(\
1856 AlertDescription.handshake_failure,
1857 "Client's public key too small: %d" % len(publicKey)):
1858 yield result
1859
1860 if len(publicKey) > settings.maxKeySize:
1861 for result in self._sendError(\
1862 AlertDescription.handshake_failure,
1863 "Client's public key too large: %d" % len(publicKey)):
1864 yield result
1865
1866 if not publicKey.verify(certificateVerify.signature, verifyBytes):
1867 for result in self._sendError(\
1868 AlertDescription.decrypt_error,
1869 "Signature failed to verify"):
1870 yield result
1871 yield (premasterSecret, clientCertChain)
1872
1873
1876
1877
1878 dh_g, dh_p = goodGroupParameters[2]
1879 dh_Xs = bytesToNumber(getRandomBytes(32))
1880 dh_Ys = powMod(dh_g, dh_Xs, dh_p)
1881
1882
1883 serverKeyExchange = ServerKeyExchange(cipherSuite, self.version)
1884 serverKeyExchange.createDH(dh_p, dh_g, dh_Ys)
1885
1886
1887
1888 msgs = []
1889 msgs.append(serverHello)
1890 msgs.append(serverKeyExchange)
1891 msgs.append(ServerHelloDone())
1892 for result in self._sendMsgs(msgs):
1893 yield result
1894
1895
1896 for result in self._getMsg(ContentType.handshake,
1897 HandshakeType.client_key_exchange,
1898 cipherSuite):
1899 if result in (0,1):
1900 yield result
1901 else:
1902 break
1903 clientKeyExchange = result
1904 dh_Yc = clientKeyExchange.dh_Yc
1905
1906 if dh_Yc % dh_p == 0:
1907 for result in self._sendError(AlertDescription.illegal_parameter,
1908 "Suspicious dh_Yc value"):
1909 yield result
1910 assert(False)
1911
1912
1913 S = powMod(dh_Yc,dh_Xs,dh_p)
1914 premasterSecret = numberToByteArray(S)
1915
1916 yield premasterSecret
1917
1918
1919 - def _serverFinished(self, premasterSecret, clientRandom, serverRandom,
1920 cipherSuite, cipherImplementations, nextProtos):
1921 masterSecret = calcMasterSecret(self.version,
1922 cipherSuite,
1923 premasterSecret,
1924 clientRandom,
1925 serverRandom)
1926
1927
1928 self._calcPendingStates(cipherSuite, masterSecret,
1929 clientRandom, serverRandom,
1930 cipherImplementations)
1931
1932
1933 for result in self._getFinished(masterSecret,
1934 cipherSuite,
1935 expect_next_protocol=nextProtos is not None):
1936 yield result
1937
1938 for result in self._sendFinished(masterSecret, cipherSuite):
1939 yield result
1940
1941 yield masterSecret
1942
1943
1944
1945
1946
1947
1948
1949 - def _sendFinished(self, masterSecret, cipherSuite=None, nextProto=None):
1975
1976 - def _getFinished(self, masterSecret, cipherSuite=None,
1977 expect_next_protocol=False, nextProto=None):
1978
1979 for result in self._getMsg(ContentType.change_cipher_spec):
1980 if result in (0,1):
1981 yield result
1982 changeCipherSpec = result
1983
1984 if changeCipherSpec.type != 1:
1985 for result in self._sendError(AlertDescription.illegal_parameter,
1986 "ChangeCipherSpec type incorrect"):
1987 yield result
1988
1989
1990 self._changeReadState()
1991
1992
1993 if expect_next_protocol:
1994 for result in self._getMsg(ContentType.handshake, HandshakeType.next_protocol):
1995 if result in (0,1):
1996 yield result
1997 if result is None:
1998 for result in self._sendError(AlertDescription.unexpected_message,
1999 "Didn't get NextProtocol message"):
2000 yield result
2001
2002 self.next_proto = result.next_proto
2003 else:
2004 self.next_proto = None
2005
2006
2007 if nextProto:
2008 self.next_proto = nextProto
2009
2010
2011 verifyData = calcFinished(self.version,
2012 masterSecret,
2013 cipherSuite,
2014 self._handshake_hash,
2015 not self._client)
2016
2017
2018 for result in self._getMsg(ContentType.handshake,
2019 HandshakeType.finished):
2020 if result in (0,1):
2021 yield result
2022 finished = result
2023 if finished.verify_data != verifyData:
2024 for result in self._sendError(AlertDescription.decrypt_error,
2025 "Finished message is incorrect"):
2026 yield result
2027
2053