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 | |
136 | 135 |
137 def create(self, version, random, session_id, cipher_suites, | 136 def create(self, version, random, session_id, cipher_suites, |
138 certificate_types=None, srp_username=None): | 137 certificate_types=None, srp_username=None): |
139 self.client_version = version | 138 self.client_version = version |
140 self.random = random | 139 self.random = random |
141 self.session_id = session_id | 140 self.session_id = session_id |
142 self.cipher_suites = cipher_suites | 141 self.cipher_suites = cipher_suites |
143 self.certificate_types = certificate_types | 142 self.certificate_types = certificate_types |
144 self.compression_methods = [0] | 143 self.compression_methods = [0] |
145 self.srp_username = srp_username | 144 self.srp_username = srp_username |
(...skipping 30 matching lines...) Expand all Loading... |
176 if extType == 6: | 175 if extType == 6: |
177 self.srp_username = bytesToString(p.getVarBytes(1)) | 176 self.srp_username = bytesToString(p.getVarBytes(1)) |
178 elif extType == 7: | 177 elif extType == 7: |
179 self.certificate_types = p.getVarList(1, 1) | 178 self.certificate_types = p.getVarList(1, 1) |
180 elif extType == ExtensionType.channel_id: | 179 elif extType == ExtensionType.channel_id: |
181 self.channel_id = True | 180 self.channel_id = True |
182 elif extType == ExtensionType.signed_cert_timestamps: | 181 elif extType == ExtensionType.signed_cert_timestamps: |
183 if extLength: | 182 if extLength: |
184 raise SyntaxError() | 183 raise SyntaxError() |
185 self.support_signed_cert_timestamps = True | 184 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 | |
199 else: | 185 else: |
200 p.getFixBytes(extLength) | 186 p.getFixBytes(extLength) |
201 soFar += 4 + extLength | 187 soFar += 4 + extLength |
202 p.stopLengthCheck() | 188 p.stopLengthCheck() |
203 return self | 189 return self |
204 | 190 |
205 def write(self, trial=False): | 191 def write(self, trial=False): |
206 w = HandshakeMsg.preWrite(self, HandshakeType.client_hello, trial) | 192 w = HandshakeMsg.preWrite(self, HandshakeType.client_hello, trial) |
207 w.add(self.client_version[0], 1) | 193 w.add(self.client_version[0], 1) |
208 w.add(self.client_version[1], 1) | 194 w.add(self.client_version[1], 1) |
(...skipping 28 matching lines...) Expand all Loading... |
237 def __init__(self): | 223 def __init__(self): |
238 self.contentType = ContentType.handshake | 224 self.contentType = ContentType.handshake |
239 self.server_version = (0,0) | 225 self.server_version = (0,0) |
240 self.random = createByteArrayZeros(32) | 226 self.random = createByteArrayZeros(32) |
241 self.session_id = createByteArraySequence([]) | 227 self.session_id = createByteArraySequence([]) |
242 self.cipher_suite = 0 | 228 self.cipher_suite = 0 |
243 self.certificate_type = CertificateType.x509 | 229 self.certificate_type = CertificateType.x509 |
244 self.compression_method = 0 | 230 self.compression_method = 0 |
245 self.channel_id = False | 231 self.channel_id = False |
246 self.signed_cert_timestamps = None | 232 self.signed_cert_timestamps = None |
247 self.status_request = False | |
248 | 233 |
249 def create(self, version, random, session_id, cipher_suite, | 234 def create(self, version, random, session_id, cipher_suite, |
250 certificate_type): | 235 certificate_type): |
251 self.server_version = version | 236 self.server_version = version |
252 self.random = random | 237 self.random = random |
253 self.session_id = session_id | 238 self.session_id = session_id |
254 self.cipher_suite = cipher_suite | 239 self.cipher_suite = cipher_suite |
255 self.certificate_type = certificate_type | 240 self.certificate_type = certificate_type |
256 self.compression_method = 0 | 241 self.compression_method = 0 |
257 return self | 242 return self |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 if self.certificate_type and self.certificate_type != \ | 275 if self.certificate_type and self.certificate_type != \ |
291 CertificateType.x509: | 276 CertificateType.x509: |
292 extLength += 5 | 277 extLength += 5 |
293 | 278 |
294 if self.channel_id: | 279 if self.channel_id: |
295 extLength += 4 | 280 extLength += 4 |
296 | 281 |
297 if self.signed_cert_timestamps: | 282 if self.signed_cert_timestamps: |
298 extLength += 4 + len(self.signed_cert_timestamps) | 283 extLength += 4 + len(self.signed_cert_timestamps) |
299 | 284 |
300 if self.status_request: | |
301 extLength += 4 | |
302 | |
303 if extLength != 0: | 285 if extLength != 0: |
304 w.add(extLength, 2) | 286 w.add(extLength, 2) |
305 | 287 |
306 if self.certificate_type and self.certificate_type != \ | 288 if self.certificate_type and self.certificate_type != \ |
307 CertificateType.x509: | 289 CertificateType.x509: |
308 w.add(7, 2) | 290 w.add(7, 2) |
309 w.add(1, 2) | 291 w.add(1, 2) |
310 w.add(self.certificate_type, 1) | 292 w.add(self.certificate_type, 1) |
311 | 293 |
312 if self.channel_id: | 294 if self.channel_id: |
313 w.add(ExtensionType.channel_id, 2) | 295 w.add(ExtensionType.channel_id, 2) |
314 w.add(0, 2) | 296 w.add(0, 2) |
315 | 297 |
316 if self.signed_cert_timestamps: | 298 if self.signed_cert_timestamps: |
317 w.add(ExtensionType.signed_cert_timestamps, 2) | 299 w.add(ExtensionType.signed_cert_timestamps, 2) |
318 w.addVarSeq(stringToBytes(self.signed_cert_timestamps), 1, 2) | 300 w.addVarSeq(stringToBytes(self.signed_cert_timestamps), 1, 2) |
319 | 301 |
320 if self.status_request: | |
321 w.add(ExtensionType.status_request, 2) | |
322 w.add(0, 2) | |
323 | |
324 return HandshakeMsg.postWrite(self, w, trial) | 302 return HandshakeMsg.postWrite(self, w, trial) |
325 | 303 |
326 class Certificate(HandshakeMsg): | 304 class Certificate(HandshakeMsg): |
327 def __init__(self, certificateType): | 305 def __init__(self, certificateType): |
328 self.certificateType = certificateType | 306 self.certificateType = certificateType |
329 self.contentType = ContentType.handshake | 307 self.contentType = ContentType.handshake |
330 self.certChain = None | 308 self.certChain = None |
331 | 309 |
332 def create(self, certChain): | 310 def create(self, certChain): |
333 self.certChain = certChain | 311 self.certChain = certChain |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 elif self.certificateType == CertificateType.cryptoID: | 360 elif self.certificateType == CertificateType.cryptoID: |
383 if self.certChain: | 361 if self.certChain: |
384 bytes = stringToBytes(self.certChain.write()) | 362 bytes = stringToBytes(self.certChain.write()) |
385 else: | 363 else: |
386 bytes = createByteArraySequence([]) | 364 bytes = createByteArraySequence([]) |
387 w.addVarSeq(bytes, 1, 2) | 365 w.addVarSeq(bytes, 1, 2) |
388 else: | 366 else: |
389 raise AssertionError() | 367 raise AssertionError() |
390 return HandshakeMsg.postWrite(self, w, trial) | 368 return HandshakeMsg.postWrite(self, w, trial) |
391 | 369 |
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 | |
423 class CertificateRequest(HandshakeMsg): | 370 class CertificateRequest(HandshakeMsg): |
424 def __init__(self): | 371 def __init__(self): |
425 self.contentType = ContentType.handshake | 372 self.contentType = ContentType.handshake |
426 #Apple's Secure Transport library rejects empty certificate_types, so | 373 #Apple's Secure Transport library rejects empty certificate_types, so |
427 #default to rsa_sign. | 374 #default to rsa_sign. |
428 self.certificate_types = [ClientCertificateType.rsa_sign] | 375 self.certificate_types = [ClientCertificateType.rsa_sign] |
429 self.certificate_authorities = [] | 376 self.certificate_authorities = [] |
430 | 377 |
431 def create(self, certificate_types, certificate_authorities): | 378 def create(self, certificate_types, certificate_authorities): |
432 self.certificate_types = certificate_types | 379 self.certificate_types = certificate_types |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
674 def create(self, bytes): | 621 def create(self, bytes): |
675 self.bytes = bytes | 622 self.bytes = bytes |
676 return self | 623 return self |
677 | 624 |
678 def parse(self, p): | 625 def parse(self, p): |
679 self.bytes = p.bytes | 626 self.bytes = p.bytes |
680 return self | 627 return self |
681 | 628 |
682 def write(self): | 629 def write(self): |
683 return self.bytes | 630 return self.bytes |
OLD | NEW |