1
2
3
4
5
6
7
8
9
10
11
12
13
14 """
15 MAIN CLASS FOR TLS LITE (START HERE!).
16 """
17
18 from __future__ import division
19 import socket
20 from .utils.compat import formatExceptionTrace
21 from .tlsrecordlayer import TLSRecordLayer
22 from .session import Session
23 from .constants import *
24 from .utils.cryptomath import getRandomBytes
25 from .errors import *
26 from .messages import *
27 from .mathtls import *
28 from .handshakesettings import HandshakeSettings
29 from .utils.tackwrapper import *
30 from .keyexchange import KeyExchange, RSAKeyExchange, DHE_RSAKeyExchange, \
31 ECDHE_RSAKeyExchange, SRPKeyExchange, ADHKeyExchange, AECDHKeyExchange
32 from .handshakehelpers import HandshakeHelpers
35 """
36 This class wraps a socket and provides TLS handshaking and data transfer.
37
38 To use this class, create a new instance, passing a connected
39 socket into the constructor. Then call some handshake function.
40 If the handshake completes without raising an exception, then a TLS
41 connection has been negotiated. You can transfer data over this
42 connection as if it were a socket.
43
44 This class provides both synchronous and asynchronous versions of
45 its key functions. The synchronous versions should be used when
46 writing single-or multi-threaded code using blocking sockets. The
47 asynchronous versions should be used when performing asynchronous,
48 event-based I/O with non-blocking sockets.
49
50 Asynchronous I/O is a complicated subject; typically, you should
51 not use the asynchronous functions directly, but should use some
52 framework like asyncore or Twisted which TLS Lite integrates with
53 (see
54 L{tlslite.integration.tlsasyncdispatchermixin.TLSAsyncDispatcherMixIn}).
55 """
56
58 """Create a new TLSConnection instance.
59
60 @param sock: The socket data will be transmitted on. The
61 socket should already be connected. It may be in blocking or
62 non-blocking mode.
63
64 @type sock: L{socket.socket}
65 """
66 TLSRecordLayer.__init__(self, sock)
67 self.serverSigAlg = None
68 self.ecdhCurve = None
69 self.dhGroupSize = None
70 self.extendedMasterSecret = False
71 self._clientRandom = bytearray(0)
72 self._serverRandom = bytearray(0)
73
75 """Return keying material as described in RFC 5705
76
77 @type label: bytearray
78 @param label: label to be provided for the exporter
79
80 @type length: int
81 @param length: number of bytes of the keying material to export
82 """
83 if label in (b'server finished', b'client finished',
84 b'master secret', b'key expansion'):
85 raise ValueError("Forbidden label value")
86 if self.version < (3, 1):
87 raise ValueError("Supported only in TLSv1.0 and later")
88 elif self.version < (3, 3):
89 return PRF(self.session.masterSecret, label,
90 self._clientRandom + self._serverRandom,
91 length)
92 elif self.version == (3, 3):
93 if self.session.cipherSuite in CipherSuite.sha384PrfSuites:
94 return PRF_1_2_SHA384(self.session.masterSecret, label,
95 self._clientRandom + self._serverRandom,
96 length)
97 else:
98 return PRF_1_2(self.session.masterSecret, label,
99 self._clientRandom + self._serverRandom,
100 length)
101 else:
102 raise AssertionError("Unknown protocol version")
103
104
105
106
107
111 """Perform an anonymous handshake in the role of client.
112
113 This function performs an SSL or TLS handshake using an
114 anonymous Diffie Hellman ciphersuite.
115
116 Like any handshake function, this can be called on a closed
117 TLS connection, or on a TLS connection that is already open.
118 If called on an open connection it performs a re-handshake.
119
120 If the function completes without raising an exception, the
121 TLS connection will be open and available for data transfer.
122
123 If an exception is raised, the connection will have been
124 automatically closed (if it was ever open).
125
126 @type session: L{tlslite.Session.Session}
127 @param session: A TLS session to attempt to resume. If the
128 resumption does not succeed, a full handshake will be
129 performed.
130
131 @type settings: L{tlslite.HandshakeSettings.HandshakeSettings}
132 @param settings: Various settings which can be used to control
133 the ciphersuites, certificate types, and SSL/TLS versions
134 offered by the client.
135
136 @type checker: L{tlslite.Checker.Checker}
137 @param checker: A Checker instance. This instance will be
138 invoked to examine the other party's authentication
139 credentials, if the handshake completes succesfully.
140
141 @type serverName: string
142 @param serverName: The ServerNameIndication TLS Extension.
143
144 @type async: bool
145 @param async: If False, this function will block until the
146 handshake is completed. If True, this function will return a
147 generator. Successive invocations of the generator will
148 return 0 if it is waiting to read from the socket, 1 if it is
149 waiting to write to the socket, or will raise StopIteration if
150 the handshake operation is completed.
151
152 @rtype: None or an iterable
153 @return: If 'async' is True, a generator object will be
154 returned.
155
156 @raise socket.error: If a socket error occurs.
157 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
158 without a preceding alert.
159 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
160 @raise tlslite.errors.TLSAuthenticationError: If the checker
161 doesn't like the other party's authentication credentials.
162 """
163 handshaker = self._handshakeClientAsync(anonParams=(True),
164 session=session,
165 settings=settings,
166 checker=checker,
167 serverName=serverName)
168 if async:
169 return handshaker
170 for result in handshaker:
171 pass
172
173 - def handshakeClientSRP(self, username, password, session=None,
174 settings=None, checker=None,
175 reqTack=True, serverName=None,
176 async=False):
177 """Perform an SRP handshake in the role of client.
178
179 This function performs a TLS/SRP handshake. SRP mutually
180 authenticates both parties to each other using only a
181 username and password. This function may also perform a
182 combined SRP and server-certificate handshake, if the server
183 chooses to authenticate itself with a certificate chain in
184 addition to doing SRP.
185
186 If the function completes without raising an exception, the
187 TLS connection will be open and available for data transfer.
188
189 If an exception is raised, the connection will have been
190 automatically closed (if it was ever open).
191
192 @type username: bytearray
193 @param username: The SRP username.
194
195 @type password: bytearray
196 @param password: The SRP password.
197
198 @type session: L{tlslite.session.Session}
199 @param session: A TLS session to attempt to resume. This
200 session must be an SRP session performed with the same username
201 and password as were passed in. If the resumption does not
202 succeed, a full SRP handshake will be performed.
203
204 @type settings: L{tlslite.handshakesettings.HandshakeSettings}
205 @param settings: Various settings which can be used to control
206 the ciphersuites, certificate types, and SSL/TLS versions
207 offered by the client.
208
209 @type checker: L{tlslite.checker.Checker}
210 @param checker: A Checker instance. This instance will be
211 invoked to examine the other party's authentication
212 credentials, if the handshake completes succesfully.
213
214 @type reqTack: bool
215 @param reqTack: Whether or not to send a "tack" TLS Extension,
216 requesting the server return a TackExtension if it has one.
217
218 @type serverName: string
219 @param serverName: The ServerNameIndication TLS Extension.
220
221 @type async: bool
222 @param async: If False, this function will block until the
223 handshake is completed. If True, this function will return a
224 generator. Successive invocations of the generator will
225 return 0 if it is waiting to read from the socket, 1 if it is
226 waiting to write to the socket, or will raise StopIteration if
227 the handshake operation is completed.
228
229 @rtype: None or an iterable
230 @return: If 'async' is True, a generator object will be
231 returned.
232
233 @raise socket.error: If a socket error occurs.
234 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
235 without a preceding alert.
236 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
237 @raise tlslite.errors.TLSAuthenticationError: If the checker
238 doesn't like the other party's authentication credentials.
239 """
240
241 if isinstance(username, str):
242 username = bytearray(username, 'utf-8')
243 if isinstance(password, str):
244 password = bytearray(password, 'utf-8')
245 handshaker = self._handshakeClientAsync(srpParams=(username, password),
246 session=session, settings=settings, checker=checker,
247 reqTack=reqTack, serverName=serverName)
248
249
250
251
252
253
254
255 if async:
256 return handshaker
257 for result in handshaker:
258 pass
259
260 - def handshakeClientCert(self, certChain=None, privateKey=None,
261 session=None, settings=None, checker=None,
262 nextProtos=None, reqTack=True, serverName=None,
263 async=False, alpn=None):
264 """Perform a certificate-based handshake in the role of client.
265
266 This function performs an SSL or TLS handshake. The server
267 will authenticate itself using an X.509 certificate
268 chain. If the handshake succeeds, the server's certificate
269 chain will be stored in the session's serverCertChain attribute.
270 Unless a checker object is passed in, this function does no
271 validation or checking of the server's certificate chain.
272
273 If the server requests client authentication, the
274 client will send the passed-in certificate chain, and use the
275 passed-in private key to authenticate itself. If no
276 certificate chain and private key were passed in, the client
277 will attempt to proceed without client authentication. The
278 server may or may not allow this.
279
280 If the function completes without raising an exception, the
281 TLS connection will be open and available for data transfer.
282
283 If an exception is raised, the connection will have been
284 automatically closed (if it was ever open).
285
286 @type certChain: L{tlslite.x509certchain.X509CertChain}
287 @param certChain: The certificate chain to be used if the
288 server requests client authentication.
289
290 @type privateKey: L{tlslite.utils.rsakey.RSAKey}
291 @param privateKey: The private key to be used if the server
292 requests client authentication.
293
294 @type session: L{tlslite.session.Session}
295 @param session: A TLS session to attempt to resume. If the
296 resumption does not succeed, a full handshake will be
297 performed.
298
299 @type settings: L{tlslite.handshakesettings.HandshakeSettings}
300 @param settings: Various settings which can be used to control
301 the ciphersuites, certificate types, and SSL/TLS versions
302 offered by the client.
303
304 @type checker: L{tlslite.checker.Checker}
305 @param checker: A Checker instance. This instance will be
306 invoked to examine the other party's authentication
307 credentials, if the handshake completes succesfully.
308
309 @type nextProtos: list of strings.
310 @param nextProtos: A list of upper layer protocols ordered by
311 preference, to use in the Next-Protocol Negotiation Extension.
312
313 @type reqTack: bool
314 @param reqTack: Whether or not to send a "tack" TLS Extension,
315 requesting the server return a TackExtension if it has one.
316
317 @type serverName: string
318 @param serverName: The ServerNameIndication TLS Extension.
319
320 @type async: bool
321 @param async: If False, this function will block until the
322 handshake is completed. If True, this function will return a
323 generator. Successive invocations of the generator will
324 return 0 if it is waiting to read from the socket, 1 if it is
325 waiting to write to the socket, or will raise StopIteration if
326 the handshake operation is completed.
327
328 @type alpn: list of bytearrays
329 @param alpn: protocol names to advertise to server as supported by
330 client in the Application Layer Protocol Negotiation extension.
331 Example items in the array include b'http/1.1' or b'h2'.
332
333 @rtype: None or an iterable
334 @return: If 'async' is True, a generator object will be
335 returned.
336
337 @raise socket.error: If a socket error occurs.
338 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
339 without a preceding alert.
340 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
341 @raise tlslite.errors.TLSAuthenticationError: If the checker
342 doesn't like the other party's authentication credentials.
343 """
344 handshaker = \
345 self._handshakeClientAsync(certParams=(certChain, privateKey),
346 session=session, settings=settings,
347 checker=checker,
348 serverName=serverName,
349 nextProtos=nextProtos,
350 reqTack=reqTack,
351 alpn=alpn)
352
353
354
355
356
357
358
359 if async:
360 return handshaker
361 for result in handshaker:
362 pass
363
364
365 - def _handshakeClientAsync(self, srpParams=(), certParams=(), anonParams=(),
366 session=None, settings=None, checker=None,
367 nextProtos=None, serverName=None, reqTack=True,
368 alpn=None):
381
382
383 - def _handshakeClientAsyncHelper(self, srpParams, certParams, anonParams,
384 session, settings, serverName, nextProtos,
385 reqTack, alpn):
386
387 self._handshakeStart(client=True)
388
389
390 srpUsername = None
391 password = None
392 clientCertChain = None
393 privateKey = None
394
395
396 if srpParams:
397 assert(not certParams)
398 assert(not anonParams)
399 srpUsername, password = srpParams
400 if certParams:
401 assert(not srpParams)
402 assert(not anonParams)
403 clientCertChain, privateKey = certParams
404 if anonParams:
405 assert(not srpParams)
406 assert(not certParams)
407
408
409 if srpUsername and not password:
410 raise ValueError("Caller passed a username but no password")
411 if password and not srpUsername:
412 raise ValueError("Caller passed a password but no username")
413 if clientCertChain and not privateKey:
414 raise ValueError("Caller passed a certChain but no privateKey")
415 if privateKey and not clientCertChain:
416 raise ValueError("Caller passed a privateKey but no certChain")
417 if reqTack:
418 if not tackpyLoaded:
419 reqTack = False
420 if not settings or not settings.useExperimentalTackExtension:
421 reqTack = False
422 if nextProtos is not None:
423 if len(nextProtos) == 0:
424 raise ValueError("Caller passed no nextProtos")
425 if alpn is not None and not alpn:
426 raise ValueError("Caller passed empty alpn list")
427
428
429
430 if not settings:
431 settings = HandshakeSettings()
432 settings = settings.validate()
433
434 if clientCertChain:
435 if not isinstance(clientCertChain, X509CertChain):
436 raise ValueError("Unrecognized certificate type")
437 if "x509" not in settings.certificateTypes:
438 raise ValueError("Client certificate doesn't match "\
439 "Handshake Settings")
440
441 if session:
442
443
444 if not session.valid():
445 session = None
446 elif session.resumable:
447 if session.srpUsername != srpUsername:
448 raise ValueError("Session username doesn't match")
449 if session.serverName != serverName:
450 raise ValueError("Session servername doesn't match")
451
452
453 if srpUsername and self.fault == Fault.badUsername:
454 srpUsername += bytearray(b"GARBAGE")
455 if password and self.fault == Fault.badPassword:
456 password += bytearray(b"GARBAGE")
457
458
459
460
461 self.version = settings.maxVersion
462
463
464
465
466
467 for result in self._clientSendClientHello(settings, session,
468 srpUsername, srpParams, certParams,
469 anonParams, serverName, nextProtos,
470 reqTack, alpn):
471 if result in (0,1): yield result
472 else: break
473 clientHello = result
474
475
476 for result in self._clientGetServerHello(settings, clientHello):
477 if result in (0,1): yield result
478 else: break
479 serverHello = result
480 cipherSuite = serverHello.cipher_suite
481
482
483
484 nextProto = self._clientSelectNextProto(nextProtos, serverHello)
485
486
487 if serverHello.getExtension(ExtensionType.encrypt_then_mac):
488 self._recordLayer.encryptThenMAC = True
489
490 if serverHello.getExtension(ExtensionType.extended_master_secret):
491 self.extendedMasterSecret = True
492
493
494 for result in self._clientResume(session, serverHello,
495 clientHello.random,
496 settings.cipherImplementations,
497 nextProto):
498 if result in (0,1): yield result
499 else: break
500 if result == "resumed_and_finished":
501 self._handshakeDone(resumed=True)
502 self._serverRandom = serverHello.random
503 self._clientRandom = clientHello.random
504
505
506 alpnExt = serverHello.getExtension(ExtensionType.alpn)
507 if alpnExt:
508 session.appProto = alpnExt.protocol_names[0]
509 return
510
511
512
513
514 if cipherSuite in CipherSuite.srpAllSuites:
515 keyExchange = SRPKeyExchange(cipherSuite, clientHello,
516 serverHello, None, None,
517 srpUsername=srpUsername,
518 password=password,
519 settings=settings)
520
521
522
523 elif cipherSuite in CipherSuite.dhAllSuites:
524 keyExchange = DHE_RSAKeyExchange(cipherSuite, clientHello,
525 serverHello, None)
526
527 elif cipherSuite in CipherSuite.ecdhAllSuites:
528 acceptedCurves = self._curveNamesToList(settings)
529 keyExchange = ECDHE_RSAKeyExchange(cipherSuite, clientHello,
530 serverHello, None,
531 acceptedCurves)
532
533
534
535
536
537
538
539 else:
540 keyExchange = RSAKeyExchange(cipherSuite, clientHello,
541 serverHello, None)
542
543
544 self.sock.buffer_writes = True
545 for result in self._clientKeyExchange(settings, cipherSuite,
546 clientCertChain,
547 privateKey,
548 serverHello.certificate_type,
549 serverHello.tackExt,
550 clientHello.random,
551 serverHello.random,
552 keyExchange):
553 if result in (0, 1):
554 yield result
555 else: break
556 (premasterSecret, serverCertChain, clientCertChain,
557 tackExt) = result
558
559
560
561
562 for result in self._clientFinished(premasterSecret,
563 clientHello.random,
564 serverHello.random,
565 cipherSuite, settings.cipherImplementations,
566 nextProto):
567 if result in (0,1): yield result
568 else: break
569 masterSecret = result
570
571
572 alpnProto = None
573 alpnExt = serverHello.getExtension(ExtensionType.alpn)
574 if alpnExt:
575 alpnProto = alpnExt.protocol_names[0]
576
577
578 self.session = Session()
579 self.session.create(masterSecret, serverHello.session_id, cipherSuite,
580 srpUsername, clientCertChain, serverCertChain,
581 tackExt, (serverHello.tackExt is not None),
582 serverName,
583 encryptThenMAC=self._recordLayer.encryptThenMAC,
584 extendedMasterSecret=self.extendedMasterSecret,
585 appProto=alpnProto)
586 self._handshakeDone(resumed=False)
587 self._serverRandom = serverHello.random
588 self._clientRandom = clientHello.random
589
590
591 - def _clientSendClientHello(self, settings, session, srpUsername,
592 srpParams, certParams, anonParams,
593 serverName, nextProtos, reqTack, alpn):
594
595 cipherSuites = [CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
596 if srpParams:
597 cipherSuites += CipherSuite.getSrpAllSuites(settings)
598 elif certParams:
599 cipherSuites += CipherSuite.getEcdheCertSuites(settings)
600 cipherSuites += CipherSuite.getDheCertSuites(settings)
601 cipherSuites += CipherSuite.getCertSuites(settings)
602 elif anonParams:
603 cipherSuites += CipherSuite.getEcdhAnonSuites(settings)
604 cipherSuites += CipherSuite.getAnonSuites(settings)
605 else:
606 assert False
607
608
609
610 wireCipherSuites = list(cipherSuites)
611 if settings.sendFallbackSCSV:
612 wireCipherSuites.append(CipherSuite.TLS_FALLBACK_SCSV)
613
614
615 certificateTypes = settings.getCertificateTypes()
616
617 extensions = []
618
619
620 if settings.useEncryptThenMAC:
621 extensions.append(TLSExtension().\
622 create(ExtensionType.encrypt_then_mac,
623 bytearray(0)))
624 if settings.useExtendedMasterSecret:
625 extensions.append(TLSExtension().create(ExtensionType.
626 extended_master_secret,
627 bytearray(0)))
628 groups = []
629
630 if next((cipher for cipher in cipherSuites \
631 if cipher in CipherSuite.ecdhAllSuites), None) is not None:
632 groups.extend(self._curveNamesToList(settings))
633 extensions.append(ECPointFormatsExtension().\
634 create([ECPointFormat.uncompressed]))
635
636 if next((cipher for cipher in cipherSuites
637 if cipher in CipherSuite.dhAllSuites), None) is not None:
638 groups.extend(self._groupNamesToList(settings))
639
640 if groups:
641 extensions.append(SupportedGroupsExtension().create(groups))
642
643 if settings.maxVersion >= (3, 3):
644 sigList = self._sigHashesToList(settings)
645 assert len(sigList) > 0
646 extensions.append(SignatureAlgorithmsExtension().\
647 create(sigList))
648
649 if alpn:
650 extensions.append(ALPNExtension().create(alpn))
651
652 if not extensions or settings.maxVersion == (3, 0):
653 extensions = None
654
655
656 if session and session.sessionID:
657
658
659 if session.cipherSuite not in cipherSuites:
660 raise ValueError("Session's cipher suite not consistent "\
661 "with parameters")
662 else:
663 clientHello = ClientHello()
664 clientHello.create(settings.maxVersion, getRandomBytes(32),
665 session.sessionID, wireCipherSuites,
666 certificateTypes,
667 session.srpUsername,
668 reqTack, nextProtos is not None,
669 session.serverName,
670 extensions=extensions)
671
672
673 else:
674 clientHello = ClientHello()
675 clientHello.create(settings.maxVersion, getRandomBytes(32),
676 bytearray(0), wireCipherSuites,
677 certificateTypes,
678 srpUsername,
679 reqTack, nextProtos is not None,
680 serverName,
681 extensions=extensions)
682
683
684
685 if settings.usePaddingExtension:
686 HandshakeHelpers.alignClientHelloPadding(clientHello)
687
688 for result in self._sendMsg(clientHello):
689 yield result
690 yield clientHello
691
692
694 for result in self._getMsg(ContentType.handshake,
695 HandshakeType.server_hello):
696 if result in (0,1): yield result
697 else: break
698 serverHello = result
699
700
701
702 self.version = serverHello.server_version
703
704
705 if serverHello.server_version < settings.minVersion:
706 for result in self._sendError(\
707 AlertDescription.protocol_version,
708 "Too old version: %s" % str(serverHello.server_version)):
709 yield result
710 if serverHello.server_version > settings.maxVersion:
711 for result in self._sendError(\
712 AlertDescription.protocol_version,
713 "Too new version: %s" % str(serverHello.server_version)):
714 yield result
715 serverVer = serverHello.server_version
716 cipherSuites = CipherSuite.filterForVersion(clientHello.cipher_suites,
717 minVersion=serverVer,
718 maxVersion=serverVer)
719 if serverHello.cipher_suite not in cipherSuites:
720 for result in self._sendError(\
721 AlertDescription.illegal_parameter,
722 "Server responded with incorrect ciphersuite"):
723 yield result
724 if serverHello.certificate_type not in clientHello.certificate_types:
725 for result in self._sendError(\
726 AlertDescription.illegal_parameter,
727 "Server responded with incorrect certificate type"):
728 yield result
729 if serverHello.compression_method != 0:
730 for result in self._sendError(\
731 AlertDescription.illegal_parameter,
732 "Server responded with incorrect compression method"):
733 yield result
734 if serverHello.tackExt:
735 if not clientHello.tack:
736 for result in self._sendError(\
737 AlertDescription.illegal_parameter,
738 "Server responded with unrequested Tack Extension"):
739 yield result
740 if not serverHello.tackExt.verifySignatures():
741 for result in self._sendError(\
742 AlertDescription.decrypt_error,
743 "TackExtension contains an invalid signature"):
744 yield result
745 if serverHello.next_protos and not clientHello.supports_npn:
746 for result in self._sendError(\
747 AlertDescription.illegal_parameter,
748 "Server responded with unrequested NPN Extension"):
749 yield result
750 if not serverHello.getExtension(ExtensionType.extended_master_secret)\
751 and settings.requireExtendedMasterSecret:
752 for result in self._sendError(
753 AlertDescription.insufficient_security,
754 "Negotiation of Extended master Secret failed"):
755 yield result
756 alpnExt = serverHello.getExtension(ExtensionType.alpn)
757 if alpnExt:
758 if not alpnExt.protocol_names or \
759 len(alpnExt.protocol_names) != 1:
760 for result in self._sendError(
761 AlertDescription.illegal_parameter,
762 "Server responded with invalid ALPN extension"):
763 yield result
764 clntAlpnExt = clientHello.getExtension(ExtensionType.alpn)
765 if not clntAlpnExt:
766 for result in self._sendError(
767 AlertDescription.unsupported_extension,
768 "Server sent ALPN extension without one in "
769 "client hello"):
770 yield result
771 if alpnExt.protocol_names[0] not in clntAlpnExt.protocol_names:
772 for result in self._sendError(
773 AlertDescription.illegal_parameter,
774 "Server selected ALPN protocol we did not advertise"):
775 yield result
776 yield serverHello
777
779
780
781
782
783
784
785
786 if nextProtos is not None and serverHello.next_protos is not None:
787 for p in nextProtos:
788 if bytearray(p) in serverHello.next_protos:
789 return bytearray(p)
790 else:
791
792
793
794 return bytearray(nextProtos[0])
795 return None
796
797 - def _clientResume(self, session, serverHello, clientRandom,
798 cipherImplementations, nextProto):
831
832 - def _clientKeyExchange(self, settings, cipherSuite,
833 clientCertChain, privateKey,
834 certificateType,
835 tackExt, clientRandom, serverRandom,
836 keyExchange):
837 """Perform the client side of key exchange"""
838
839 if cipherSuite in CipherSuite.certAllSuites:
840 for result in self._getMsg(ContentType.handshake,
841 HandshakeType.certificate,
842 certificateType):
843 if result in (0, 1):
844 yield result
845 else: break
846 serverCertificate = result
847 else:
848 serverCertificate = None
849
850 if cipherSuite not in CipherSuite.certSuites:
851 for result in self._getMsg(ContentType.handshake,
852 HandshakeType.server_key_exchange,
853 cipherSuite):
854 if result in (0, 1):
855 yield result
856 else: break
857 serverKeyExchange = result
858 else:
859 serverKeyExchange = None
860
861 for result in self._getMsg(ContentType.handshake,
862 (HandshakeType.certificate_request,
863 HandshakeType.server_hello_done)):
864 if result in (0, 1):
865 yield result
866 else: break
867
868 certificateRequest = None
869 if isinstance(result, CertificateRequest):
870 certificateRequest = result
871
872
873 if cipherSuite not in CipherSuite.certAllSuites \
874 or cipherSuite in CipherSuite.srpAllSuites:
875 for result in self._sendError(\
876 AlertDescription.unexpected_message,
877 "Certificate Request with incompatible cipher suite"):
878 yield result
879
880
881 for result in self._getMsg(ContentType.handshake,
882 HandshakeType.server_hello_done):
883 if result in (0, 1):
884 yield result
885 else: break
886 serverHelloDone = result
887
888 serverCertChain = None
889 publicKey = None
890 if cipherSuite in CipherSuite.certAllSuites:
891
892 for result in self._clientGetKeyFromChain(serverCertificate,
893 settings,
894 tackExt):
895 if result in (0, 1):
896 yield result
897 else: break
898 publicKey, serverCertChain, tackExt = result
899
900
901
902 if serverKeyExchange:
903 validSigAlgs = self._sigHashesToList(settings)
904 try:
905 KeyExchange.verifyServerKeyExchange(serverKeyExchange,
906 publicKey,
907 clientRandom,
908 serverRandom,
909 validSigAlgs)
910 except TLSIllegalParameterException:
911 for result in self._sendError(AlertDescription.\
912 illegal_parameter):
913 yield result
914 except TLSDecryptionFailed:
915 for result in self._sendError(\
916 AlertDescription.decrypt_error):
917 yield result
918
919 if serverKeyExchange:
920
921 if self.version >= (3, 3) \
922 and cipherSuite in CipherSuite.certAllSuites \
923 and cipherSuite not in CipherSuite.certSuites:
924 self.serverSigAlg = (serverKeyExchange.hashAlg,
925 serverKeyExchange.signAlg)
926
927 if cipherSuite in CipherSuite.dhAllSuites:
928 self.dhGroupSize = numBits(serverKeyExchange.dh_p)
929 if cipherSuite in CipherSuite.ecdhAllSuites:
930 self.ecdhCurve = serverKeyExchange.named_curve
931
932
933 if certificateRequest:
934
935
936
937 if self.version == (3, 3)\
938 and not [sig for sig in \
939 certificateRequest.supported_signature_algs\
940 if sig[1] == SignatureAlgorithm.rsa]:
941 for result in self._sendError(\
942 AlertDescription.handshake_failure,
943 "Server doesn't accept any sigalgs we support: " +
944 str(certificateRequest.supported_signature_algs)):
945 yield result
946 clientCertificate = Certificate(certificateType)
947
948 if clientCertChain:
949
950
951 if certificateType == CertificateType.x509 \
952 and not isinstance(clientCertChain, X509CertChain):
953 for result in self._sendError(\
954 AlertDescription.handshake_failure,
955 "Client certificate is of wrong type"):
956 yield result
957
958 clientCertificate.create(clientCertChain)
959
960 for result in self._sendMsg(clientCertificate):
961 yield result
962 else:
963
964 privateKey = None
965 clientCertChain = None
966
967 try:
968 ske = serverKeyExchange
969 premasterSecret = keyExchange.processServerKeyExchange(publicKey,
970 ske)
971 except TLSInsufficientSecurity as e:
972 for result in self._sendError(\
973 AlertDescription.insufficient_security, e):
974 yield result
975 except TLSIllegalParameterException as e:
976 for result in self._sendError(\
977 AlertDescription.illegal_parameter, e):
978 yield result
979
980 clientKeyExchange = keyExchange.makeClientKeyExchange()
981
982
983 for result in self._sendMsg(clientKeyExchange):
984 yield result
985
986
987
988 if certificateRequest and privateKey:
989 validSigAlgs = self._sigHashesToList(settings)
990 try:
991 certificateVerify = KeyExchange.makeCertificateVerify(
992 self.version,
993 self._handshake_hash,
994 validSigAlgs,
995 privateKey,
996 certificateRequest,
997 premasterSecret,
998 clientRandom,
999 serverRandom)
1000 except TLSInternalError as exception:
1001 for result in self._sendError(
1002 AlertDescription.internal_error, exception):
1003 yield result
1004 for result in self._sendMsg(certificateVerify):
1005 yield result
1006
1007 yield (premasterSecret, serverCertChain, clientCertChain, tackExt)
1008
1009 - def _clientFinished(self, premasterSecret, clientRandom, serverRandom,
1010 cipherSuite, cipherImplementations, nextProto):
1011 if self.extendedMasterSecret:
1012 masterSecret = calcExtendedMasterSecret(self.version,
1013 cipherSuite,
1014 premasterSecret,
1015 self._handshake_hash)
1016 else:
1017 masterSecret = calcMasterSecret(self.version,
1018 cipherSuite,
1019 premasterSecret,
1020 clientRandom,
1021 serverRandom)
1022 self._calcPendingStates(cipherSuite, masterSecret,
1023 clientRandom, serverRandom,
1024 cipherImplementations)
1025
1026
1027 for result in self._sendFinished(masterSecret, cipherSuite, nextProto):
1028 yield result
1029 self.sock.flush()
1030 self.sock.buffer_writes = False
1031 for result in self._getFinished(masterSecret,
1032 cipherSuite,
1033 nextProto=nextProto):
1034 yield result
1035 yield masterSecret
1036
1073
1074
1075
1076
1077
1078
1079
1080 - def handshakeServer(self, verifierDB=None,
1081 certChain=None, privateKey=None, reqCert=False,
1082 sessionCache=None, settings=None, checker=None,
1083 reqCAs = None,
1084 tacks=None, activationFlags=0,
1085 nextProtos=None, anon=False, alpn=None):
1086 """Perform a handshake in the role of server.
1087
1088 This function performs an SSL or TLS handshake. Depending on
1089 the arguments and the behavior of the client, this function can
1090 perform an SRP, or certificate-based handshake. It
1091 can also perform a combined SRP and server-certificate
1092 handshake.
1093
1094 Like any handshake function, this can be called on a closed
1095 TLS connection, or on a TLS connection that is already open.
1096 If called on an open connection it performs a re-handshake.
1097 This function does not send a Hello Request message before
1098 performing the handshake, so if re-handshaking is required,
1099 the server must signal the client to begin the re-handshake
1100 through some other means.
1101
1102 If the function completes without raising an exception, the
1103 TLS connection will be open and available for data transfer.
1104
1105 If an exception is raised, the connection will have been
1106 automatically closed (if it was ever open).
1107
1108 @type verifierDB: L{tlslite.verifierdb.VerifierDB}
1109 @param verifierDB: A database of SRP password verifiers
1110 associated with usernames. If the client performs an SRP
1111 handshake, the session's srpUsername attribute will be set.
1112
1113 @type certChain: L{tlslite.x509certchain.X509CertChain}
1114 @param certChain: The certificate chain to be used if the
1115 client requests server certificate authentication.
1116
1117 @type privateKey: L{tlslite.utils.rsakey.RSAKey}
1118 @param privateKey: The private key to be used if the client
1119 requests server certificate authentication.
1120
1121 @type reqCert: bool
1122 @param reqCert: Whether to request client certificate
1123 authentication. This only applies if the client chooses server
1124 certificate authentication; if the client chooses SRP
1125 authentication, this will be ignored. If the client
1126 performs a client certificate authentication, the sessions's
1127 clientCertChain attribute will be set.
1128
1129 @type sessionCache: L{tlslite.sessioncache.SessionCache}
1130 @param sessionCache: An in-memory cache of resumable sessions.
1131 The client can resume sessions from this cache. Alternatively,
1132 if the client performs a full handshake, a new session will be
1133 added to the cache.
1134
1135 @type settings: L{tlslite.handshakesettings.HandshakeSettings}
1136 @param settings: Various settings which can be used to control
1137 the ciphersuites and SSL/TLS version chosen by the server.
1138
1139 @type checker: L{tlslite.checker.Checker}
1140 @param checker: A Checker instance. This instance will be
1141 invoked to examine the other party's authentication
1142 credentials, if the handshake completes succesfully.
1143
1144 @type reqCAs: list of L{bytearray} of unsigned bytes
1145 @param reqCAs: A collection of DER-encoded DistinguishedNames that
1146 will be sent along with a certificate request. This does not affect
1147 verification.
1148
1149 @type nextProtos: list of strings.
1150 @param nextProtos: A list of upper layer protocols to expose to the
1151 clients through the Next-Protocol Negotiation Extension,
1152 if they support it.
1153
1154 @type alpn: list of bytearrays
1155 @param alpn: names of application layer protocols supported.
1156 Note that it will be used instead of NPN if both were advertised by
1157 client.
1158
1159 @raise socket.error: If a socket error occurs.
1160 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
1161 without a preceding alert.
1162 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
1163 @raise tlslite.errors.TLSAuthenticationError: If the checker
1164 doesn't like the other party's authentication credentials.
1165 """
1166 for result in self.handshakeServerAsync(verifierDB,
1167 certChain, privateKey, reqCert, sessionCache, settings,
1168 checker, reqCAs,
1169 tacks=tacks, activationFlags=activationFlags,
1170 nextProtos=nextProtos, anon=anon, alpn=alpn):
1171 pass
1172
1173
1174 - def handshakeServerAsync(self, verifierDB=None,
1175 certChain=None, privateKey=None, reqCert=False,
1176 sessionCache=None, settings=None, checker=None,
1177 reqCAs=None,
1178 tacks=None, activationFlags=0,
1179 nextProtos=None, anon=False, alpn=None
1180 ):
1181 """Start a server handshake operation on the TLS connection.
1182
1183 This function returns a generator which behaves similarly to
1184 handshakeServer(). Successive invocations of the generator
1185 will return 0 if it is waiting to read from the socket, 1 if it is
1186 waiting to write to the socket, or it will raise StopIteration
1187 if the handshake operation is complete.
1188
1189 @rtype: iterable
1190 @return: A generator; see above for details.
1191 """
1192 handshaker = self._handshakeServerAsyncHelper(\
1193 verifierDB=verifierDB, certChain=certChain,
1194 privateKey=privateKey, reqCert=reqCert,
1195 sessionCache=sessionCache, settings=settings,
1196 reqCAs=reqCAs,
1197 tacks=tacks, activationFlags=activationFlags,
1198 nextProtos=nextProtos, anon=anon, alpn=alpn)
1199 for result in self._handshakeWrapperAsync(handshaker, checker):
1200 yield result
1201
1202
1203 - def _handshakeServerAsyncHelper(self, verifierDB,
1204 certChain, privateKey, reqCert, sessionCache,
1205 settings, reqCAs,
1206 tacks, activationFlags,
1207 nextProtos, anon, alpn):
1208
1209 self._handshakeStart(client=False)
1210
1211 if (not verifierDB) and (not certChain) and not anon:
1212 raise ValueError("Caller passed no authentication credentials")
1213 if certChain and not privateKey:
1214 raise ValueError("Caller passed a certChain but no privateKey")
1215 if privateKey and not certChain:
1216 raise ValueError("Caller passed a privateKey but no certChain")
1217 if reqCAs and not reqCert:
1218 raise ValueError("Caller passed reqCAs but not reqCert")
1219 if certChain and not isinstance(certChain, X509CertChain):
1220 raise ValueError("Unrecognized certificate type")
1221 if activationFlags and not tacks:
1222 raise ValueError("Nonzero activationFlags requires tacks")
1223 if tacks:
1224 if not tackpyLoaded:
1225 raise ValueError("tackpy is not loaded")
1226 if not settings or not settings.useExperimentalTackExtension:
1227 raise ValueError("useExperimentalTackExtension not enabled")
1228 if alpn is not None and not alpn:
1229 raise ValueError("Empty list of ALPN protocols")
1230
1231 if not settings:
1232 settings = HandshakeSettings()
1233 settings = settings.validate()
1234
1235
1236
1237
1238
1239 for result in self._serverGetClientHello(settings, certChain,
1240 verifierDB, sessionCache,
1241 anon, alpn):
1242 if result in (0,1): yield result
1243 elif result == None:
1244 self._handshakeDone(resumed=True)
1245 return
1246 else: break
1247 (clientHello, cipherSuite) = result
1248
1249
1250
1251
1252 if sessionCache:
1253 sessionID = getRandomBytes(32)
1254 else:
1255 sessionID = bytearray(0)
1256
1257 if not clientHello.supports_npn:
1258 nextProtos = None
1259
1260 alpnExt = clientHello.getExtension(ExtensionType.alpn)
1261 if alpnExt and alpn:
1262
1263 nextProtos = None
1264
1265
1266 if not cipherSuite in CipherSuite.certAllSuites:
1267 tacks = None
1268
1269
1270 if clientHello.tack:
1271 tackExt = TackExtension.create(tacks, activationFlags)
1272 else:
1273 tackExt = None
1274
1275 extensions = []
1276
1277 if settings.useEncryptThenMAC and \
1278 clientHello.getExtension(ExtensionType.encrypt_then_mac) and \
1279 cipherSuite not in CipherSuite.streamSuites and \
1280 cipherSuite not in CipherSuite.aeadSuites:
1281 extensions.append(TLSExtension().create(ExtensionType.
1282 encrypt_then_mac,
1283 bytearray(0)))
1284 self._recordLayer.encryptThenMAC = True
1285
1286 if settings.useExtendedMasterSecret:
1287 if clientHello.getExtension(ExtensionType.extended_master_secret):
1288 extensions.append(TLSExtension().create(ExtensionType.
1289 extended_master_secret,
1290 bytearray(0)))
1291 self.extendedMasterSecret = True
1292 elif settings.requireExtendedMasterSecret:
1293 for result in self._sendError(
1294 AlertDescription.insufficient_security,
1295 "Failed to negotiate Extended Master Secret"):
1296 yield result
1297
1298 selectedALPN = None
1299 if alpnExt and alpn:
1300 for protoName in alpnExt.protocol_names:
1301 if protoName in alpn:
1302 selectedALPN = protoName
1303 ext = ALPNExtension().create([protoName])
1304 extensions.append(ext)
1305 break
1306 else:
1307 for result in self._sendError(
1308 AlertDescription.no_application_protocol,
1309 "No mutually supported application layer protocols"):
1310 yield result
1311
1312
1313 secureRenego = False
1314 renegoExt = clientHello.getExtension(ExtensionType.renegotiation_info)
1315 if renegoExt:
1316 if renegoExt.renegotiated_connection:
1317 for result in self._sendError(
1318 AlertDescription.handshake_failure,
1319 "Non empty renegotiation info extension in "
1320 "initial Client Hello"):
1321 yield result
1322 secureRenego = True
1323 elif CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV in \
1324 clientHello.cipher_suites:
1325 secureRenego = True
1326 if secureRenego:
1327 extensions.append(RenegotiationInfoExtension()
1328 .create(bytearray(0)))
1329
1330
1331 if clientHello.getExtension(ExtensionType.ec_point_formats):
1332
1333
1334 extensions.append(ECPointFormatsExtension().create(
1335 [ECPointFormat.uncompressed]))
1336
1337
1338 if not extensions:
1339 extensions = None
1340
1341 serverHello = ServerHello()
1342 serverHello.create(self.version, getRandomBytes(32), sessionID, \
1343 cipherSuite, CertificateType.x509, tackExt,
1344 nextProtos, extensions=extensions)
1345
1346
1347 clientCertChain = None
1348 if cipherSuite in CipherSuite.srpAllSuites:
1349 for result in self._serverSRPKeyExchange(clientHello, serverHello,
1350 verifierDB, cipherSuite,
1351 privateKey, certChain,
1352 settings):
1353 if result in (0, 1):
1354 yield result
1355 else: break
1356 premasterSecret = result
1357
1358
1359 elif (cipherSuite in CipherSuite.certSuites or
1360 cipherSuite in CipherSuite.dheCertSuites or
1361 cipherSuite in CipherSuite.ecdheCertSuites):
1362 if cipherSuite in CipherSuite.certSuites:
1363 keyExchange = RSAKeyExchange(cipherSuite,
1364 clientHello,
1365 serverHello,
1366 privateKey)
1367 elif cipherSuite in CipherSuite.dheCertSuites:
1368 dhGroups = self._groupNamesToList(settings)
1369 keyExchange = DHE_RSAKeyExchange(cipherSuite,
1370 clientHello,
1371 serverHello,
1372 privateKey,
1373 settings.dhParams,
1374 dhGroups)
1375 elif cipherSuite in CipherSuite.ecdheCertSuites:
1376 acceptedCurves = self._curveNamesToList(settings)
1377 keyExchange = ECDHE_RSAKeyExchange(cipherSuite,
1378 clientHello,
1379 serverHello,
1380 privateKey,
1381 acceptedCurves)
1382 else:
1383 assert(False)
1384 for result in self._serverCertKeyExchange(clientHello, serverHello,
1385 certChain, keyExchange,
1386 reqCert, reqCAs, cipherSuite,
1387 settings):
1388 if result in (0,1): yield result
1389 else: break
1390 (premasterSecret, clientCertChain) = result
1391
1392
1393 elif (cipherSuite in CipherSuite.anonSuites or
1394 cipherSuite in CipherSuite.ecdhAnonSuites):
1395 if cipherSuite in CipherSuite.anonSuites:
1396 dhGroups = self._groupNamesToList(settings)
1397 keyExchange = ADHKeyExchange(cipherSuite, clientHello,
1398 serverHello, settings.dhParams,
1399 dhGroups)
1400 else:
1401 acceptedCurves = self._curveNamesToList(settings)
1402 keyExchange = AECDHKeyExchange(cipherSuite, clientHello,
1403 serverHello, acceptedCurves)
1404 for result in self._serverAnonKeyExchange(serverHello, keyExchange,
1405 cipherSuite):
1406 if result in (0,1): yield result
1407 else: break
1408 premasterSecret = result
1409
1410 else:
1411 assert(False)
1412
1413
1414 for result in self._serverFinished(premasterSecret,
1415 clientHello.random, serverHello.random,
1416 cipherSuite, settings.cipherImplementations,
1417 nextProtos):
1418 if result in (0,1): yield result
1419 else: break
1420 masterSecret = result
1421
1422
1423 self.session = Session()
1424 if cipherSuite in CipherSuite.certAllSuites:
1425 serverCertChain = certChain
1426 else:
1427 serverCertChain = None
1428 srpUsername = None
1429 serverName = None
1430 if clientHello.srp_username:
1431 srpUsername = clientHello.srp_username.decode("utf-8")
1432 if clientHello.server_name:
1433 serverName = clientHello.server_name.decode("utf-8")
1434 self.session.create(masterSecret, serverHello.session_id, cipherSuite,
1435 srpUsername, clientCertChain, serverCertChain,
1436 tackExt, (serverHello.tackExt is not None),
1437 serverName,
1438 encryptThenMAC=self._recordLayer.encryptThenMAC,
1439 appProto=selectedALPN)
1440
1441
1442 if sessionCache and sessionID:
1443 sessionCache[sessionID] = self.session
1444
1445 self._handshakeDone(resumed=False)
1446 self._serverRandom = serverHello.random
1447 self._clientRandom = clientHello.random
1448
1449
1452
1453
1454
1455 self.version = settings.maxVersion
1456
1457
1458 for result in self._getMsg(ContentType.handshake,
1459 HandshakeType.client_hello):
1460 if result in (0,1): yield result
1461 else: break
1462 clientHello = result
1463
1464
1465 if clientHello.client_version < settings.minVersion:
1466 self.version = settings.minVersion
1467 for result in self._sendError(\
1468 AlertDescription.protocol_version,
1469 "Too old version: %s" % str(clientHello.client_version)):
1470 yield result
1471
1472
1473 if not clientHello.cipher_suites or \
1474 not clientHello.compression_methods:
1475 for result in self._sendError(
1476 AlertDescription.decode_error,
1477 "Malformed Client Hello message"):
1478 yield result
1479
1480
1481 if 0 not in clientHello.compression_methods:
1482 for result in self._sendError(
1483 AlertDescription.illegal_parameter,
1484 "Client Hello missing uncompressed method"):
1485 yield result
1486
1487
1488
1489 ext = clientHello.getExtension(ExtensionType.signature_algorithms)
1490 if clientHello.client_version >= (3, 3) and ext and not ext.sigalgs:
1491 for result in self._sendError(
1492 AlertDescription.decode_error,
1493 "Malformed signature_algorithms extension"):
1494 yield result
1495
1496
1497 alpnExt = clientHello.getExtension(ExtensionType.alpn)
1498 if alpnExt:
1499 for protocolName in alpnExt.protocol_names:
1500 if not protocolName:
1501 for result in self._sendError(
1502 AlertDescription.illegal_parameter,
1503 "Client sent empty name in ALPN extension"):
1504 yield result
1505
1506
1507 elif clientHello.client_version > settings.maxVersion:
1508 self.version = settings.maxVersion
1509
1510 else:
1511
1512 self.version = clientHello.client_version
1513
1514
1515 if clientHello.client_version < settings.maxVersion and \
1516 CipherSuite.TLS_FALLBACK_SCSV in clientHello.cipher_suites:
1517 for result in self._sendError(\
1518 AlertDescription.inappropriate_fallback):
1519 yield result
1520
1521
1522
1523 client_groups = clientHello.getExtension(ExtensionType.supported_groups)
1524 group_intersect = []
1525
1526 ffgroup_intersect = [GroupName.ffdhe2048]
1527 if client_groups is not None:
1528 client_groups = client_groups.groups
1529 if client_groups is None:
1530 client_groups = []
1531 server_groups = self._curveNamesToList(settings)
1532 group_intersect = [x for x in client_groups if x in server_groups]
1533
1534 server_groups = self._groupNamesToList(settings)
1535 ffgroup_intersect = [i for i in client_groups
1536 if i in server_groups]
1537
1538
1539 if not ffgroup_intersect:
1540 if any(i for i in client_groups if i in range(256, 512)):
1541 ffgroup_intersect = []
1542 else:
1543 ffgroup_intersect = [GroupName.ffdhe2048]
1544
1545
1546
1547
1548 cipherSuites = []
1549 if verifierDB:
1550 if certChain:
1551 cipherSuites += \
1552 CipherSuite.getSrpCertSuites(settings, self.version)
1553 cipherSuites += CipherSuite.getSrpSuites(settings, self.version)
1554 elif certChain:
1555 if group_intersect:
1556 cipherSuites += CipherSuite.getEcdheCertSuites(settings,
1557 self.version)
1558 if ffgroup_intersect:
1559 cipherSuites += CipherSuite.getDheCertSuites(settings,
1560 self.version)
1561 cipherSuites += CipherSuite.getCertSuites(settings, self.version)
1562 elif anon:
1563 cipherSuites += CipherSuite.getAnonSuites(settings, self.version)
1564 cipherSuites += CipherSuite.getEcdhAnonSuites(settings,
1565 self.version)
1566 else:
1567 assert(False)
1568 cipherSuites = CipherSuite.filterForVersion(cipherSuites,
1569 minVersion=self.version,
1570 maxVersion=self.version)
1571
1572 if clientHello.session_id and sessionCache:
1573 session = None
1574
1575
1576 if sessionCache and not session:
1577 try:
1578 session = sessionCache[clientHello.session_id]
1579 if not session.resumable:
1580 raise AssertionError()
1581
1582 if session.cipherSuite not in cipherSuites:
1583 for result in self._sendError(\
1584 AlertDescription.handshake_failure):
1585 yield result
1586 if session.cipherSuite not in clientHello.cipher_suites:
1587 for result in self._sendError(\
1588 AlertDescription.handshake_failure):
1589 yield result
1590 if clientHello.srp_username:
1591 if not session.srpUsername or \
1592 clientHello.srp_username != bytearray(session.srpUsername, "utf-8"):
1593 for result in self._sendError(\
1594 AlertDescription.handshake_failure):
1595 yield result
1596 if clientHello.server_name:
1597 if not session.serverName or \
1598 clientHello.server_name != bytearray(session.serverName, "utf-8"):
1599 for result in self._sendError(\
1600 AlertDescription.handshake_failure):
1601 yield result
1602 if session.encryptThenMAC and \
1603 not clientHello.getExtension(
1604 ExtensionType.encrypt_then_mac):
1605 for result in self._sendError(\
1606 AlertDescription.handshake_failure):
1607 yield result
1608 if session.extendedMasterSecret and \
1609 not clientHello.getExtension(
1610 ExtensionType.extended_master_secret):
1611 for result in self._sendError(\
1612 AlertDescription.handshake_failure):
1613 yield result
1614 except KeyError:
1615 pass
1616
1617
1618 if session:
1619
1620 extensions = []
1621 if session.encryptThenMAC:
1622 self._recordLayer.encryptThenMAC = True
1623 mte = TLSExtension().create(ExtensionType.encrypt_then_mac,
1624 bytearray(0))
1625 extensions.append(mte)
1626 if session.extendedMasterSecret:
1627 ems = TLSExtension().create(ExtensionType.
1628 extended_master_secret,
1629 bytearray(0))
1630 extensions.append(ems)
1631 secureRenego = False
1632 renegoExt = clientHello.\
1633 getExtension(ExtensionType.renegotiation_info)
1634 if renegoExt:
1635 if renegoExt.renegotiated_connection:
1636 for result in self._sendError(
1637 AlertDescription.handshake_failure):
1638 yield result
1639 secureRenego = True
1640 elif CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV in \
1641 clientHello.cipher_suites:
1642 secureRenego = True
1643 if secureRenego:
1644 extensions.append(RenegotiationInfoExtension()
1645 .create(bytearray(0)))
1646 selectedALPN = None
1647 if alpn:
1648 alpnExt = clientHello.getExtension(ExtensionType.alpn)
1649 if alpnExt:
1650 for protocolName in alpnExt.protocol_names:
1651 if protocolName in alpn:
1652 ext = ALPNExtension().create([protocolName])
1653 extensions.append(ext)
1654 selectedALPN = protocolName
1655 break
1656 else:
1657 for result in self._sendError(
1658 AlertDescription.no_application_protocol,
1659 "No commonly supported application layer"
1660 "protocol supported"):
1661 yield result
1662
1663
1664 if not extensions:
1665 extensions = None
1666 serverHello = ServerHello()
1667 serverHello.create(self.version, getRandomBytes(32),
1668 session.sessionID, session.cipherSuite,
1669 CertificateType.x509, None, None,
1670 extensions=extensions)
1671 for result in self._sendMsg(serverHello):
1672 yield result
1673
1674
1675 self._calcPendingStates(session.cipherSuite,
1676 session.masterSecret,
1677 clientHello.random,
1678 serverHello.random,
1679 settings.cipherImplementations)
1680
1681
1682 for result in self._sendFinished(session.masterSecret,
1683 session.cipherSuite):
1684 yield result
1685 for result in self._getFinished(session.masterSecret,
1686 session.cipherSuite):
1687 yield result
1688
1689
1690 self.session = session
1691 self._clientRandom = clientHello.random
1692 self._serverRandom = serverHello.random
1693 self.session.appProto = selectedALPN
1694 yield None
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704 for cipherSuite in cipherSuites:
1705 if cipherSuite in clientHello.cipher_suites:
1706 break
1707 else:
1708 if client_groups and \
1709 any(i in range(256, 512) for i in client_groups) and \
1710 any(i in CipherSuite.dhAllSuites
1711 for i in clientHello.cipher_suites):
1712 for result in self._sendError(
1713 AlertDescription.insufficient_security,
1714 "FFDHE groups not acceptable and no other common "
1715 "ciphers"):
1716 yield result
1717 else:
1718 for result in self._sendError(\
1719 AlertDescription.handshake_failure,
1720 "No mutual ciphersuite"):
1721 yield result
1722 if cipherSuite in CipherSuite.srpAllSuites and \
1723 not clientHello.srp_username:
1724 for result in self._sendError(\
1725 AlertDescription.unknown_psk_identity,
1726 "Client sent a hello, but without the SRP username"):
1727 yield result
1728
1729
1730 if cipherSuite in CipherSuite.certAllSuites and CertificateType.x509 \
1731 not in clientHello.certificate_types:
1732 for result in self._sendError(\
1733 AlertDescription.handshake_failure,
1734 "the client doesn't support my certificate type"):
1735 yield result
1736
1737
1738
1739
1740 yield (clientHello, cipherSuite)
1741
1742 - def _serverSRPKeyExchange(self, clientHello, serverHello, verifierDB,
1743 cipherSuite, privateKey, serverCertChain,
1744 settings):
1745 """Perform the server side of SRP key exchange"""
1746 keyExchange = SRPKeyExchange(cipherSuite,
1747 clientHello,
1748 serverHello,
1749 privateKey,
1750 verifierDB)
1751
1752 try:
1753 sigHash = self._pickServerKeyExchangeSig(settings, clientHello)
1754 except TLSHandshakeFailure as alert:
1755 for result in self._sendError(
1756 AlertDescription.handshake_failure,
1757 str(alert)):
1758 yield result
1759
1760
1761 try:
1762 serverKeyExchange = keyExchange.makeServerKeyExchange(sigHash)
1763 except TLSUnknownPSKIdentity:
1764 for result in self._sendError(\
1765 AlertDescription.unknown_psk_identity):
1766 yield result
1767
1768
1769
1770 msgs = []
1771 msgs.append(serverHello)
1772 if cipherSuite in CipherSuite.srpCertSuites:
1773 certificateMsg = Certificate(CertificateType.x509)
1774 certificateMsg.create(serverCertChain)
1775 msgs.append(certificateMsg)
1776 msgs.append(serverKeyExchange)
1777 msgs.append(ServerHelloDone())
1778 for result in self._sendMsgs(msgs):
1779 yield result
1780
1781
1782 for result in self._getMsg(ContentType.handshake,
1783 HandshakeType.client_key_exchange,
1784 cipherSuite):
1785 if result in (0,1): yield result
1786 else: break
1787 try:
1788 premasterSecret = keyExchange.processClientKeyExchange(result)
1789 except TLSIllegalParameterException:
1790 for result in self._sendError(AlertDescription.illegal_parameter,
1791 "Suspicious A value"):
1792 yield result
1793
1794 yield premasterSecret
1795
1796 - def _serverCertKeyExchange(self, clientHello, serverHello,
1797 serverCertChain, keyExchange,
1798 reqCert, reqCAs, cipherSuite,
1799 settings):
1800
1801
1802 msgs = []
1803
1804
1805 clientCertChain = None
1806
1807 msgs.append(serverHello)
1808 msgs.append(Certificate(CertificateType.x509).create(serverCertChain))
1809 try:
1810 sigHashAlg = self._pickServerKeyExchangeSig(settings, clientHello)
1811 except TLSHandshakeFailure as alert:
1812 for result in self._sendError(
1813 AlertDescription.handshake_failure,
1814 str(alert)):
1815 yield result
1816 serverKeyExchange = keyExchange.makeServerKeyExchange(sigHashAlg)
1817 if serverKeyExchange is not None:
1818 msgs.append(serverKeyExchange)
1819 if reqCert:
1820 certificateRequest = CertificateRequest(self.version)
1821 if not reqCAs:
1822 reqCAs = []
1823 validSigAlgs = self._sigHashesToList(settings)
1824 certificateRequest.create([ClientCertificateType.rsa_sign],
1825 reqCAs,
1826 validSigAlgs)
1827 msgs.append(certificateRequest)
1828 msgs.append(ServerHelloDone())
1829 for result in self._sendMsgs(msgs):
1830 yield result
1831
1832
1833 if reqCert:
1834 if self.version == (3,0):
1835 for result in self._getMsg((ContentType.handshake,
1836 ContentType.alert),
1837 HandshakeType.certificate,
1838 CertificateType.x509):
1839 if result in (0,1): yield result
1840 else: break
1841 msg = result
1842
1843 if isinstance(msg, Alert):
1844
1845 alert = msg
1846 if alert.description != \
1847 AlertDescription.no_certificate:
1848 self._shutdown(False)
1849 raise TLSRemoteAlert(alert)
1850 elif isinstance(msg, Certificate):
1851 clientCertificate = msg
1852 if clientCertificate.certChain and \
1853 clientCertificate.certChain.getNumCerts()!=0:
1854 clientCertChain = clientCertificate.certChain
1855 else:
1856 raise AssertionError()
1857 elif self.version in ((3,1), (3,2), (3,3)):
1858 for result in self._getMsg(ContentType.handshake,
1859 HandshakeType.certificate,
1860 CertificateType.x509):
1861 if result in (0,1): yield result
1862 else: break
1863 clientCertificate = result
1864 if clientCertificate.certChain and \
1865 clientCertificate.certChain.getNumCerts()!=0:
1866 clientCertChain = clientCertificate.certChain
1867 else:
1868 raise AssertionError()
1869
1870
1871 for result in self._getMsg(ContentType.handshake,
1872 HandshakeType.client_key_exchange,
1873 cipherSuite):
1874 if result in (0,1): yield result
1875 else: break
1876 clientKeyExchange = result
1877
1878
1879 try:
1880 premasterSecret = \
1881 keyExchange.processClientKeyExchange(clientKeyExchange)
1882 except TLSIllegalParameterException as alert:
1883 for result in self._sendError(AlertDescription.illegal_parameter,
1884 str(alert)):
1885 yield result
1886
1887
1888 if clientCertChain:
1889 handshakeHash = self._handshake_hash.copy()
1890 for result in self._getMsg(ContentType.handshake,
1891 HandshakeType.certificate_verify):
1892 if result in (0, 1):
1893 yield result
1894 else: break
1895 certificateVerify = result
1896 signatureAlgorithm = None
1897 if self.version == (3, 3):
1898 validSigAlgs = self._sigHashesToList(settings)
1899 if certificateVerify.signatureAlgorithm not in validSigAlgs:
1900 for result in self._sendError(\
1901 AlertDescription.decryption_failed,
1902 "Invalid signature on Certificate Verify"):
1903 yield result
1904 signatureAlgorithm = certificateVerify.signatureAlgorithm
1905
1906 verifyBytes = KeyExchange.calcVerifyBytes(self.version,
1907 handshakeHash,
1908 signatureAlgorithm,
1909 premasterSecret,
1910 clientHello.random,
1911 serverHello.random)
1912 publicKey = clientCertChain.getEndEntityPublicKey()
1913 if len(publicKey) < settings.minKeySize:
1914 for result in self._sendError(\
1915 AlertDescription.handshake_failure,
1916 "Client's public key too small: %d" % len(publicKey)):
1917 yield result
1918
1919 if len(publicKey) > settings.maxKeySize:
1920 for result in self._sendError(\
1921 AlertDescription.handshake_failure,
1922 "Client's public key too large: %d" % len(publicKey)):
1923 yield result
1924
1925 if not publicKey.verify(certificateVerify.signature, verifyBytes):
1926 for result in self._sendError(\
1927 AlertDescription.decrypt_error,
1928 "Signature failed to verify"):
1929 yield result
1930 yield (premasterSecret, clientCertChain)
1931
1932
1959
1960
1961 - def _serverFinished(self, premasterSecret, clientRandom, serverRandom,
1962 cipherSuite, cipherImplementations, nextProtos):
1963 if self.extendedMasterSecret:
1964 masterSecret = calcExtendedMasterSecret(self.version,
1965 cipherSuite,
1966 premasterSecret,
1967 self._handshake_hash)
1968 else:
1969 masterSecret = calcMasterSecret(self.version,
1970 cipherSuite,
1971 premasterSecret,
1972 clientRandom,
1973 serverRandom)
1974
1975
1976 self._calcPendingStates(cipherSuite, masterSecret,
1977 clientRandom, serverRandom,
1978 cipherImplementations)
1979
1980
1981 for result in self._getFinished(masterSecret,
1982 cipherSuite,
1983 expect_next_protocol=nextProtos is not None):
1984 yield result
1985
1986 for result in self._sendFinished(masterSecret, cipherSuite):
1987 yield result
1988
1989 yield masterSecret
1990
1991
1992
1993
1994
1995
1996
1997 - def _sendFinished(self, masterSecret, cipherSuite=None, nextProto=None):
2027
2028 - def _getFinished(self, masterSecret, cipherSuite=None,
2029 expect_next_protocol=False, nextProto=None):
2030
2031 for result in self._getMsg(ContentType.change_cipher_spec):
2032 if result in (0,1):
2033 yield result
2034 changeCipherSpec = result
2035
2036 if changeCipherSpec.type != 1:
2037 for result in self._sendError(AlertDescription.illegal_parameter,
2038 "ChangeCipherSpec type incorrect"):
2039 yield result
2040
2041
2042 self._changeReadState()
2043
2044
2045 if expect_next_protocol:
2046 for result in self._getMsg(ContentType.handshake, HandshakeType.next_protocol):
2047 if result in (0,1):
2048 yield result
2049 if result is None:
2050 for result in self._sendError(AlertDescription.unexpected_message,
2051 "Didn't get NextProtocol message"):
2052 yield result
2053
2054 self.next_proto = result.next_proto
2055 else:
2056 self.next_proto = None
2057
2058
2059 if nextProto:
2060 self.next_proto = nextProto
2061
2062
2063 verifyData = calcFinished(self.version,
2064 masterSecret,
2065 cipherSuite,
2066 self._handshake_hash,
2067 not self._client)
2068
2069
2070 for result in self._getMsg(ContentType.handshake,
2071 HandshakeType.finished):
2072 if result in (0,1):
2073 yield result
2074 finished = result
2075 if finished.verify_data != verifyData:
2076 for result in self._sendError(AlertDescription.decrypt_error,
2077 "Finished message is incorrect"):
2078 yield result
2079
2105
2106 @staticmethod
2108 """Pick a hash that matches most closely the supported ones"""
2109 hashAndAlgsExt = clientHello.getExtension(\
2110 ExtensionType.signature_algorithms)
2111
2112 if hashAndAlgsExt is None or hashAndAlgsExt.sigalgs is None:
2113
2114
2115 return "sha1"
2116
2117 rsaHashes = [alg[0] for alg in hashAndAlgsExt.sigalgs
2118 if alg[1] == SignatureAlgorithm.rsa]
2119 for hashName in settings.rsaSigHashes:
2120 hashID = getattr(HashAlgorithm, hashName)
2121 if hashID in rsaHashes:
2122 return hashName
2123
2124
2125 raise TLSHandshakeFailure("No common signature algorithms")
2126
2127 @staticmethod
2129 """Convert list of valid signature hashes to array of tuples"""
2130 sigAlgs = []
2131 for hashName in settings.rsaSigHashes:
2132 sigAlgs.append((getattr(HashAlgorithm, hashName),
2133 SignatureAlgorithm.rsa))
2134 return sigAlgs
2135
2136 @staticmethod
2138 """Convert list of acceptable curves to array identifiers"""
2139 return [getattr(GroupName, val) for val in settings.eccCurves]
2140
2141 @staticmethod
2143 """Convert list of acceptable ff groups to TLS identifiers."""
2144 return [getattr(GroupName, val) for val in settings.dhGroups]
2145