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  #   Google (adapted by Sam Rushing and Marcelo Fernandez) - NPN support 
   5  #   Dimitris Moraitis - Anon ciphersuites 
   6  #   Yngve Pettersen (ported by Paul Sokolovsky) - TLS 1.2 
   7  #   Hubert Kario - 'extensions' cleanup 
   8  # 
   9  # See the LICENSE file for legal information regarding use of this file. 
  10   
  11  """Classes representing TLS messages.""" 
  12   
  13  from .utils.compat import * 
  14  from .utils.cryptomath import * 
  15  from .errors import * 
  16  from .utils.codec import * 
  17  from .constants import * 
  18  from .x509 import X509 
  19  from .x509certchain import X509CertChain 
  20  from .utils.tackwrapper import * 
  21  from .extensions import * 
22 23 24 -class RecordHeader(object):
25 """Generic interface to SSLv2 and SSLv3 (and later) record headers.""" 26
27 - def __init__(self, ssl2):
28 """Define instance variables.""" 29 self.type = 0 30 self.version = (0, 0) 31 self.length = 0 32 self.ssl2 = ssl2
33
34 35 -class RecordHeader3(RecordHeader):
36 """SSLv3 (and later) TLS record header.""" 37
38 - def __init__(self):
39 """Define a SSLv3 style class.""" 40 super(RecordHeader3, self).__init__(ssl2=False)
41
42 - def create(self, version, type, length):
43 """Set object values for writing (serialisation).""" 44 self.type = type 45 self.version = version 46 self.length = length 47 return self
48
49 - def write(self):
50 """Serialise object to bytearray.""" 51 writer = Writer() 52 writer.add(self.type, 1) 53 writer.add(self.version[0], 1) 54 writer.add(self.version[1], 1) 55 writer.add(self.length, 2) 56 return writer.bytes
57
58 - def parse(self, parser):
59 """Deserialise object from Parser.""" 60 self.type = parser.get(1) 61 self.version = (parser.get(1), parser.get(1)) 62 self.length = parser.get(2) 63 self.ssl2 = False 64 return self
65 66 @property
67 - def typeName(self):
68 matching = [x[0] for x in ContentType.__dict__.items() 69 if x[1] == self.type] 70 if len(matching) == 0: 71 return "unknown(" + str(self.type) + ")" 72 else: 73 return str(matching[0])
74
75 - def __str__(self):
76 return "SSLv3 record,version({0[0]}.{0[1]}),"\ 77 "content type({1}),length({2})".format(self.version, 78 self.typeName, 79 self.length)
80
81 - def __repr__(self):
82 return "RecordHeader3(type={0}, version=({1[0]}.{1[1]}), length={2})".\ 83 format(self.type, self.version, self.length)
84
85 86 -class RecordHeader2(RecordHeader):
87 """ 88 SSLv2 record header. 89 90 @type padding: int 91 @ivar padding: number of bytes added at end of message to make it multiple 92 of block cipher size 93 @type securityEscape: boolean 94 @ivar securityEscape: whether the record contains a security escape message 95 """ 96
97 - def __init__(self):
98 """Define a SSLv2 style class.""" 99 super(RecordHeader2, self).__init__(ssl2=True) 100 self.padding = 0 101 self.securityEscape = False
102
103 - def parse(self, parser):
104 """Deserialise object from Parser.""" 105 firstByte = parser.get(1) 106 secondByte = parser.get(1) 107 if firstByte & 0x80: 108 self.length = ((firstByte & 0x7f) << 8) | secondByte 109 else: 110 self.length = ((firstByte & 0x3f) << 8) | secondByte 111 self.securityEscape = firstByte & 0x40 != 0 112 self.padding = parser.get(1) 113 114 self.type = ContentType.handshake 115 self.version = (2, 0) 116 return self
117
118 - def create(self, length, padding=0, securityEscape=False):
119 """Set object's values.""" 120 self.length = length 121 self.padding = padding 122 self.securityEscape = securityEscape 123 return self
124
125 - def write(self):
126 """Serialise object to bytearray.""" 127 writer = Writer() 128 129 shortHeader = not (self.padding or self.securityEscape) 130 131 if ((shortHeader and self.length >= 0x8000) or 132 (not shortHeader and self.length >= 0x4000)): 133 raise ValueError("length too large") 134 135 firstByte = 0 136 if shortHeader: 137 firstByte |= 0x80 138 if self.securityEscape: 139 firstByte |= 0x40 140 firstByte |= self.length >> 8 141 secondByte = self.length & 0xff 142 143 writer.add(firstByte, 1) 144 writer.add(secondByte, 1) 145 if not shortHeader: 146 writer.add(self.padding, 1) 147 148 return writer.bytes
149
150 151 -class Message(object):
152 """Generic TLS message.""" 153
154 - def __init__(self, contentType, data):
155 """ 156 Initialize object with specified contentType and data. 157 158 @type contentType: int 159 @param contentType: TLS record layer content type of associated data 160 @type data: bytearray 161 @param data: data 162 """ 163 self.contentType = contentType 164 self.data = data
165
166 - def write(self):
167 """Return serialised object data.""" 168 return self.data
169
170 171 -class Alert(object):
172 - def __init__(self):
173 self.contentType = ContentType.alert 174 self.level = 0 175 self.description = 0
176
177 - def create(self, description, level=AlertLevel.fatal):
178 self.level = level 179 self.description = description 180 return self
181
182 - def parse(self, p):
183 p.setLengthCheck(2) 184 self.level = p.get(1) 185 self.description = p.get(1) 186 p.stopLengthCheck() 187 return self
188
189 - def write(self):
190 w = Writer() 191 w.add(self.level, 1) 192 w.add(self.description, 1) 193 return w.bytes
194 195 @staticmethod
196 - def _noneAsUnknown(text, number):
197 """if text is None or empty, format number as 'unknown(number)'""" 198 if not text: 199 text = "unknown({0})".format(number) 200 return text
201 202 @property
203 - def levelName(self):
204 return self._noneAsUnknown(AlertLevel.toRepr(self.level), 205 self.level)
206 207 @property
208 - def descriptionName(self):
209 return self._noneAsUnknown(AlertDescription.toRepr(self.description), 210 self.description)
211
212 - def __str__(self):
213 return "Alert, level:{0}, description:{1}".format(self.levelName, 214 self.descriptionName)
215
216 - def __repr__(self):
217 return "Alert(level={0}, description={1})".format(self.level, 218 self.description)
219
220 221 -class HandshakeMsg(object):
222 - def __init__(self, handshakeType):
223 self.contentType = ContentType.handshake 224 self.handshakeType = handshakeType
225
226 - def postWrite(self, w):
227 headerWriter = Writer() 228 headerWriter.add(self.handshakeType, 1) 229 headerWriter.add(len(w.bytes), 3) 230 return headerWriter.bytes + w.bytes
231
232 233 -class HelloMessage(HandshakeMsg):
234 """Class for sharing code between L{ClientHello} and L{ServerHello}""" 235
236 - def __init__(self, *args, **kwargs):
237 """Initialize object.""" 238 super(HelloMessage, self).__init__(*args, **kwargs) 239 self.extensions = None
240
241 - def getExtension(self, extType):
242 """ 243 Return extension of given type if present, None otherwise. 244 245 @rtype: L{tlslite.extensions.TLSExtension} 246 @raise TLSInternalError: when there are multiple extensions of the 247 same type 248 """ 249 if self.extensions is None: 250 return None 251 252 exts = [ext for ext in self.extensions if ext.extType == extType] 253 if len(exts) > 1: 254 raise TLSInternalError( 255 "Multiple extensions of the same type present") 256 elif len(exts) == 1: 257 return exts[0] 258 else: 259 return None
260
261 - def addExtension(self, ext):
262 """ 263 Add extension to internal list of extensions. 264 265 @type ext: TLSExtension 266 @param ext: extension object to add to list 267 """ 268 if self.extensions is None: 269 self.extensions = [] 270 271 self.extensions.append(ext)
272
273 - def _addExt(self, extType):
274 """Add en empty extension of given type, if not already present""" 275 ext = self.getExtension(extType) 276 if ext is None: 277 ext = TLSExtension(extType=extType).create(bytearray(0)) 278 self.addExtension(ext)
279
280 - def _removeExt(self, extType):
281 """Remove extension of given type""" 282 if self.extensions is not None: 283 self.extensions[:] = (i for i in self.extensions 284 if i.extType != extType)
285 286
287 - def _addOrRemoveExt(self, extType, add):
288 """ 289 Remove or add an empty extension of given type. 290 291 @type extType: int 292 @param extType: numeric id of extension to add or remove 293 @type add: boolean 294 @param add: whether to add (True) or remove (False) the extension 295 """ 296 if add: 297 self._addExt(extType) 298 else: 299 self._removeExt(extType)
300
301 302 -class ClientHello(HelloMessage):
303 """ 304 Class for handling the ClientHello SSLv2/SSLv3/TLS message. 305 306 @type certificate_types: list 307 @ivar certificate_types: list of supported certificate types (deprecated) 308 309 @type srp_username: bytearray 310 @ivar srp_username: name of the user in SRP extension (deprecated) 311 312 @type supports_npn: boolean 313 @ivar supports_npn: NPN extension presence (deprecated) 314 315 @type tack: boolean 316 @ivar tack: TACK extension presence (deprecated) 317 318 @type server_name: bytearray 319 @ivar server_name: first host_name (type 0) present in SNI extension 320 (deprecated) 321 322 @type extensions: list of L{TLSExtension} 323 @ivar extensions: list of TLS extensions parsed from wire or to send, see 324 L{TLSExtension} and child classes for exact examples 325 """ 326
327 - def __init__(self, ssl2=False):
328 super(ClientHello, self).__init__(HandshakeType.client_hello) 329 self.ssl2 = ssl2 330 self.client_version = (0, 0) 331 self.random = bytearray(32) 332 self.session_id = bytearray(0) 333 self.cipher_suites = [] # a list of 16-bit values 334 self.compression_methods = [] # a list of 8-bit values
335
336 - def __str__(self):
337 """ 338 Return human readable representation of Client Hello. 339 340 @rtype: str 341 """ 342 if self.session_id.count(bytearray(b'\x00')) == len(self.session_id)\ 343 and len(self.session_id) != 0: 344 session = "bytearray(b'\\x00'*{0})".format(len(self.session_id)) 345 else: 346 session = repr(self.session_id) 347 ret = "client_hello,version({0[0]}.{0[1]}),random(...),"\ 348 "session ID({1!s}),cipher suites({2!r}),"\ 349 "compression methods({3!r})".format( 350 self.client_version, session, 351 self.cipher_suites, self.compression_methods) 352 353 if self.extensions is not None: 354 ret += ",extensions({0!r})".format(self.extensions) 355 356 return ret
357
358 - def __repr__(self):
359 """ 360 Return machine readable representation of Client Hello. 361 362 @rtype: str 363 """ 364 return "ClientHello(ssl2={0}, client_version=({1[0]}.{1[1]}), "\ 365 "random={2!r}, session_id={3!r}, cipher_suites={4!r}, "\ 366 "compression_methods={5}, extensions={6})".format( 367 self.ssl2, self.client_version, self.random, 368 self.session_id, self.cipher_suites, 369 self.compression_methods, self.extensions)
370 371 @property
372 - def certificate_types(self):
373 """ 374 Return the list of certificate types supported. 375 376 @deprecated: use extensions field to get the extension for inspection 377 """ 378 cert_type = self.getExtension(ExtensionType.cert_type) 379 if cert_type is None: 380 # XXX backwards compatibility: TLSConnection 381 # depends on a default value of this property 382 return [CertificateType.x509] 383 else: 384 return cert_type.certTypes
385 386 @certificate_types.setter
387 - def certificate_types(self, val):
388 """ 389 Set list of supported certificate types. 390 391 Sets the list of supported types to list given in L{val} if the 392 cert_type extension is present. Creates the extension and places it 393 last in the list otherwise. 394 395 @type val: list 396 @param val: list of supported certificate types by client encoded as 397 single byte integers 398 """ 399 cert_type = self.getExtension(ExtensionType.cert_type) 400 401 if cert_type is None: 402 ext = ClientCertTypeExtension().create(val) 403 self.addExtension(ext) 404 else: 405 cert_type.certTypes = val
406 407 @property
408 - def srp_username(self):
409 """ 410 Return username for the SRP. 411 412 @deprecated: use extensions field to get the extension for inspection 413 """ 414 srp_ext = self.getExtension(ExtensionType.srp) 415 416 if srp_ext is None: 417 return None 418 else: 419 return srp_ext.identity
420 421 @srp_username.setter
422 - def srp_username(self, name):
423 """ 424 Set the username for SRP. 425 426 @type name: bytearray 427 @param name: UTF-8 encoded username 428 """ 429 srp_ext = self.getExtension(ExtensionType.srp) 430 431 if srp_ext is None: 432 ext = SRPExtension().create(name) 433 self.addExtension(ext) 434 else: 435 srp_ext.identity = name
436 437 @property
438 - def tack(self):
439 """ 440 Return whether the client supports TACK. 441 442 @rtype: boolean 443 @deprecated: use extensions field to get the extension for inspection 444 """ 445 return self.getExtension(ExtensionType.tack) is not None
446 447 @tack.setter
448 - def tack(self, present):
449 """ 450 Create or delete the TACK extension. 451 452 @type present: boolean 453 @param present: True will create extension while False will remove 454 extension from client hello 455 """ 456 self._addOrRemoveExt(ExtensionType.tack, present)
457 458 @property
459 - def supports_npn(self):
460 """ 461 Return whether client supports NPN extension. 462 463 @rtype: boolean 464 @deprecated: use extensions field to get the extension for inspection 465 """ 466 return self.getExtension(ExtensionType.supports_npn) is not None
467 468 @supports_npn.setter
469 - def supports_npn(self, present):
470 """ 471 Create or delete the NPN extension. 472 473 @type present: boolean 474 @param present: selects whatever to create or remove the extension 475 from list of supported ones 476 """ 477 self._addOrRemoveExt(ExtensionType.supports_npn, present)
478 479 @property
480 - def server_name(self):
481 """ 482 Return first host_name present in SNI extension. 483 484 @rtype: bytearray 485 @deprecated: use extensions field to get the extension for inspection 486 """ 487 sni_ext = self.getExtension(ExtensionType.server_name) 488 if sni_ext is None: 489 return bytearray(0) 490 else: 491 if len(sni_ext.hostNames) > 0: 492 return sni_ext.hostNames[0] 493 else: 494 return bytearray(0)
495 496 @server_name.setter
497 - def server_name(self, hostname):
498 """ 499 Set the first host_name present in SNI extension. 500 501 @type hostname: bytearray 502 @param hostname: name of the host_name to set 503 """ 504 sni_ext = self.getExtension(ExtensionType.server_name) 505 if sni_ext is None: 506 sni_ext = SNIExtension().create(hostname) 507 self.addExtension(sni_ext) 508 else: 509 names = list(sni_ext.hostNames) 510 names[0] = hostname 511 sni_ext.hostNames = names
512
513 - def create(self, version, random, session_id, cipher_suites, 514 certificate_types=None, srpUsername=None, 515 tack=False, supports_npn=None, serverName=None, 516 extensions=None):
517 """ 518 Create a ClientHello message for sending. 519 520 @type version: tuple 521 @param version: the highest supported TLS version encoded as two int 522 tuple 523 524 @type random: bytearray 525 @param random: client provided random value, in old versions of TLS 526 (before 1.2) the first 32 bits should include system time, also 527 used as the "challenge" field in SSLv2 528 529 @type session_id: bytearray 530 @param session_id: ID of session, set when doing session resumption 531 532 @type cipher_suites: list 533 @param cipher_suites: list of ciphersuites advertised as supported 534 535 @type certificate_types: list 536 @param certificate_types: list of supported certificate types, uses 537 TLS extension for signalling, as such requires TLS1.0 to work 538 539 @type srpUsername: bytearray 540 @param srpUsername: utf-8 encoded username for SRP, TLS extension 541 542 @type tack: boolean 543 @param tack: whatever to advertise support for TACK, TLS extension 544 545 @type supports_npn: boolean 546 @param supports_npn: whatever to advertise support for NPN, TLS 547 extension 548 549 @type serverName: bytearray 550 @param serverName: the hostname to request in server name indication 551 extension, TLS extension. Note that SNI allows to set multiple 552 hostnames and values that are not hostnames, use L{SNIExtension} 553 together with L{extensions} to use it. 554 555 @type extensions: list of L{TLSExtension} 556 @param extensions: list of extensions to advertise 557 """ 558 self.client_version = version 559 self.random = random 560 self.session_id = session_id 561 self.cipher_suites = cipher_suites 562 self.compression_methods = [0] 563 if extensions is not None: 564 self.extensions = extensions 565 if certificate_types is not None: 566 self.certificate_types = certificate_types 567 if srpUsername is not None: 568 if not isinstance(srpUsername, bytearray): 569 raise TypeError("srpUsername must be a bytearray object") 570 self.srp_username = srpUsername 571 self.tack = tack 572 if supports_npn is not None: 573 self.supports_npn = supports_npn 574 if serverName is not None: 575 self.server_name = bytearray(serverName, "utf-8") 576 return self
577
578 - def parse(self, p):
579 """Deserialise object from on the wire data.""" 580 if self.ssl2: 581 self.client_version = (p.get(1), p.get(1)) 582 cipherSpecsLength = p.get(2) 583 sessionIDLength = p.get(2) 584 randomLength = p.get(2) 585 p.setLengthCheck(cipherSpecsLength + 586 sessionIDLength + 587 randomLength) 588 self.cipher_suites = p.getFixList(3, cipherSpecsLength//3) 589 self.session_id = p.getFixBytes(sessionIDLength) 590 self.random = p.getFixBytes(randomLength) 591 if len(self.random) < 32: 592 zeroBytes = 32-len(self.random) 593 self.random = bytearray(zeroBytes) + self.random 594 self.compression_methods = [0] # Fake this value 595 p.stopLengthCheck() 596 else: 597 p.startLengthCheck(3) 598 self.client_version = (p.get(1), p.get(1)) 599 self.random = p.getFixBytes(32) 600 self.session_id = p.getVarBytes(1) 601 self.cipher_suites = p.getVarList(2, 2) 602 self.compression_methods = p.getVarList(1, 1) 603 if not p.atLengthCheck(): 604 self.extensions = [] 605 totalExtLength = p.get(2) 606 p2 = Parser(p.getFixBytes(totalExtLength)) 607 while p2.getRemainingLength() > 0: 608 ext = TLSExtension().parse(p2) 609 self.extensions += [ext] 610 p.stopLengthCheck() 611 return self
612
613 - def _writeSSL2(self):
614 """Serialise SSLv2 object to on the wire data.""" 615 writer = Writer() 616 writer.add(self.handshakeType, 1) 617 writer.add(self.client_version[0], 1) 618 writer.add(self.client_version[1], 1) 619 620 ciphersWriter = Writer() 621 ciphersWriter.addFixSeq(self.cipher_suites, 3) 622 623 writer.add(len(ciphersWriter.bytes), 2) 624 writer.add(len(self.session_id), 2) 625 writer.add(len(self.random), 2) 626 627 writer.bytes += ciphersWriter.bytes 628 writer.bytes += self.session_id 629 writer.bytes += self.random 630 631 # postWrite() is necessary only for SSLv3/TLS 632 return writer.bytes
633
634 - def _write(self):
635 """Serialise SSLv3 or TLS object to on the wire data.""" 636 w = Writer() 637 w.add(self.client_version[0], 1) 638 w.add(self.client_version[1], 1) 639 w.addFixSeq(self.random, 1) 640 w.addVarSeq(self.session_id, 1, 1) 641 w.addVarSeq(self.cipher_suites, 2, 2) 642 w.addVarSeq(self.compression_methods, 1, 1) 643 644 if self.extensions is not None: 645 w2 = Writer() 646 for ext in self.extensions: 647 w2.bytes += ext.write() 648 649 w.add(len(w2.bytes), 2) 650 w.bytes += w2.bytes 651 return self.postWrite(w)
652
653 - def write(self):
654 """Serialise object to on the wire data.""" 655 if self.ssl2: 656 return self._writeSSL2() 657 else: 658 return self._write()
659
660 661 -class ServerHello(HelloMessage):
662 """ 663 Handling of Server Hello messages. 664 665 @type server_version: tuple 666 @ivar server_version: protocol version encoded as two int tuple 667 668 @type random: bytearray 669 @ivar random: server random value 670 671 @type session_id: bytearray 672 @ivar session_id: session identifier for resumption 673 674 @type cipher_suite: int 675 @ivar cipher_suite: server selected cipher_suite 676 677 @type compression_method: int 678 @ivar compression_method: server selected compression method 679 680 @type next_protos: list of bytearray 681 @ivar next_protos: list of advertised protocols in NPN extension 682 683 @type next_protos_advertised: list of bytearray 684 @ivar next_protos_advertised: list of protocols advertised in NPN extension 685 686 @type certificate_type: int 687 @ivar certificate_type: certificate type selected by server 688 689 @type extensions: list 690 @ivar extensions: list of TLS extensions present in server_hello message, 691 see L{TLSExtension} and child classes for exact examples 692 """ 693
694 - def __init__(self):
695 """Initialise ServerHello object.""" 696 super(ServerHello, self).__init__(HandshakeType.server_hello) 697 self.server_version = (0, 0) 698 self.random = bytearray(32) 699 self.session_id = bytearray(0) 700 self.cipher_suite = 0 701 self.compression_method = 0 702 self._tack_ext = None
703
704 - def __str__(self):
705 base = "server_hello,length({0}),version({1[0]}.{1[1]}),random(...),"\ 706 "session ID({2!r}),cipher({3:#x}),compression method({4})"\ 707 .format(len(self.write())-4, self.server_version, 708 self.session_id, self.cipher_suite, 709 self.compression_method) 710 711 if self.extensions is None: 712 return base 713 714 ret = ",extensions[" 715 ret += ",".join(repr(x) for x in self.extensions) 716 ret += "]" 717 return base + ret
718
719 - def __repr__(self):
720 return "ServerHello(server_version=({0[0]}, {0[1]}), random={1!r}, "\ 721 "session_id={2!r}, cipher_suite={3}, compression_method={4}, "\ 722 "_tack_ext={5}, extensions={6!r})".format( 723 self.server_version, self.random, self.session_id, 724 self.cipher_suite, self.compression_method, self._tack_ext, 725 self.extensions)
726 727 @property
728 - def tackExt(self):
729 """Return the TACK extension.""" 730 if self._tack_ext is None: 731 ext = self.getExtension(ExtensionType.tack) 732 if ext is None or not tackpyLoaded: 733 return None 734 else: 735 self._tack_ext = TackExtension(ext.extData) 736 return self._tack_ext
737 738 @tackExt.setter
739 - def tackExt(self, val):
740 """Set the TACK extension.""" 741 self._tack_ext = val 742 # makes sure that extensions are included in the on the wire encoding 743 if val is not None: 744 if self.extensions is None: 745 self.extensions = []
746 747 @property
748 - def certificate_type(self):
749 """ 750 Return the certificate type selected by server. 751 752 @rtype: int 753 """ 754 cert_type = self.getExtension(ExtensionType.cert_type) 755 if cert_type is None: 756 # XXX backwards compatibility, TLSConnection expects the default 757 # value to be that 758 return CertificateType.x509 759 return cert_type.cert_type
760 761 @certificate_type.setter
762 - def certificate_type(self, val):
763 """ 764 Set the certificate type supported. 765 766 @type val: int 767 @param val: type of certificate 768 """ 769 # XXX backwards compatibility, 0 means x.509 and should not be sent 770 if val == 0 or val is None: 771 return 772 773 cert_type = self.getExtension(ExtensionType.cert_type) 774 if cert_type is None: 775 ext = ServerCertTypeExtension().create(val) 776 self.addExtension(ext) 777 else: 778 cert_type.cert_type = val
779 780 @property
781 - def next_protos(self):
782 """ 783 Return the advertised protocols in NPN extension. 784 785 @rtype: list of bytearrays 786 """ 787 npn_ext = self.getExtension(ExtensionType.supports_npn) 788 789 if npn_ext is None: 790 return None 791 else: 792 return npn_ext.protocols
793 794 @next_protos.setter
795 - def next_protos(self, val):
796 """ 797 Set the advertised protocols in NPN extension. 798 799 @type val: list 800 @param val: list of protocols to advertise as UTF-8 encoded names 801 """ 802 if val is None: 803 return 804 else: 805 # convinience function, make sure the values are properly encoded 806 val = [bytearray(x) for x in val] 807 808 npn_ext = self.getExtension(ExtensionType.supports_npn) 809 810 if npn_ext is None: 811 ext = NPNExtension().create(val) 812 self.addExtension(ext) 813 else: 814 npn_ext.protocols = val
815 816 @property
817 - def next_protos_advertised(self):
818 """ 819 Return the advertised protocols in NPN extension. 820 821 @rtype: list of bytearrays 822 """ 823 return self.next_protos
824 825 @next_protos_advertised.setter
826 - def next_protos_advertised(self, val):
827 """ 828 Set the advertised protocols in NPN extension. 829 830 @type val: list 831 @param val: list of protocols to advertise as UTF-8 encoded names 832 """ 833 self.next_protos = val
834
835 - def create(self, version, random, session_id, cipher_suite, 836 certificate_type=None, tackExt=None, 837 next_protos_advertised=None, 838 extensions=None):
839 """Initialize the object for deserialisation.""" 840 self.extensions = extensions 841 self.server_version = version 842 self.random = random 843 self.session_id = session_id 844 self.cipher_suite = cipher_suite 845 self.certificate_type = certificate_type 846 self.compression_method = 0 847 if tackExt is not None: 848 self.tackExt = tackExt 849 self.next_protos_advertised = next_protos_advertised 850 return self
851
852 - def parse(self, p):
853 p.startLengthCheck(3) 854 self.server_version = (p.get(1), p.get(1)) 855 self.random = p.getFixBytes(32) 856 self.session_id = p.getVarBytes(1) 857 self.cipher_suite = p.get(2) 858 self.compression_method = p.get(1) 859 if not p.atLengthCheck(): 860 self.extensions = [] 861 totalExtLength = p.get(2) 862 p2 = Parser(p.getFixBytes(totalExtLength)) 863 while p2.getRemainingLength() > 0: 864 ext = TLSExtension(server=True).parse(p2) 865 self.extensions += [ext] 866 p.stopLengthCheck() 867 return self
868
869 - def write(self):
870 w = Writer() 871 w.add(self.server_version[0], 1) 872 w.add(self.server_version[1], 1) 873 w.addFixSeq(self.random, 1) 874 w.addVarSeq(self.session_id, 1, 1) 875 w.add(self.cipher_suite, 2) 876 w.add(self.compression_method, 1) 877 878 if self.extensions is not None: 879 w2 = Writer() 880 for ext in self.extensions: 881 w2.bytes += ext.write() 882 883 if self.tackExt: 884 b = self.tackExt.serialize() 885 w2.add(ExtensionType.tack, 2) 886 w2.add(len(b), 2) 887 w2.bytes += b 888 889 w.add(len(w2.bytes), 2) 890 w.bytes += w2.bytes 891 return self.postWrite(w)
892
893 894 -class ServerHello2(HandshakeMsg):
895 """ 896 SERVER-HELLO message from SSLv2. 897 898 @type session_id_hit: int 899 @ivar session_id_hit: non zero if the client provided session ID was 900 matched in server's session cache 901 902 @type certificate_type: int 903 @ivar certificate_type: type of certificate sent 904 905 @type server_version: tuple of ints 906 @ivar server_version: protocol version selected by server 907 908 @type certificate: bytearray 909 @ivar certificate: certificate sent by server 910 911 @type ciphers: array of int 912 @ivar ciphers: list of ciphers supported by server 913 914 @type session_id: bytearray 915 @ivar session_id: idendifier of negotiated session 916 """ 917
918 - def __init__(self):
919 super(ServerHello2, self).__init__(SSL2HandshakeType.server_hello) 920 self.session_id_hit = 0 921 self.certificate_type = 0 922 self.server_version = (0, 0) 923 self.certificate = bytearray(0) 924 self.ciphers = [] 925 self.session_id = bytearray(0)
926
927 - def create(self, session_id_hit, certificate_type, server_version, 928 certificate, ciphers, session_id):
929 """Initialize fields of the SERVER-HELLO message.""" 930 self.session_id_hit = session_id_hit 931 self.certificate_type = certificate_type 932 self.server_version = server_version 933 self.certificate = certificate 934 self.ciphers = ciphers 935 self.session_id = session_id 936 return self
937
938 - def write(self):
939 """Serialise object to on the wire data.""" 940 writer = Writer() 941 writer.add(self.handshakeType, 1) 942 writer.add(self.session_id_hit, 1) 943 writer.add(self.certificate_type, 1) 944 if len(self.server_version) != 2: 945 raise ValueError("server version must be a 2-element tuple") 946 writer.addFixSeq(self.server_version, 1) 947 writer.add(len(self.certificate), 2) 948 949 ciphersWriter = Writer() 950 ciphersWriter.addFixSeq(self.ciphers, 3) 951 952 writer.add(len(ciphersWriter.bytes), 2) 953 writer.add(len(self.session_id), 2) 954 955 writer.bytes += self.certificate 956 writer.bytes += ciphersWriter.bytes 957 writer.bytes += self.session_id 958 959 # postWrite() is necessary only for SSLv3/TLS 960 return writer.bytes
961
962 - def parse(self, parser):
963 """Deserialise object from on the wire data.""" 964 self.session_id_hit = parser.get(1) 965 self.certificate_type = parser.get(1) 966 self.server_version = (parser.get(1), parser.get(1)) 967 certificateLength = parser.get(2) 968 ciphersLength = parser.get(2) 969 sessionIDLength = parser.get(2) 970 parser.setLengthCheck(certificateLength + 971 ciphersLength + 972 sessionIDLength) 973 self.certificate = parser.getFixBytes(certificateLength) 974 self.ciphers = parser.getFixList(3, ciphersLength // 3) 975 self.session_id = parser.getFixBytes(sessionIDLength) 976 parser.stopLengthCheck() 977 return self
978
979 980 -class Certificate(HandshakeMsg):
981 - def __init__(self, certificateType):
982 HandshakeMsg.__init__(self, HandshakeType.certificate) 983 self.certificateType = certificateType 984 self.certChain = None
985
986 - def create(self, certChain):
987 self.certChain = certChain 988 return self
989
990 - def parse(self, p):
991 p.startLengthCheck(3) 992 if self.certificateType == CertificateType.x509: 993 chainLength = p.get(3) 994 index = 0 995 certificate_list = [] 996 while index != chainLength: 997 certBytes = p.getVarBytes(3) 998 x509 = X509() 999 x509.parseBinary(certBytes) 1000 certificate_list.append(x509) 1001 index += len(certBytes)+3 1002 if certificate_list: 1003 self.certChain = X509CertChain(certificate_list) 1004 else: 1005 raise AssertionError() 1006 1007 p.stopLengthCheck() 1008 return self
1009
1010 - def write(self):
1011 w = Writer() 1012 if self.certificateType == CertificateType.x509: 1013 chainLength = 0 1014 if self.certChain: 1015 certificate_list = self.certChain.x509List 1016 else: 1017 certificate_list = [] 1018 # determine length 1019 for cert in certificate_list: 1020 bytes = cert.writeBytes() 1021 chainLength += len(bytes)+3 1022 # add bytes 1023 w.add(chainLength, 3) 1024 for cert in certificate_list: 1025 bytes = cert.writeBytes() 1026 w.addVarSeq(bytes, 1, 3) 1027 else: 1028 raise AssertionError() 1029 return self.postWrite(w)
1030
1031 1032 -class CertificateRequest(HandshakeMsg):
1033 - def __init__(self, version):
1034 HandshakeMsg.__init__(self, HandshakeType.certificate_request) 1035 self.certificate_types = [] 1036 self.certificate_authorities = [] 1037 self.version = version 1038 self.supported_signature_algs = []
1039
1040 - def create(self, certificate_types, certificate_authorities, sig_algs=()):
1041 self.certificate_types = certificate_types 1042 self.certificate_authorities = certificate_authorities 1043 self.supported_signature_algs = sig_algs 1044 return self
1045
1046 - def parse(self, p):
1047 p.startLengthCheck(3) 1048 self.certificate_types = p.getVarList(1, 1) 1049 if self.version >= (3, 3): 1050 self.supported_signature_algs = p.getVarTupleList(1, 2, 2) 1051 ca_list_length = p.get(2) 1052 index = 0 1053 self.certificate_authorities = [] 1054 while index != ca_list_length: 1055 ca_bytes = p.getVarBytes(2) 1056 self.certificate_authorities.append(ca_bytes) 1057 index += len(ca_bytes)+2 1058 p.stopLengthCheck() 1059 return self
1060
1061 - def write(self):
1062 w = Writer() 1063 w.addVarSeq(self.certificate_types, 1, 1) 1064 if self.version >= (3, 3): 1065 w.addVarTupleSeq(self.supported_signature_algs, 1, 2) 1066 caLength = 0 1067 # determine length 1068 for ca_dn in self.certificate_authorities: 1069 caLength += len(ca_dn)+2 1070 w.add(caLength, 2) 1071 # add bytes 1072 for ca_dn in self.certificate_authorities: 1073 w.addVarSeq(ca_dn, 1, 2) 1074 return self.postWrite(w)
1075
1076 1077 -class ServerKeyExchange(HandshakeMsg):
1078 """ 1079 Handling TLS Handshake protocol Server Key Exchange messages. 1080 1081 @type cipherSuite: int 1082 @cvar cipherSuite: id of ciphersuite selected in Server Hello message 1083 @type srp_N: int 1084 @cvar srp_N: SRP protocol prime 1085 @type srp_g: int 1086 @cvar srp_g: SRP protocol generator 1087 @type srp_s: bytearray 1088 @cvar srp_s: SRP protocol salt value 1089 @type srp_B: int 1090 @cvar srp_B: SRP protocol server public value 1091 @type dh_p: int 1092 @cvar dh_p: FFDHE protocol prime 1093 @type dh_g: int 1094 @cvar dh_g: FFDHE protocol generator 1095 @type dh_Ys: int 1096 @cvar dh_Ys: FFDH protocol server key share 1097 @type curve_type: int 1098 @cvar curve_type: Type of curve used (explicit, named, etc.) 1099 @type named_curve: int 1100 @cvar named_curve: TLS ID of named curve 1101 @type ecdh_Ys: bytearray 1102 @cvar ecdh_Ys: ECDH protocol encoded point key share 1103 @type signature: bytearray 1104 @cvar signature: signature performed over the parameters by server 1105 @type hashAlg: int 1106 @cvar hashAlg: id of hash algorithm used for signature 1107 @type signAlg: int 1108 @cvar signAlg: id of signature algorithm used for signature 1109 """ 1110
1111 - def __init__(self, cipherSuite, version):
1112 """ 1113 Initialise Server Key Exchange for reading or writing. 1114 1115 @type cipherSuite: int 1116 @param cipherSuite: id of ciphersuite selected by server 1117 """ 1118 HandshakeMsg.__init__(self, HandshakeType.server_key_exchange) 1119 self.cipherSuite = cipherSuite 1120 self.version = version 1121 self.srp_N = 0 1122 self.srp_g = 0 1123 self.srp_s = bytearray(0) 1124 self.srp_B = 0 1125 # Anon DH params: 1126 self.dh_p = 0 1127 self.dh_g = 0 1128 self.dh_Ys = 0 1129 # EC settings 1130 self.curve_type = None 1131 self.named_curve = None 1132 self.ecdh_Ys = bytearray(0) 1133 # signature for certificate authenticated ciphersuites 1134 self.signature = bytearray(0) 1135 # signature hash algorithm and signing algorithm for TLSv1.2 1136 self.hashAlg = 0 1137 self.signAlg = 0
1138
1139 - def __repr__(self):
1140 ret = "ServerKeyExchange(cipherSuite=CipherSuite.{0}, version={1}"\ 1141 "".format(CipherSuite.ietfNames[self.cipherSuite], self.version) 1142 1143 if self.srp_N != 0: 1144 ret += ", srp_N={0}, srp_g={1}, srp_s={2!r}, srp_B={3}".format( 1145 self.srp_N, self.srp_g, self.srp_s, self.srp_B) 1146 if self.dh_p != 0: 1147 ret += ", dh_p={0}, dh_g={1}, dh_Ys={2}".format( 1148 self.dh_p, self.dh_g, self.dh_Ys) 1149 if self.signAlg != 0: 1150 ret += ", hashAlg={0}, signAlg={1}".format( 1151 self.hashAlg, self.signAlg) 1152 if self.signature != bytearray(0): 1153 ret += ", signature={0!r}".format(self.signature) 1154 ret += ")" 1155 1156 return ret
1157
1158 - def createSRP(self, srp_N, srp_g, srp_s, srp_B):
1159 """Set SRP protocol parameters.""" 1160 self.srp_N = srp_N 1161 self.srp_g = srp_g 1162 self.srp_s = srp_s 1163 self.srp_B = srp_B 1164 return self
1165
1166 - def createDH(self, dh_p, dh_g, dh_Ys):
1167 """Set FFDH protocol parameters.""" 1168 self.dh_p = dh_p 1169 self.dh_g = dh_g 1170 self.dh_Ys = dh_Ys 1171 return self
1172
1173 - def createECDH(self, curve_type, named_curve=None, point=None):
1174 """Set ECDH protocol parameters.""" 1175 self.curve_type = curve_type 1176 self.named_curve = named_curve 1177 self.ecdh_Ys = point
1178
1179 - def parse(self, parser):
1180 """ 1181 Deserialise message from L{Parser}. 1182 1183 @type parser: L{Parser} 1184 @param parser: parser to read data from 1185 """ 1186 parser.startLengthCheck(3) 1187 if self.cipherSuite in CipherSuite.srpAllSuites: 1188 self.srp_N = bytesToNumber(parser.getVarBytes(2)) 1189 self.srp_g = bytesToNumber(parser.getVarBytes(2)) 1190 self.srp_s = parser.getVarBytes(1) 1191 self.srp_B = bytesToNumber(parser.getVarBytes(2)) 1192 elif self.cipherSuite in CipherSuite.dhAllSuites: 1193 self.dh_p = bytesToNumber(parser.getVarBytes(2)) 1194 self.dh_g = bytesToNumber(parser.getVarBytes(2)) 1195 self.dh_Ys = bytesToNumber(parser.getVarBytes(2)) 1196 elif self.cipherSuite in CipherSuite.ecdhAllSuites: 1197 self.curve_type = parser.get(1) 1198 # only named curves supported 1199 assert self.curve_type == 3 1200 self.named_curve = parser.get(2) 1201 self.ecdh_Ys = parser.getVarBytes(1) 1202 else: 1203 raise AssertionError() 1204 1205 if self.cipherSuite in CipherSuite.certAllSuites: 1206 if self.version == (3, 3): 1207 self.hashAlg = parser.get(1) 1208 self.signAlg = parser.get(1) 1209 self.signature = parser.getVarBytes(2) 1210 1211 parser.stopLengthCheck() 1212 return self
1213
1214 - def writeParams(self):
1215 """ 1216 Serialise the key exchange parameters. 1217 1218 @rtype: bytearray 1219 """ 1220 writer = Writer() 1221 if self.cipherSuite in CipherSuite.srpAllSuites: 1222 writer.addVarSeq(numberToByteArray(self.srp_N), 1, 2) 1223 writer.addVarSeq(numberToByteArray(self.srp_g), 1, 2) 1224 writer.addVarSeq(self.srp_s, 1, 1) 1225 writer.addVarSeq(numberToByteArray(self.srp_B), 1, 2) 1226 elif self.cipherSuite in CipherSuite.dhAllSuites: 1227 writer.addVarSeq(numberToByteArray(self.dh_p), 1, 2) 1228 writer.addVarSeq(numberToByteArray(self.dh_g), 1, 2) 1229 writer.addVarSeq(numberToByteArray(self.dh_Ys), 1, 2) 1230 elif self.cipherSuite in CipherSuite.ecdhAllSuites: 1231 writer.add(self.curve_type, 1) 1232 assert self.curve_type == 3 1233 writer.add(self.named_curve, 2) 1234 writer.addVarSeq(self.ecdh_Ys, 1, 1) 1235 else: 1236 assert(False) 1237 return writer.bytes
1238
1239 - def write(self):
1240 """ 1241 Serialise complete message. 1242 1243 @rtype: bytearray 1244 """ 1245 writer = Writer() 1246 writer.bytes += self.writeParams() 1247 if self.cipherSuite in CipherSuite.certAllSuites: 1248 if self.version >= (3, 3): 1249 assert self.hashAlg != 0 and self.signAlg != 0 1250 writer.add(self.hashAlg, 1) 1251 writer.add(self.signAlg, 1) 1252 writer.addVarSeq(self.signature, 1, 2) 1253 return self.postWrite(writer)
1254
1255 - def hash(self, clientRandom, serverRandom):
1256 """ 1257 Calculate hash of parameters to sign. 1258 1259 @rtype: bytearray 1260 """ 1261 bytesToHash = clientRandom + serverRandom + self.writeParams() 1262 if self.version >= (3, 3): 1263 hashAlg = HashAlgorithm.toRepr(self.hashAlg) 1264 if hashAlg is None: 1265 raise AssertionError("Unknown hash algorithm: {0}". 1266 format(self.hashAlg)) 1267 return secureHash(bytesToHash, hashAlg) 1268 return MD5(bytesToHash) + SHA1(bytesToHash)
1269
1270 1271 -class ServerHelloDone(HandshakeMsg):
1272 - def __init__(self):
1274
1275 - def create(self):
1276 return self
1277
1278 - def parse(self, p):
1279 p.startLengthCheck(3) 1280 p.stopLengthCheck() 1281 return self
1282
1283 - def write(self):
1284 w = Writer() 1285 return self.postWrite(w)
1286
1287 - def __repr__(self):
1288 """Human readable representation of object.""" 1289 return "ServerHelloDone()"
1290
1291 1292 -class ClientKeyExchange(HandshakeMsg):
1293 """ 1294 Handling of TLS Handshake protocol ClientKeyExchange message. 1295 1296 @type cipherSuite: int 1297 @ivar cipherSuite: the cipher suite id used for the connection 1298 @type version: tuple(int, int) 1299 @ivar version: TLS protocol version used for the connection 1300 @type srp_A: int 1301 @ivar srp_A: SRP protocol client answer value 1302 @type dh_Yc: int 1303 @ivar dh_Yc: client Finite Field Diffie-Hellman protocol key share 1304 @type ecdh_Yc: bytearray 1305 @ivar ecdh_Yc: encoded curve coordinates 1306 @type encryptedPreMasterSecret: bytearray 1307 @ivar encryptedPreMasterSecret: client selected PremMaster secret encrypted 1308 with server public key (from certificate) 1309 """ 1310
1311 - def __init__(self, cipherSuite, version=None):
1312 """ 1313 Initialise ClientKeyExchange for reading or writing. 1314 1315 @type cipherSuite: int 1316 @param cipherSuite: id of the ciphersuite selected by server 1317 @type version: tuple(int, int) 1318 @param version: protocol version selected by server 1319 """ 1320 HandshakeMsg.__init__(self, HandshakeType.client_key_exchange) 1321 self.cipherSuite = cipherSuite 1322 self.version = version 1323 self.srp_A = 0 1324 self.dh_Yc = 0 1325 self.ecdh_Yc = bytearray(0) 1326 self.encryptedPreMasterSecret = bytearray(0)
1327
1328 - def createSRP(self, srp_A):
1329 """ 1330 Set the SRP client answer. 1331 1332 returns self 1333 1334 @type srp_A: int 1335 @param srp_A: client SRP answer 1336 @rtype: L{ClientKeyExchange} 1337 """ 1338 self.srp_A = srp_A 1339 return self
1340
1341 - def createRSA(self, encryptedPreMasterSecret):
1342 """ 1343 Set the encrypted PreMaster Secret. 1344 1345 returns self 1346 1347 @type encryptedPreMasterSecret: bytearray 1348 @rtype: L{ClientKeyExchange} 1349 """ 1350 self.encryptedPreMasterSecret = encryptedPreMasterSecret 1351 return self
1352
1353 - def createDH(self, dh_Yc):
1354 """ 1355 Set the client FFDH key share. 1356 1357 returns self 1358 1359 @type dh_Yc: int 1360 @rtype: L{ClientKeyExchange} 1361 """ 1362 self.dh_Yc = dh_Yc 1363 return self
1364
1365 - def createECDH(self, ecdh_Yc):
1366 """ 1367 Set the client ECDH key share. 1368 1369 returns self 1370 1371 @type ecdh_Yc: bytearray 1372 @rtype: L{ClientKeyExchange} 1373 """ 1374 self.ecdh_Yc = ecdh_Yc 1375 return self
1376
1377 - def parse(self, parser):
1378 """ 1379 Deserialise the message from L{Parser}, 1380 1381 returns self 1382 1383 @type parser: L{Parser} 1384 @rtype: L{ClientKeyExchange} 1385 """ 1386 parser.startLengthCheck(3) 1387 if self.cipherSuite in CipherSuite.srpAllSuites: 1388 self.srp_A = bytesToNumber(parser.getVarBytes(2)) 1389 elif self.cipherSuite in CipherSuite.certSuites: 1390 if self.version in ((3, 1), (3, 2), (3, 3)): 1391 self.encryptedPreMasterSecret = parser.getVarBytes(2) 1392 elif self.version == (3, 0): 1393 self.encryptedPreMasterSecret = \ 1394 parser.getFixBytes(parser.getRemainingLength()) 1395 else: 1396 raise AssertionError() 1397 elif self.cipherSuite in CipherSuite.dhAllSuites: 1398 self.dh_Yc = bytesToNumber(parser.getVarBytes(2)) 1399 elif self.cipherSuite in CipherSuite.ecdhAllSuites: 1400 self.ecdh_Yc = parser.getVarBytes(1) 1401 else: 1402 raise AssertionError() 1403 parser.stopLengthCheck() 1404 return self
1405
1406 - def write(self):
1407 """ 1408 Serialise the object. 1409 1410 @rtype: bytearray 1411 """ 1412 w = Writer() 1413 if self.cipherSuite in CipherSuite.srpAllSuites: 1414 w.addVarSeq(numberToByteArray(self.srp_A), 1, 2) 1415 elif self.cipherSuite in CipherSuite.certSuites: 1416 if self.version in ((3, 1), (3, 2), (3, 3)): 1417 w.addVarSeq(self.encryptedPreMasterSecret, 1, 2) 1418 elif self.version == (3, 0): 1419 w.addFixSeq(self.encryptedPreMasterSecret, 1) 1420 else: 1421 raise AssertionError() 1422 elif self.cipherSuite in CipherSuite.dhAllSuites: 1423 w.addVarSeq(numberToByteArray(self.dh_Yc), 1, 2) 1424 elif self.cipherSuite in CipherSuite.ecdhAllSuites: 1425 w.addVarSeq(self.ecdh_Yc, 1, 1) 1426 else: 1427 raise AssertionError() 1428 return self.postWrite(w)
1429
1430 1431 -class ClientMasterKey(HandshakeMsg):
1432 """ 1433 Handling of SSLv2 CLIENT-MASTER-KEY message. 1434 1435 @type cipher: int 1436 @ivar cipher: negotiated cipher 1437 1438 @type clear_key: bytearray 1439 @ivar clear_key: the part of master secret key that is sent in clear for 1440 export cipher suites 1441 1442 @type encrypted_key: bytearray 1443 @ivar encrypted_key: (part of) master secret encrypted using server key 1444 1445 @type key_argument: bytearray 1446 @ivar key_argument: additional key argument for block ciphers 1447 """ 1448
1449 - def __init__(self):
1450 super(ClientMasterKey, 1451 self).__init__(SSL2HandshakeType.client_master_key) 1452 self.cipher = 0 1453 self.clear_key = bytearray(0) 1454 self.encrypted_key = bytearray(0) 1455 self.key_argument = bytearray(0)
1456
1457 - def create(self, cipher, clear_key, encrypted_key, key_argument):
1458 """Set values of the CLIENT-MASTER-KEY object.""" 1459 self.cipher = cipher 1460 self.clear_key = clear_key 1461 self.encrypted_key = encrypted_key 1462 self.key_argument = key_argument 1463 return self
1464
1465 - def write(self):
1466 """Serialise the object to on the wire data.""" 1467 writer = Writer() 1468 writer.add(self.handshakeType, 1) 1469 writer.add(self.cipher, 3) 1470 writer.add(len(self.clear_key), 2) 1471 writer.add(len(self.encrypted_key), 2) 1472 writer.add(len(self.key_argument), 2) 1473 writer.bytes += self.clear_key 1474 writer.bytes += self.encrypted_key 1475 writer.bytes += self.key_argument 1476 return writer.bytes
1477
1478 - def parse(self, parser):
1479 """Deserialise object from on the wire data.""" 1480 self.cipher = parser.get(3) 1481 clear_key_length = parser.get(2) 1482 encrypted_key_length = parser.get(2) 1483 key_argument_length = parser.get(2) 1484 parser.setLengthCheck(clear_key_length + 1485 encrypted_key_length + 1486 key_argument_length) 1487 self.clear_key = parser.getFixBytes(clear_key_length) 1488 self.encrypted_key = parser.getFixBytes(encrypted_key_length) 1489 self.key_argument = parser.getFixBytes(key_argument_length) 1490 parser.stopLengthCheck() 1491 return self
1492
1493 1494 -class CertificateVerify(HandshakeMsg):
1495 """Serializer for TLS handshake protocol Certificate Verify message.""" 1496
1497 - def __init__(self, version):
1498 """ 1499 Create message. 1500 1501 @param version: TLS protocol version in use 1502 """ 1503 HandshakeMsg.__init__(self, HandshakeType.certificate_verify) 1504 self.version = version 1505 self.signatureAlgorithm = None 1506 self.signature = bytearray(0)
1507
1508 - def create(self, signature, signatureAlgorithm=None):
1509 """ 1510 Provide data for serialisation of message. 1511 1512 @param signature: signature carried in the message 1513 @param signatureAlgorithm: signature algorithm used to make the 1514 signature (TLSv1.2 only) 1515 """ 1516 self.signatureAlgorithm = signatureAlgorithm 1517 self.signature = signature 1518 return self
1519
1520 - def parse(self, parser):
1521 """ 1522 Deserialize message from parser. 1523 1524 @param parser: parser with data to read 1525 """ 1526 parser.startLengthCheck(3) 1527 if self.version >= (3, 3): 1528 self.signatureAlgorithm = (parser.get(1), parser.get(1)) 1529 self.signature = parser.getVarBytes(2) 1530 parser.stopLengthCheck() 1531 return self
1532
1533 - def write(self):
1534 """ 1535 Serialize the data to bytearray. 1536 1537 @rtype: bytearray 1538 """ 1539 writer = Writer() 1540 if self.version >= (3, 3): 1541 writer.add(self.signatureAlgorithm[0], 1) 1542 writer.add(self.signatureAlgorithm[1], 1) 1543 writer.addVarSeq(self.signature, 1, 2) 1544 return self.postWrite(writer)
1545
1546 1547 -class ChangeCipherSpec(object):
1548 - def __init__(self):
1549 self.contentType = ContentType.change_cipher_spec 1550 self.type = 1
1551
1552 - def create(self):
1553 self.type = 1 1554 return self
1555
1556 - def parse(self, p):
1557 p.setLengthCheck(1) 1558 self.type = p.get(1) 1559 p.stopLengthCheck() 1560 return self
1561
1562 - def write(self):
1563 w = Writer() 1564 w.add(self.type, 1) 1565 return w.bytes
1566
1567 1568 -class NextProtocol(HandshakeMsg):
1569 - def __init__(self):
1570 HandshakeMsg.__init__(self, HandshakeType.next_protocol) 1571 self.next_proto = None
1572
1573 - def create(self, next_proto):
1574 self.next_proto = next_proto 1575 return self
1576
1577 - def parse(self, p):
1578 p.startLengthCheck(3) 1579 self.next_proto = p.getVarBytes(1) 1580 _ = p.getVarBytes(1) 1581 p.stopLengthCheck() 1582 return self
1583
1584 - def write(self, trial=False):
1585 w = Writer() 1586 w.addVarSeq(self.next_proto, 1, 1) 1587 paddingLen = 32 - ((len(self.next_proto) + 2) % 32) 1588 w.addVarSeq(bytearray(paddingLen), 1, 1) 1589 return self.postWrite(w)
1590
1591 1592 -class Finished(HandshakeMsg):
1593 - def __init__(self, version):
1594 HandshakeMsg.__init__(self, HandshakeType.finished) 1595 self.version = version 1596 self.verify_data = bytearray(0)
1597
1598 - def create(self, verify_data):
1599 self.verify_data = verify_data 1600 return self
1601
1602 - def parse(self, p):
1603 p.startLengthCheck(3) 1604 if self.version == (3, 0): 1605 self.verify_data = p.getFixBytes(36) 1606 elif self.version in ((3, 1), (3, 2), (3, 3)): 1607 self.verify_data = p.getFixBytes(12) 1608 else: 1609 raise AssertionError() 1610 p.stopLengthCheck() 1611 return self
1612
1613 - def write(self):
1614 w = Writer() 1615 w.addFixSeq(self.verify_data, 1) 1616 return self.postWrite(w)
1617
1618 1619 -class SSL2Finished(HandshakeMsg):
1620 """Handling of the SSL2 FINISHED messages.""" 1621
1622 - def __init__(self, msg_type):
1623 super(SSL2Finished, self).__init__(msg_type) 1624 self.verify_data = bytearray(0)
1625
1626 - def create(self, verify_data):
1627 """Set the message payload.""" 1628 self.verify_data = verify_data 1629 return self
1630
1631 - def parse(self, parser):
1632 """Deserialise the message from on the wire data.""" 1633 self.verify_data = parser.getFixBytes(parser.getRemainingLength()) 1634 return self
1635
1636 - def write(self):
1637 """Serialise the message to on the wire data.""" 1638 writer = Writer() 1639 writer.add(self.handshakeType, 1) 1640 writer.addFixSeq(self.verify_data, 1) 1641 # does not use postWrite() as it's a SSLv2 message 1642 return writer.bytes
1643
1644 1645 -class ClientFinished(SSL2Finished):
1646 """ 1647 Handling of SSLv2 CLIENT-FINISHED message. 1648 1649 @type verify_data: bytearray 1650 @ivar verify_data: payload of the message, should be the CONNECTION-ID 1651 """ 1652
1653 - def __init__(self):
1655
1656 1657 -class ServerFinished(SSL2Finished):
1658 """ 1659 Handling of SSLv2 SERVER-FINISHED message. 1660 1661 @type verify_data: bytearray 1662 @ivar verify_data: payload of the message, should be SESSION-ID 1663 """ 1664
1665 - def __init__(self):
1667
1668 1669 -class CertificateStatus(HandshakeMsg):
1670 """ 1671 Handling of the CertificateStatus message from RFC 6066. 1672 1673 Handling of the handshake protocol message that includes the OCSP staple. 1674 1675 @type status_type: int 1676 @ivar status_type: type of response returned 1677 1678 @type ocsp: bytearray 1679 @ivar ocsp: OCSPResponse from RFC 2560 1680 """ 1681
1682 - def __init__(self):
1683 """Create the objet, set its type.""" 1684 super(CertificateStatus, self).__init__( 1685 HandshakeType.certificate_status) 1686 self.status_type = None 1687 self.ocsp = bytearray()
1688
1689 - def create(self, status_type, ocsp):
1690 """Set up message payload.""" 1691 self.status_type = status_type 1692 self.ocsp = ocsp 1693 return self
1694
1695 - def parse(self, parser):
1696 """Deserialise the message from one the wire data.""" 1697 parser.startLengthCheck(3) 1698 self.status_type = parser.get(1) 1699 self.ocsp = parser.getVarBytes(3) 1700 parser.stopLengthCheck() 1701 return self
1702
1703 - def write(self):
1704 """Serialise the message.""" 1705 writer = Writer() 1706 writer.add(self.status_type, 1) 1707 writer.add(len(self.ocsp), 3) 1708 writer.bytes += self.ocsp 1709 return self.postWrite(writer)
1710
1711 1712 -class ApplicationData(object):
1713 - def __init__(self):
1714 self.contentType = ContentType.application_data 1715 self.bytes = bytearray(0)
1716
1717 - def create(self, bytes):
1718 self.bytes = bytes 1719 return self
1720
1721 - def splitFirstByte(self):
1722 newMsg = ApplicationData().create(self.bytes[:1]) 1723 self.bytes = self.bytes[1:] 1724 return newMsg
1725
1726 - def parse(self, p):
1727 self.bytes = p.bytes 1728 return self
1729
1730 - def write(self):
1731 return self.bytes
1732