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