Package tlslite :: Module messages
[hide private]
[frames] | no frames]

Source Code for Module tlslite.messages

  1  # Authors:  
  2  #   Trevor Perrin 
  3  #   Google - handling CertificateRequest.certificate_types 
  4  # 
  5  # See the LICENSE file for legal information regarding use of this file. 
  6   
  7  """Classes representing TLS messages.""" 
  8   
  9  from .utils.compat import * 
 10  from .utils.cryptomath import * 
 11  from .errors import * 
 12  from .utils.codec import * 
 13  from .constants import * 
 14  from .x509 import X509 
 15  from .x509certchain import X509CertChain 
 16  from .utils.tackwrapper import * 
 17   
18 -class RecordHeader3:
19 - def __init__(self):
20 self.type = 0 21 self.version = (0,0) 22 self.length = 0 23 self.ssl2 = False
24
25 - def create(self, version, type, length):
26 self.type = type 27 self.version = version 28 self.length = length 29 return self
30
31 - def write(self):
32 w = Writer() 33 w.add(self.type, 1) 34 w.add(self.version[0], 1) 35 w.add(self.version[1], 1) 36 w.add(self.length, 2) 37 return w.bytes
38
39 - def parse(self, p):
40 self.type = p.get(1) 41 self.version = (p.get(1), p.get(1)) 42 self.length = p.get(2) 43 self.ssl2 = False 44 return self
45
46 -class RecordHeader2:
47 - def __init__(self):
48 self.type = 0 49 self.version = (0,0) 50 self.length = 0 51 self.ssl2 = True
52
53 - def parse(self, p):
54 if p.get(1)!=128: 55 raise SyntaxError() 56 self.type = ContentType.handshake 57 self.version = (2,0) 58 #We don't support 2-byte-length-headers; could be a problem 59 self.length = p.get(1) 60 return self
61 62
63 -class Alert:
64 - def __init__(self):
65 self.contentType = ContentType.alert 66 self.level = 0 67 self.description = 0
68
69 - def create(self, description, level=AlertLevel.fatal):
70 self.level = level 71 self.description = description 72 return self
73
74 - def parse(self, p):
75 p.setLengthCheck(2) 76 self.level = p.get(1) 77 self.description = p.get(1) 78 p.stopLengthCheck() 79 return self
80
81 - def write(self):
82 w = Writer() 83 w.add(self.level, 1) 84 w.add(self.description, 1) 85 return w.bytes
86 87
88 -class HandshakeMsg:
89 - def __init__(self, handshakeType):
90 self.contentType = ContentType.handshake 91 self.handshakeType = handshakeType
92
93 - def postWrite(self, w):
94 headerWriter = Writer() 95 headerWriter.add(self.handshakeType, 1) 96 headerWriter.add(len(w.bytes), 3) 97 return headerWriter.bytes + w.bytes
98
99 -class ClientHello(HandshakeMsg):
100 - def __init__(self, ssl2=False):
101 HandshakeMsg.__init__(self, HandshakeType.client_hello) 102 self.ssl2 = ssl2 103 self.client_version = (0,0) 104 self.random = createByteArrayZeros(32) 105 self.session_id = createByteArraySequence([]) 106 self.cipher_suites = [] # a list of 16-bit values 107 self.certificate_types = [CertificateType.x509] 108 self.compression_methods = [] # a list of 8-bit values 109 self.srp_username = None # a string 110 self.tack = False
111
112 - def create(self, version, random, session_id, cipher_suites, 113 certificate_types=None, srp_username=None, 114 tack=False):
115 self.client_version = version 116 self.random = random 117 self.session_id = session_id 118 self.cipher_suites = cipher_suites 119 self.certificate_types = certificate_types 120 self.compression_methods = [0] 121 self.srp_username = srp_username 122 self.tack = tack 123 return self
124
125 - def parse(self, p):
126 if self.ssl2: 127 self.client_version = (p.get(1), p.get(1)) 128 cipherSpecsLength = p.get(2) 129 sessionIDLength = p.get(2) 130 randomLength = p.get(2) 131 self.cipher_suites = p.getFixList(3, cipherSpecsLength//3) 132 self.session_id = p.getFixBytes(sessionIDLength) 133 self.random = p.getFixBytes(randomLength) 134 if len(self.random) < 32: 135 zeroBytes = 32-len(self.random) 136 self.random = createByteArrayZeros(zeroBytes) + self.random 137 self.compression_methods = [0]#Fake this value 138 139 #We're not doing a stopLengthCheck() for SSLv2, oh well.. 140 else: 141 p.startLengthCheck(3) 142 self.client_version = (p.get(1), p.get(1)) 143 self.random = p.getFixBytes(32) 144 self.session_id = p.getVarBytes(1) 145 self.cipher_suites = p.getVarList(2, 2) 146 self.compression_methods = p.getVarList(1, 1) 147 if not p.atLengthCheck(): 148 totalExtLength = p.get(2) 149 soFar = 0 150 while soFar != totalExtLength: 151 extType = p.get(2) 152 extLength = p.get(2) 153 index1 = p.index 154 if extType == ExtensionType.srp: 155 self.srp_username = bytesToString(p.getVarBytes(1)) 156 elif extType == ExtensionType.cert_type: 157 self.certificate_types = p.getVarList(1, 1) 158 elif extType == ExtensionType.tack: 159 self.tack = True 160 else: 161 p.getFixBytes(extLength) 162 index2 = p.index 163 if index2 - index1 != extLength: 164 raise SyntaxError("Bad length for extension_data") 165 soFar += 4 + extLength 166 p.stopLengthCheck() 167 return self
168
169 - def write(self):
170 w = Writer() 171 w.add(self.client_version[0], 1) 172 w.add(self.client_version[1], 1) 173 w.addFixSeq(self.random, 1) 174 w.addVarSeq(self.session_id, 1, 1) 175 w.addVarSeq(self.cipher_suites, 2, 2) 176 w.addVarSeq(self.compression_methods, 1, 1) 177 178 w2 = Writer() # For Extensions 179 if self.certificate_types and self.certificate_types != \ 180 [CertificateType.x509]: 181 w2.add(ExtensionType.cert_type, 2) 182 w2.add(len(self.certificate_types)+1, 2) 183 w2.addVarSeq(self.certificate_types, 1, 1) 184 if self.srp_username: 185 w2.add(ExtensionType.srp, 2) 186 w2.add(len(self.srp_username)+1, 2) 187 w2.addVarSeq(stringToBytes(self.srp_username), 1, 1) 188 if self.tack: 189 w2.add(ExtensionType.tack, 2) 190 w2.add(0, 2) 191 if len(w2.bytes): 192 w.add(len(w2.bytes), 2) 193 w.bytes += w2.bytes 194 return self.postWrite(w)
195
196 -class ServerHello(HandshakeMsg):
197 - def __init__(self):
198 HandshakeMsg.__init__(self, HandshakeType.server_hello) 199 self.server_version = (0,0) 200 self.random = createByteArrayZeros(32) 201 self.session_id = createByteArraySequence([]) 202 self.cipher_suite = 0 203 self.certificate_type = CertificateType.x509 204 self.compression_method = 0 205 self.tackExt = None
206
207 - def create(self, version, random, session_id, cipher_suite, 208 certificate_type, tackExt):
209 self.server_version = version 210 self.random = random 211 self.session_id = session_id 212 self.cipher_suite = cipher_suite 213 self.certificate_type = certificate_type 214 self.compression_method = 0 215 self.tackExt = tackExt 216 return self
217
218 - def parse(self, p):
219 p.startLengthCheck(3) 220 self.server_version = (p.get(1), p.get(1)) 221 self.random = p.getFixBytes(32) 222 self.session_id = p.getVarBytes(1) 223 self.cipher_suite = p.get(2) 224 self.compression_method = p.get(1) 225 if not p.atLengthCheck(): 226 totalExtLength = p.get(2) 227 soFar = 0 228 while soFar != totalExtLength: 229 extType = p.get(2) 230 extLength = p.get(2) 231 if extType == ExtensionType.cert_type: 232 if extLength != 1: 233 raise SyntaxError() 234 self.certificate_type = p.get(1) 235 elif extType == ExtensionType.tack and tackpyLoaded: 236 self.tackExt = TACK_Extension() 237 self.tackExt.parse(p.getFixBytes(extLength)) 238 else: 239 p.getFixBytes(extLength) 240 soFar += 4 + extLength 241 p.stopLengthCheck() 242 return self
243
244 - def write(self):
245 w = Writer() 246 w.add(self.server_version[0], 1) 247 w.add(self.server_version[1], 1) 248 w.addFixSeq(self.random, 1) 249 w.addVarSeq(self.session_id, 1, 1) 250 w.add(self.cipher_suite, 2) 251 w.add(self.compression_method, 1) 252 253 w2 = Writer() # For Extensions 254 if self.certificate_type and self.certificate_type != \ 255 CertificateType.x509: 256 w2.add(ExtensionType.cert_type, 2) 257 w2.add(1, 2) 258 w2.add(self.certificate_type, 1) 259 if self.tackExt: 260 b = self.tackExt.write() 261 w2.add(ExtensionType.tack, 2) 262 w2.add(len(b), 2) 263 w2.bytes += b 264 if len(w2.bytes): 265 w.add(len(w2.bytes), 2) 266 w.bytes += w2.bytes 267 return self.postWrite(w)
268 269
270 -class Certificate(HandshakeMsg):
271 - def __init__(self, certificateType):
272 HandshakeMsg.__init__(self, HandshakeType.certificate) 273 self.certificateType = certificateType 274 self.certChain = None
275
276 - def create(self, certChain):
277 self.certChain = certChain 278 return self
279
280 - def parse(self, p):
281 p.startLengthCheck(3) 282 if self.certificateType == CertificateType.x509: 283 chainLength = p.get(3) 284 index = 0 285 certificate_list = [] 286 while index != chainLength: 287 certBytes = p.getVarBytes(3) 288 x509 = X509() 289 x509.parseBinary(certBytes) 290 certificate_list.append(x509) 291 index += len(certBytes)+3 292 if certificate_list: 293 self.certChain = X509CertChain(certificate_list) 294 else: 295 raise AssertionError() 296 297 p.stopLengthCheck() 298 return self
299
300 - def write(self):
301 w = Writer() 302 if self.certificateType == CertificateType.x509: 303 chainLength = 0 304 if self.certChain: 305 certificate_list = self.certChain.x509List 306 else: 307 certificate_list = [] 308 #determine length 309 for cert in certificate_list: 310 bytes = cert.writeBytes() 311 chainLength += len(bytes)+3 312 #add bytes 313 w.add(chainLength, 3) 314 for cert in certificate_list: 315 bytes = cert.writeBytes() 316 w.addVarSeq(bytes, 1, 3) 317 else: 318 raise AssertionError() 319 return self.postWrite(w)
320
321 -class CertificateRequest(HandshakeMsg):
322 - def __init__(self):
323 HandshakeMsg.__init__(self, HandshakeType.certificate_request) 324 #Apple's Secure Transport library rejects empty certificate_types, so 325 #default to rsa_sign. 326 self.certificate_types = [ClientCertificateType.rsa_sign] 327 self.certificate_authorities = []
328
329 - def create(self, certificate_types, certificate_authorities):
330 self.certificate_types = certificate_types 331 self.certificate_authorities = certificate_authorities 332 return self
333
334 - def parse(self, p):
335 p.startLengthCheck(3) 336 self.certificate_types = p.getVarList(1, 1) 337 ca_list_length = p.get(2) 338 index = 0 339 self.certificate_authorities = [] 340 while index != ca_list_length: 341 ca_bytes = p.getVarBytes(2) 342 self.certificate_authorities.append(ca_bytes) 343 index += len(ca_bytes)+2 344 p.stopLengthCheck() 345 return self
346
347 - def write(self):
348 w = Writer() 349 w.addVarSeq(self.certificate_types, 1, 1) 350 caLength = 0 351 #determine length 352 for ca_dn in self.certificate_authorities: 353 caLength += len(ca_dn)+2 354 w.add(caLength, 2) 355 #add bytes 356 for ca_dn in self.certificate_authorities: 357 w.addVarSeq(ca_dn, 1, 2) 358 return self.postWrite(w)
359
360 -class ServerKeyExchange(HandshakeMsg):
361 - def __init__(self, cipherSuite):
362 HandshakeMsg.__init__(self, HandshakeType.server_key_exchange) 363 self.cipherSuite = cipherSuite 364 self.srp_N = 0L 365 self.srp_g = 0L 366 self.srp_s = createByteArraySequence([]) 367 self.srp_B = 0L 368 self.signature = createByteArraySequence([])
369
370 - def createSRP(self, srp_N, srp_g, srp_s, srp_B):
371 self.srp_N = srp_N 372 self.srp_g = srp_g 373 self.srp_s = srp_s 374 self.srp_B = srp_B 375 return self
376
377 - def parse(self, p):
378 p.startLengthCheck(3) 379 self.srp_N = bytesToNumber(p.getVarBytes(2)) 380 self.srp_g = bytesToNumber(p.getVarBytes(2)) 381 self.srp_s = p.getVarBytes(1) 382 self.srp_B = bytesToNumber(p.getVarBytes(2)) 383 if self.cipherSuite in CipherSuite.srpCertSuites: 384 self.signature = p.getVarBytes(2) 385 p.stopLengthCheck() 386 return self
387
388 - def write(self):
389 w = Writer() 390 w.addVarSeq(numberToBytes(self.srp_N), 1, 2) 391 w.addVarSeq(numberToBytes(self.srp_g), 1, 2) 392 w.addVarSeq(self.srp_s, 1, 1) 393 w.addVarSeq(numberToBytes(self.srp_B), 1, 2) 394 if self.cipherSuite in CipherSuite.srpCertSuites: 395 w.addVarSeq(self.signature, 1, 2) 396 return self.postWrite(w)
397
398 - def hash(self, clientRandom, serverRandom):
399 oldCipherSuite = self.cipherSuite 400 self.cipherSuite = None 401 try: 402 bytes = clientRandom + serverRandom + self.write()[4:] 403 s = bytesToString(bytes) 404 return stringToBytes(md5(s).digest() + sha1(s).digest()) 405 finally: 406 self.cipherSuite = oldCipherSuite
407
408 -class ServerHelloDone(HandshakeMsg):
409 - def __init__(self):
411
412 - def create(self):
413 return self
414
415 - def parse(self, p):
416 p.startLengthCheck(3) 417 p.stopLengthCheck() 418 return self
419
420 - def write(self):
421 w = Writer() 422 return self.postWrite(w)
423
424 -class ClientKeyExchange(HandshakeMsg):
425 - def __init__(self, cipherSuite, version=None):
426 HandshakeMsg.__init__(self, HandshakeType.client_key_exchange) 427 self.cipherSuite = cipherSuite 428 self.version = version 429 self.srp_A = 0 430 self.encryptedPreMasterSecret = createByteArraySequence([])
431
432 - def createSRP(self, srp_A):
433 self.srp_A = srp_A 434 return self
435
436 - def createRSA(self, encryptedPreMasterSecret):
437 self.encryptedPreMasterSecret = encryptedPreMasterSecret 438 return self
439
440 - def parse(self, p):
441 p.startLengthCheck(3) 442 if self.cipherSuite in CipherSuite.srpAllSuites: 443 self.srp_A = bytesToNumber(p.getVarBytes(2)) 444 elif self.cipherSuite in CipherSuite.certSuites: 445 if self.version in ((3,1), (3,2)): 446 self.encryptedPreMasterSecret = p.getVarBytes(2) 447 elif self.version == (3,0): 448 self.encryptedPreMasterSecret = \ 449 p.getFixBytes(len(p.bytes)-p.index) 450 else: 451 raise AssertionError() 452 else: 453 raise AssertionError() 454 p.stopLengthCheck() 455 return self
456
457 - def write(self):
458 w = Writer() 459 if self.cipherSuite in CipherSuite.srpAllSuites: 460 w.addVarSeq(numberToBytes(self.srp_A), 1, 2) 461 elif self.cipherSuite in CipherSuite.certSuites: 462 if self.version in ((3,1), (3,2)): 463 w.addVarSeq(self.encryptedPreMasterSecret, 1, 2) 464 elif self.version == (3,0): 465 w.addFixSeq(self.encryptedPreMasterSecret, 1) 466 else: 467 raise AssertionError() 468 else: 469 raise AssertionError() 470 return self.postWrite(w)
471
472 -class CertificateVerify(HandshakeMsg):
473 - def __init__(self):
476
477 - def create(self, signature):
478 self.signature = signature 479 return self
480
481 - def parse(self, p):
482 p.startLengthCheck(3) 483 self.signature = p.getVarBytes(2) 484 p.stopLengthCheck() 485 return self
486
487 - def write(self):
488 w = Writer() 489 w.addVarSeq(self.signature, 1, 2) 490 return self.postWrite(w)
491
492 -class ChangeCipherSpec:
493 - def __init__(self):
494 self.contentType = ContentType.change_cipher_spec 495 self.type = 1
496
497 - def create(self):
498 self.type = 1 499 return self
500
501 - def parse(self, p):
502 p.setLengthCheck(1) 503 self.type = p.get(1) 504 p.stopLengthCheck() 505 return self
506
507 - def write(self):
508 w = Writer() 509 w.add(self.type,1) 510 return w.bytes
511 512
513 -class Finished(HandshakeMsg):
514 - def __init__(self, version):
515 HandshakeMsg.__init__(self, HandshakeType.finished) 516 self.version = version 517 self.verify_data = createByteArraySequence([])
518
519 - def create(self, verify_data):
520 self.verify_data = verify_data 521 return self
522
523 - def parse(self, p):
524 p.startLengthCheck(3) 525 if self.version == (3,0): 526 self.verify_data = p.getFixBytes(36) 527 elif self.version in ((3,1), (3,2)): 528 self.verify_data = p.getFixBytes(12) 529 else: 530 raise AssertionError() 531 p.stopLengthCheck() 532 return self
533
534 - def write(self):
535 w = Writer() 536 w.addFixSeq(self.verify_data, 1) 537 return self.postWrite(w)
538
539 -class ApplicationData:
540 - def __init__(self):
541 self.contentType = ContentType.application_data 542 self.bytes = createByteArraySequence([])
543
544 - def create(self, bytes):
545 self.bytes = bytes 546 return self
547
548 - def splitFirstByte(self):
549 newMsg = ApplicationData().create(self.bytes[:1]) 550 self.bytes = self.bytes[1:] 551 return newMsg
552
553 - def parse(self, p):
554 self.bytes = p.bytes 555 return self
556
557 - def write(self):
558 return self.bytes
559