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 certList=serverCertChain)
910 try:
911 KeyExchange.verifyServerKeyExchange(serverKeyExchange,
912 publicKey,
913 clientRandom,
914 serverRandom,
915 validSigAlgs)
916 except TLSIllegalParameterException:
917 for result in self._sendError(AlertDescription.\
918 illegal_parameter):
919 yield result
920 except TLSDecryptionFailed:
921 for result in self._sendError(\
922 AlertDescription.decrypt_error):
923 yield result
924
925 if serverKeyExchange:
926
927 if self.version >= (3, 3) \
928 and cipherSuite in CipherSuite.certAllSuites \
929 and cipherSuite not in CipherSuite.certSuites:
930 self.serverSigAlg = (serverKeyExchange.hashAlg,
931 serverKeyExchange.signAlg)
932
933 if cipherSuite in CipherSuite.dhAllSuites:
934 self.dhGroupSize = numBits(serverKeyExchange.dh_p)
935 if cipherSuite in CipherSuite.ecdhAllSuites:
936 self.ecdhCurve = serverKeyExchange.named_curve
937
938
939 if certificateRequest:
940
941
942
943 if self.version == (3, 3)\
944 and not [sig for sig in \
945 certificateRequest.supported_signature_algs\
946 if sig[1] == SignatureAlgorithm.rsa]:
947 for result in self._sendError(\
948 AlertDescription.handshake_failure,
949 "Server doesn't accept any sigalgs we support: " +
950 str(certificateRequest.supported_signature_algs)):
951 yield result
952 clientCertificate = Certificate(certificateType)
953
954 if clientCertChain:
955
956
957 if certificateType == CertificateType.x509 \
958 and not isinstance(clientCertChain, X509CertChain):
959 for result in self._sendError(\
960 AlertDescription.handshake_failure,
961 "Client certificate is of wrong type"):
962 yield result
963
964 clientCertificate.create(clientCertChain)
965
966 for result in self._sendMsg(clientCertificate):
967 yield result
968 else:
969
970 privateKey = None
971 clientCertChain = None
972
973 try:
974 ske = serverKeyExchange
975 premasterSecret = keyExchange.processServerKeyExchange(publicKey,
976 ske)
977 except TLSInsufficientSecurity as e:
978 for result in self._sendError(\
979 AlertDescription.insufficient_security, e):
980 yield result
981 except TLSIllegalParameterException as e:
982 for result in self._sendError(\
983 AlertDescription.illegal_parameter, e):
984 yield result
985
986 clientKeyExchange = keyExchange.makeClientKeyExchange()
987
988
989 for result in self._sendMsg(clientKeyExchange):
990 yield result
991
992
993
994
995 self._certificate_verify_handshake_hash = self._handshake_hash.copy()
996
997
998
999 if certificateRequest and privateKey:
1000 validSigAlgs = self._sigHashesToList(settings, privateKey,
1001 clientCertChain)
1002 try:
1003 certificateVerify = KeyExchange.makeCertificateVerify(
1004 self.version,
1005 self._certificate_verify_handshake_hash,
1006 validSigAlgs,
1007 privateKey,
1008 certificateRequest,
1009 premasterSecret,
1010 clientRandom,
1011 serverRandom)
1012 except TLSInternalError as exception:
1013 for result in self._sendError(
1014 AlertDescription.internal_error, exception):
1015 yield result
1016 for result in self._sendMsg(certificateVerify):
1017 yield result
1018
1019 yield (premasterSecret, serverCertChain, clientCertChain, tackExt)
1020
1021 - def _clientFinished(self, premasterSecret, clientRandom, serverRandom,
1022 cipherSuite, cipherImplementations, nextProto):
1023 if self.extendedMasterSecret:
1024 cvhh = self._certificate_verify_handshake_hash
1025
1026
1027 if not cvhh:
1028 cvhh = self._handshake_hash
1029 masterSecret = calcExtendedMasterSecret(self.version,
1030 cipherSuite,
1031 premasterSecret,
1032 cvhh)
1033 else:
1034 masterSecret = calcMasterSecret(self.version,
1035 cipherSuite,
1036 premasterSecret,
1037 clientRandom,
1038 serverRandom)
1039 self._calcPendingStates(cipherSuite, masterSecret,
1040 clientRandom, serverRandom,
1041 cipherImplementations)
1042
1043
1044 for result in self._sendFinished(masterSecret, cipherSuite, nextProto):
1045 yield result
1046 self.sock.flush()
1047 self.sock.buffer_writes = False
1048 for result in self._getFinished(masterSecret,
1049 cipherSuite,
1050 nextProto=nextProto):
1051 yield result
1052 yield masterSecret
1053
1090
1091
1092
1093
1094
1095
1096
1097 - def handshakeServer(self, verifierDB=None,
1098 certChain=None, privateKey=None, reqCert=False,
1099 sessionCache=None, settings=None, checker=None,
1100 reqCAs = None,
1101 tacks=None, activationFlags=0,
1102 nextProtos=None, anon=False, alpn=None, sni=None):
1103 """Perform a handshake in the role of server.
1104
1105 This function performs an SSL or TLS handshake. Depending on
1106 the arguments and the behavior of the client, this function can
1107 perform an SRP, or certificate-based handshake. It
1108 can also perform a combined SRP and server-certificate
1109 handshake.
1110
1111 Like any handshake function, this can be called on a closed
1112 TLS connection, or on a TLS connection that is already open.
1113 If called on an open connection it performs a re-handshake.
1114 This function does not send a Hello Request message before
1115 performing the handshake, so if re-handshaking is required,
1116 the server must signal the client to begin the re-handshake
1117 through some other means.
1118
1119 If the function completes without raising an exception, the
1120 TLS connection will be open and available for data transfer.
1121
1122 If an exception is raised, the connection will have been
1123 automatically closed (if it was ever open).
1124
1125 @type verifierDB: L{tlslite.verifierdb.VerifierDB}
1126 @param verifierDB: A database of SRP password verifiers
1127 associated with usernames. If the client performs an SRP
1128 handshake, the session's srpUsername attribute will be set.
1129
1130 @type certChain: L{tlslite.x509certchain.X509CertChain}
1131 @param certChain: The certificate chain to be used if the
1132 client requests server certificate authentication.
1133
1134 @type privateKey: L{tlslite.utils.rsakey.RSAKey}
1135 @param privateKey: The private key to be used if the client
1136 requests server certificate authentication.
1137
1138 @type reqCert: bool
1139 @param reqCert: Whether to request client certificate
1140 authentication. This only applies if the client chooses server
1141 certificate authentication; if the client chooses SRP
1142 authentication, this will be ignored. If the client
1143 performs a client certificate authentication, the sessions's
1144 clientCertChain attribute will be set.
1145
1146 @type sessionCache: L{tlslite.sessioncache.SessionCache}
1147 @param sessionCache: An in-memory cache of resumable sessions.
1148 The client can resume sessions from this cache. Alternatively,
1149 if the client performs a full handshake, a new session will be
1150 added to the cache.
1151
1152 @type settings: L{tlslite.handshakesettings.HandshakeSettings}
1153 @param settings: Various settings which can be used to control
1154 the ciphersuites and SSL/TLS version chosen by the server.
1155
1156 @type checker: L{tlslite.checker.Checker}
1157 @param checker: A Checker instance. This instance will be
1158 invoked to examine the other party's authentication
1159 credentials, if the handshake completes succesfully.
1160
1161 @type reqCAs: list of L{bytearray} of unsigned bytes
1162 @param reqCAs: A collection of DER-encoded DistinguishedNames that
1163 will be sent along with a certificate request. This does not affect
1164 verification.
1165
1166 @type nextProtos: list of strings.
1167 @param nextProtos: A list of upper layer protocols to expose to the
1168 clients through the Next-Protocol Negotiation Extension,
1169 if they support it.
1170
1171 @type alpn: list of bytearrays
1172 @param alpn: names of application layer protocols supported.
1173 Note that it will be used instead of NPN if both were advertised by
1174 client.
1175
1176 @type sni: bytearray
1177 @param sni: expected virtual name hostname.
1178
1179 @raise socket.error: If a socket error occurs.
1180 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
1181 without a preceding alert.
1182 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
1183 @raise tlslite.errors.TLSAuthenticationError: If the checker
1184 doesn't like the other party's authentication credentials.
1185 """
1186 for result in self.handshakeServerAsync(verifierDB,
1187 certChain, privateKey, reqCert, sessionCache, settings,
1188 checker, reqCAs,
1189 tacks=tacks, activationFlags=activationFlags,
1190 nextProtos=nextProtos, anon=anon, alpn=alpn, sni=sni):
1191 pass
1192
1193
1194 - def handshakeServerAsync(self, verifierDB=None,
1195 certChain=None, privateKey=None, reqCert=False,
1196 sessionCache=None, settings=None, checker=None,
1197 reqCAs=None,
1198 tacks=None, activationFlags=0,
1199 nextProtos=None, anon=False, alpn=None, sni=None
1200 ):
1201 """Start a server handshake operation on the TLS connection.
1202
1203 This function returns a generator which behaves similarly to
1204 handshakeServer(). Successive invocations of the generator
1205 will return 0 if it is waiting to read from the socket, 1 if it is
1206 waiting to write to the socket, or it will raise StopIteration
1207 if the handshake operation is complete.
1208
1209 @rtype: iterable
1210 @return: A generator; see above for details.
1211 """
1212 handshaker = self._handshakeServerAsyncHelper(\
1213 verifierDB=verifierDB, certChain=certChain,
1214 privateKey=privateKey, reqCert=reqCert,
1215 sessionCache=sessionCache, settings=settings,
1216 reqCAs=reqCAs,
1217 tacks=tacks, activationFlags=activationFlags,
1218 nextProtos=nextProtos, anon=anon, alpn=alpn, sni=sni)
1219 for result in self._handshakeWrapperAsync(handshaker, checker):
1220 yield result
1221
1222
1223 - def _handshakeServerAsyncHelper(self, verifierDB,
1224 certChain, privateKey, reqCert, sessionCache,
1225 settings, reqCAs,
1226 tacks, activationFlags,
1227 nextProtos, anon, alpn, sni):
1228
1229 self._handshakeStart(client=False)
1230
1231 if (not verifierDB) and (not certChain) and not anon:
1232 raise ValueError("Caller passed no authentication credentials")
1233 if certChain and not privateKey:
1234 raise ValueError("Caller passed a certChain but no privateKey")
1235 if privateKey and not certChain:
1236 raise ValueError("Caller passed a privateKey but no certChain")
1237 if reqCAs and not reqCert:
1238 raise ValueError("Caller passed reqCAs but not reqCert")
1239 if certChain and not isinstance(certChain, X509CertChain):
1240 raise ValueError("Unrecognized certificate type")
1241 if activationFlags and not tacks:
1242 raise ValueError("Nonzero activationFlags requires tacks")
1243 if tacks:
1244 if not tackpyLoaded:
1245 raise ValueError("tackpy is not loaded")
1246 if not settings or not settings.useExperimentalTackExtension:
1247 raise ValueError("useExperimentalTackExtension not enabled")
1248 if alpn is not None and not alpn:
1249 raise ValueError("Empty list of ALPN protocols")
1250
1251 if not settings:
1252 settings = HandshakeSettings()
1253 settings = settings.validate()
1254
1255
1256
1257
1258
1259 for result in self._serverGetClientHello(settings, certChain,
1260 verifierDB, sessionCache,
1261 anon, alpn, sni):
1262 if result in (0,1): yield result
1263 elif result == None:
1264 self._handshakeDone(resumed=True)
1265 return
1266 else: break
1267 (clientHello, cipherSuite) = result
1268
1269
1270
1271
1272 if sessionCache:
1273 sessionID = getRandomBytes(32)
1274 else:
1275 sessionID = bytearray(0)
1276
1277 if not clientHello.supports_npn:
1278 nextProtos = None
1279
1280 alpnExt = clientHello.getExtension(ExtensionType.alpn)
1281 if alpnExt and alpn:
1282
1283 nextProtos = None
1284
1285
1286 if not cipherSuite in CipherSuite.certAllSuites:
1287 tacks = None
1288
1289
1290 if clientHello.tack:
1291 tackExt = TackExtension.create(tacks, activationFlags)
1292 else:
1293 tackExt = None
1294
1295 extensions = []
1296
1297 if settings.useEncryptThenMAC and \
1298 clientHello.getExtension(ExtensionType.encrypt_then_mac) and \
1299 cipherSuite not in CipherSuite.streamSuites and \
1300 cipherSuite not in CipherSuite.aeadSuites:
1301 extensions.append(TLSExtension().create(ExtensionType.
1302 encrypt_then_mac,
1303 bytearray(0)))
1304 self._recordLayer.encryptThenMAC = True
1305
1306 if settings.useExtendedMasterSecret:
1307 if clientHello.getExtension(ExtensionType.extended_master_secret):
1308 extensions.append(TLSExtension().create(ExtensionType.
1309 extended_master_secret,
1310 bytearray(0)))
1311 self.extendedMasterSecret = True
1312 elif settings.requireExtendedMasterSecret:
1313 for result in self._sendError(
1314 AlertDescription.insufficient_security,
1315 "Failed to negotiate Extended Master Secret"):
1316 yield result
1317
1318 selectedALPN = None
1319 if alpnExt and alpn:
1320 for protoName in alpnExt.protocol_names:
1321 if protoName in alpn:
1322 selectedALPN = protoName
1323 ext = ALPNExtension().create([protoName])
1324 extensions.append(ext)
1325 break
1326 else:
1327 for result in self._sendError(
1328 AlertDescription.no_application_protocol,
1329 "No mutually supported application layer protocols"):
1330 yield result
1331
1332
1333 secureRenego = False
1334 renegoExt = clientHello.getExtension(ExtensionType.renegotiation_info)
1335 if renegoExt:
1336 if renegoExt.renegotiated_connection:
1337 for result in self._sendError(
1338 AlertDescription.handshake_failure,
1339 "Non empty renegotiation info extension in "
1340 "initial Client Hello"):
1341 yield result
1342 secureRenego = True
1343 elif CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV in \
1344 clientHello.cipher_suites:
1345 secureRenego = True
1346 if secureRenego:
1347 extensions.append(RenegotiationInfoExtension()
1348 .create(bytearray(0)))
1349
1350
1351 if clientHello.getExtension(ExtensionType.ec_point_formats):
1352
1353
1354 extensions.append(ECPointFormatsExtension().create(
1355 [ECPointFormat.uncompressed]))
1356
1357
1358 if not extensions:
1359 extensions = None
1360
1361 serverHello = ServerHello()
1362 serverHello.create(self.version, getRandomBytes(32), sessionID, \
1363 cipherSuite, CertificateType.x509, tackExt,
1364 nextProtos, extensions=extensions)
1365
1366
1367 clientCertChain = None
1368 if cipherSuite in CipherSuite.srpAllSuites:
1369 for result in self._serverSRPKeyExchange(clientHello, serverHello,
1370 verifierDB, cipherSuite,
1371 privateKey, certChain,
1372 settings):
1373 if result in (0, 1):
1374 yield result
1375 else: break
1376 premasterSecret = result
1377
1378
1379 elif (cipherSuite in CipherSuite.certSuites or
1380 cipherSuite in CipherSuite.dheCertSuites or
1381 cipherSuite in CipherSuite.ecdheCertSuites):
1382 if cipherSuite in CipherSuite.certSuites:
1383 keyExchange = RSAKeyExchange(cipherSuite,
1384 clientHello,
1385 serverHello,
1386 privateKey)
1387 elif cipherSuite in CipherSuite.dheCertSuites:
1388 dhGroups = self._groupNamesToList(settings)
1389 keyExchange = DHE_RSAKeyExchange(cipherSuite,
1390 clientHello,
1391 serverHello,
1392 privateKey,
1393 settings.dhParams,
1394 dhGroups)
1395 elif cipherSuite in CipherSuite.ecdheCertSuites:
1396 acceptedCurves = self._curveNamesToList(settings)
1397 keyExchange = ECDHE_RSAKeyExchange(cipherSuite,
1398 clientHello,
1399 serverHello,
1400 privateKey,
1401 acceptedCurves)
1402 else:
1403 assert(False)
1404 for result in self._serverCertKeyExchange(clientHello, serverHello,
1405 certChain, keyExchange,
1406 reqCert, reqCAs, cipherSuite,
1407 settings):
1408 if result in (0,1): yield result
1409 else: break
1410 (premasterSecret, clientCertChain) = result
1411
1412
1413 elif (cipherSuite in CipherSuite.anonSuites or
1414 cipherSuite in CipherSuite.ecdhAnonSuites):
1415 if cipherSuite in CipherSuite.anonSuites:
1416 dhGroups = self._groupNamesToList(settings)
1417 keyExchange = ADHKeyExchange(cipherSuite, clientHello,
1418 serverHello, settings.dhParams,
1419 dhGroups)
1420 else:
1421 acceptedCurves = self._curveNamesToList(settings)
1422 keyExchange = AECDHKeyExchange(cipherSuite, clientHello,
1423 serverHello, acceptedCurves)
1424 for result in self._serverAnonKeyExchange(serverHello, keyExchange,
1425 cipherSuite):
1426 if result in (0,1): yield result
1427 else: break
1428 premasterSecret = result
1429
1430 else:
1431 assert(False)
1432
1433
1434 for result in self._serverFinished(premasterSecret,
1435 clientHello.random, serverHello.random,
1436 cipherSuite, settings.cipherImplementations,
1437 nextProtos):
1438 if result in (0,1): yield result
1439 else: break
1440 masterSecret = result
1441
1442
1443 self.session = Session()
1444 if cipherSuite in CipherSuite.certAllSuites:
1445 serverCertChain = certChain
1446 else:
1447 serverCertChain = None
1448 srpUsername = None
1449 serverName = None
1450 if clientHello.srp_username:
1451 srpUsername = clientHello.srp_username.decode("utf-8")
1452 if clientHello.server_name:
1453 serverName = clientHello.server_name.decode("utf-8")
1454 self.session.create(masterSecret, serverHello.session_id, cipherSuite,
1455 srpUsername, clientCertChain, serverCertChain,
1456 tackExt, (serverHello.tackExt is not None),
1457 serverName,
1458 encryptThenMAC=self._recordLayer.encryptThenMAC,
1459 extendedMasterSecret=self.extendedMasterSecret,
1460 appProto=selectedALPN)
1461
1462
1463 if sessionCache and sessionID:
1464 sessionCache[sessionID] = self.session
1465
1466 self._handshakeDone(resumed=False)
1467 self._serverRandom = serverHello.random
1468 self._clientRandom = clientHello.random
1469
1470
1473
1474
1475
1476 self.version = settings.maxVersion
1477
1478
1479 for result in self._getMsg(ContentType.handshake,
1480 HandshakeType.client_hello):
1481 if result in (0,1): yield result
1482 else: break
1483 clientHello = result
1484
1485
1486 if clientHello.client_version < settings.minVersion:
1487 self.version = settings.minVersion
1488 for result in self._sendError(\
1489 AlertDescription.protocol_version,
1490 "Too old version: %s" % str(clientHello.client_version)):
1491 yield result
1492
1493
1494 if not clientHello.cipher_suites or \
1495 not clientHello.compression_methods:
1496 for result in self._sendError(
1497 AlertDescription.decode_error,
1498 "Malformed Client Hello message"):
1499 yield result
1500
1501
1502 if 0 not in clientHello.compression_methods:
1503 for result in self._sendError(
1504 AlertDescription.illegal_parameter,
1505 "Client Hello missing uncompressed method"):
1506 yield result
1507
1508
1509
1510 ext = clientHello.getExtension(ExtensionType.signature_algorithms)
1511 if clientHello.client_version >= (3, 3) and ext and not ext.sigalgs:
1512 for result in self._sendError(
1513 AlertDescription.decode_error,
1514 "Malformed signature_algorithms extension"):
1515 yield result
1516
1517
1518 alpnExt = clientHello.getExtension(ExtensionType.alpn)
1519 if alpnExt:
1520 if not alpnExt.protocol_names:
1521 for result in self._sendError(
1522 AlertDescription.decode_error,
1523 "Client sent empty list of ALPN names"):
1524 yield result
1525 for protocolName in alpnExt.protocol_names:
1526 if not protocolName:
1527 for result in self._sendError(
1528 AlertDescription.decode_error,
1529 "Client sent empty name in ALPN extension"):
1530 yield result
1531
1532
1533 sniExt = clientHello.getExtension(ExtensionType.server_name)
1534 if sniExt and sniExt.hostNames:
1535
1536 if len(sniExt.hostNames) > 1:
1537 for result in self._sendError(
1538 AlertDescription.illegal_parameter,
1539 "Client sent multiple host names in SNI extension"):
1540 yield result
1541 try:
1542 name = sniExt.hostNames[0].decode('ascii', 'strict')
1543 except UnicodeDecodeError:
1544 for result in self._sendError(
1545 AlertDescription.illegal_parameter,
1546 "Host name in SNI is not valid ASCII"):
1547 yield result
1548 if not is_valid_hostname(name):
1549 for result in self._sendError(
1550 AlertDescription.illegal_parameter,
1551 "Host name in SNI is not valid DNS name"):
1552 yield result
1553
1554 if sni and sni != name:
1555 alert = Alert().create(AlertDescription.unrecognized_name,
1556 AlertLevel.warning)
1557 for result in self._sendMsg(alert):
1558 yield result
1559
1560
1561 emsExt = clientHello.getExtension(ExtensionType.extended_master_secret)
1562 if emsExt and emsExt.extData:
1563 for result in self._sendError(
1564 AlertDescription.decode_error,
1565 "Non empty payload of the Extended "
1566 "Master Secret extension"):
1567 yield result
1568
1569
1570 elif clientHello.client_version > settings.maxVersion:
1571 self.version = settings.maxVersion
1572
1573 else:
1574
1575 self.version = clientHello.client_version
1576
1577
1578 if clientHello.client_version < settings.maxVersion and \
1579 CipherSuite.TLS_FALLBACK_SCSV in clientHello.cipher_suites:
1580 for result in self._sendError(\
1581 AlertDescription.inappropriate_fallback):
1582 yield result
1583
1584
1585
1586 client_groups = clientHello.getExtension(ExtensionType.supported_groups)
1587
1588
1589 group_intersect = [GroupName.secp256r1]
1590
1591 ffgroup_intersect = [GroupName.ffdhe2048]
1592 if client_groups is not None:
1593 client_groups = client_groups.groups
1594 if client_groups is None:
1595 client_groups = []
1596 server_groups = self._curveNamesToList(settings)
1597 group_intersect = [x for x in client_groups if x in server_groups]
1598
1599 server_groups = self._groupNamesToList(settings)
1600 ffgroup_intersect = [i for i in client_groups
1601 if i in server_groups]
1602
1603
1604 if not ffgroup_intersect:
1605 if any(i for i in client_groups if i in range(256, 512)):
1606 ffgroup_intersect = []
1607 else:
1608 ffgroup_intersect = [GroupName.ffdhe2048]
1609
1610
1611
1612
1613 cipherSuites = []
1614 if verifierDB:
1615 if certChain:
1616 cipherSuites += \
1617 CipherSuite.getSrpCertSuites(settings, self.version)
1618 cipherSuites += CipherSuite.getSrpSuites(settings, self.version)
1619 elif certChain:
1620 if group_intersect:
1621 cipherSuites += CipherSuite.getEcdheCertSuites(settings,
1622 self.version)
1623 if ffgroup_intersect:
1624 cipherSuites += CipherSuite.getDheCertSuites(settings,
1625 self.version)
1626 cipherSuites += CipherSuite.getCertSuites(settings, self.version)
1627 elif anon:
1628 cipherSuites += CipherSuite.getAnonSuites(settings, self.version)
1629 cipherSuites += CipherSuite.getEcdhAnonSuites(settings,
1630 self.version)
1631 else:
1632 assert(False)
1633 cipherSuites = CipherSuite.filterForVersion(cipherSuites,
1634 minVersion=self.version,
1635 maxVersion=self.version)
1636
1637 if clientHello.session_id and sessionCache:
1638 session = None
1639
1640
1641 if sessionCache and not session:
1642 try:
1643 session = sessionCache[clientHello.session_id]
1644 if not session.resumable:
1645 raise AssertionError()
1646
1647 if session.cipherSuite not in cipherSuites:
1648 for result in self._sendError(\
1649 AlertDescription.handshake_failure):
1650 yield result
1651 if session.cipherSuite not in clientHello.cipher_suites:
1652 for result in self._sendError(\
1653 AlertDescription.handshake_failure):
1654 yield result
1655 if clientHello.srp_username:
1656 if not session.srpUsername or \
1657 clientHello.srp_username != bytearray(session.srpUsername, "utf-8"):
1658 for result in self._sendError(\
1659 AlertDescription.handshake_failure):
1660 yield result
1661 if clientHello.server_name:
1662 if not session.serverName or \
1663 clientHello.server_name != bytearray(session.serverName, "utf-8"):
1664 for result in self._sendError(\
1665 AlertDescription.handshake_failure):
1666 yield result
1667 if session.encryptThenMAC and \
1668 not clientHello.getExtension(
1669 ExtensionType.encrypt_then_mac):
1670 for result in self._sendError(\
1671 AlertDescription.handshake_failure):
1672 yield result
1673
1674 if session.extendedMasterSecret and \
1675 not clientHello.getExtension(
1676 ExtensionType.extended_master_secret):
1677 for result in self._sendError(\
1678 AlertDescription.handshake_failure):
1679 yield result
1680
1681
1682 elif not session.extendedMasterSecret and \
1683 clientHello.getExtension(
1684 ExtensionType.extended_master_secret):
1685 session = None
1686 except KeyError:
1687 pass
1688
1689
1690 if session:
1691
1692 extensions = []
1693 if session.encryptThenMAC:
1694 self._recordLayer.encryptThenMAC = True
1695 mte = TLSExtension().create(ExtensionType.encrypt_then_mac,
1696 bytearray(0))
1697 extensions.append(mte)
1698 if session.extendedMasterSecret:
1699 ems = TLSExtension().create(ExtensionType.
1700 extended_master_secret,
1701 bytearray(0))
1702 extensions.append(ems)
1703 secureRenego = False
1704 renegoExt = clientHello.\
1705 getExtension(ExtensionType.renegotiation_info)
1706 if renegoExt:
1707 if renegoExt.renegotiated_connection:
1708 for result in self._sendError(
1709 AlertDescription.handshake_failure):
1710 yield result
1711 secureRenego = True
1712 elif CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV in \
1713 clientHello.cipher_suites:
1714 secureRenego = True
1715 if secureRenego:
1716 extensions.append(RenegotiationInfoExtension()
1717 .create(bytearray(0)))
1718 selectedALPN = None
1719 if alpn:
1720 alpnExt = clientHello.getExtension(ExtensionType.alpn)
1721 if alpnExt:
1722 for protocolName in alpnExt.protocol_names:
1723 if protocolName in alpn:
1724 ext = ALPNExtension().create([protocolName])
1725 extensions.append(ext)
1726 selectedALPN = protocolName
1727 break
1728 else:
1729 for result in self._sendError(
1730 AlertDescription.no_application_protocol,
1731 "No commonly supported application layer"
1732 "protocol supported"):
1733 yield result
1734
1735
1736 if not extensions:
1737 extensions = None
1738 serverHello = ServerHello()
1739 serverHello.create(self.version, getRandomBytes(32),
1740 session.sessionID, session.cipherSuite,
1741 CertificateType.x509, None, None,
1742 extensions=extensions)
1743 for result in self._sendMsg(serverHello):
1744 yield result
1745
1746
1747 self._calcPendingStates(session.cipherSuite,
1748 session.masterSecret,
1749 clientHello.random,
1750 serverHello.random,
1751 settings.cipherImplementations)
1752
1753
1754 for result in self._sendFinished(session.masterSecret,
1755 session.cipherSuite):
1756 yield result
1757 for result in self._getFinished(session.masterSecret,
1758 session.cipherSuite):
1759 yield result
1760
1761
1762 self.session = session
1763 self._clientRandom = clientHello.random
1764 self._serverRandom = serverHello.random
1765 self.session.appProto = selectedALPN
1766 yield None
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776 for cipherSuite in cipherSuites:
1777 if cipherSuite in clientHello.cipher_suites:
1778 break
1779 else:
1780 if client_groups and \
1781 any(i in range(256, 512) for i in client_groups) and \
1782 any(i in CipherSuite.dhAllSuites
1783 for i in clientHello.cipher_suites):
1784 for result in self._sendError(
1785 AlertDescription.insufficient_security,
1786 "FFDHE groups not acceptable and no other common "
1787 "ciphers"):
1788 yield result
1789 else:
1790 for result in self._sendError(\
1791 AlertDescription.handshake_failure,
1792 "No mutual ciphersuite"):
1793 yield result
1794 if cipherSuite in CipherSuite.srpAllSuites and \
1795 not clientHello.srp_username:
1796 for result in self._sendError(\
1797 AlertDescription.unknown_psk_identity,
1798 "Client sent a hello, but without the SRP username"):
1799 yield result
1800
1801
1802 if cipherSuite in CipherSuite.certAllSuites and CertificateType.x509 \
1803 not in clientHello.certificate_types:
1804 for result in self._sendError(\
1805 AlertDescription.handshake_failure,
1806 "the client doesn't support my certificate type"):
1807 yield result
1808
1809
1810
1811
1812 yield (clientHello, cipherSuite)
1813
1814 - def _serverSRPKeyExchange(self, clientHello, serverHello, verifierDB,
1815 cipherSuite, privateKey, serverCertChain,
1816 settings):
1817 """Perform the server side of SRP key exchange"""
1818 keyExchange = SRPKeyExchange(cipherSuite,
1819 clientHello,
1820 serverHello,
1821 privateKey,
1822 verifierDB)
1823
1824 try:
1825 sigHash = self._pickServerKeyExchangeSig(settings, clientHello,
1826 serverCertChain)
1827 except TLSHandshakeFailure as alert:
1828 for result in self._sendError(
1829 AlertDescription.handshake_failure,
1830 str(alert)):
1831 yield result
1832
1833
1834 try:
1835 serverKeyExchange = keyExchange.makeServerKeyExchange(sigHash)
1836 except TLSUnknownPSKIdentity:
1837 for result in self._sendError(\
1838 AlertDescription.unknown_psk_identity):
1839 yield result
1840
1841
1842
1843 msgs = []
1844 msgs.append(serverHello)
1845 if cipherSuite in CipherSuite.srpCertSuites:
1846 certificateMsg = Certificate(CertificateType.x509)
1847 certificateMsg.create(serverCertChain)
1848 msgs.append(certificateMsg)
1849 msgs.append(serverKeyExchange)
1850 msgs.append(ServerHelloDone())
1851 for result in self._sendMsgs(msgs):
1852 yield result
1853
1854
1855 for result in self._getMsg(ContentType.handshake,
1856 HandshakeType.client_key_exchange,
1857 cipherSuite):
1858 if result in (0,1): yield result
1859 else: break
1860 try:
1861 premasterSecret = keyExchange.processClientKeyExchange(result)
1862 except TLSIllegalParameterException:
1863 for result in self._sendError(AlertDescription.illegal_parameter,
1864 "Suspicious A value"):
1865 yield result
1866
1867 yield premasterSecret
1868
1869 - def _serverCertKeyExchange(self, clientHello, serverHello,
1870 serverCertChain, keyExchange,
1871 reqCert, reqCAs, cipherSuite,
1872 settings):
1873
1874
1875 msgs = []
1876
1877
1878 clientCertChain = None
1879
1880 msgs.append(serverHello)
1881 msgs.append(Certificate(CertificateType.x509).create(serverCertChain))
1882 try:
1883 sigHashAlg = self._pickServerKeyExchangeSig(settings, clientHello,
1884 serverCertChain)
1885 except TLSHandshakeFailure as alert:
1886 for result in self._sendError(
1887 AlertDescription.handshake_failure,
1888 str(alert)):
1889 yield result
1890 serverKeyExchange = keyExchange.makeServerKeyExchange(sigHashAlg)
1891 if serverKeyExchange is not None:
1892 msgs.append(serverKeyExchange)
1893 if reqCert:
1894 certificateRequest = CertificateRequest(self.version)
1895 if not reqCAs:
1896 reqCAs = []
1897 validSigAlgs = self._sigHashesToList(settings)
1898 certificateRequest.create([ClientCertificateType.rsa_sign],
1899 reqCAs,
1900 validSigAlgs)
1901 msgs.append(certificateRequest)
1902 msgs.append(ServerHelloDone())
1903 for result in self._sendMsgs(msgs):
1904 yield result
1905
1906
1907 if reqCert:
1908 if self.version == (3,0):
1909 for result in self._getMsg((ContentType.handshake,
1910 ContentType.alert),
1911 HandshakeType.certificate,
1912 CertificateType.x509):
1913 if result in (0,1): yield result
1914 else: break
1915 msg = result
1916
1917 if isinstance(msg, Alert):
1918
1919 alert = msg
1920 if alert.description != \
1921 AlertDescription.no_certificate:
1922 self._shutdown(False)
1923 raise TLSRemoteAlert(alert)
1924 elif isinstance(msg, Certificate):
1925 clientCertificate = msg
1926 if clientCertificate.certChain and \
1927 clientCertificate.certChain.getNumCerts()!=0:
1928 clientCertChain = clientCertificate.certChain
1929 else:
1930 raise AssertionError()
1931 elif self.version in ((3,1), (3,2), (3,3)):
1932 for result in self._getMsg(ContentType.handshake,
1933 HandshakeType.certificate,
1934 CertificateType.x509):
1935 if result in (0,1): yield result
1936 else: break
1937 clientCertificate = result
1938 if clientCertificate.certChain and \
1939 clientCertificate.certChain.getNumCerts()!=0:
1940 clientCertChain = clientCertificate.certChain
1941 else:
1942 raise AssertionError()
1943
1944
1945 for result in self._getMsg(ContentType.handshake,
1946 HandshakeType.client_key_exchange,
1947 cipherSuite):
1948 if result in (0,1): yield result
1949 else: break
1950 clientKeyExchange = result
1951
1952
1953 try:
1954 premasterSecret = \
1955 keyExchange.processClientKeyExchange(clientKeyExchange)
1956 except TLSIllegalParameterException as alert:
1957 for result in self._sendError(AlertDescription.illegal_parameter,
1958 str(alert)):
1959 yield result
1960
1961
1962 self._certificate_verify_handshake_hash = self._handshake_hash.copy()
1963 if clientCertChain:
1964 for result in self._getMsg(ContentType.handshake,
1965 HandshakeType.certificate_verify):
1966 if result in (0, 1):
1967 yield result
1968 else: break
1969 certificateVerify = result
1970 signatureAlgorithm = None
1971 if self.version == (3, 3):
1972 validSigAlgs = self._sigHashesToList(settings)
1973 if certificateVerify.signatureAlgorithm not in validSigAlgs:
1974 for result in self._sendError(\
1975 AlertDescription.decryption_failed,
1976 "Invalid signature on Certificate Verify"):
1977 yield result
1978 signatureAlgorithm = certificateVerify.signatureAlgorithm
1979
1980 cvhh = self._certificate_verify_handshake_hash
1981 verifyBytes = KeyExchange.calcVerifyBytes(self.version,
1982 cvhh,
1983 signatureAlgorithm,
1984 premasterSecret,
1985 clientHello.random,
1986 serverHello.random)
1987 publicKey = clientCertChain.getEndEntityPublicKey()
1988 if len(publicKey) < settings.minKeySize:
1989 for result in self._sendError(\
1990 AlertDescription.handshake_failure,
1991 "Client's public key too small: %d" % len(publicKey)):
1992 yield result
1993
1994 if len(publicKey) > settings.maxKeySize:
1995 for result in self._sendError(\
1996 AlertDescription.handshake_failure,
1997 "Client's public key too large: %d" % len(publicKey)):
1998 yield result
1999
2000 scheme = SignatureScheme.toRepr(signatureAlgorithm)
2001
2002
2003 hashName = None
2004 saltLen = 0
2005 if scheme is None:
2006 padding = 'pkcs1'
2007 else:
2008 padding = SignatureScheme.getPadding(scheme)
2009 if padding == 'pss':
2010 hashName = SignatureScheme.getHash(scheme)
2011 saltLen = getattr(hashlib, hashName)().digest_size
2012
2013 if not publicKey.verify(certificateVerify.signature,
2014 verifyBytes,
2015 padding,
2016 hashName,
2017 saltLen):
2018 for result in self._sendError(\
2019 AlertDescription.decrypt_error,
2020 "Signature failed to verify"):
2021 yield result
2022 yield (premasterSecret, clientCertChain)
2023
2024
2051
2052
2053 - def _serverFinished(self, premasterSecret, clientRandom, serverRandom,
2054 cipherSuite, cipherImplementations, nextProtos):
2055 if self.extendedMasterSecret:
2056 cvhh = self._certificate_verify_handshake_hash
2057
2058
2059
2060 if not cvhh:
2061 cvhh = self._handshake_hash
2062 masterSecret = calcExtendedMasterSecret(self.version,
2063 cipherSuite,
2064 premasterSecret,
2065 cvhh)
2066 else:
2067 masterSecret = calcMasterSecret(self.version,
2068 cipherSuite,
2069 premasterSecret,
2070 clientRandom,
2071 serverRandom)
2072
2073
2074 self._calcPendingStates(cipherSuite, masterSecret,
2075 clientRandom, serverRandom,
2076 cipherImplementations)
2077
2078
2079 for result in self._getFinished(masterSecret,
2080 cipherSuite,
2081 expect_next_protocol=nextProtos is not None):
2082 yield result
2083
2084 for result in self._sendFinished(masterSecret, cipherSuite):
2085 yield result
2086
2087 yield masterSecret
2088
2089
2090
2091
2092
2093
2094
2095 - def _sendFinished(self, masterSecret, cipherSuite=None, nextProto=None):
2125
2126 - def _getFinished(self, masterSecret, cipherSuite=None,
2127 expect_next_protocol=False, nextProto=None):
2128
2129 for result in self._getMsg(ContentType.change_cipher_spec):
2130 if result in (0,1):
2131 yield result
2132 changeCipherSpec = result
2133
2134 if changeCipherSpec.type != 1:
2135 for result in self._sendError(AlertDescription.illegal_parameter,
2136 "ChangeCipherSpec type incorrect"):
2137 yield result
2138
2139
2140 self._changeReadState()
2141
2142
2143 if expect_next_protocol:
2144 for result in self._getMsg(ContentType.handshake, HandshakeType.next_protocol):
2145 if result in (0,1):
2146 yield result
2147 if result is None:
2148 for result in self._sendError(AlertDescription.unexpected_message,
2149 "Didn't get NextProtocol message"):
2150 yield result
2151
2152 self.next_proto = result.next_proto
2153 else:
2154 self.next_proto = None
2155
2156
2157 if nextProto:
2158 self.next_proto = nextProto
2159
2160
2161 verifyData = calcFinished(self.version,
2162 masterSecret,
2163 cipherSuite,
2164 self._handshake_hash,
2165 not self._client)
2166
2167
2168 for result in self._getMsg(ContentType.handshake,
2169 HandshakeType.finished):
2170 if result in (0,1):
2171 yield result
2172 finished = result
2173 if finished.verify_data != verifyData:
2174 for result in self._sendError(AlertDescription.decrypt_error,
2175 "Finished message is incorrect"):
2176 yield result
2177
2203
2204 @staticmethod
2229
2230 @staticmethod
2232 """Convert list of valid signature hashes to array of tuples"""
2233 certType = None
2234 if certList:
2235 certType = certList.x509List[0].certAlg
2236
2237 sigAlgs = []
2238 for schemeName in settings.rsaSchemes:
2239 for hashName in settings.rsaSigHashes:
2240
2241
2242 if certType == "rsa-pss" and schemeName == "pkcs1":
2243 continue
2244 try:
2245
2246
2247 if schemeName == 'pss' and hashName == 'sha512'\
2248 and privateKey and privateKey.n < 2**2047:
2249 continue
2250 sigAlgs.append(getattr(SignatureScheme,
2251 "rsa_{0}_{1}".format(schemeName,
2252 hashName)))
2253 except AttributeError:
2254 if schemeName == 'pkcs1':
2255 sigAlgs.append((getattr(HashAlgorithm, hashName),
2256 SignatureAlgorithm.rsa))
2257 continue
2258 return sigAlgs
2259
2260 @staticmethod
2262 """Convert list of acceptable curves to array identifiers"""
2263 return [getattr(GroupName, val) for val in settings.eccCurves]
2264
2265 @staticmethod
2267 """Convert list of acceptable ff groups to TLS identifiers."""
2268 return [getattr(GroupName, val) for val in settings.dhGroups]
2269