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..de5d5802323ad6e3cb6f0e167a82b3d848a1bd7d 100644 |
--- a/third_party/tlslite/tlslite/tlsconnection.py |
+++ b/third_party/tlslite/tlslite/tlsconnection.py |
@@ -495,6 +495,10 @@ class TLSConnection(TLSRecordLayer): |
settings = HandshakeSettings() |
settings = settings._filter() |
+ if settings.alpnProtos is not None: |
+ if len(settings.alpnProtos) == 0: |
+ raise ValueError("Caller passed no alpnProtos") |
+ |
if clientCertChain: |
if not isinstance(clientCertChain, X509CertChain): |
raise ValueError("Unrecognized certificate type") |
@@ -651,7 +655,8 @@ class TLSConnection(TLSRecordLayer): |
session.sessionID, cipherSuites, |
certificateTypes, |
session.srpUsername, |
- reqTack, nextProtos is not None, |
+ reqTack, settings.alpnProtos, |
+ nextProtos is not None, |
session.serverName) |
#Or send ClientHello (without) |
@@ -661,7 +666,8 @@ class TLSConnection(TLSRecordLayer): |
bytearray(0), cipherSuites, |
certificateTypes, |
srpUsername, |
- reqTack, nextProtos is not None, |
+ reqTack, settings.alpnProtos, |
+ nextProtos is not None, |
serverName) |
for result in self._sendMsg(clientHello): |
yield result |
@@ -714,6 +720,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, |
@@ -1315,6 +1331,15 @@ class TLSConnection(TLSRecordLayer): |
else: |
sessionID = bytearray(0) |
+ alpn_proto_selected = None |
+ if (clientHello.alpn_protos_advertised is not None |
+ and settings.alpnProtos is not None): |
+ for proto in settings.alpnProtos: |
+ if proto in clientHello.alpn_protos_advertised: |
+ alpn_proto_selected = proto |
+ nextProtos = None |
+ break; |
+ |
if not clientHello.supports_npn: |
nextProtos = None |
@@ -1330,6 +1355,7 @@ class TLSConnection(TLSRecordLayer): |
serverHello = ServerHello() |
serverHello.create(self.version, getRandomBytes(32), sessionID, \ |
cipherSuite, CertificateType.x509, tackExt, |
+ alpn_proto_selected, |
nextProtos) |
serverHello.channel_id = \ |
clientHello.channel_id and settings.enableChannelID |
@@ -1500,6 +1526,14 @@ class TLSConnection(TLSRecordLayer): |
else: |
assert(False) |
+ alpn_proto_selected = None |
+ if (clientHello.alpn_protos_advertised is not None |
+ and settings.alpnProtos is not None): |
+ for proto in settings.alpnProtos: |
+ if proto in clientHello.alpn_protos_advertised: |
+ alpn_proto_selected = proto |
+ break; |
+ |
#If resumption was requested and we have a session cache... |
if clientHello.session_id and sessionCache: |
session = None |
@@ -1540,7 +1574,8 @@ class TLSConnection(TLSRecordLayer): |
serverHello = ServerHello() |
serverHello.create(self.version, getRandomBytes(32), |
session.sessionID, session.cipherSuite, |
- CertificateType.x509, None, None) |
+ CertificateType.x509, None, |
+ alpn_proto_selected, None) |
serverHello.extended_master_secret = \ |
clientHello.extended_master_secret and \ |
settings.enableExtendedMasterSecret |