OLD | NEW |
1 """Classes representing TLS messages.""" | 1 """Classes representing TLS messages.""" |
2 | 2 |
3 from utils.compat import * | 3 from utils.compat import * |
4 from utils.cryptomath import * | 4 from utils.cryptomath import * |
5 from errors import * | 5 from errors import * |
6 from utils.codec import * | 6 from utils.codec import * |
7 from constants import * | 7 from constants import * |
8 from X509 import X509 | 8 from X509 import X509 |
9 from X509CertChain import X509CertChain | 9 from X509CertChain import X509CertChain |
10 | 10 |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 self.ssl2 = ssl2 | 125 self.ssl2 = ssl2 |
126 self.client_version = (0,0) | 126 self.client_version = (0,0) |
127 self.random = createByteArrayZeros(32) | 127 self.random = createByteArrayZeros(32) |
128 self.session_id = createByteArraySequence([]) | 128 self.session_id = createByteArraySequence([]) |
129 self.cipher_suites = [] # a list of 16-bit values | 129 self.cipher_suites = [] # a list of 16-bit values |
130 self.certificate_types = [CertificateType.x509] | 130 self.certificate_types = [CertificateType.x509] |
131 self.compression_methods = [] # a list of 8-bit values | 131 self.compression_methods = [] # a list of 8-bit values |
132 self.srp_username = None # a string | 132 self.srp_username = None # a string |
133 self.channel_id = False | 133 self.channel_id = False |
134 self.support_signed_cert_timestamps = False | 134 self.support_signed_cert_timestamps = False |
| 135 self.status_request = False |
135 | 136 |
136 def create(self, version, random, session_id, cipher_suites, | 137 def create(self, version, random, session_id, cipher_suites, |
137 certificate_types=None, srp_username=None): | 138 certificate_types=None, srp_username=None): |
138 self.client_version = version | 139 self.client_version = version |
139 self.random = random | 140 self.random = random |
140 self.session_id = session_id | 141 self.session_id = session_id |
141 self.cipher_suites = cipher_suites | 142 self.cipher_suites = cipher_suites |
142 self.certificate_types = certificate_types | 143 self.certificate_types = certificate_types |
143 self.compression_methods = [0] | 144 self.compression_methods = [0] |
144 self.srp_username = srp_username | 145 self.srp_username = srp_username |
(...skipping 30 matching lines...) Expand all Loading... |
175 if extType == 6: | 176 if extType == 6: |
176 self.srp_username = bytesToString(p.getVarBytes(1)) | 177 self.srp_username = bytesToString(p.getVarBytes(1)) |
177 elif extType == 7: | 178 elif extType == 7: |
178 self.certificate_types = p.getVarList(1, 1) | 179 self.certificate_types = p.getVarList(1, 1) |
179 elif extType == ExtensionType.channel_id: | 180 elif extType == ExtensionType.channel_id: |
180 self.channel_id = True | 181 self.channel_id = True |
181 elif extType == ExtensionType.signed_cert_timestamps: | 182 elif extType == ExtensionType.signed_cert_timestamps: |
182 if extLength: | 183 if extLength: |
183 raise SyntaxError() | 184 raise SyntaxError() |
184 self.support_signed_cert_timestamps = True | 185 self.support_signed_cert_timestamps = True |
| 186 elif extType == ExtensionType.status_request: |
| 187 # Extension contents are currently ignored. |
| 188 # According to RFC 6066, this is not strictly forbidden |
| 189 # (although it is suboptimal): |
| 190 # Servers that receive a client hello containing the |
| 191 # "status_request" extension MAY return a suitable |
| 192 # certificate status response to the client along with |
| 193 # their certificate. If OCSP is requested, they |
| 194 # SHOULD use the information contained in the extension |
| 195 # when selecting an OCSP responder and SHOULD include |
| 196 # request_extensions in the OCSP request. |
| 197 p.getFixBytes(extLength) |
| 198 self.status_request = True |
185 else: | 199 else: |
186 p.getFixBytes(extLength) | 200 p.getFixBytes(extLength) |
187 soFar += 4 + extLength | 201 soFar += 4 + extLength |
188 p.stopLengthCheck() | 202 p.stopLengthCheck() |
189 return self | 203 return self |
190 | 204 |
191 def write(self, trial=False): | 205 def write(self, trial=False): |
192 w = HandshakeMsg.preWrite(self, HandshakeType.client_hello, trial) | 206 w = HandshakeMsg.preWrite(self, HandshakeType.client_hello, trial) |
193 w.add(self.client_version[0], 1) | 207 w.add(self.client_version[0], 1) |
194 w.add(self.client_version[1], 1) | 208 w.add(self.client_version[1], 1) |
(...skipping 28 matching lines...) Expand all Loading... |
223 def __init__(self): | 237 def __init__(self): |
224 self.contentType = ContentType.handshake | 238 self.contentType = ContentType.handshake |
225 self.server_version = (0,0) | 239 self.server_version = (0,0) |
226 self.random = createByteArrayZeros(32) | 240 self.random = createByteArrayZeros(32) |
227 self.session_id = createByteArraySequence([]) | 241 self.session_id = createByteArraySequence([]) |
228 self.cipher_suite = 0 | 242 self.cipher_suite = 0 |
229 self.certificate_type = CertificateType.x509 | 243 self.certificate_type = CertificateType.x509 |
230 self.compression_method = 0 | 244 self.compression_method = 0 |
231 self.channel_id = False | 245 self.channel_id = False |
232 self.signed_cert_timestamps = None | 246 self.signed_cert_timestamps = None |
| 247 self.status_request = False |
233 | 248 |
234 def create(self, version, random, session_id, cipher_suite, | 249 def create(self, version, random, session_id, cipher_suite, |
235 certificate_type): | 250 certificate_type): |
236 self.server_version = version | 251 self.server_version = version |
237 self.random = random | 252 self.random = random |
238 self.session_id = session_id | 253 self.session_id = session_id |
239 self.cipher_suite = cipher_suite | 254 self.cipher_suite = cipher_suite |
240 self.certificate_type = certificate_type | 255 self.certificate_type = certificate_type |
241 self.compression_method = 0 | 256 self.compression_method = 0 |
242 return self | 257 return self |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 if self.certificate_type and self.certificate_type != \ | 290 if self.certificate_type and self.certificate_type != \ |
276 CertificateType.x509: | 291 CertificateType.x509: |
277 extLength += 5 | 292 extLength += 5 |
278 | 293 |
279 if self.channel_id: | 294 if self.channel_id: |
280 extLength += 4 | 295 extLength += 4 |
281 | 296 |
282 if self.signed_cert_timestamps: | 297 if self.signed_cert_timestamps: |
283 extLength += 4 + len(self.signed_cert_timestamps) | 298 extLength += 4 + len(self.signed_cert_timestamps) |
284 | 299 |
| 300 if self.status_request: |
| 301 extLength += 4 |
| 302 |
285 if extLength != 0: | 303 if extLength != 0: |
286 w.add(extLength, 2) | 304 w.add(extLength, 2) |
287 | 305 |
288 if self.certificate_type and self.certificate_type != \ | 306 if self.certificate_type and self.certificate_type != \ |
289 CertificateType.x509: | 307 CertificateType.x509: |
290 w.add(7, 2) | 308 w.add(7, 2) |
291 w.add(1, 2) | 309 w.add(1, 2) |
292 w.add(self.certificate_type, 1) | 310 w.add(self.certificate_type, 1) |
293 | 311 |
294 if self.channel_id: | 312 if self.channel_id: |
295 w.add(ExtensionType.channel_id, 2) | 313 w.add(ExtensionType.channel_id, 2) |
296 w.add(0, 2) | 314 w.add(0, 2) |
297 | 315 |
298 if self.signed_cert_timestamps: | 316 if self.signed_cert_timestamps: |
299 w.add(ExtensionType.signed_cert_timestamps, 2) | 317 w.add(ExtensionType.signed_cert_timestamps, 2) |
300 w.addVarSeq(stringToBytes(self.signed_cert_timestamps), 1, 2) | 318 w.addVarSeq(stringToBytes(self.signed_cert_timestamps), 1, 2) |
301 | 319 |
| 320 if self.status_request: |
| 321 w.add(ExtensionType.status_request, 2) |
| 322 w.add(0, 2) |
| 323 |
302 return HandshakeMsg.postWrite(self, w, trial) | 324 return HandshakeMsg.postWrite(self, w, trial) |
303 | 325 |
304 class Certificate(HandshakeMsg): | 326 class Certificate(HandshakeMsg): |
305 def __init__(self, certificateType): | 327 def __init__(self, certificateType): |
306 self.certificateType = certificateType | 328 self.certificateType = certificateType |
307 self.contentType = ContentType.handshake | 329 self.contentType = ContentType.handshake |
308 self.certChain = None | 330 self.certChain = None |
309 | 331 |
310 def create(self, certChain): | 332 def create(self, certChain): |
311 self.certChain = certChain | 333 self.certChain = certChain |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 elif self.certificateType == CertificateType.cryptoID: | 382 elif self.certificateType == CertificateType.cryptoID: |
361 if self.certChain: | 383 if self.certChain: |
362 bytes = stringToBytes(self.certChain.write()) | 384 bytes = stringToBytes(self.certChain.write()) |
363 else: | 385 else: |
364 bytes = createByteArraySequence([]) | 386 bytes = createByteArraySequence([]) |
365 w.addVarSeq(bytes, 1, 2) | 387 w.addVarSeq(bytes, 1, 2) |
366 else: | 388 else: |
367 raise AssertionError() | 389 raise AssertionError() |
368 return HandshakeMsg.postWrite(self, w, trial) | 390 return HandshakeMsg.postWrite(self, w, trial) |
369 | 391 |
| 392 class CertificateStatus(HandshakeMsg): |
| 393 def __init__(self): |
| 394 self.contentType = ContentType.handshake |
| 395 |
| 396 def create(self, ocsp_response): |
| 397 self.ocsp_response = ocsp_response |
| 398 return self |
| 399 |
| 400 # Defined for the sake of completeness, even though we currently only |
| 401 # support sending the status message (server-side), not requesting |
| 402 # or receiving it (client-side). |
| 403 def parse(self, p): |
| 404 p.startLengthCheck(3) |
| 405 status_type = p.get(1) |
| 406 # Only one type is specified, so hardwire it. |
| 407 if status_type != CertificateStatusType.ocsp: |
| 408 raise SyntaxError() |
| 409 ocsp_response = p.getVarBytes(3) |
| 410 if not ocsp_response: |
| 411 # Can't be empty |
| 412 raise SyntaxError() |
| 413 self.ocsp_response = ocsp_response |
| 414 return self |
| 415 |
| 416 def write(self, trial=False): |
| 417 w = HandshakeMsg.preWrite(self, HandshakeType.certificate_status, |
| 418 trial) |
| 419 w.add(CertificateStatusType.ocsp, 1) |
| 420 w.addVarSeq(stringToBytes(self.ocsp_response), 1, 3) |
| 421 return HandshakeMsg.postWrite(self, w, trial) |
| 422 |
370 class CertificateRequest(HandshakeMsg): | 423 class CertificateRequest(HandshakeMsg): |
371 def __init__(self): | 424 def __init__(self): |
372 self.contentType = ContentType.handshake | 425 self.contentType = ContentType.handshake |
373 #Apple's Secure Transport library rejects empty certificate_types, so | 426 #Apple's Secure Transport library rejects empty certificate_types, so |
374 #default to rsa_sign. | 427 #default to rsa_sign. |
375 self.certificate_types = [ClientCertificateType.rsa_sign] | 428 self.certificate_types = [ClientCertificateType.rsa_sign] |
376 self.certificate_authorities = [] | 429 self.certificate_authorities = [] |
377 | 430 |
378 def create(self, certificate_types, certificate_authorities): | 431 def create(self, certificate_types, certificate_authorities): |
379 self.certificate_types = certificate_types | 432 self.certificate_types = certificate_types |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
621 def create(self, bytes): | 674 def create(self, bytes): |
622 self.bytes = bytes | 675 self.bytes = bytes |
623 return self | 676 return self |
624 | 677 |
625 def parse(self, p): | 678 def parse(self, p): |
626 self.bytes = p.bytes | 679 self.bytes = p.bytes |
627 return self | 680 return self |
628 | 681 |
629 def write(self): | 682 def write(self): |
630 return self.bytes | 683 return self.bytes |
OLD | NEW |