Index: third_party/tlslite/tlslite/messages.py |
diff --git a/third_party/tlslite/tlslite/messages.py b/third_party/tlslite/tlslite/messages.py |
index 296f422b33743cff288a39fbdf3ea567a2337340..497ef6048df786d96f62b317c24e933019f35219 100644 |
--- 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 |
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): |
if extLength: |
raise SyntaxError() |
self.support_signed_cert_timestamps = True |
+ elif extType == ExtensionType.status_request: |
+ # Extension contents are currently ignored. |
+ # According to RFC 6066, this is not strictly forbidden |
+ # (although it is suboptimal): |
+ # Servers that receive a client hello containing the |
+ # "status_request" extension MAY return a suitable |
+ # certificate status response to the client along with |
+ # their certificate. If OCSP is requested, they |
+ # SHOULD use the information contained in the extension |
+ # when selecting an OCSP responder and SHOULD include |
+ # request_extensions in the OCSP request. |
+ 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 |
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): |
if self.signed_cert_timestamps: |
extLength += 4 + len(self.signed_cert_timestamps) |
+ 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): |
raise AssertionError() |
return HandshakeMsg.postWrite(self, w, trial) |
+class CertificateStatus(HandshakeMsg): |
+ def __init__(self): |
+ self.contentType = ContentType.handshake |
+ |
+ def create(self, ocsp_response): |
+ self.ocsp_response = ocsp_response |
+ return self |
+ |
+ # Defined for the sake of completeness, even though we currently only |
+ # support sending the status message (server-side), not requesting |
+ # or receiving it (client-side). |
+ def parse(self, p): |
+ p.startLengthCheck(3) |
+ status_type = p.get(1) |
+ # Only one type is specified, so hardwire it. |
+ if status_type != CertificateStatusType.ocsp: |
+ raise SyntaxError() |
+ ocsp_response = p.getVarBytes(3) |
+ if not ocsp_response: |
+ # Can't be empty |
+ raise SyntaxError() |
+ self.ocsp_response = ocsp_response |
+ return self |
+ |
+ def write(self, trial=False): |
+ w = HandshakeMsg.preWrite(self, HandshakeType.certificate_status, |
+ trial) |
+ w.add(CertificateStatusType.ocsp, 1) |
+ w.addVarSeq(stringToBytes(self.ocsp_response), 1, 3) |
+ return HandshakeMsg.postWrite(self, w, trial) |
+ |
class CertificateRequest(HandshakeMsg): |
def __init__(self): |
self.contentType = ContentType.handshake |