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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: third_party/tlslite/tlslite/tlsconnection.py
diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/tlslite/tlsconnection.py
index 41aab85a71b3726d8cafb6060c94c44000e999a8..e06294064ea563824afb66915bdce3a1b03a9aed 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)
davidben 2016/08/04 22:29:26 Unintentional lost comment?
Bence 2016/08/05 14:27:55 Oops. Done.
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
#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
davidben 2016/08/04 22:29:26 This function probably should not mutate the setti
Bence 2016/08/05 14:27:55 Done.
# 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
« 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