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