| 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
|
|
|