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