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 alpnExt = clientHello.getExtension(ExtensionType.alpn)
1457 if alpnExt:
1458 for protocolName in alpnExt.protocol_names:
1459 if not protocolName:
1460 for result in self._sendError(
1461 AlertDescription.illegal_parameter,
1462 "Client sent empty name in ALPN extension"):
1463 yield result
1464
1465
1466 elif clientHello.client_version > settings.maxVersion:
1467 self.version = settings.maxVersion
1468
1469 else:
1470
1471 self.version = clientHello.client_version
1472
1473
1474 if clientHello.client_version < settings.maxVersion and \
1475 CipherSuite.TLS_FALLBACK_SCSV in clientHello.cipher_suites:
1476 for result in self._sendError(\
1477 AlertDescription.inappropriate_fallback):
1478 yield result
1479
1480
1481
1482 client_groups = clientHello.getExtension(ExtensionType.supported_groups)
1483 group_intersect = []
1484 if client_groups is not None:
1485 client_groups = client_groups.groups
1486 if client_groups is None:
1487 client_groups = []
1488 server_groups = self._curveNamesToList(settings)
1489 group_intersect = [x for x in client_groups if x in server_groups]
1490
1491
1492
1493 cipherSuites = []
1494 if verifierDB:
1495 if certChain:
1496 cipherSuites += \
1497 CipherSuite.getSrpCertSuites(settings, self.version)
1498 cipherSuites += CipherSuite.getSrpSuites(settings, self.version)
1499 elif certChain:
1500 if group_intersect:
1501 cipherSuites += CipherSuite.getEcdheCertSuites(settings,
1502 self.version)
1503 cipherSuites += CipherSuite.getDheCertSuites(settings, self.version)
1504 cipherSuites += CipherSuite.getCertSuites(settings, self.version)
1505 elif anon:
1506 cipherSuites += CipherSuite.getAnonSuites(settings, self.version)
1507 cipherSuites += CipherSuite.getEcdhAnonSuites(settings,
1508 self.version)
1509 else:
1510 assert(False)
1511 cipherSuites = CipherSuite.filterForVersion(cipherSuites,
1512 minVersion=self.version,
1513 maxVersion=self.version)
1514
1515 if clientHello.session_id and sessionCache:
1516 session = None
1517
1518
1519 if sessionCache and not session:
1520 try:
1521 session = sessionCache[clientHello.session_id]
1522 if not session.resumable:
1523 raise AssertionError()
1524
1525 if session.cipherSuite not in cipherSuites:
1526 for result in self._sendError(\
1527 AlertDescription.handshake_failure):
1528 yield result
1529 if session.cipherSuite not in clientHello.cipher_suites:
1530 for result in self._sendError(\
1531 AlertDescription.handshake_failure):
1532 yield result
1533 if clientHello.srp_username:
1534 if not session.srpUsername or \
1535 clientHello.srp_username != bytearray(session.srpUsername, "utf-8"):
1536 for result in self._sendError(\
1537 AlertDescription.handshake_failure):
1538 yield result
1539 if clientHello.server_name:
1540 if not session.serverName or \
1541 clientHello.server_name != bytearray(session.serverName, "utf-8"):
1542 for result in self._sendError(\
1543 AlertDescription.handshake_failure):
1544 yield result
1545 if session.encryptThenMAC and \
1546 not clientHello.getExtension(
1547 ExtensionType.encrypt_then_mac):
1548 for result in self._sendError(\
1549 AlertDescription.handshake_failure):
1550 yield result
1551 if session.extendedMasterSecret and \
1552 not clientHello.getExtension(
1553 ExtensionType.extended_master_secret):
1554 for result in self._sendError(\
1555 AlertDescription.handshake_failure):
1556 yield result
1557 except KeyError:
1558 pass
1559
1560
1561 if session:
1562
1563 extensions = []
1564 if session.encryptThenMAC:
1565 self._recordLayer.encryptThenMAC = True
1566 mte = TLSExtension().create(ExtensionType.encrypt_then_mac,
1567 bytearray(0))
1568 extensions.append(mte)
1569 if session.extendedMasterSecret:
1570 ems = TLSExtension().create(ExtensionType.
1571 extended_master_secret,
1572 bytearray(0))
1573 extensions.append(ems)
1574 secureRenego = False
1575 renegoExt = clientHello.\
1576 getExtension(ExtensionType.renegotiation_info)
1577 if renegoExt:
1578 if renegoExt.renegotiated_connection:
1579 for result in self._sendError(
1580 AlertDescription.handshake_failure):
1581 yield result
1582 secureRenego = True
1583 elif CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV in \
1584 clientHello.cipher_suites:
1585 secureRenego = True
1586 if secureRenego:
1587 extensions.append(RenegotiationInfoExtension()
1588 .create(bytearray(0)))
1589 selectedALPN = None
1590 if alpn:
1591 alpnExt = clientHello.getExtension(ExtensionType.alpn)
1592 if alpnExt:
1593 for protocolName in alpnExt.protocol_names:
1594 if protocolName in alpn:
1595 ext = ALPNExtension().create([protocolName])
1596 extensions.append(ext)
1597 selectedALPN = protocolName
1598 break
1599 else:
1600 for result in self._sendError(
1601 AlertDescription.no_application_protocol,
1602 "No commonly supported application layer"
1603 "protocol supported"):
1604 yield result
1605
1606
1607 if not extensions:
1608 extensions = None
1609 serverHello = ServerHello()
1610 serverHello.create(self.version, getRandomBytes(32),
1611 session.sessionID, session.cipherSuite,
1612 CertificateType.x509, None, None,
1613 extensions=extensions)
1614 for result in self._sendMsg(serverHello):
1615 yield result
1616
1617
1618 self._calcPendingStates(session.cipherSuite,
1619 session.masterSecret,
1620 clientHello.random,
1621 serverHello.random,
1622 settings.cipherImplementations)
1623
1624
1625 for result in self._sendFinished(session.masterSecret,
1626 session.cipherSuite):
1627 yield result
1628 for result in self._getFinished(session.masterSecret,
1629 session.cipherSuite):
1630 yield result
1631
1632
1633 self.session = session
1634 self._clientRandom = clientHello.random
1635 self._serverRandom = serverHello.random
1636 self.session.appProto = selectedALPN
1637 yield None
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647 for cipherSuite in cipherSuites:
1648 if cipherSuite in clientHello.cipher_suites:
1649 break
1650 else:
1651 for result in self._sendError(\
1652 AlertDescription.handshake_failure,
1653 "No mutual ciphersuite"):
1654 yield result
1655 if cipherSuite in CipherSuite.srpAllSuites and \
1656 not clientHello.srp_username:
1657 for result in self._sendError(\
1658 AlertDescription.unknown_psk_identity,
1659 "Client sent a hello, but without the SRP username"):
1660 yield result
1661
1662
1663 if cipherSuite in CipherSuite.certAllSuites and CertificateType.x509 \
1664 not in clientHello.certificate_types:
1665 for result in self._sendError(\
1666 AlertDescription.handshake_failure,
1667 "the client doesn't support my certificate type"):
1668 yield result
1669
1670
1671
1672
1673 yield (clientHello, cipherSuite)
1674
1675 - def _serverSRPKeyExchange(self, clientHello, serverHello, verifierDB,
1676 cipherSuite, privateKey, serverCertChain,
1677 settings):
1722
1723 - def _serverCertKeyExchange(self, clientHello, serverHello,
1724 serverCertChain, keyExchange,
1725 reqCert, reqCAs, cipherSuite,
1726 settings):
1727
1728
1729 msgs = []
1730
1731
1732 clientCertChain = None
1733
1734 msgs.append(serverHello)
1735 msgs.append(Certificate(CertificateType.x509).create(serverCertChain))
1736 sigHashAlg = self._pickServerKeyExchangeSig(settings, clientHello)
1737 serverKeyExchange = keyExchange.makeServerKeyExchange(sigHashAlg)
1738 if serverKeyExchange is not None:
1739 msgs.append(serverKeyExchange)
1740 if reqCert:
1741 certificateRequest = CertificateRequest(self.version)
1742 if not reqCAs:
1743 reqCAs = []
1744 validSigAlgs = self._sigHashesToList(settings)
1745 certificateRequest.create([ClientCertificateType.rsa_sign],
1746 reqCAs,
1747 validSigAlgs)
1748 msgs.append(certificateRequest)
1749 msgs.append(ServerHelloDone())
1750 for result in self._sendMsgs(msgs):
1751 yield result
1752
1753
1754 if reqCert:
1755 if self.version == (3,0):
1756 for result in self._getMsg((ContentType.handshake,
1757 ContentType.alert),
1758 HandshakeType.certificate,
1759 CertificateType.x509):
1760 if result in (0,1): yield result
1761 else: break
1762 msg = result
1763
1764 if isinstance(msg, Alert):
1765
1766 alert = msg
1767 if alert.description != \
1768 AlertDescription.no_certificate:
1769 self._shutdown(False)
1770 raise TLSRemoteAlert(alert)
1771 elif isinstance(msg, Certificate):
1772 clientCertificate = msg
1773 if clientCertificate.certChain and \
1774 clientCertificate.certChain.getNumCerts()!=0:
1775 clientCertChain = clientCertificate.certChain
1776 else:
1777 raise AssertionError()
1778 elif self.version in ((3,1), (3,2), (3,3)):
1779 for result in self._getMsg(ContentType.handshake,
1780 HandshakeType.certificate,
1781 CertificateType.x509):
1782 if result in (0,1): yield result
1783 else: break
1784 clientCertificate = result
1785 if clientCertificate.certChain and \
1786 clientCertificate.certChain.getNumCerts()!=0:
1787 clientCertChain = clientCertificate.certChain
1788 else:
1789 raise AssertionError()
1790
1791
1792 for result in self._getMsg(ContentType.handshake,
1793 HandshakeType.client_key_exchange,
1794 cipherSuite):
1795 if result in (0,1): yield result
1796 else: break
1797 clientKeyExchange = result
1798
1799
1800 try:
1801 premasterSecret = \
1802 keyExchange.processClientKeyExchange(clientKeyExchange)
1803 except TLSIllegalParameterException as alert:
1804 for result in self._sendError(AlertDescription.illegal_parameter,
1805 str(alert)):
1806 yield result
1807
1808
1809 if clientCertChain:
1810 handshakeHash = self._handshake_hash.copy()
1811 for result in self._getMsg(ContentType.handshake,
1812 HandshakeType.certificate_verify):
1813 if result in (0, 1):
1814 yield result
1815 else: break
1816 certificateVerify = result
1817 signatureAlgorithm = None
1818 if self.version == (3, 3):
1819 validSigAlgs = self._sigHashesToList(settings)
1820 if certificateVerify.signatureAlgorithm not in validSigAlgs:
1821 for result in self._sendError(\
1822 AlertDescription.decryption_failed,
1823 "Invalid signature on Certificate Verify"):
1824 yield result
1825 signatureAlgorithm = certificateVerify.signatureAlgorithm
1826
1827 verifyBytes = KeyExchange.calcVerifyBytes(self.version,
1828 handshakeHash,
1829 signatureAlgorithm,
1830 premasterSecret,
1831 clientHello.random,
1832 serverHello.random)
1833 publicKey = clientCertChain.getEndEntityPublicKey()
1834 if len(publicKey) < settings.minKeySize:
1835 for result in self._sendError(\
1836 AlertDescription.handshake_failure,
1837 "Client's public key too small: %d" % len(publicKey)):
1838 yield result
1839
1840 if len(publicKey) > settings.maxKeySize:
1841 for result in self._sendError(\
1842 AlertDescription.handshake_failure,
1843 "Client's public key too large: %d" % len(publicKey)):
1844 yield result
1845
1846 if not publicKey.verify(certificateVerify.signature, verifyBytes):
1847 for result in self._sendError(\
1848 AlertDescription.decrypt_error,
1849 "Signature failed to verify"):
1850 yield result
1851 yield (premasterSecret, clientCertChain)
1852
1853
1880
1881
1882 - def _serverFinished(self, premasterSecret, clientRandom, serverRandom,
1883 cipherSuite, cipherImplementations, nextProtos):
1884 if self.extendedMasterSecret:
1885 masterSecret = calcExtendedMasterSecret(self.version,
1886 cipherSuite,
1887 premasterSecret,
1888 self._handshake_hash)
1889 else:
1890 masterSecret = calcMasterSecret(self.version,
1891 cipherSuite,
1892 premasterSecret,
1893 clientRandom,
1894 serverRandom)
1895
1896
1897 self._calcPendingStates(cipherSuite, masterSecret,
1898 clientRandom, serverRandom,
1899 cipherImplementations)
1900
1901
1902 for result in self._getFinished(masterSecret,
1903 cipherSuite,
1904 expect_next_protocol=nextProtos is not None):
1905 yield result
1906
1907 for result in self._sendFinished(masterSecret, cipherSuite):
1908 yield result
1909
1910 yield masterSecret
1911
1912
1913
1914
1915
1916
1917
1918 - def _sendFinished(self, masterSecret, cipherSuite=None, nextProto=None):
1948
1949 - def _getFinished(self, masterSecret, cipherSuite=None,
1950 expect_next_protocol=False, nextProto=None):
1951
1952 for result in self._getMsg(ContentType.change_cipher_spec):
1953 if result in (0,1):
1954 yield result
1955 changeCipherSpec = result
1956
1957 if changeCipherSpec.type != 1:
1958 for result in self._sendError(AlertDescription.illegal_parameter,
1959 "ChangeCipherSpec type incorrect"):
1960 yield result
1961
1962
1963 self._changeReadState()
1964
1965
1966 if expect_next_protocol:
1967 for result in self._getMsg(ContentType.handshake, HandshakeType.next_protocol):
1968 if result in (0,1):
1969 yield result
1970 if result is None:
1971 for result in self._sendError(AlertDescription.unexpected_message,
1972 "Didn't get NextProtocol message"):
1973 yield result
1974
1975 self.next_proto = result.next_proto
1976 else:
1977 self.next_proto = None
1978
1979
1980 if nextProto:
1981 self.next_proto = nextProto
1982
1983
1984 verifyData = calcFinished(self.version,
1985 masterSecret,
1986 cipherSuite,
1987 self._handshake_hash,
1988 not self._client)
1989
1990
1991 for result in self._getMsg(ContentType.handshake,
1992 HandshakeType.finished):
1993 if result in (0,1):
1994 yield result
1995 finished = result
1996 if finished.verify_data != verifyData:
1997 for result in self._sendError(AlertDescription.decrypt_error,
1998 "Finished message is incorrect"):
1999 yield result
2000
2026
2027 @staticmethod
2029 """Pick a hash that matches most closely the supported ones"""
2030 hashAndAlgsExt = clientHello.getExtension(\
2031 ExtensionType.signature_algorithms)
2032
2033 if hashAndAlgsExt is None or hashAndAlgsExt.sigalgs is None:
2034
2035
2036 return "sha1"
2037
2038 rsaHashes = [alg[0] for alg in hashAndAlgsExt.sigalgs
2039 if alg[1] == SignatureAlgorithm.rsa]
2040 for hashName in settings.rsaSigHashes:
2041 hashID = getattr(HashAlgorithm, hashName)
2042 if hashID in rsaHashes:
2043 return hashName
2044
2045
2046 return "sha1"
2047
2048 @staticmethod
2050 """Convert list of valid signature hashes to array of tuples"""
2051 sigAlgs = []
2052 for hashName in settings.rsaSigHashes:
2053 sigAlgs.append((getattr(HashAlgorithm, hashName),
2054 SignatureAlgorithm.rsa))
2055 return sigAlgs
2056
2057 @staticmethod
2059 """Convert list of acceptable curves to array identifiers"""
2060 return [getattr(GroupName, val) for val in settings.eccCurves]
2061