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