1 diff --git a/third_party/tlslite/tlslite/TLSConnection.py b/third_party/tlslite/tlslite/TLSConnection.py 2 index e882e2c..d2270a9 100644 3 --- a/third_party/tlslite/tlslite/TLSConnection.py 4 +++ b/third_party/tlslite/tlslite/TLSConnection.py 5 @@ -936,7 +936,8 @@ class TLSConnection(TLSRecordLayer): 6 def handshakeServer(self, sharedKeyDB=None, verifierDB=None, 7 certChain=None, privateKey=None, reqCert=False, 8 sessionCache=None, settings=None, checker=None, 9 - reqCAs=None, tlsIntolerant=0): 10 + reqCAs=None, tlsIntolerant=0, 11 + signedCertTimestamps=None): 12 """Perform a handshake in the role of server. 13 14 This function performs an SSL or TLS handshake. Depending on 15 @@ -1007,6 +1008,11 @@ class TLSConnection(TLSRecordLayer): 16 will be sent along with a certificate request. This does not affect 17 verification. 18 19 + @type signedCertTimestamps: str 20 + @param signedCertTimestamps: A SignedCertificateTimestampList (as a 21 + binary 8-bit string) that will be sent as a TLS extension whenever 22 + the client announces support for the extension. 23 + 24 @raise socket.error: If a socket error occurs. 25 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed 26 without a preceding alert. 27 @@ -1016,14 +1022,15 @@ class TLSConnection(TLSRecordLayer): 28 """ 29 for result in self.handshakeServerAsync(sharedKeyDB, verifierDB, 30 certChain, privateKey, reqCert, sessionCache, settings, 31 - checker, reqCAs, tlsIntolerant): 32 + checker, reqCAs, tlsIntolerant, signedCertTimestamps): 33 pass 34 35 36 def handshakeServerAsync(self, sharedKeyDB=None, verifierDB=None, 37 certChain=None, privateKey=None, reqCert=False, 38 sessionCache=None, settings=None, checker=None, 39 - reqCAs=None, tlsIntolerant=0): 40 + reqCAs=None, tlsIntolerant=0, 41 + signedCertTimestamps=None): 42 """Start a server handshake operation on the TLS connection. 43 44 This function returns a generator which behaves similarly to 45 @@ -1041,14 +1048,16 @@ class TLSConnection(TLSRecordLayer): 46 privateKey=privateKey, reqCert=reqCert, 47 sessionCache=sessionCache, settings=settings, 48 reqCAs=reqCAs, 49 - tlsIntolerant=tlsIntolerant) 50 + tlsIntolerant=tlsIntolerant, 51 + signedCertTimestamps=signedCertTimestamps) 52 for result in self._handshakeWrapperAsync(handshaker, checker): 53 yield result 54 55 56 def _handshakeServerAsyncHelper(self, sharedKeyDB, verifierDB, 57 - certChain, privateKey, reqCert, sessionCache, 58 - settings, reqCAs, tlsIntolerant): 59 + certChain, privateKey, reqCert, 60 + sessionCache, settings, reqCAs, 61 + tlsIntolerant, signedCertTimestamps): 62 63 self._handshakeStart(client=False) 64 65 @@ -1060,6 +1069,9 @@ class TLSConnection(TLSRecordLayer): 66 raise ValueError("Caller passed a privateKey but no certChain") 67 if reqCAs and not reqCert: 68 raise ValueError("Caller passed reqCAs but not reqCert") 69 + if signedCertTimestamps and not certChain: 70 + raise ValueError("Caller passed signedCertTimestamps but no " 71 + "certChain") 72 73 if not settings: 74 settings = HandshakeSettings() 75 @@ -1415,6 +1427,8 @@ class TLSConnection(TLSRecordLayer): 76 self.version, serverRandom, 77 sessionID, cipherSuite, certificateType) 78 serverHello.channel_id = clientHello.channel_id 79 + if clientHello.support_signed_cert_timestamps: 80 + serverHello.signed_cert_timestamps = signedCertTimestamps 81 doingChannelID = clientHello.channel_id 82 msgs.append(serverHello) 83 msgs.append(Certificate(certificateType).create(serverCertChain)) 84 diff --git a/third_party/tlslite/tlslite/constants.py b/third_party/tlslite/tlslite/constants.py 85 index e357dd0..b5a345a 100644 86 --- a/third_party/tlslite/tlslite/constants.py 87 +++ b/third_party/tlslite/tlslite/constants.py 88 @@ -32,6 +32,7 @@ class ContentType: 89 all = (20,21,22,23) 90 91 class ExtensionType: 92 + signed_cert_timestamps = 18 # signed_certificate_timestamp in RFC 6962 93 channel_id = 30031 94 95 class AlertLevel: 96 diff --git a/third_party/tlslite/tlslite/messages.py b/third_party/tlslite/tlslite/messages.py 97 index fa4d817..296f422 100644 98 --- a/third_party/tlslite/tlslite/messages.py 99 +++ b/third_party/tlslite/tlslite/messages.py 100 @@ -131,6 +131,7 @@ class ClientHello(HandshakeMsg): 101 self.compression_methods = [] # a list of 8-bit values 102 self.srp_username = None # a string 103 self.channel_id = False 104 + self.support_signed_cert_timestamps = False 105 106 def create(self, version, random, session_id, cipher_suites, 107 certificate_types=None, srp_username=None): 108 @@ -177,6 +178,10 @@ class ClientHello(HandshakeMsg): 109 self.certificate_types = p.getVarList(1, 1) 110 elif extType == ExtensionType.channel_id: 111 self.channel_id = True 112 + elif extType == ExtensionType.signed_cert_timestamps: 113 + if extLength: 114 + raise SyntaxError() 115 + self.support_signed_cert_timestamps = True 116 else: 117 p.getFixBytes(extLength) 118 soFar += 4 + extLength 119 @@ -224,6 +229,7 @@ class ServerHello(HandshakeMsg): 120 self.certificate_type = CertificateType.x509 121 self.compression_method = 0 122 self.channel_id = False 123 + self.signed_cert_timestamps = None 124 125 def create(self, version, random, session_id, cipher_suite, 126 certificate_type): 127 @@ -273,6 +279,9 @@ class ServerHello(HandshakeMsg): 128 if self.channel_id: 129 extLength += 4 130 131 + if self.signed_cert_timestamps: 132 + extLength += 4 + len(self.signed_cert_timestamps) 133 + 134 if extLength != 0: 135 w.add(extLength, 2) 136 137 @@ -286,6 +295,10 @@ class ServerHello(HandshakeMsg): 138 w.add(ExtensionType.channel_id, 2) 139 w.add(0, 2) 140 141 + if self.signed_cert_timestamps: 142 + w.add(ExtensionType.signed_cert_timestamps, 2) 143 + w.addVarSeq(stringToBytes(self.signed_cert_timestamps), 1, 2) 144 + 145 return HandshakeMsg.postWrite(self, w, trial) 146 147 class Certificate(HandshakeMsg): 148