Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(311)

Side by Side Diff: third_party/tlslite/tlslite/tlsconnection.py

Issue 2205433002: Implement ALPN in tlslite. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase; update alpn.patch. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Authors: 1 # Authors:
2 # Trevor Perrin 2 # Trevor Perrin
3 # Google - added reqCAs parameter 3 # Google - added reqCAs parameter
4 # Google (adapted by Sam Rushing and Marcelo Fernandez) - NPN support 4 # Google (adapted by Sam Rushing and Marcelo Fernandez) - NPN support
5 # Dimitris Moraitis - Anon ciphersuites 5 # Dimitris Moraitis - Anon ciphersuites
6 # Martin von Loewis - python 3 port 6 # Martin von Loewis - python 3 port
7 # Yngve Pettersen (ported by Paul Sokolovsky) - TLS 1.2 7 # Yngve Pettersen (ported by Paul Sokolovsky) - TLS 1.2
8 # 8 #
9 # See the LICENSE file for legal information regarding use of this file. 9 # See the LICENSE file for legal information regarding use of this file.
10 10
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 # 330 #
331 # If 'async' is True, the generator is returned to the caller, 331 # If 'async' is True, the generator is returned to the caller,
332 # otherwise it is executed to completion here. 332 # otherwise it is executed to completion here.
333 if async: 333 if async:
334 return handshaker 334 return handshaker
335 for result in handshaker: 335 for result in handshaker:
336 pass 336 pass
337 337
338 def handshakeClientCert(self, certChain=None, privateKey=None, 338 def handshakeClientCert(self, certChain=None, privateKey=None,
339 session=None, settings=None, checker=None, 339 session=None, settings=None, checker=None,
340 nextProtos=None, reqTack=True, serverName="", 340 reqTack=True, serverName="", async=False):
341 async=False):
342 """Perform a certificate-based handshake in the role of client. 341 """Perform a certificate-based handshake in the role of client.
343 342
344 This function performs an SSL or TLS handshake. The server 343 This function performs an SSL or TLS handshake. The server
345 will authenticate itself using an X.509 certificate 344 will authenticate itself using an X.509 certificate
346 chain. If the handshake succeeds, the server's certificate 345 chain. If the handshake succeeds, the server's certificate
347 chain will be stored in the session's serverCertChain attribute. 346 chain will be stored in the session's serverCertChain attribute.
348 Unless a checker object is passed in, this function does no 347 Unless a checker object is passed in, this function does no
349 validation or checking of the server's certificate chain. 348 validation or checking of the server's certificate chain.
350 349
351 If the server requests client authentication, the 350 If the server requests client authentication, the
(...skipping 24 matching lines...) Expand all
376 375
377 @type settings: L{tlslite.handshakesettings.HandshakeSettings} 376 @type settings: L{tlslite.handshakesettings.HandshakeSettings}
378 @param settings: Various settings which can be used to control 377 @param settings: Various settings which can be used to control
379 the ciphersuites, certificate types, and SSL/TLS versions 378 the ciphersuites, certificate types, and SSL/TLS versions
380 offered by the client. 379 offered by the client.
381 380
382 @type checker: L{tlslite.checker.Checker} 381 @type checker: L{tlslite.checker.Checker}
383 @param checker: A Checker instance. This instance will be 382 @param checker: A Checker instance. This instance will be
384 invoked to examine the other party's authentication 383 invoked to examine the other party's authentication
385 credentials, if the handshake completes succesfully. 384 credentials, if the handshake completes succesfully.
386 385
387 @type nextProtos: list of strings.
388 @param nextProtos: A list of upper layer protocols ordered by
389 preference, to use in the Next-Protocol Negotiation Extension.
390
391 @type reqTack: bool 386 @type reqTack: bool
392 @param reqTack: Whether or not to send a "tack" TLS Extension, 387 @param reqTack: Whether or not to send a "tack" TLS Extension,
393 requesting the server return a TackExtension if it has one. 388 requesting the server return a TackExtension if it has one.
394 389
395 @type serverName: string 390 @type serverName: string
396 @param serverName: The ServerNameIndication TLS Extension. 391 @param serverName: The ServerNameIndication TLS Extension.
397 392
398 @type async: bool 393 @type async: bool
399 @param async: If False, this function will block until the 394 @param async: If False, this function will block until the
400 handshake is completed. If True, this function will return a 395 handshake is completed. If True, this function will return a
401 generator. Successive invocations of the generator will 396 generator. Successive invocations of the generator will
402 return 0 if it is waiting to read from the socket, 1 if it is 397 return 0 if it is waiting to read from the socket, 1 if it is
403 waiting to write to the socket, or will raise StopIteration if 398 waiting to write to the socket, or will raise StopIteration if
404 the handshake operation is completed. 399 the handshake operation is completed.
405 400
406 @rtype: None or an iterable 401 @rtype: None or an iterable
407 @return: If 'async' is True, a generator object will be 402 @return: If 'async' is True, a generator object will be
408 returned. 403 returned.
409 404
410 @raise socket.error: If a socket error occurs. 405 @raise socket.error: If a socket error occurs.
411 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed 406 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
412 without a preceding alert. 407 without a preceding alert.
413 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled. 408 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
414 @raise tlslite.errors.TLSAuthenticationError: If the checker 409 @raise tlslite.errors.TLSAuthenticationError: If the checker
415 doesn't like the other party's authentication credentials. 410 doesn't like the other party's authentication credentials.
416 """ 411 """
417 handshaker = self._handshakeClientAsync(certParams=(certChain, 412 handshaker = self._handshakeClientAsync(certParams=(certChain,
418 privateKey), session=session, settings=settings, 413 privateKey), session=session, settings=settings,
419 checker=checker, serverName=serverName, 414 checker=checker, serverName=serverName,
420 nextProtos=nextProtos, reqTack=reqTack) 415 reqTack=reqTack)
421 # The handshaker is a Python Generator which executes the handshake. 416 # The handshaker is a Python Generator which executes the handshake.
422 # It allows the handshake to be run in a "piecewise", asynchronous 417 # It allows the handshake to be run in a "piecewise", asynchronous
423 # fashion, returning 1 when it is waiting to able to write, 0 when 418 # fashion, returning 1 when it is waiting to able to write, 0 when
424 # it is waiting to read. 419 # it is waiting to read.
425 # 420 #
426 # If 'async' is True, the generator is returned to the caller, 421 # If 'async' is True, the generator is returned to the caller,
427 # otherwise it is executed to completion here. 422 # otherwise it is executed to completion here.
428 if async: 423 if async:
429 return handshaker 424 return handshaker
430 for result in handshaker: 425 for result in handshaker:
431 pass 426 pass
432 427
433 428
434 def _handshakeClientAsync(self, srpParams=(), certParams=(), anonParams=(), 429 def _handshakeClientAsync(self, srpParams=(), certParams=(), anonParams=(),
435 session=None, settings=None, checker=None, 430 session=None, settings=None, checker=None,
436 nextProtos=None, serverName="", reqTack=True): 431 serverName="", reqTack=True):
437 432
438 handshaker = self._handshakeClientAsyncHelper(srpParams=srpParams, 433 handshaker = self._handshakeClientAsyncHelper(srpParams=srpParams,
439 certParams=certParams, 434 certParams=certParams,
440 anonParams=anonParams, 435 anonParams=anonParams,
441 session=session, 436 session=session,
442 settings=settings, 437 settings=settings,
443 serverName=serverName, 438 serverName=serverName,
444 nextProtos=nextProtos,
445 reqTack=reqTack) 439 reqTack=reqTack)
446 for result in self._handshakeWrapperAsync(handshaker, checker): 440 for result in self._handshakeWrapperAsync(handshaker, checker):
447 yield result 441 yield result
448 442
449 443
450 def _handshakeClientAsyncHelper(self, srpParams, certParams, anonParams, 444 def _handshakeClientAsyncHelper(self, srpParams, certParams, anonParams,
451 session, settings, serverName, nextProtos, reqTac k): 445 session, settings, serverName, reqTack):
452 446
453 self._handshakeStart(client=True) 447 self._handshakeStart(client=True)
454 448
455 #Unpack parameters 449 #Unpack parameters
456 srpUsername = None # srpParams[0] 450 srpUsername = None # srpParams[0]
457 password = None # srpParams[1] 451 password = None # srpParams[1]
458 clientCertChain = None # certParams[0] 452 clientCertChain = None # certParams[0]
459 privateKey = None # certParams[1] 453 privateKey = None # certParams[1]
460 454
461 # Allow only one of (srpParams, certParams, anonParams) 455 # Allow only one of (srpParams, certParams, anonParams)
(...skipping 16 matching lines...) Expand all
478 raise ValueError("Caller passed a password but no username") 472 raise ValueError("Caller passed a password but no username")
479 if clientCertChain and not privateKey: 473 if clientCertChain and not privateKey:
480 raise ValueError("Caller passed a certChain but no privateKey") 474 raise ValueError("Caller passed a certChain but no privateKey")
481 if privateKey and not clientCertChain: 475 if privateKey and not clientCertChain:
482 raise ValueError("Caller passed a privateKey but no certChain") 476 raise ValueError("Caller passed a privateKey but no certChain")
483 if reqTack: 477 if reqTack:
484 if not tackpyLoaded: 478 if not tackpyLoaded:
485 reqTack = False 479 reqTack = False
486 if not settings or not settings.useExperimentalTackExtension: 480 if not settings or not settings.useExperimentalTackExtension:
487 reqTack = False 481 reqTack = False
488 if nextProtos is not None:
489 if len(nextProtos) == 0:
490 raise ValueError("Caller passed no nextProtos")
491
492 # Validates the settings and filters out any unsupported ciphers 482 # Validates the settings and filters out any unsupported ciphers
493 # or crypto libraries that were requested 483 # or crypto libraries that were requested
494 if not settings: 484 if not settings:
495 settings = HandshakeSettings() 485 settings = HandshakeSettings()
496 settings = settings._filter() 486 settings = settings._filter()
497 487
488 if settings.alpnProtos is not None:
489 if len(settings.alpnProtos) == 0:
490 raise ValueError("Caller passed no alpnProtos")
491 if settings.nextProtos is not None:
492 if len(settings.nextProtos) == 0:
493 raise ValueError("Caller passed no nextProtos")
494
498 if clientCertChain: 495 if clientCertChain:
499 if not isinstance(clientCertChain, X509CertChain): 496 if not isinstance(clientCertChain, X509CertChain):
500 raise ValueError("Unrecognized certificate type") 497 raise ValueError("Unrecognized certificate type")
501 if "x509" not in settings.certificateTypes: 498 if "x509" not in settings.certificateTypes:
502 raise ValueError("Client certificate doesn't match "\ 499 raise ValueError("Client certificate doesn't match "\
503 "Handshake Settings") 500 "Handshake Settings")
504 501
505 if session: 502 if session:
506 # session.valid() ensures session is resumable and has 503 # session.valid() ensures session is resumable and has
507 # non-empty sessionID 504 # non-empty sessionID
(...skipping 15 matching lines...) Expand all
523 #We'll use this for the ClientHello, and if an error occurs 520 #We'll use this for the ClientHello, and if an error occurs
524 #parsing the Server Hello, we'll use this version for the response 521 #parsing the Server Hello, we'll use this version for the response
525 self.version = settings.maxVersion 522 self.version = settings.maxVersion
526 523
527 # OK Start sending messages! 524 # OK Start sending messages!
528 # ***************************** 525 # *****************************
529 526
530 # Send the ClientHello. 527 # Send the ClientHello.
531 for result in self._clientSendClientHello(settings, session, 528 for result in self._clientSendClientHello(settings, session,
532 srpUsername, srpParams, certParams, 529 srpUsername, srpParams, certParams,
533 anonParams, serverName, nextProtos, 530 anonParams, serverName, reqTack):
534 reqTack):
535 if result in (0,1): yield result 531 if result in (0,1): yield result
536 else: break 532 else: break
537 clientHello = result 533 clientHello = result
538 534
539 #Get the ServerHello. 535 #Get the ServerHello.
540 for result in self._clientGetServerHello(settings, clientHello): 536 for result in self._clientGetServerHello(settings, clientHello):
541 if result in (0,1): yield result 537 if result in (0,1): yield result
542 else: break 538 else: break
543 serverHello = result 539 serverHello = result
544 cipherSuite = serverHello.cipher_suite 540 cipherSuite = serverHello.cipher_suite
545 541
546 # Choose a matching Next Protocol from server list against ours
547 # (string or None)
davidben 2016/08/04 22:29:26 Unintentional lost comment?
Bence 2016/08/05 14:27:55 Oops. Done.
548 nextProto = self._clientSelectNextProto(nextProtos, serverHello) 542 nextProto = self._clientSelectNextProto(nextProtos, serverHello)
davidben 2016/08/04 22:29:26 This variable isn't even defined anymore. I suspec
Bence 2016/08/05 14:27:55 (1) Done. (2) I have to admit that I have not run
549 543
550 #If the server elected to resume the session, it is handled here. 544 #If the server elected to resume the session, it is handled here.
551 for result in self._clientResume(session, serverHello, 545 for result in self._clientResume(session, serverHello,
552 clientHello.random, 546 clientHello.random,
553 settings.cipherImplementations, 547 settings.cipherImplementations,
554 nextProto): 548 nextProto):
555 if result in (0,1): yield result 549 if result in (0,1): yield result
556 else: break 550 else: break
557 if result == "resumed_and_finished": 551 if result == "resumed_and_finished":
558 self._handshakeDone(resumed=True) 552 self._handshakeDone(resumed=True)
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 else: break 602 else: break
609 masterSecret = result 603 masterSecret = result
610 604
611 self.clientRandom = clientHello.random 605 self.clientRandom = clientHello.random
612 self.serverRandom = serverHello.random 606 self.serverRandom = serverHello.random
613 607
614 # Create the session object which is used for resumptions 608 # Create the session object which is used for resumptions
615 self.session = Session() 609 self.session = Session()
616 self.session.create(masterSecret, serverHello.session_id, cipherSuite, 610 self.session.create(masterSecret, serverHello.session_id, cipherSuite,
617 srpUsername, clientCertChain, serverCertChain, 611 srpUsername, clientCertChain, serverCertChain,
618 tackExt, serverHello.tackExt!=None, serverName) 612 tackExt, serverHello.tackExt!=None, None, serverName)
619 self._handshakeDone(resumed=False) 613 self._handshakeDone(resumed=False)
620 614
621 615
622 def _clientSendClientHello(self, settings, session, srpUsername, 616 def _clientSendClientHello(self, settings, session, srpUsername, srpParams,
623 srpParams, certParams, anonParams, 617 certParams, anonParams, serverName, reqTack):
624 serverName, nextProtos, reqTack):
625 #Initialize acceptable ciphersuites 618 #Initialize acceptable ciphersuites
626 cipherSuites = [CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV] 619 cipherSuites = [CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
627 if srpParams: 620 if srpParams:
628 cipherSuites += CipherSuite.getSrpAllSuites(settings) 621 cipherSuites += CipherSuite.getSrpAllSuites(settings)
629 elif certParams: 622 elif certParams:
630 # TODO: Client DHE_RSA not supported. 623 # TODO: Client DHE_RSA not supported.
631 # cipherSuites += CipherSuite.getDheCertSuites(settings) 624 # cipherSuites += CipherSuite.getDheCertSuites(settings)
632 cipherSuites += CipherSuite.getCertSuites(settings) 625 cipherSuites += CipherSuite.getCertSuites(settings)
633 elif anonParams: 626 elif anonParams:
634 cipherSuites += CipherSuite.getAnonSuites(settings) 627 cipherSuites += CipherSuite.getAnonSuites(settings)
635 else: 628 else:
636 assert(False) 629 assert(False)
637 630
638 #Initialize acceptable certificate types 631 #Initialize acceptable certificate types
639 certificateTypes = settings._getCertificateTypes() 632 certificateTypes = settings._getCertificateTypes()
640 633
641 #Either send ClientHello (with a resumable session)... 634 #Either send ClientHello (with a resumable session)...
642 if session and session.sessionID: 635 if session and session.sessionID:
643 #If it's resumable, then its 636 #If it's resumable, then its
644 #ciphersuite must be one of the acceptable ciphersuites 637 #ciphersuite must be one of the acceptable ciphersuites
645 if session.cipherSuite not in cipherSuites: 638 if session.cipherSuite not in cipherSuites:
646 raise ValueError("Session's cipher suite not consistent "\ 639 raise ValueError("Session's cipher suite not consistent "\
647 "with parameters") 640 "with parameters")
648 else: 641 else:
649 clientHello = ClientHello() 642 clientHello = ClientHello()
650 clientHello.create(settings.maxVersion, getRandomBytes(32), 643 clientHello.create(settings.maxVersion, getRandomBytes(32),
651 session.sessionID, cipherSuites, 644 session.sessionID, cipherSuites,
652 certificateTypes, 645 certificateTypes,
653 session.srpUsername, 646 session.srpUsername,
654 reqTack, nextProtos is not None, 647 reqTack, settings.alpnProtos,
648 settings.nextProtos is not None,
655 session.serverName) 649 session.serverName)
656 650
657 #Or send ClientHello (without) 651 #Or send ClientHello (without)
658 else: 652 else:
659 clientHello = ClientHello() 653 clientHello = ClientHello()
660 clientHello.create(settings.maxVersion, getRandomBytes(32), 654 clientHello.create(settings.maxVersion, getRandomBytes(32),
661 bytearray(0), cipherSuites, 655 bytearray(0), cipherSuites,
662 certificateTypes, 656 certificateTypes,
663 srpUsername, 657 srpUsername,
664 reqTack, nextProtos is not None, 658 reqTack, settings.alpnProtos,
665 serverName) 659 settings.nextProtos is not None, serverName)
666 for result in self._sendMsg(clientHello): 660 for result in self._sendMsg(clientHello):
667 yield result 661 yield result
668 yield clientHello 662 yield clientHello
669 663
670 664
671 def _clientGetServerHello(self, settings, clientHello): 665 def _clientGetServerHello(self, settings, clientHello):
672 for result in self._getMsg(ContentType.handshake, 666 for result in self._getMsg(ContentType.handshake,
673 HandshakeType.server_hello): 667 HandshakeType.server_hello):
674 if result in (0,1): yield result 668 if result in (0,1): yield result
675 else: break 669 else: break
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
707 for result in self._sendError(\ 701 for result in self._sendError(\
708 AlertDescription.illegal_parameter, 702 AlertDescription.illegal_parameter,
709 "Server responded with incorrect compression method"): 703 "Server responded with incorrect compression method"):
710 yield result 704 yield result
711 if serverHello.tackExt: 705 if serverHello.tackExt:
712 if not clientHello.tack: 706 if not clientHello.tack:
713 for result in self._sendError(\ 707 for result in self._sendError(\
714 AlertDescription.illegal_parameter, 708 AlertDescription.illegal_parameter,
715 "Server responded with unrequested Tack Extension"): 709 "Server responded with unrequested Tack Extension"):
716 yield result 710 yield result
711 if serverHello.alpn_proto_selected and not clientHello.alpn_protos_adver tised:
712 for result in self._sendError(\
713 AlertDescription.illegal_parameter,
714 "Server responded with unrequested ALPN Extension"):
715 yield result
716 if serverHello.alpn_proto_selected and serverHello.next_protos:
717 for result in self._sendError(\
718 AlertDescription.illegal_parameter,
719 "Server responded with both ALPN and NPN extension"):
720 yield result
717 if serverHello.next_protos and not clientHello.supports_npn: 721 if serverHello.next_protos and not clientHello.supports_npn:
718 for result in self._sendError(\ 722 for result in self._sendError(\
719 AlertDescription.illegal_parameter, 723 AlertDescription.illegal_parameter,
720 "Server responded with unrequested NPN Extension"): 724 "Server responded with unrequested NPN Extension"):
721 yield result 725 yield result
722 if not serverHello.tackExt.verifySignatures(): 726 if not serverHello.tackExt.verifySignatures():
723 for result in self._sendError(\ 727 for result in self._sendError(\
724 AlertDescription.decrypt_error, 728 AlertDescription.decrypt_error,
725 "TackExtension contains an invalid signature"): 729 "TackExtension contains an invalid signature"):
726 yield result 730 yield result
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
1094 1098
1095 #********************************************************* 1099 #*********************************************************
1096 # Server Handshake Functions 1100 # Server Handshake Functions
1097 #********************************************************* 1101 #*********************************************************
1098 1102
1099 1103
1100 def handshakeServer(self, verifierDB=None, 1104 def handshakeServer(self, verifierDB=None,
1101 certChain=None, privateKey=None, reqCert=False, 1105 certChain=None, privateKey=None, reqCert=False,
1102 sessionCache=None, settings=None, checker=None, 1106 sessionCache=None, settings=None, checker=None,
1103 reqCAs = None, reqCertTypes = None, 1107 reqCAs = None, reqCertTypes = None,
1104 tacks=None, activationFlags=0, 1108 tacks=None, activationFlags=0, anon=False,
1105 nextProtos=None, anon=False,
1106 signedCertTimestamps=None, 1109 signedCertTimestamps=None,
1107 fallbackSCSV=False, ocspResponse=None): 1110 fallbackSCSV=False, ocspResponse=None):
1108 """Perform a handshake in the role of server. 1111 """Perform a handshake in the role of server.
1109 1112
1110 This function performs an SSL or TLS handshake. Depending on 1113 This function performs an SSL or TLS handshake. Depending on
1111 the arguments and the behavior of the client, this function can 1114 the arguments and the behavior of the client, this function can
1112 perform an SRP, or certificate-based handshake. It 1115 perform an SRP, or certificate-based handshake. It
1113 can also perform a combined SRP and server-certificate 1116 can also perform a combined SRP and server-certificate
1114 handshake. 1117 handshake.
1115 1118
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1165 1168
1166 @type reqCAs: list of L{bytearray} of unsigned bytes 1169 @type reqCAs: list of L{bytearray} of unsigned bytes
1167 @param reqCAs: A collection of DER-encoded DistinguishedNames that 1170 @param reqCAs: A collection of DER-encoded DistinguishedNames that
1168 will be sent along with a certificate request. This does not affect 1171 will be sent along with a certificate request. This does not affect
1169 verification. 1172 verification.
1170 1173
1171 @type reqCertTypes: list of int 1174 @type reqCertTypes: list of int
1172 @param reqCertTypes: A list of certificate_type values to be sent 1175 @param reqCertTypes: A list of certificate_type values to be sent
1173 along with a certificate request. This does not affect verification. 1176 along with a certificate request. This does not affect verification.
1174 1177
1175 @type nextProtos: list of strings.
1176 @param nextProtos: A list of upper layer protocols to expose to the
1177 clients through the Next-Protocol Negotiation Extension,
1178 if they support it.
1179
1180 @type signedCertTimestamps: str 1178 @type signedCertTimestamps: str
1181 @param signedCertTimestamps: A SignedCertificateTimestampList (as a 1179 @param signedCertTimestamps: A SignedCertificateTimestampList (as a
1182 binary 8-bit string) that will be sent as a TLS extension whenever 1180 binary 8-bit string) that will be sent as a TLS extension whenever
1183 the client announces support for the extension. 1181 the client announces support for the extension.
1184 1182
1185 @type fallbackSCSV: bool 1183 @type fallbackSCSV: bool
1186 @param fallbackSCSV: if true, the server will implement 1184 @param fallbackSCSV: if true, the server will implement
1187 TLS_FALLBACK_SCSV and thus reject connections using less than the 1185 TLS_FALLBACK_SCSV and thus reject connections using less than the
1188 server's maximum TLS version that include this cipher suite. 1186 server's maximum TLS version that include this cipher suite.
1189 1187
1190 @type ocspResponse: str 1188 @type ocspResponse: str
1191 @param ocspResponse: An OCSP response (as a binary 8-bit string) that 1189 @param ocspResponse: An OCSP response (as a binary 8-bit string) that
1192 will be sent stapled in the handshake whenever the client announces 1190 will be sent stapled in the handshake whenever the client announces
1193 support for the status_request extension. 1191 support for the status_request extension.
1194 Note that the response is sent independent of the ClientHello 1192 Note that the response is sent independent of the ClientHello
1195 status_request extension contents, and is thus only meant for testing 1193 status_request extension contents, and is thus only meant for testing
1196 environments. Real OCSP stapling is more complicated as it requires 1194 environments. Real OCSP stapling is more complicated as it requires
1197 choosing a suitable response based on the ClientHello status_request 1195 choosing a suitable response based on the ClientHello status_request
1198 extension contents. 1196 extension contents.
1199 1197
1200 @raise socket.error: If a socket error occurs. 1198 @raise socket.error: If a socket error occurs.
1201 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed 1199 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
1202 without a preceding alert. 1200 without a preceding alert.
1203 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled. 1201 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
1204 @raise tlslite.errors.TLSAuthenticationError: If the checker 1202 @raise tlslite.errors.TLSAuthenticationError: If the checker
1205 doesn't like the other party's authentication credentials. 1203 doesn't like the other party's authentication credentials.
1206 """ 1204 """
1207 for result in self.handshakeServerAsync(verifierDB, 1205 for result in self.handshakeServerAsync(verifierDB,
1208 certChain, privateKey, reqCert, sessionCache, settings, 1206 certChain, privateKey, reqCert, sessionCache, settings,
1209 checker, reqCAs, reqCertTypes, 1207 checker, reqCAs, reqCertTypes, tacks=tacks,
1210 tacks=tacks, activationFlags=activationFlags, 1208 activationFlags=activationFlags, anon=anon,
1211 nextProtos=nextProtos, anon=anon,
1212 signedCertTimestamps=signedCertTimestamps, 1209 signedCertTimestamps=signedCertTimestamps,
1213 fallbackSCSV=fallbackSCSV, ocspResponse=ocspResponse): 1210 fallbackSCSV=fallbackSCSV, ocspResponse=ocspResponse):
1214 pass 1211 pass
1215 1212
1216 1213
1217 def handshakeServerAsync(self, verifierDB=None, 1214 def handshakeServerAsync(self, verifierDB=None,
1218 certChain=None, privateKey=None, reqCert=False, 1215 certChain=None, privateKey=None, reqCert=False,
1219 sessionCache=None, settings=None, checker=None, 1216 sessionCache=None, settings=None, checker=None,
1220 reqCAs=None, reqCertTypes=None, 1217 reqCAs=None, reqCertTypes=None,
1221 tacks=None, activationFlags=0, 1218 tacks=None, activationFlags=0, anon=False,
1222 nextProtos=None, anon=False,
1223 signedCertTimestamps=None, 1219 signedCertTimestamps=None,
1224 fallbackSCSV=False, 1220 fallbackSCSV=False,
1225 ocspResponse=None 1221 ocspResponse=None
1226 ): 1222 ):
1227 """Start a server handshake operation on the TLS connection. 1223 """Start a server handshake operation on the TLS connection.
1228 1224
1229 This function returns a generator which behaves similarly to 1225 This function returns a generator which behaves similarly to
1230 handshakeServer(). Successive invocations of the generator 1226 handshakeServer(). Successive invocations of the generator
1231 will return 0 if it is waiting to read from the socket, 1 if it is 1227 will return 0 if it is waiting to read from the socket, 1 if it is
1232 waiting to write to the socket, or it will raise StopIteration 1228 waiting to write to the socket, or it will raise StopIteration
1233 if the handshake operation is complete. 1229 if the handshake operation is complete.
1234 1230
1235 @rtype: iterable 1231 @rtype: iterable
1236 @return: A generator; see above for details. 1232 @return: A generator; see above for details.
1237 """ 1233 """
1238 handshaker = self._handshakeServerAsyncHelper(\ 1234 handshaker = self._handshakeServerAsyncHelper(\
1239 verifierDB=verifierDB, certChain=certChain, 1235 verifierDB=verifierDB, certChain=certChain,
1240 privateKey=privateKey, reqCert=reqCert, 1236 privateKey=privateKey, reqCert=reqCert,
1241 sessionCache=sessionCache, settings=settings, 1237 sessionCache=sessionCache, settings=settings,
1242 reqCAs=reqCAs, reqCertTypes=reqCertTypes, 1238 reqCAs=reqCAs, reqCertTypes=reqCertTypes,
1243 tacks=tacks, activationFlags=activationFlags, 1239 tacks=tacks, activationFlags=activationFlags, anon=anon,
1244 nextProtos=nextProtos, anon=anon,
1245 signedCertTimestamps=signedCertTimestamps, 1240 signedCertTimestamps=signedCertTimestamps,
1246 fallbackSCSV=fallbackSCSV, 1241 fallbackSCSV=fallbackSCSV,
1247 ocspResponse=ocspResponse) 1242 ocspResponse=ocspResponse)
1248 for result in self._handshakeWrapperAsync(handshaker, checker): 1243 for result in self._handshakeWrapperAsync(handshaker, checker):
1249 yield result 1244 yield result
1250 if settings and settings.alertAfterHandshake: 1245 if settings and settings.alertAfterHandshake:
1251 for result in self._sendError(AlertDescription.internal_error, 1246 for result in self._sendError(AlertDescription.internal_error,
1252 "Spurious alert"): 1247 "Spurious alert"):
1253 yield result 1248 yield result
1254 1249
1255 1250
1256 def _handshakeServerAsyncHelper(self, verifierDB, 1251 def _handshakeServerAsyncHelper(self, verifierDB,
1257 certChain, privateKey, reqCert, sessionCache, 1252 certChain, privateKey, reqCert, sessionCache,
1258 settings, reqCAs, reqCertTypes, 1253 settings, reqCAs, reqCertTypes,
1259 tacks, activationFlags, 1254 tacks, activationFlags, anon,
1260 nextProtos, anon,
1261 signedCertTimestamps, fallbackSCSV, 1255 signedCertTimestamps, fallbackSCSV,
1262 ocspResponse): 1256 ocspResponse):
1263 1257
1264 self._handshakeStart(client=False) 1258 self._handshakeStart(client=False)
1265 1259
1266 if (not verifierDB) and (not certChain) and not anon: 1260 if (not verifierDB) and (not certChain) and not anon:
1267 raise ValueError("Caller passed no authentication credentials") 1261 raise ValueError("Caller passed no authentication credentials")
1268 if certChain and not privateKey: 1262 if certChain and not privateKey:
1269 raise ValueError("Caller passed a certChain but no privateKey") 1263 raise ValueError("Caller passed a certChain but no privateKey")
1270 if privateKey and not certChain: 1264 if privateKey and not certChain:
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1307 # Save the ClientHello for external code to query. 1301 # Save the ClientHello for external code to query.
1308 self.clientHello = clientHello 1302 self.clientHello = clientHello
1309 1303
1310 #If not a resumption... 1304 #If not a resumption...
1311 1305
1312 # Create the ServerHello message 1306 # Create the ServerHello message
1313 if sessionCache: 1307 if sessionCache:
1314 sessionID = getRandomBytes(32) 1308 sessionID = getRandomBytes(32)
1315 else: 1309 else:
1316 sessionID = bytearray(0) 1310 sessionID = bytearray(0)
1317 1311
1312 alpn_proto_selected = None
1313 if clientHello.alpn_protos_advertised is not None:
1314 if settings.alpnProtos is not None:
1315 for proto in settings.alpnProtos:
1316 if proto in clientHello.alpn_protos_advertised:
1317 alpn_proto_selected = proto
1318 settings.nextProtos = None
1319 break;
1320
1318 if not clientHello.supports_npn: 1321 if not clientHello.supports_npn:
1319 nextProtos = None 1322 settings.nextProtos = None
davidben 2016/08/04 22:29:26 This function probably should not mutate the setti
Bence 2016/08/05 14:27:55 Done.
1320 1323
1321 # If not doing a certificate-based suite, discard the TACK 1324 # If not doing a certificate-based suite, discard the TACK
1322 if not cipherSuite in CipherSuite.certAllSuites: 1325 if not cipherSuite in CipherSuite.certAllSuites:
1323 tacks = None 1326 tacks = None
1324 1327
1325 # Prepare a TACK Extension if requested 1328 # Prepare a TACK Extension if requested
1326 if clientHello.tack: 1329 if clientHello.tack:
1327 tackExt = TackExtension.create(tacks, activationFlags) 1330 tackExt = TackExtension.create(tacks, activationFlags)
1328 else: 1331 else:
1329 tackExt = None 1332 tackExt = None
1330 serverHello = ServerHello() 1333 serverHello = ServerHello()
1331 serverHello.create(self.version, getRandomBytes(32), sessionID, \ 1334 serverHello.create(self.version, getRandomBytes(32), sessionID, \
1332 cipherSuite, CertificateType.x509, tackExt, 1335 cipherSuite, CertificateType.x509, tackExt,
1333 nextProtos) 1336 alpn_proto_selected, settings.nextProtos)
1334 serverHello.channel_id = \ 1337 serverHello.channel_id = \
1335 clientHello.channel_id and settings.enableChannelID 1338 clientHello.channel_id and settings.enableChannelID
1336 serverHello.extended_master_secret = \ 1339 serverHello.extended_master_secret = \
1337 clientHello.extended_master_secret and \ 1340 clientHello.extended_master_secret and \
1338 settings.enableExtendedMasterSecret 1341 settings.enableExtendedMasterSecret
1339 for param in clientHello.tb_client_params: 1342 for param in clientHello.tb_client_params:
1340 if param in settings.supportedTokenBindingParams: 1343 if param in settings.supportedTokenBindingParams:
1341 serverHello.tb_params = param 1344 serverHello.tb_params = param
1342 break 1345 break
1343 if clientHello.support_signed_cert_timestamps: 1346 if clientHello.support_signed_cert_timestamps:
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1390 else: break 1393 else: break
1391 premasterSecret = result 1394 premasterSecret = result
1392 1395
1393 else: 1396 else:
1394 assert(False) 1397 assert(False)
1395 1398
1396 # Exchange Finished messages 1399 # Exchange Finished messages
1397 for result in self._serverFinished(premasterSecret, 1400 for result in self._serverFinished(premasterSecret,
1398 clientHello.random, serverHello.random, 1401 clientHello.random, serverHello.random,
1399 cipherSuite, settings.cipherImplementations, 1402 cipherSuite, settings.cipherImplementations,
1400 nextProtos, serverHello.channel_id, 1403 settings.nextProtos, serverHello.channel_id,
1401 serverHello.extended_master_secret): 1404 serverHello.extended_master_secret):
1402 if result in (0,1): yield result 1405 if result in (0,1): yield result
1403 else: break 1406 else: break
1404 masterSecret = result 1407 masterSecret = result
1405 1408
1406 self.clientRandom = clientHello.random 1409 self.clientRandom = clientHello.random
1407 self.serverRandom = serverHello.random 1410 self.serverRandom = serverHello.random
1408 1411
1409 #Create the session object 1412 #Create the session object
1410 self.session = Session() 1413 self.session = Session()
1411 if cipherSuite in CipherSuite.certAllSuites: 1414 if cipherSuite in CipherSuite.certAllSuites:
1412 serverCertChain = certChain 1415 serverCertChain = certChain
1413 else: 1416 else:
1414 serverCertChain = None 1417 serverCertChain = None
1415 srpUsername = None 1418 srpUsername = None
1416 serverName = None 1419 serverName = None
1417 if clientHello.srp_username: 1420 if clientHello.srp_username:
1418 srpUsername = clientHello.srp_username.decode("utf-8") 1421 srpUsername = clientHello.srp_username.decode("utf-8")
1419 if clientHello.server_name: 1422 if clientHello.server_name:
1420 serverName = clientHello.server_name.decode("utf-8") 1423 serverName = clientHello.server_name.decode("utf-8")
1421 self.session.create(masterSecret, serverHello.session_id, cipherSuite, 1424 self.session.create(masterSecret, serverHello.session_id, cipherSuite,
1422 srpUsername, clientCertChain, serverCertChain, 1425 srpUsername, clientCertChain, serverCertChain,
1423 tackExt, serverHello.tackExt!=None, serverName) 1426 tackExt, serverHello.tackExt!=None, alpn_proto_selected, serverName)
1424 1427
1425 #Add the session object to the session cache 1428 #Add the session object to the session cache
1426 if sessionCache and sessionID: 1429 if sessionCache and sessionID:
1427 sessionCache[sessionID] = self.session 1430 sessionCache[sessionID] = self.session
1428 1431
1429 self._handshakeDone(resumed=False) 1432 self._handshakeDone(resumed=False)
1430 1433
1431 1434
1432 def _serverGetClientHello(self, settings, certChain, verifierDB, 1435 def _serverGetClientHello(self, settings, certChain, verifierDB,
1433 sessionCache, anon, fallbackSCSV): 1436 sessionCache, anon, fallbackSCSV):
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1533 yield result 1536 yield result
1534 except KeyError: 1537 except KeyError:
1535 pass 1538 pass
1536 1539
1537 #If a session is found.. 1540 #If a session is found..
1538 if session: 1541 if session:
1539 #Send ServerHello 1542 #Send ServerHello
1540 serverHello = ServerHello() 1543 serverHello = ServerHello()
1541 serverHello.create(self.version, getRandomBytes(32), 1544 serverHello.create(self.version, getRandomBytes(32),
1542 session.sessionID, session.cipherSuite, 1545 session.sessionID, session.cipherSuite,
1543 CertificateType.x509, None, None) 1546 CertificateType.x509, None,
1547 session.alpn_proto_selected, None)
1544 serverHello.extended_master_secret = \ 1548 serverHello.extended_master_secret = \
1545 clientHello.extended_master_secret and \ 1549 clientHello.extended_master_secret and \
1546 settings.enableExtendedMasterSecret 1550 settings.enableExtendedMasterSecret
1547 for param in clientHello.tb_client_params: 1551 for param in clientHello.tb_client_params:
1548 if param in settings.supportedTokenBindingParams: 1552 if param in settings.supportedTokenBindingParams:
1549 serverHello.tb_params = param 1553 serverHello.tb_params = param
1550 break 1554 break
1551 for result in self._sendMsg(serverHello): 1555 for result in self._sendMsg(serverHello):
1552 yield result 1556 yield result
1553 1557
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after
2039 seed += bytearray(2) 2043 seed += bytearray(2)
2040 seed[len(seed) - 2] = len(context) >> 8 2044 seed[len(seed) - 2] = len(context) >> 8
2041 seed[len(seed) - 1] = len(context) & 0xFF 2045 seed[len(seed) - 1] = len(context) & 0xFF
2042 seed += context 2046 seed += context
2043 if self.version in ((3,1), (3,2)): 2047 if self.version in ((3,1), (3,2)):
2044 return PRF(self.session.masterSecret, label, seed, length) 2048 return PRF(self.session.masterSecret, label, seed, length)
2045 elif self.version == (3,3): 2049 elif self.version == (3,3):
2046 return PRF_1_2(self.session.masterSecret, label, seed, length) 2050 return PRF_1_2(self.session.masterSecret, label, seed, length)
2047 else: 2051 else:
2048 raise AssertionError() 2052 raise AssertionError()
OLDNEW
« third_party/tlslite/tlslite/session.py ('K') | « third_party/tlslite/tlslite/session.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698