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

Unified Diff: third_party/tlslite/patches/alpn.patch

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 side-by-side diff with in-line comments
Download patch
Index: third_party/tlslite/patches/alpn.patch
diff --git a/third_party/tlslite/patches/alpn.patch b/third_party/tlslite/patches/alpn.patch
new file mode 100644
index 0000000000000000000000000000000000000000..a52bf63ad8812f5ee291d57670dde182a0c7bfa9
--- /dev/null
+++ b/third_party/tlslite/patches/alpn.patch
@@ -0,0 +1,567 @@
+diff --git a/third_party/tlslite/patches/alpn.patch b/third_party/tlslite/patches/alpn.patch
+new file mode 100644
+index 0000000..e69de29
+diff --git a/third_party/tlslite/tlslite/constants.py b/third_party/tlslite/tlslite/constants.py
+index 715def9..e9743e4 100644
+--- a/third_party/tlslite/tlslite/constants.py
++++ b/third_party/tlslite/tlslite/constants.py
+@@ -54,6 +54,7 @@ class ExtensionType: # RFC 6066 / 4366
+ status_request = 5 # RFC 6066 / 4366
+ srp = 12 # RFC 5054
+ cert_type = 9 # RFC 6091
++ alpn = 16 # RFC 7301
+ signed_cert_timestamps = 18 # RFC 6962
+ extended_master_secret = 23 # RFC 7627
+ token_binding = 24 # draft-ietf-tokbind-negotiation
+diff --git a/third_party/tlslite/tlslite/handshakesettings.py b/third_party/tlslite/tlslite/handshakesettings.py
+index d7be5b3..284c474 100644
+--- a/third_party/tlslite/tlslite/handshakesettings.py
++++ b/third_party/tlslite/tlslite/handshakesettings.py
+@@ -128,6 +128,18 @@ class HandshakeSettings(object):
+
+ Note that TACK support is not standardized by IETF and uses a temporary
+ TLS Extension number, so should NOT be used in production software.
++
++ @type alpnProtos: list of strings.
++ @param alpnProtos: A list of supported upper layer protocols to use in the
++ Application-Layer Protocol Negotiation Extension (RFC 7301). For the
++ client, the order does not matter. For the server, the list is in
++ decreasing order of preference.
++
++ @type nextProtos: list of strings.
++ @param nextProtos: A list of supported upper layer protocols to use in the
++ Next-Protocol Negotiation Extension. For the server, the order does not
++ matter. For the client, the list is in decreasing order of preference, with
++ the first entry used for fallback.
+ """
+ def __init__(self):
+ self.minKeySize = 1023
+@@ -146,6 +158,8 @@ class HandshakeSettings(object):
+ self.enableChannelID = True
+ self.enableExtendedMasterSecret = True
+ self.supportedTokenBindingParams = []
++ self.alpnProtos = None
++ self.nextProtos = None
+
+ # Validates the min/max fields, and certificateTypes
+ # Filters out unsupported cipherNames and cipherImplementations
+@@ -166,6 +180,8 @@ class HandshakeSettings(object):
+ other.enableChannelID = self.enableChannelID
+ other.enableExtendedMasterSecret = self.enableExtendedMasterSecret
+ other.supportedTokenBindingParams = self.supportedTokenBindingParams
++ other.alpnProtos = self.alpnProtos;
++ other.nextProtos = self.nextProtos;
+
+ if not cipherfactory.tripleDESPresent:
+ other.cipherNames = [e for e in self.cipherNames if e != "3des"]
+diff --git a/third_party/tlslite/tlslite/messages.py b/third_party/tlslite/tlslite/messages.py
+index 5762ac6..651492b 100644
+--- a/third_party/tlslite/tlslite/messages.py
++++ b/third_party/tlslite/tlslite/messages.py
+@@ -99,6 +99,27 @@ class HandshakeMsg(object):
+ headerWriter.add(len(w.bytes), 3)
+ return headerWriter.bytes + w.bytes
+
++ def parse_next_protos(self, b):
++ protos = []
++ while True:
++ if len(b) == 0:
++ break
++ l = b[0]
++ b = b[1:]
++ if len(b) < l:
++ raise BadNextProtos(len(b))
++ protos.append(b[:l])
++ b = b[l:]
++ return protos
++
++ def next_protos_encoded(self, protocol_list):
++ b = bytearray()
++ for e in protocol_list:
++ if len(e) > 255 or len(e) == 0:
++ raise BadNextProtos(len(e))
++ b += bytearray( [len(e)] ) + bytearray(e)
++ return b
++
+ class ClientHello(HandshakeMsg):
+ def __init__(self, ssl2=False):
+ HandshakeMsg.__init__(self, HandshakeType.client_hello)
+@@ -111,6 +132,7 @@ class ClientHello(HandshakeMsg):
+ self.compression_methods = [] # a list of 8-bit values
+ self.srp_username = None # a string
+ self.tack = False
++ self.alpn_protos_advertised = None
+ self.supports_npn = False
+ self.server_name = bytearray(0)
+ self.channel_id = False
+@@ -120,8 +142,8 @@ class ClientHello(HandshakeMsg):
+ self.status_request = False
+
+ def create(self, version, random, session_id, cipher_suites,
+- certificate_types=None, srpUsername=None,
+- tack=False, supports_npn=False, serverName=None):
++ certificate_types=None, srpUsername=None, tack=False,
++ alpn_protos_advertised=None, supports_npn=False, serverName=None):
+ self.client_version = version
+ self.random = random
+ self.session_id = session_id
+@@ -131,6 +153,7 @@ class ClientHello(HandshakeMsg):
+ if srpUsername:
+ self.srp_username = bytearray(srpUsername, "utf-8")
+ self.tack = tack
++ self.alpn_protos_advertised = alpn_protos_advertised
+ self.supports_npn = supports_npn
+ if serverName:
+ self.server_name = bytearray(serverName, "utf-8")
+@@ -171,6 +194,11 @@ class ClientHello(HandshakeMsg):
+ self.certificate_types = p.getVarList(1, 1)
+ elif extType == ExtensionType.tack:
+ self.tack = True
++ elif extType == ExtensionType.alpn:
++ structLength = p.get(2)
++ if (structLength + 2 != extLength):
++ raise SyntaxError()
++ self.alpn_protos_advertised = self.parse_next_protos(p.getFixBytes(structLength))
+ elif extType == ExtensionType.supports_npn:
+ self.supports_npn = True
+ elif extType == ExtensionType.server_name:
+@@ -243,6 +271,12 @@ class ClientHello(HandshakeMsg):
+ w2.add(ExtensionType.srp, 2)
+ w2.add(len(self.srp_username)+1, 2)
+ w2.addVarSeq(self.srp_username, 1, 1)
++ if self.alpn_protos_advertised is not None:
++ encoded_alpn_protos_advertised = self.next_protos_encoded(self.alpn_protos_advertised)
++ w2.add(ExtensionType.alpn, 2)
++ w2.add(len(encoded_alpn_protos_advertised) + 2, 2)
++ w2.add(len(encoded_alpn_protos_advertised), 2)
++ w2.addFixSeq(encoded_alpn_protos_advertised, 1)
+ if self.supports_npn:
+ w2.add(ExtensionType.supports_npn, 2)
+ w2.add(0, 2)
+@@ -267,6 +301,13 @@ class BadNextProtos(Exception):
+ def __str__(self):
+ return 'Cannot encode a list of next protocols because it contains an element with invalid length %d. Element lengths must be 0 < x < 256' % self.length
+
++class InvalidAlpnResponse(Exception):
++ def __init__(self, l):
++ self.length = l
++
++ def __str__(self):
++ return 'ALPN server response protocol list has invalid length %d. It must be of length one.' % self.length
++
+ class ServerHello(HandshakeMsg):
+ def __init__(self):
+ HandshakeMsg.__init__(self, HandshakeType.server_hello)
+@@ -277,6 +318,7 @@ class ServerHello(HandshakeMsg):
+ self.certificate_type = CertificateType.x509
+ self.compression_method = 0
+ self.tackExt = None
++ self.alpn_proto_selected = None
+ self.next_protos_advertised = None
+ self.next_protos = None
+ self.channel_id = False
+@@ -286,7 +328,8 @@ class ServerHello(HandshakeMsg):
+ self.status_request = False
+
+ def create(self, version, random, session_id, cipher_suite,
+- certificate_type, tackExt, next_protos_advertised):
++ certificate_type, tackExt, alpn_proto_selected,
++ next_protos_advertised):
+ self.server_version = version
+ self.random = random
+ self.session_id = session_id
+@@ -294,6 +337,7 @@ class ServerHello(HandshakeMsg):
+ self.certificate_type = certificate_type
+ self.compression_method = 0
+ self.tackExt = tackExt
++ self.alpn_proto_selected = alpn_proto_selected
+ self.next_protos_advertised = next_protos_advertised
+ return self
+
+@@ -316,35 +360,22 @@ class ServerHello(HandshakeMsg):
+ self.certificate_type = p.get(1)
+ elif extType == ExtensionType.tack and tackpyLoaded:
+ self.tackExt = TackExtension(p.getFixBytes(extLength))
++ elif extType == ExtensionType.alpn:
++ structLength = p.get(2)
++ if structLength + 2 != extLength:
++ raise SyntaxError()
++ alpn_protos = self.parse_next_protos(p.getFixBytes(structLength))
++ if alpn_protos.len() != 1:
++ raise InvalidAlpnResponse(alpn_protos.len());
++ self.alpn_proto_selected = alpn_protos[0]
+ elif extType == ExtensionType.supports_npn:
+- self.next_protos = self.__parse_next_protos(p.getFixBytes(extLength))
++ self.next_protos = self.parse_next_protos(p.getFixBytes(extLength))
+ else:
+ p.getFixBytes(extLength)
+ soFar += 4 + extLength
+ p.stopLengthCheck()
+ return self
+
+- def __parse_next_protos(self, b):
+- protos = []
+- while True:
+- if len(b) == 0:
+- break
+- l = b[0]
+- b = b[1:]
+- if len(b) < l:
+- raise BadNextProtos(len(b))
+- protos.append(b[:l])
+- b = b[l:]
+- return protos
+-
+- def __next_protos_encoded(self):
+- b = bytearray()
+- for e in self.next_protos_advertised:
+- if len(e) > 255 or len(e) == 0:
+- raise BadNextProtos(len(e))
+- b += bytearray( [len(e)] ) + bytearray(e)
+- return b
+-
+ def write(self):
+ w = Writer()
+ w.add(self.server_version[0], 1)
+@@ -365,8 +396,15 @@ class ServerHello(HandshakeMsg):
+ w2.add(ExtensionType.tack, 2)
+ w2.add(len(b), 2)
+ w2.bytes += b
++ if self.alpn_proto_selected is not None:
++ alpn_protos_single_element_list = [self.alpn_proto_selected]
++ encoded_alpn_protos_advertised = self.next_protos_encoded(alpn_protos_single_element_list)
++ w2.add(ExtensionType.alpn, 2)
++ w2.add(len(encoded_alpn_protos_advertised) + 2, 2)
++ w2.add(len(encoded_alpn_protos_advertised), 2)
++ w2.addFixSeq(encoded_alpn_protos_advertised, 1)
+ if self.next_protos_advertised is not None:
+- encoded_next_protos_advertised = self.__next_protos_encoded()
++ encoded_next_protos_advertised = self.next_protos_encoded(self.next_protos_advertised)
+ w2.add(ExtensionType.supports_npn, 2)
+ w2.add(len(encoded_next_protos_advertised), 2)
+ w2.addFixSeq(encoded_next_protos_advertised, 1)
+diff --git a/third_party/tlslite/tlslite/session.py b/third_party/tlslite/tlslite/session.py
+index 6aadf58..7758b7c 100644
+--- a/third_party/tlslite/tlslite/session.py
++++ b/third_party/tlslite/tlslite/session.py
+@@ -54,11 +54,13 @@ class Session(object):
+ self.tackExt = None
+ self.tackInHelloExt = False
+ self.serverName = ""
++ self.alpn_proto_selected = None
+ self.resumable = False
+
+ def create(self, masterSecret, sessionID, cipherSuite,
+ srpUsername, clientCertChain, serverCertChain,
+- tackExt, tackInHelloExt, serverName, resumable=True):
++ tackExt, tackInHelloExt, alpn_proto_selected, serverName,
++ resumable=True):
+ self.masterSecret = masterSecret
+ self.sessionID = sessionID
+ self.cipherSuite = cipherSuite
+@@ -68,6 +70,7 @@ class Session(object):
+ self.tackExt = tackExt
+ self.tackInHelloExt = tackInHelloExt
+ self.serverName = serverName
++ self.alpn_proto_selected = alpn_proto_selected
+ self.resumable = resumable
+
+ def _clone(self):
+@@ -81,6 +84,7 @@ class Session(object):
+ other.tackExt = self.tackExt
+ other.tackInHelloExt = self.tackInHelloExt
+ other.serverName = self.serverName
++ other.alpn_proto_selected = self.alpn_proto_selected
+ other.resumable = self.resumable
+ return other
+
+diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/tlslite/tlsconnection.py
+index 41aab85..e062940 100644
+--- a/third_party/tlslite/tlslite/tlsconnection.py
++++ b/third_party/tlslite/tlslite/tlsconnection.py
+@@ -337,8 +337,7 @@ class TLSConnection(TLSRecordLayer):
+
+ def handshakeClientCert(self, certChain=None, privateKey=None,
+ session=None, settings=None, checker=None,
+- nextProtos=None, reqTack=True, serverName="",
+- async=False):
++ reqTack=True, serverName="", async=False):
+ """Perform a certificate-based handshake in the role of client.
+
+ This function performs an SSL or TLS handshake. The server
+@@ -383,11 +382,7 @@ class TLSConnection(TLSRecordLayer):
+ @param checker: A Checker instance. This instance will be
+ invoked to examine the other party's authentication
+ credentials, if the handshake completes succesfully.
+-
+- @type nextProtos: list of strings.
+- @param nextProtos: A list of upper layer protocols ordered by
+- preference, to use in the Next-Protocol Negotiation Extension.
+-
++
+ @type reqTack: bool
+ @param reqTack: Whether or not to send a "tack" TLS Extension,
+ requesting the server return a TackExtension if it has one.
+@@ -417,7 +412,7 @@ class TLSConnection(TLSRecordLayer):
+ handshaker = self._handshakeClientAsync(certParams=(certChain,
+ privateKey), session=session, settings=settings,
+ checker=checker, serverName=serverName,
+- nextProtos=nextProtos, reqTack=reqTack)
++ reqTack=reqTack)
+ # The handshaker is a Python Generator which executes the handshake.
+ # It allows the handshake to be run in a "piecewise", asynchronous
+ # fashion, returning 1 when it is waiting to able to write, 0 when
+@@ -433,7 +428,7 @@ class TLSConnection(TLSRecordLayer):
+
+ def _handshakeClientAsync(self, srpParams=(), certParams=(), anonParams=(),
+ session=None, settings=None, checker=None,
+- nextProtos=None, serverName="", reqTack=True):
++ serverName="", reqTack=True):
+
+ handshaker = self._handshakeClientAsyncHelper(srpParams=srpParams,
+ certParams=certParams,
+@@ -441,14 +436,13 @@ class TLSConnection(TLSRecordLayer):
+ session=session,
+ settings=settings,
+ serverName=serverName,
+- nextProtos=nextProtos,
+ reqTack=reqTack)
+ for result in self._handshakeWrapperAsync(handshaker, checker):
+ yield result
+
+
+ def _handshakeClientAsyncHelper(self, srpParams, certParams, anonParams,
+- session, settings, serverName, nextProtos, reqTack):
++ session, settings, serverName, reqTack):
+
+ self._handshakeStart(client=True)
+
+@@ -485,16 +479,19 @@ class TLSConnection(TLSRecordLayer):
+ reqTack = False
+ if not settings or not settings.useExperimentalTackExtension:
+ reqTack = False
+- if nextProtos is not None:
+- if len(nextProtos) == 0:
+- raise ValueError("Caller passed no nextProtos")
+-
+ # Validates the settings and filters out any unsupported ciphers
+ # or crypto libraries that were requested
+ if not settings:
+ settings = HandshakeSettings()
+ settings = settings._filter()
+
++ if settings.alpnProtos is not None:
++ if len(settings.alpnProtos) == 0:
++ raise ValueError("Caller passed no alpnProtos")
++ if settings.nextProtos is not None:
++ if len(settings.nextProtos) == 0:
++ raise ValueError("Caller passed no nextProtos")
++
+ if clientCertChain:
+ if not isinstance(clientCertChain, X509CertChain):
+ raise ValueError("Unrecognized certificate type")
+@@ -530,8 +527,7 @@ class TLSConnection(TLSRecordLayer):
+ # Send the ClientHello.
+ for result in self._clientSendClientHello(settings, session,
+ srpUsername, srpParams, certParams,
+- anonParams, serverName, nextProtos,
+- reqTack):
++ anonParams, serverName, reqTack):
+ if result in (0,1): yield result
+ else: break
+ clientHello = result
+@@ -543,8 +539,6 @@ class TLSConnection(TLSRecordLayer):
+ serverHello = result
+ cipherSuite = serverHello.cipher_suite
+
+- # Choose a matching Next Protocol from server list against ours
+- # (string or None)
+ nextProto = self._clientSelectNextProto(nextProtos, serverHello)
+
+ #If the server elected to resume the session, it is handled here.
+@@ -615,13 +609,12 @@ class TLSConnection(TLSRecordLayer):
+ self.session = Session()
+ self.session.create(masterSecret, serverHello.session_id, cipherSuite,
+ srpUsername, clientCertChain, serverCertChain,
+- tackExt, serverHello.tackExt!=None, serverName)
++ tackExt, serverHello.tackExt!=None, None, serverName)
+ self._handshakeDone(resumed=False)
+
+
+- def _clientSendClientHello(self, settings, session, srpUsername,
+- srpParams, certParams, anonParams,
+- serverName, nextProtos, reqTack):
++ def _clientSendClientHello(self, settings, session, srpUsername, srpParams,
++ certParams, anonParams, serverName, reqTack):
+ #Initialize acceptable ciphersuites
+ cipherSuites = [CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
+ if srpParams:
+@@ -649,9 +642,10 @@ class TLSConnection(TLSRecordLayer):
+ clientHello = ClientHello()
+ clientHello.create(settings.maxVersion, getRandomBytes(32),
+ session.sessionID, cipherSuites,
+- certificateTypes,
++ certificateTypes,
+ session.srpUsername,
+- reqTack, nextProtos is not None,
++ reqTack, settings.alpnProtos,
++ settings.nextProtos is not None,
+ session.serverName)
+
+ #Or send ClientHello (without)
+@@ -659,10 +653,10 @@ class TLSConnection(TLSRecordLayer):
+ clientHello = ClientHello()
+ clientHello.create(settings.maxVersion, getRandomBytes(32),
+ bytearray(0), cipherSuites,
+- certificateTypes,
++ certificateTypes,
+ srpUsername,
+- reqTack, nextProtos is not None,
+- serverName)
++ reqTack, settings.alpnProtos,
++ settings.nextProtos is not None, serverName)
+ for result in self._sendMsg(clientHello):
+ yield result
+ yield clientHello
+@@ -714,6 +708,16 @@ class TLSConnection(TLSRecordLayer):
+ AlertDescription.illegal_parameter,
+ "Server responded with unrequested Tack Extension"):
+ yield result
++ if serverHello.alpn_proto_selected and not clientHello.alpn_protos_advertised:
++ for result in self._sendError(\
++ AlertDescription.illegal_parameter,
++ "Server responded with unrequested ALPN Extension"):
++ yield result
++ if serverHello.alpn_proto_selected and serverHello.next_protos:
++ for result in self._sendError(\
++ AlertDescription.illegal_parameter,
++ "Server responded with both ALPN and NPN extension"):
++ yield result
+ if serverHello.next_protos and not clientHello.supports_npn:
+ for result in self._sendError(\
+ AlertDescription.illegal_parameter,
+@@ -1101,8 +1105,7 @@ class TLSConnection(TLSRecordLayer):
+ certChain=None, privateKey=None, reqCert=False,
+ sessionCache=None, settings=None, checker=None,
+ reqCAs = None, reqCertTypes = None,
+- tacks=None, activationFlags=0,
+- nextProtos=None, anon=False,
++ tacks=None, activationFlags=0, anon=False,
+ signedCertTimestamps=None,
+ fallbackSCSV=False, ocspResponse=None):
+ """Perform a handshake in the role of server.
+@@ -1172,11 +1175,6 @@ class TLSConnection(TLSRecordLayer):
+ @param reqCertTypes: A list of certificate_type values to be sent
+ along with a certificate request. This does not affect verification.
+
+- @type nextProtos: list of strings.
+- @param nextProtos: A list of upper layer protocols to expose to the
+- clients through the Next-Protocol Negotiation Extension,
+- if they support it.
+-
+ @type signedCertTimestamps: str
+ @param signedCertTimestamps: A SignedCertificateTimestampList (as a
+ binary 8-bit string) that will be sent as a TLS extension whenever
+@@ -1206,9 +1204,8 @@ class TLSConnection(TLSRecordLayer):
+ """
+ for result in self.handshakeServerAsync(verifierDB,
+ certChain, privateKey, reqCert, sessionCache, settings,
+- checker, reqCAs, reqCertTypes,
+- tacks=tacks, activationFlags=activationFlags,
+- nextProtos=nextProtos, anon=anon,
++ checker, reqCAs, reqCertTypes, tacks=tacks,
++ activationFlags=activationFlags, anon=anon,
+ signedCertTimestamps=signedCertTimestamps,
+ fallbackSCSV=fallbackSCSV, ocspResponse=ocspResponse):
+ pass
+@@ -1218,8 +1215,7 @@ class TLSConnection(TLSRecordLayer):
+ certChain=None, privateKey=None, reqCert=False,
+ sessionCache=None, settings=None, checker=None,
+ reqCAs=None, reqCertTypes=None,
+- tacks=None, activationFlags=0,
+- nextProtos=None, anon=False,
++ tacks=None, activationFlags=0, anon=False,
+ signedCertTimestamps=None,
+ fallbackSCSV=False,
+ ocspResponse=None
+@@ -1238,10 +1234,9 @@ class TLSConnection(TLSRecordLayer):
+ handshaker = self._handshakeServerAsyncHelper(\
+ verifierDB=verifierDB, certChain=certChain,
+ privateKey=privateKey, reqCert=reqCert,
+- sessionCache=sessionCache, settings=settings,
++ sessionCache=sessionCache, settings=settings,
+ reqCAs=reqCAs, reqCertTypes=reqCertTypes,
+- tacks=tacks, activationFlags=activationFlags,
+- nextProtos=nextProtos, anon=anon,
++ tacks=tacks, activationFlags=activationFlags, anon=anon,
+ signedCertTimestamps=signedCertTimestamps,
+ fallbackSCSV=fallbackSCSV,
+ ocspResponse=ocspResponse)
+@@ -1256,8 +1251,7 @@ class TLSConnection(TLSRecordLayer):
+ def _handshakeServerAsyncHelper(self, verifierDB,
+ certChain, privateKey, reqCert, sessionCache,
+ settings, reqCAs, reqCertTypes,
+- tacks, activationFlags,
+- nextProtos, anon,
++ tacks, activationFlags, anon,
+ signedCertTimestamps, fallbackSCSV,
+ ocspResponse):
+
+@@ -1314,9 +1308,18 @@ class TLSConnection(TLSRecordLayer):
+ sessionID = getRandomBytes(32)
+ else:
+ sessionID = bytearray(0)
+-
++
++ alpn_proto_selected = None
++ if clientHello.alpn_protos_advertised is not None:
++ if settings.alpnProtos is not None:
++ for proto in settings.alpnProtos:
++ if proto in clientHello.alpn_protos_advertised:
++ alpn_proto_selected = proto
++ settings.nextProtos = None
++ break;
++
+ if not clientHello.supports_npn:
+- nextProtos = None
++ settings.nextProtos = None
+
+ # If not doing a certificate-based suite, discard the TACK
+ if not cipherSuite in CipherSuite.certAllSuites:
+@@ -1330,7 +1333,7 @@ class TLSConnection(TLSRecordLayer):
+ serverHello = ServerHello()
+ serverHello.create(self.version, getRandomBytes(32), sessionID, \
+ cipherSuite, CertificateType.x509, tackExt,
+- nextProtos)
++ alpn_proto_selected, settings.nextProtos)
+ serverHello.channel_id = \
+ clientHello.channel_id and settings.enableChannelID
+ serverHello.extended_master_secret = \
+@@ -1397,7 +1400,7 @@ class TLSConnection(TLSRecordLayer):
+ for result in self._serverFinished(premasterSecret,
+ clientHello.random, serverHello.random,
+ cipherSuite, settings.cipherImplementations,
+- nextProtos, serverHello.channel_id,
++ settings.nextProtos, serverHello.channel_id,
+ serverHello.extended_master_secret):
+ if result in (0,1): yield result
+ else: break
+@@ -1420,7 +1423,7 @@ class TLSConnection(TLSRecordLayer):
+ serverName = clientHello.server_name.decode("utf-8")
+ self.session.create(masterSecret, serverHello.session_id, cipherSuite,
+ srpUsername, clientCertChain, serverCertChain,
+- tackExt, serverHello.tackExt!=None, serverName)
++ tackExt, serverHello.tackExt!=None, alpn_proto_selected, serverName)
+
+ #Add the session object to the session cache
+ if sessionCache and sessionID:
+@@ -1540,7 +1543,8 @@ class TLSConnection(TLSRecordLayer):
+ serverHello = ServerHello()
+ serverHello.create(self.version, getRandomBytes(32),
+ session.sessionID, session.cipherSuite,
+- CertificateType.x509, None, None)
++ CertificateType.x509, None,
++ session.alpn_proto_selected, None)
+ serverHello.extended_master_secret = \
+ clientHello.extended_master_secret and \
+ settings.enableExtendedMasterSecret

Powered by Google App Engine
This is Rietveld 408576698