• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1diff --git a/third_party/tlslite/tlslite/constants.py b/third_party/tlslite/tlslite/constants.py
2index d132b78..ceaa903 100755
3--- a/third_party/tlslite/tlslite/constants.py
4+++ b/third_party/tlslite/tlslite/constants.py
5@@ -30,6 +30,7 @@ class HandshakeType:
6     certificate_verify = 15
7     client_key_exchange = 16
8     finished = 20
9+    certificate_status = 22
10     next_protocol = 67
11     encrypted_extensions = 203
12
13@@ -40,8 +41,12 @@ class ContentType:
14     application_data = 23
15     all = (20,21,22,23)
16
17+class CertificateStatusType:
18+    ocsp = 1
19+
20 class ExtensionType:    # RFC 6066 / 4366
21     server_name = 0     # RFC 6066 / 4366
22+    status_request = 5  # RFC 6066 / 4366
23     srp = 12            # RFC 5054
24     cert_type = 9       # RFC 6091
25     signed_cert_timestamps = 18  # RFC 6962
26diff --git a/third_party/tlslite/tlslite/messages.py b/third_party/tlslite/tlslite/messages.py
27index 5a2cd6c..532d86b 100755
28--- a/third_party/tlslite/tlslite/messages.py
29+++ b/third_party/tlslite/tlslite/messages.py
30@@ -114,6 +114,7 @@ class ClientHello(HandshakeMsg):
31         self.server_name = bytearray(0)
32         self.channel_id = False
33         self.support_signed_cert_timestamps = False
34+        self.status_request = False
35
36     def create(self, version, random, session_id, cipher_suites,
37                certificate_types=None, srpUsername=None,
38@@ -187,6 +188,19 @@ class ClientHello(HandshakeMsg):
39                         if extLength:
40                             raise SyntaxError()
41                         self.support_signed_cert_timestamps = True
42+                    elif extType == ExtensionType.status_request:
43+                        # Extension contents are currently ignored.
44+                        # According to RFC 6066, this is not strictly forbidden
45+                        # (although it is suboptimal):
46+                        # Servers that receive a client hello containing the
47+                        # "status_request" extension MAY return a suitable
48+                        # certificate status response to the client along with
49+                        # their certificate.  If OCSP is requested, they
50+                        # SHOULD use the information contained in the extension
51+                        # when selecting an OCSP responder and SHOULD include
52+                        # request_extensions in the OCSP request.
53+                        p.getFixBytes(extLength)
54+                        self.status_request = True
55                     else:
56                         _ = p.getFixBytes(extLength)
57                     index2 = p.index
58@@ -253,6 +267,7 @@ class ServerHello(HandshakeMsg):
59         self.next_protos = None
60         self.channel_id = False
61         self.signed_cert_timestamps = None
62+        self.status_request = False
63
64     def create(self, version, random, session_id, cipher_suite,
65                certificate_type, tackExt, next_protos_advertised):
66@@ -345,6 +360,9 @@ class ServerHello(HandshakeMsg):
67         if self.signed_cert_timestamps:
68             w2.add(ExtensionType.signed_cert_timestamps, 2)
69             w2.addVarSeq(bytearray(self.signed_cert_timestamps), 1, 2)
70+        if self.status_request:
71+            w2.add(ExtensionType.status_request, 2)
72+            w2.add(0, 2)
73         if len(w2.bytes):
74             w.add(len(w2.bytes), 2)
75             w.bytes += w2.bytes
76@@ -402,6 +420,37 @@ class Certificate(HandshakeMsg):
77             raise AssertionError()
78         return self.postWrite(w)
79
80+class CertificateStatus(HandshakeMsg):
81+    def __init__(self):
82+        HandshakeMsg.__init__(self, HandshakeType.certificate_status)
83+
84+    def create(self, ocsp_response):
85+        self.ocsp_response = ocsp_response
86+        return self
87+
88+    # Defined for the sake of completeness, even though we currently only
89+    # support sending the status message (server-side), not requesting
90+    # or receiving it (client-side).
91+    def parse(self, p):
92+        p.startLengthCheck(3)
93+        status_type = p.get(1)
94+        # Only one type is specified, so hardwire it.
95+        if status_type != CertificateStatusType.ocsp:
96+            raise SyntaxError()
97+        ocsp_response = p.getVarBytes(3)
98+        if not ocsp_response:
99+            # Can't be empty
100+            raise SyntaxError()
101+        self.ocsp_response = ocsp_response
102+        p.stopLengthCheck()
103+        return self
104+
105+    def write(self):
106+        w = Writer()
107+        w.add(CertificateStatusType.ocsp, 1)
108+        w.addVarSeq(bytearray(self.ocsp_response), 1, 3)
109+        return self.postWrite(w)
110+
111 class CertificateRequest(HandshakeMsg):
112     def __init__(self):
113         HandshakeMsg.__init__(self, HandshakeType.certificate_request)
114diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/tlslite/tlsconnection.py
115index bd92161..b9797d2 100755
116--- a/third_party/tlslite/tlslite/tlsconnection.py
117+++ b/third_party/tlslite/tlslite/tlsconnection.py
118@@ -967,7 +967,7 @@ class TLSConnection(TLSRecordLayer):
119                         tacks=None, activationFlags=0,
120                         nextProtos=None, anon=False,
121                         tlsIntolerant=None, signedCertTimestamps=None,
122-                        fallbackSCSV=False):
123+                        fallbackSCSV=False, ocspResponse=None):
124         """Perform a handshake in the role of server.
125
126         This function performs an SSL or TLS handshake.  Depending on
127@@ -1051,6 +1051,16 @@ class TLSConnection(TLSRecordLayer):
128         TLS_FALLBACK_SCSV and thus reject connections using less than the
129         server's maximum TLS version that include this cipher suite.
130
131+        @type ocspResponse: str
132+        @param ocspResponse: An OCSP response (as a binary 8-bit string) that
133+        will be sent stapled in the handshake whenever the client announces
134+        support for the status_request extension.
135+        Note that the response is sent independent of the ClientHello
136+        status_request extension contents, and is thus only meant for testing
137+        environments. Real OCSP stapling is more complicated as it requires
138+        choosing a suitable response based on the ClientHello status_request
139+        extension contents.
140+
141         @raise socket.error: If a socket error occurs.
142         @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
143         without a preceding alert.
144@@ -1064,7 +1074,7 @@ class TLSConnection(TLSRecordLayer):
145                 tacks=tacks, activationFlags=activationFlags,
146                 nextProtos=nextProtos, anon=anon, tlsIntolerant=tlsIntolerant,
147                 signedCertTimestamps=signedCertTimestamps,
148-                fallbackSCSV=fallbackSCSV):
149+                fallbackSCSV=fallbackSCSV, ocspResponse=ocspResponse):
150             pass
151
152
153@@ -1076,7 +1086,8 @@ class TLSConnection(TLSRecordLayer):
154                              nextProtos=None, anon=False,
155                              tlsIntolerant=None,
156                              signedCertTimestamps=None,
157-                             fallbackSCSV=False
158+                             fallbackSCSV=False,
159+                             ocspResponse=None
160                              ):
161         """Start a server handshake operation on the TLS connection.
162
163@@ -1098,7 +1109,8 @@ class TLSConnection(TLSRecordLayer):
164             nextProtos=nextProtos, anon=anon,
165             tlsIntolerant=tlsIntolerant,
166             signedCertTimestamps=signedCertTimestamps,
167-            fallbackSCSV=fallbackSCSV)
168+            fallbackSCSV=fallbackSCSV,
169+            ocspResponse=ocspResponse)
170         for result in self._handshakeWrapperAsync(handshaker, checker):
171             yield result
172
173@@ -1108,7 +1120,8 @@ class TLSConnection(TLSRecordLayer):
174                              settings, reqCAs,
175                              tacks, activationFlags,
176                              nextProtos, anon,
177-                             tlsIntolerant, signedCertTimestamps, fallbackSCSV):
178+                             tlsIntolerant, signedCertTimestamps, fallbackSCSV,
179+                             ocspResponse):
180
181         self._handshakeStart(client=False)
182
183@@ -1178,6 +1191,8 @@ class TLSConnection(TLSRecordLayer):
184         serverHello.channel_id = clientHello.channel_id
185         if clientHello.support_signed_cert_timestamps:
186             serverHello.signed_cert_timestamps = signedCertTimestamps
187+        if clientHello.status_request:
188+            serverHello.status_request = ocspResponse
189
190         # Perform the SRP key exchange
191         clientCertChain = None
192@@ -1194,7 +1209,7 @@ class TLSConnection(TLSRecordLayer):
193             for result in self._serverCertKeyExchange(clientHello, serverHello,
194                                         certChain, privateKey,
195                                         reqCert, reqCAs, cipherSuite,
196-                                        settings):
197+                                        settings, ocspResponse):
198                 if result in (0,1): yield result
199                 else: break
200             (premasterSecret, clientCertChain) = result
201@@ -1471,7 +1486,7 @@ class TLSConnection(TLSRecordLayer):
202     def _serverCertKeyExchange(self, clientHello, serverHello,
203                                 serverCertChain, privateKey,
204                                 reqCert, reqCAs, cipherSuite,
205-                                settings):
206+                                settings, ocspResponse):
207         #Send ServerHello, Certificate[, CertificateRequest],
208         #ServerHelloDone
209         msgs = []
210@@ -1481,6 +1496,8 @@ class TLSConnection(TLSRecordLayer):
211
212         msgs.append(serverHello)
213         msgs.append(Certificate(CertificateType.x509).create(serverCertChain))
214+        if serverHello.status_request:
215+            msgs.append(CertificateStatus().create(ocspResponse))
216         if reqCert and reqCAs:
217             msgs.append(CertificateRequest().create(\
218                 [ClientCertificateType.rsa_sign], reqCAs))
219