diff --git a/third_party/tlslite/tlslite/constants.py b/third_party/tlslite/tlslite/constants.py index 6429c66..8720de6 100644 --- a/third_party/tlslite/tlslite/constants.py +++ b/third_party/tlslite/tlslite/constants.py @@ -45,6 +45,7 @@ class ExtensionType: # RFC 6066 / 4366 server_name = 0 # RFC 6066 / 4366 srp = 12 # RFC 5054 cert_type = 9 # RFC 6091 + signed_cert_timestamps = 18 # RFC 6962 tack = 0xF300 supports_npn = 13172 channel_id = 30032 diff --git a/third_party/tlslite/tlslite/messages.py b/third_party/tlslite/tlslite/messages.py index 4fa9d96..876b033 100644 --- a/third_party/tlslite/tlslite/messages.py +++ b/third_party/tlslite/tlslite/messages.py @@ -114,6 +114,7 @@ class ClientHello(HandshakeMsg): self.supports_npn = False self.server_name = bytearray(0) self.channel_id = False + self.support_signed_cert_timestamps = False def create(self, version, random, session_id, cipher_suites, certificate_types=None, srpUsername=None, @@ -183,6 +184,10 @@ class ClientHello(HandshakeMsg): break elif extType == ExtensionType.channel_id: self.channel_id = True + elif extType == ExtensionType.signed_cert_timestamps: + if extLength: + raise SyntaxError() + self.support_signed_cert_timestamps = True else: _ = p.getFixBytes(extLength) index2 = p.index @@ -248,6 +253,7 @@ class ServerHello(HandshakeMsg): self.next_protos_advertised = None self.next_protos = None self.channel_id = False + self.signed_cert_timestamps = None def create(self, version, random, session_id, cipher_suite, certificate_type, tackExt, next_protos_advertised): @@ -337,6 +343,9 @@ class ServerHello(HandshakeMsg): if self.channel_id: w2.add(ExtensionType.channel_id, 2) w2.add(0, 2) + if self.signed_cert_timestamps: + w2.add(ExtensionType.signed_cert_timestamps, 2) + w2.addVarSeq(bytearray(self.signed_cert_timestamps), 1, 2) if len(w2.bytes): w.add(len(w2.bytes), 2) w.bytes += w2.bytes diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/tlslite/tlsconnection.py index b0400f8..4dedc5f 100644 --- a/third_party/tlslite/tlslite/tlsconnection.py +++ b/third_party/tlslite/tlslite/tlsconnection.py @@ -969,7 +969,7 @@ class TLSConnection(TLSRecordLayer): reqCAs = None, tacks=None, activationFlags=0, nextProtos=None, anon=False, - tlsIntolerant=None): + tlsIntolerant=None, signedCertTimestamps=None): """Perform a handshake in the role of server. This function performs an SSL or TLS handshake. Depending on @@ -1043,6 +1043,11 @@ class TLSConnection(TLSRecordLayer): simulate TLS version intolerance by returning a fatal handshake_failure alert to all TLS versions tlsIntolerant or higher. + @type signedCertTimestamps: str + @param signedCertTimestamps: A SignedCertificateTimestampList (as a + binary 8-bit string) that will be sent as a TLS extension whenever + the client announces support for the extension. + @raise socket.error: If a socket error occurs. @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed without a preceding alert. @@ -1054,7 +1059,8 @@ class TLSConnection(TLSRecordLayer): certChain, privateKey, reqCert, sessionCache, settings, checker, reqCAs, tacks=tacks, activationFlags=activationFlags, - nextProtos=nextProtos, anon=anon, tlsIntolerant=tlsIntolerant): + nextProtos=nextProtos, anon=anon, tlsIntolerant=tlsIntolerant, + signedCertTimestamps=signedCertTimestamps): pass @@ -1064,7 +1070,8 @@ class TLSConnection(TLSRecordLayer): reqCAs=None, tacks=None, activationFlags=0, nextProtos=None, anon=False, - tlsIntolerant=None + tlsIntolerant=None, + signedCertTimestamps=None ): """Start a server handshake operation on the TLS connection. @@ -1084,7 +1091,8 @@ class TLSConnection(TLSRecordLayer): reqCAs=reqCAs, tacks=tacks, activationFlags=activationFlags, nextProtos=nextProtos, anon=anon, - tlsIntolerant=tlsIntolerant) + tlsIntolerant=tlsIntolerant, + signedCertTimestamps=signedCertTimestamps) for result in self._handshakeWrapperAsync(handshaker, checker): yield result @@ -1094,7 +1102,7 @@ class TLSConnection(TLSRecordLayer): settings, reqCAs, tacks, activationFlags, nextProtos, anon, - tlsIntolerant): + tlsIntolerant, signedCertTimestamps): self._handshakeStart(client=False) @@ -1115,6 +1123,9 @@ class TLSConnection(TLSRecordLayer): raise ValueError("tackpy is not loaded") if not settings or not settings.useExperimentalTackExtension: raise ValueError("useExperimentalTackExtension not enabled") + if signedCertTimestamps and not certChain: + raise ValueError("Caller passed signedCertTimestamps but no " + "certChain") if not settings: settings = HandshakeSettings() @@ -1159,6 +1170,8 @@ class TLSConnection(TLSRecordLayer): cipherSuite, CertificateType.x509, tackExt, nextProtos) serverHello.channel_id = clientHello.channel_id + if clientHello.support_signed_cert_timestamps: + serverHello.signed_cert_timestamps = signedCertTimestamps # Perform the SRP key exchange clientCertChain = None