Index: third_party/tlslite/patches/status_request.patch |
diff --git a/third_party/tlslite/patches/status_request.patch b/third_party/tlslite/patches/status_request.patch |
index 15f01d42809edf3fea8347da8d1f225d08798077..cfd7f6f19c614ecd56a099930ef0ac8dfe8dacd6 100644 |
--- a/third_party/tlslite/patches/status_request.patch |
+++ b/third_party/tlslite/patches/status_request.patch |
@@ -1,125 +1,41 @@ |
-diff --git a/third_party/tlslite/tlslite/TLSConnection.py b/third_party/tlslite/tlslite/TLSConnection.py |
-index e6ce187..94ee5eb 100644 |
---- a/third_party/tlslite/tlslite/TLSConnection.py |
-+++ b/third_party/tlslite/tlslite/TLSConnection.py |
-@@ -937,8 +937,8 @@ class TLSConnection(TLSRecordLayer): |
- certChain=None, privateKey=None, reqCert=False, |
- sessionCache=None, settings=None, checker=None, |
- reqCAs=None, tlsIntolerant=0, |
-- signedCertTimestamps=None, |
-- fallbackSCSV=False): |
-+ signedCertTimestamps=None, fallbackSCSV=False, |
-+ ocspResponse=None): |
- """Perform a handshake in the role of server. |
- |
- This function performs an SSL or TLS handshake. Depending on |
-@@ -1014,6 +1014,16 @@ class TLSConnection(TLSRecordLayer): |
- binary 8-bit string) that will be sent as a TLS extension whenever |
- the client announces support for the extension. |
- |
-+ @type ocspResponse: str |
-+ @param ocspResponse: An OCSP response (as a binary 8-bit string) that |
-+ will be sent stapled in the handshake whenever the client announces |
-+ support for the status_request extension. |
-+ Note that the response is sent independent of the ClientHello |
-+ status_request extension contents, and is thus only meant for testing |
-+ environments. Real OCSP stapling is more complicated as it requires |
-+ choosing a suitable response based on the ClientHello status_request |
-+ extension contents. |
-+ |
- @raise socket.error: If a socket error occurs. |
- @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed |
- without a preceding alert. |
-@@ -1024,7 +1034,7 @@ class TLSConnection(TLSRecordLayer): |
- for result in self.handshakeServerAsync(sharedKeyDB, verifierDB, |
- certChain, privateKey, reqCert, sessionCache, settings, |
- checker, reqCAs, tlsIntolerant, signedCertTimestamps, |
-- fallbackSCSV): |
-+ fallbackSCSV, ocspResponse): |
- pass |
- |
- |
-@@ -1033,7 +1043,7 @@ class TLSConnection(TLSRecordLayer): |
- sessionCache=None, settings=None, checker=None, |
- reqCAs=None, tlsIntolerant=0, |
- signedCertTimestamps=None, |
-- fallbackSCSV=False): |
-+ fallbackSCSV=False, ocspResponse=None): |
- """Start a server handshake operation on the TLS connection. |
- |
- This function returns a generator which behaves similarly to |
-@@ -1053,7 +1063,8 @@ class TLSConnection(TLSRecordLayer): |
- reqCAs=reqCAs, |
- tlsIntolerant=tlsIntolerant, |
- signedCertTimestamps=signedCertTimestamps, |
-- fallbackSCSV=fallbackSCSV) |
-+ fallbackSCSV=fallbackSCSV, ocspResponse=ocspResponse) |
-+ |
- for result in self._handshakeWrapperAsync(handshaker, checker): |
- yield result |
- |
-@@ -1062,7 +1073,7 @@ class TLSConnection(TLSRecordLayer): |
- certChain, privateKey, reqCert, |
- sessionCache, settings, reqCAs, |
- tlsIntolerant, signedCertTimestamps, |
-- fallbackSCSV): |
-+ fallbackSCSV, ocspResponse): |
- |
- self._handshakeStart(client=False) |
- |
-@@ -1439,10 +1450,14 @@ class TLSConnection(TLSRecordLayer): |
- sessionID, cipherSuite, certificateType) |
- serverHello.channel_id = clientHello.channel_id |
- if clientHello.support_signed_cert_timestamps: |
-- serverHello.signed_cert_timestamps = signedCertTimestamps |
-+ serverHello.signed_cert_timestamps = signedCertTimestamps |
-+ serverHello.status_request = (clientHello.status_request and |
-+ ocspResponse) |
- doingChannelID = clientHello.channel_id |
- msgs.append(serverHello) |
- msgs.append(Certificate(certificateType).create(serverCertChain)) |
-+ if serverHello.status_request: |
-+ msgs.append(CertificateStatus().create(ocspResponse)) |
- if reqCert and reqCAs: |
- msgs.append(CertificateRequest().create([], reqCAs)) |
- elif reqCert: |
diff --git a/third_party/tlslite/tlslite/constants.py b/third_party/tlslite/tlslite/constants.py |
-index 23e3dcb..d027ef5 100644 |
+index d132b78..ceaa903 100755 |
--- a/third_party/tlslite/tlslite/constants.py |
+++ b/third_party/tlslite/tlslite/constants.py |
-@@ -22,6 +22,7 @@ class HandshakeType: |
+@@ -30,6 +30,7 @@ class HandshakeType: |
certificate_verify = 15 |
client_key_exchange = 16 |
finished = 20 |
+ certificate_status = 22 |
+ next_protocol = 67 |
encrypted_extensions = 203 |
- class ContentType: |
-@@ -31,7 +32,11 @@ class ContentType: |
+@@ -40,8 +41,12 @@ class ContentType: |
application_data = 23 |
all = (20,21,22,23) |
+class CertificateStatusType: |
+ ocsp = 1 |
+ |
- class ExtensionType: |
-+ status_request = 5 # OCSP stapling |
- signed_cert_timestamps = 18 # signed_certificate_timestamp in RFC 6962 |
- channel_id = 30031 |
- |
+ class ExtensionType: # RFC 6066 / 4366 |
+ server_name = 0 # RFC 6066 / 4366 |
++ status_request = 5 # RFC 6066 / 4366 |
+ srp = 12 # RFC 5054 |
+ cert_type = 9 # RFC 6091 |
+ signed_cert_timestamps = 18 # RFC 6962 |
diff --git a/third_party/tlslite/tlslite/messages.py b/third_party/tlslite/tlslite/messages.py |
-index 296f422..497ef60 100644 |
+index 5a2cd6c..532d86b 100755 |
--- a/third_party/tlslite/tlslite/messages.py |
+++ b/third_party/tlslite/tlslite/messages.py |
-@@ -132,6 +132,7 @@ class ClientHello(HandshakeMsg): |
- self.srp_username = None # a string |
+@@ -114,6 +114,7 @@ class ClientHello(HandshakeMsg): |
+ self.server_name = bytearray(0) |
self.channel_id = False |
self.support_signed_cert_timestamps = False |
+ self.status_request = False |
def create(self, version, random, session_id, cipher_suites, |
- certificate_types=None, srp_username=None): |
-@@ -182,6 +183,19 @@ class ClientHello(HandshakeMsg): |
+ certificate_types=None, srpUsername=None, |
+@@ -187,6 +188,19 @@ class ClientHello(HandshakeMsg): |
if extLength: |
raise SyntaxError() |
self.support_signed_cert_timestamps = True |
@@ -137,44 +53,33 @@ index 296f422..497ef60 100644 |
+ p.getFixBytes(extLength) |
+ self.status_request = True |
else: |
- p.getFixBytes(extLength) |
- soFar += 4 + extLength |
-@@ -230,6 +244,7 @@ class ServerHello(HandshakeMsg): |
- self.compression_method = 0 |
+ _ = p.getFixBytes(extLength) |
+ index2 = p.index |
+@@ -253,6 +267,7 @@ class ServerHello(HandshakeMsg): |
+ self.next_protos = None |
self.channel_id = False |
self.signed_cert_timestamps = None |
+ self.status_request = False |
def create(self, version, random, session_id, cipher_suite, |
- certificate_type): |
-@@ -282,6 +297,9 @@ class ServerHello(HandshakeMsg): |
+ certificate_type, tackExt, next_protos_advertised): |
+@@ -345,6 +360,9 @@ class ServerHello(HandshakeMsg): |
if self.signed_cert_timestamps: |
- extLength += 4 + len(self.signed_cert_timestamps) |
- |
+ w2.add(ExtensionType.signed_cert_timestamps, 2) |
+ w2.addVarSeq(bytearray(self.signed_cert_timestamps), 1, 2) |
+ if self.status_request: |
-+ extLength += 4 |
-+ |
- if extLength != 0: |
- w.add(extLength, 2) |
- |
-@@ -299,6 +317,10 @@ class ServerHello(HandshakeMsg): |
- w.add(ExtensionType.signed_cert_timestamps, 2) |
- w.addVarSeq(stringToBytes(self.signed_cert_timestamps), 1, 2) |
- |
-+ if self.status_request: |
-+ w.add(ExtensionType.status_request, 2) |
-+ w.add(0, 2) |
-+ |
- return HandshakeMsg.postWrite(self, w, trial) |
- |
- class Certificate(HandshakeMsg): |
-@@ -367,6 +389,37 @@ class Certificate(HandshakeMsg): |
++ w2.add(ExtensionType.status_request, 2) |
++ w2.add(0, 2) |
+ if len(w2.bytes): |
+ w.add(len(w2.bytes), 2) |
+ w.bytes += w2.bytes |
+@@ -402,6 +420,37 @@ class Certificate(HandshakeMsg): |
raise AssertionError() |
- return HandshakeMsg.postWrite(self, w, trial) |
+ return self.postWrite(w) |
+class CertificateStatus(HandshakeMsg): |
+ def __init__(self): |
-+ self.contentType = ContentType.handshake |
++ HandshakeMsg.__init__(self, HandshakeType.certificate_status) |
+ |
+ def create(self, ocsp_response): |
+ self.ocsp_response = ocsp_response |
@@ -194,15 +99,120 @@ index 296f422..497ef60 100644 |
+ # Can't be empty |
+ raise SyntaxError() |
+ self.ocsp_response = ocsp_response |
++ p.stopLengthCheck() |
+ return self |
+ |
-+ def write(self, trial=False): |
-+ w = HandshakeMsg.preWrite(self, HandshakeType.certificate_status, |
-+ trial) |
++ def write(self): |
++ w = Writer() |
+ w.add(CertificateStatusType.ocsp, 1) |
-+ w.addVarSeq(stringToBytes(self.ocsp_response), 1, 3) |
-+ return HandshakeMsg.postWrite(self, w, trial) |
++ w.addVarSeq(bytearray(self.ocsp_response), 1, 3) |
++ return self.postWrite(w) |
+ |
class CertificateRequest(HandshakeMsg): |
def __init__(self): |
- self.contentType = ContentType.handshake |
+ HandshakeMsg.__init__(self, HandshakeType.certificate_request) |
+diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/tlslite/tlsconnection.py |
+index bd92161..b9797d2 100755 |
+--- a/third_party/tlslite/tlslite/tlsconnection.py |
++++ b/third_party/tlslite/tlslite/tlsconnection.py |
+@@ -967,7 +967,7 @@ class TLSConnection(TLSRecordLayer): |
+ tacks=None, activationFlags=0, |
+ nextProtos=None, anon=False, |
+ tlsIntolerant=None, signedCertTimestamps=None, |
+- fallbackSCSV=False): |
++ fallbackSCSV=False, ocspResponse=None): |
+ """Perform a handshake in the role of server. |
+ |
+ This function performs an SSL or TLS handshake. Depending on |
+@@ -1051,6 +1051,16 @@ class TLSConnection(TLSRecordLayer): |
+ TLS_FALLBACK_SCSV and thus reject connections using less than the |
+ server's maximum TLS version that include this cipher suite. |
+ |
++ @type ocspResponse: str |
++ @param ocspResponse: An OCSP response (as a binary 8-bit string) that |
++ will be sent stapled in the handshake whenever the client announces |
++ support for the status_request extension. |
++ Note that the response is sent independent of the ClientHello |
++ status_request extension contents, and is thus only meant for testing |
++ environments. Real OCSP stapling is more complicated as it requires |
++ choosing a suitable response based on the ClientHello status_request |
++ extension contents. |
++ |
+ @raise socket.error: If a socket error occurs. |
+ @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed |
+ without a preceding alert. |
+@@ -1064,7 +1074,7 @@ class TLSConnection(TLSRecordLayer): |
+ tacks=tacks, activationFlags=activationFlags, |
+ nextProtos=nextProtos, anon=anon, tlsIntolerant=tlsIntolerant, |
+ signedCertTimestamps=signedCertTimestamps, |
+- fallbackSCSV=fallbackSCSV): |
++ fallbackSCSV=fallbackSCSV, ocspResponse=ocspResponse): |
+ pass |
+ |
+ |
+@@ -1076,7 +1086,8 @@ class TLSConnection(TLSRecordLayer): |
+ nextProtos=None, anon=False, |
+ tlsIntolerant=None, |
+ signedCertTimestamps=None, |
+- fallbackSCSV=False |
++ fallbackSCSV=False, |
++ ocspResponse=None |
+ ): |
+ """Start a server handshake operation on the TLS connection. |
+ |
+@@ -1098,7 +1109,8 @@ class TLSConnection(TLSRecordLayer): |
+ nextProtos=nextProtos, anon=anon, |
+ tlsIntolerant=tlsIntolerant, |
+ signedCertTimestamps=signedCertTimestamps, |
+- fallbackSCSV=fallbackSCSV) |
++ fallbackSCSV=fallbackSCSV, |
++ ocspResponse=ocspResponse) |
+ for result in self._handshakeWrapperAsync(handshaker, checker): |
+ yield result |
+ |
+@@ -1108,7 +1120,8 @@ class TLSConnection(TLSRecordLayer): |
+ settings, reqCAs, |
+ tacks, activationFlags, |
+ nextProtos, anon, |
+- tlsIntolerant, signedCertTimestamps, fallbackSCSV): |
++ tlsIntolerant, signedCertTimestamps, fallbackSCSV, |
++ ocspResponse): |
+ |
+ self._handshakeStart(client=False) |
+ |
+@@ -1178,6 +1191,8 @@ class TLSConnection(TLSRecordLayer): |
+ serverHello.channel_id = clientHello.channel_id |
+ if clientHello.support_signed_cert_timestamps: |
+ serverHello.signed_cert_timestamps = signedCertTimestamps |
++ if clientHello.status_request: |
++ serverHello.status_request = ocspResponse |
+ |
+ # Perform the SRP key exchange |
+ clientCertChain = None |
+@@ -1194,7 +1209,7 @@ class TLSConnection(TLSRecordLayer): |
+ for result in self._serverCertKeyExchange(clientHello, serverHello, |
+ certChain, privateKey, |
+ reqCert, reqCAs, cipherSuite, |
+- settings): |
++ settings, ocspResponse): |
+ if result in (0,1): yield result |
+ else: break |
+ (premasterSecret, clientCertChain) = result |
+@@ -1471,7 +1486,7 @@ class TLSConnection(TLSRecordLayer): |
+ def _serverCertKeyExchange(self, clientHello, serverHello, |
+ serverCertChain, privateKey, |
+ reqCert, reqCAs, cipherSuite, |
+- settings): |
++ settings, ocspResponse): |
+ #Send ServerHello, Certificate[, CertificateRequest], |
+ #ServerHelloDone |
+ msgs = [] |
+@@ -1481,6 +1496,8 @@ class TLSConnection(TLSRecordLayer): |
+ |
+ msgs.append(serverHello) |
+ msgs.append(Certificate(CertificateType.x509).create(serverCertChain)) |
++ if serverHello.status_request: |
++ msgs.append(CertificateStatus().create(ocspResponse)) |
+ if reqCert and reqCAs: |
+ msgs.append(CertificateRequest().create(\ |
+ [ClientCertificateType.rsa_sign], reqCAs)) |