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 self.srp_username = bytearray(srpUsername, "utf-8") 569 self.tack = tack 570 if supports_npn is not None: 571 self.supports_npn = supports_npn 572 if serverName is not None: 573 self.server_name = bytearray(serverName, "utf-8") 574 return self
575
576 - def parse(self, p):
577 """Deserialise object from on the wire data.""" 578 if self.ssl2: 579 self.client_version = (p.get(1), p.get(1)) 580 cipherSpecsLength = p.get(2) 581 sessionIDLength = p.get(2) 582 randomLength = p.get(2) 583 p.setLengthCheck(cipherSpecsLength + 584 sessionIDLength + 585 randomLength) 586 self.cipher_suites = p.getFixList(3, cipherSpecsLength//3) 587 self.session_id = p.getFixBytes(sessionIDLength) 588 self.random = p.getFixBytes(randomLength) 589 if len(self.random) < 32: 590 zeroBytes = 32-len(self.random) 591 self.random = bytearray(zeroBytes) + self.random 592 self.compression_methods = [0] # Fake this value 593 p.stopLengthCheck() 594 else: 595 p.startLengthCheck(3) 596 self.client_version = (p.get(1), p.get(1)) 597 self.random = p.getFixBytes(32) 598 self.session_id = p.getVarBytes(1) 599 self.cipher_suites = p.getVarList(2, 2) 600 self.compression_methods = p.getVarList(1, 1) 601 if not p.atLengthCheck(): 602 self.extensions = [] 603 totalExtLength = p.get(2) 604 p2 = Parser(p.getFixBytes(totalExtLength)) 605 while p2.getRemainingLength() > 0: 606 ext = TLSExtension().parse(p2) 607 self.extensions += [ext] 608 p.stopLengthCheck() 609 return self
610
611 - def _writeSSL2(self):
612 """Serialise SSLv2 object to on the wire data.""" 613 writer = Writer() 614 writer.add(self.handshakeType, 1) 615 writer.add(self.client_version[0], 1) 616 writer.add(self.client_version[1], 1) 617 618 ciphersWriter = Writer() 619 ciphersWriter.addFixSeq(self.cipher_suites, 3) 620 621 writer.add(len(ciphersWriter.bytes), 2) 622 writer.add(len(self.session_id), 2) 623 writer.add(len(self.random), 2) 624 625 writer.bytes += ciphersWriter.bytes 626 writer.bytes += self.session_id 627 writer.bytes += self.random 628 629 # postWrite() is necessary only for SSLv3/TLS 630 return writer.bytes
631
632 - def _write(self):
633 """Serialise SSLv3 or TLS object to on the wire data.""" 634 w = Writer() 635 w.add(self.client_version[0], 1) 636 w.add(self.client_version[1], 1) 637 w.addFixSeq(self.random, 1) 638 w.addVarSeq(self.session_id, 1, 1) 639 w.addVarSeq(self.cipher_suites, 2, 2) 640 w.addVarSeq(self.compression_methods, 1, 1) 641 642 if self.extensions is not None: 643 w2 = Writer() 644 for ext in self.extensions: 645 w2.bytes += ext.write() 646 647 w.add(len(w2.bytes), 2) 648 w.bytes += w2.bytes 649 return self.postWrite(w)
650
651 - def write(self):
652 """Serialise object to on the wire data.""" 653 if self.ssl2: 654 return self._writeSSL2() 655 else: 656 return self._write()
657
658 659 -class ServerHello(HelloMessage):
660 """ 661 Handling of Server Hello messages. 662 663 @type server_version: tuple 664 @ivar server_version: protocol version encoded as two int tuple 665 666 @type random: bytearray 667 @ivar random: server random value 668 669 @type session_id: bytearray 670 @ivar session_id: session identifier for resumption 671 672 @type cipher_suite: int 673 @ivar cipher_suite: server selected cipher_suite 674 675 @type compression_method: int 676 @ivar compression_method: server selected compression method 677 678 @type next_protos: list of bytearray 679 @ivar next_protos: list of advertised protocols in NPN extension 680 681 @type next_protos_advertised: list of bytearray 682 @ivar next_protos_advertised: list of protocols advertised in NPN extension 683 684 @type certificate_type: int 685 @ivar certificate_type: certificate type selected by server 686 687 @type extensions: list 688 @ivar extensions: list of TLS extensions present in server_hello message, 689 see L{TLSExtension} and child classes for exact examples 690 """ 691
692 - def __init__(self):
693 """Initialise ServerHello object.""" 694 super(ServerHello, self).__init__(HandshakeType.server_hello) 695 self.server_version = (0, 0) 696 self.random = bytearray(32) 697 self.session_id = bytearray(0) 698 self.cipher_suite = 0 699 self.compression_method = 0 700 self._tack_ext = None
701
702 - def __str__(self):
703 base = "server_hello,length({0}),version({1[0]}.{1[1]}),random(...),"\ 704 "session ID({2!r}),cipher({3:#x}),compression method({4})"\ 705 .format(len(self.write())-4, self.server_version, 706 self.session_id, self.cipher_suite, 707 self.compression_method) 708 709 if self.extensions is None: 710 return base 711 712 ret = ",extensions[" 713 ret += ",".join(repr(x) for x in self.extensions) 714 ret += "]" 715 return base + ret
716
717 - def __repr__(self):
718 return "ServerHello(server_version=({0[0]}, {0[1]}), random={1!r}, "\ 719 "session_id={2!r}, cipher_suite={3}, compression_method={4}, "\ 720 "_tack_ext={5}, extensions={6!r})".format( 721 self.server_version, self.random, self.session_id, 722 self.cipher_suite, self.compression_method, self._tack_ext, 723 self.extensions)
724 725 @property
726 - def tackExt(self):
727 """Return the TACK extension.""" 728 if self._tack_ext is None: 729 ext = self.getExtension(ExtensionType.tack) 730 if ext is None or not tackpyLoaded: 731 return None 732 else: 733 self._tack_ext = TackExtension(ext.extData) 734 return self._tack_ext
735 736 @tackExt.setter
737 - def tackExt(self, val):
738 """Set the TACK extension.""" 739 self._tack_ext = val 740 # makes sure that extensions are included in the on the wire encoding 741 if val is not None: 742 if self.extensions is None: 743 self.extensions = []
744 745 @property
746 - def certificate_type(self):
747 """ 748 Return the certificate type selected by server. 749 750 @rtype: int 751 """ 752 cert_type = self.getExtension(ExtensionType.cert_type) 753 if cert_type is None: 754 # XXX backwards compatibility, TLSConnection expects the default 755 # value to be that 756 return CertificateType.x509 757 return cert_type.cert_type
758 759 @certificate_type.setter
760 - def certificate_type(self, val):
761 """ 762 Set the certificate type supported. 763 764 @type val: int 765 @param val: type of certificate 766 """ 767 # XXX backwards compatibility, 0 means x.509 and should not be sent 768 if val == 0 or val is None: 769 return 770 771 cert_type = self.getExtension(ExtensionType.cert_type) 772 if cert_type is None: 773 ext = ServerCertTypeExtension().create(val) 774 self.addExtension(ext) 775 else: 776 cert_type.cert_type = val
777 778 @property
779 - def next_protos(self):
780 """ 781 Return the advertised protocols in NPN extension. 782 783 @rtype: list of bytearrays 784 """ 785 npn_ext = self.getExtension(ExtensionType.supports_npn) 786 787 if npn_ext is None: 788 return None 789 else: 790 return npn_ext.protocols
791 792 @next_protos.setter
793 - def next_protos(self, val):
794 """ 795 Set the advertised protocols in NPN extension. 796 797 @type val: list 798 @param val: list of protocols to advertise as UTF-8 encoded names 799 """ 800 if val is None: 801 return 802 else: 803 # convinience function, make sure the values are properly encoded 804 val = [bytearray(x) for x in val] 805 806 npn_ext = self.getExtension(ExtensionType.supports_npn) 807 808 if npn_ext is None: 809 ext = NPNExtension().create(val) 810 self.addExtension(ext) 811 else: 812 npn_ext.protocols = val
813 814 @property
815 - def next_protos_advertised(self):
816 """ 817 Return the advertised protocols in NPN extension. 818 819 @rtype: list of bytearrays 820 """ 821 return self.next_protos
822 823 @next_protos_advertised.setter
824 - def next_protos_advertised(self, val):
825 """ 826 Set the advertised protocols in NPN extension. 827 828 @type val: list 829 @param val: list of protocols to advertise as UTF-8 encoded names 830 """ 831 self.next_protos = val
832
833 - def create(self, version, random, session_id, cipher_suite, 834 certificate_type=None, tackExt=None, 835 next_protos_advertised=None, 836 extensions=None):
837 """Initialize the object for deserialisation.""" 838 self.extensions = extensions 839 self.server_version = version 840 self.random = random 841 self.session_id = session_id 842 self.cipher_suite = cipher_suite 843 self.certificate_type = certificate_type 844 self.compression_method = 0 845 if tackExt is not None: 846 self.tackExt = tackExt 847 self.next_protos_advertised = next_protos_advertised 848 return self
849
850 - def parse(self, p):
851 p.startLengthCheck(3) 852 self.server_version = (p.get(1), p.get(1)) 853 self.random = p.getFixBytes(32) 854 self.session_id = p.getVarBytes(1) 855 self.cipher_suite = p.get(2) 856 self.compression_method = p.get(1) 857 if not p.atLengthCheck(): 858 self.extensions = [] 859 totalExtLength = p.get(2) 860 p2 = Parser(p.getFixBytes(totalExtLength)) 861 while p2.getRemainingLength() > 0: 862 ext = TLSExtension(server=True).parse(p2) 863 self.extensions += [ext] 864 p.stopLengthCheck() 865 return self
866
867 - def write(self):
868 w = Writer() 869 w.add(self.server_version[0], 1) 870 w.add(self.server_version[1], 1) 871 w.addFixSeq(self.random, 1) 872 w.addVarSeq(self.session_id, 1, 1) 873 w.add(self.cipher_suite, 2) 874 w.add(self.compression_method, 1) 875 876 if self.extensions is not None: 877 w2 = Writer() 878 for ext in self.extensions: 879 w2.bytes += ext.write() 880 881 if self.tackExt: 882 b = self.tackExt.serialize() 883 w2.add(ExtensionType.tack, 2) 884 w2.add(len(b), 2) 885 w2.bytes += b 886 887 w.add(len(w2.bytes), 2) 888 w.bytes += w2.bytes 889 return self.postWrite(w)
890
891 892 -class ServerHello2(HandshakeMsg):
893 """ 894 SERVER-HELLO message from SSLv2. 895 896 @type session_id_hit: int 897 @ivar session_id_hit: non zero if the client provided session ID was 898 matched in server's session cache 899 900 @type certificate_type: int 901 @ivar certificate_type: type of certificate sent 902 903 @type server_version: tuple of ints 904 @ivar server_version: protocol version selected by server 905 906 @type certificate: bytearray 907 @ivar certificate: certificate sent by server 908 909 @type ciphers: array of int 910 @ivar ciphers: list of ciphers supported by server 911 912 @type session_id: bytearray 913 @ivar session_id: idendifier of negotiated session 914 """ 915
916 - def __init__(self):
917 super(ServerHello2, self).__init__(SSL2HandshakeType.server_hello) 918 self.session_id_hit = 0 919 self.certificate_type = 0 920 self.server_version = (0, 0) 921 self.certificate = bytearray(0) 922 self.ciphers = [] 923 self.session_id = bytearray(0)
924
925 - def create(self, session_id_hit, certificate_type, server_version, 926 certificate, ciphers, session_id):
927 """Initialize fields of the SERVER-HELLO message.""" 928 self.session_id_hit = session_id_hit 929 self.certificate_type = certificate_type 930 self.server_version = server_version 931 self.certificate = certificate 932 self.ciphers = ciphers 933 self.session_id = session_id 934 return self
935
936 - def write(self):
937 """Serialise object to on the wire data.""" 938 writer = Writer() 939 writer.add(self.handshakeType, 1) 940 writer.add(self.session_id_hit, 1) 941 writer.add(self.certificate_type, 1) 942 if len(self.server_version) != 2: 943 raise ValueError("server version must be a 2-element tuple") 944 writer.addFixSeq(self.server_version, 1) 945 writer.add(len(self.certificate), 2) 946 947 ciphersWriter = Writer() 948 ciphersWriter.addFixSeq(self.ciphers, 3) 949 950 writer.add(len(ciphersWriter.bytes), 2) 951 writer.add(len(self.session_id), 2) 952 953 writer.bytes += self.certificate 954 writer.bytes += ciphersWriter.bytes 955 writer.bytes += self.session_id 956 957 # postWrite() is necessary only for SSLv3/TLS 958 return writer.bytes
959
960 - def parse(self, parser):
961 """Deserialise object from on the wire data.""" 962 self.session_id_hit = parser.get(1) 963 self.certificate_type = parser.get(1) 964 self.server_version = (parser.get(1), parser.get(1)) 965 certificateLength = parser.get(2) 966 ciphersLength = parser.get(2) 967 sessionIDLength = parser.get(2) 968 parser.setLengthCheck(certificateLength + 969 ciphersLength + 970 sessionIDLength) 971 self.certificate = parser.getFixBytes(certificateLength) 972 self.ciphers = parser.getFixList(3, ciphersLength // 3) 973 self.session_id = parser.getFixBytes(sessionIDLength) 974 parser.stopLengthCheck() 975 return self
976
977 978 -class Certificate(HandshakeMsg):
979 - def __init__(self, certificateType):
980 HandshakeMsg.__init__(self, HandshakeType.certificate) 981 self.certificateType = certificateType 982 self.certChain = None
983
984 - def create(self, certChain):
985 self.certChain = certChain 986 return self
987
988 - def parse(self, p):
989 p.startLengthCheck(3) 990 if self.certificateType == CertificateType.x509: 991 chainLength = p.get(3) 992 index = 0 993 certificate_list = [] 994 while index != chainLength: 995 certBytes = p.getVarBytes(3) 996 x509 = X509() 997 x509.parseBinary(certBytes) 998 certificate_list.append(x509) 999 index += len(certBytes)+3 1000 if certificate_list: 1001 self.certChain = X509CertChain(certificate_list) 1002 else: 1003 raise AssertionError() 1004 1005 p.stopLengthCheck() 1006 return self
1007
1008 - def write(self):
1009 w = Writer() 1010 if self.certificateType == CertificateType.x509: 1011 chainLength = 0 1012 if self.certChain: 1013 certificate_list = self.certChain.x509List 1014 else: 1015 certificate_list = [] 1016 # determine length 1017 for cert in certificate_list: 1018 bytes = cert.writeBytes() 1019 chainLength += len(bytes)+3 1020 # add bytes 1021 w.add(chainLength, 3) 1022 for cert in certificate_list: 1023 bytes = cert.writeBytes() 1024 w.addVarSeq(bytes, 1, 3) 1025 else: 1026 raise AssertionError() 1027 return self.postWrite(w)
1028
1029 1030 -class CertificateRequest(HandshakeMsg):
1031 - def __init__(self, version):
1032 HandshakeMsg.__init__(self, HandshakeType.certificate_request) 1033 self.certificate_types = [] 1034 self.certificate_authorities = [] 1035 self.version = version 1036 self.supported_signature_algs = []
1037
1038 - def create(self, certificate_types, certificate_authorities, sig_algs=()):
1039 self.certificate_types = certificate_types 1040 self.certificate_authorities = certificate_authorities 1041 self.supported_signature_algs = sig_algs 1042 return self
1043
1044 - def parse(self, p):
1045 p.startLengthCheck(3) 1046 self.certificate_types = p.getVarList(1, 1) 1047 if self.version >= (3, 3): 1048 self.supported_signature_algs = p.getVarTupleList(1, 2, 2) 1049 ca_list_length = p.get(2) 1050 index = 0 1051 self.certificate_authorities = [] 1052 while index != ca_list_length: 1053 ca_bytes = p.getVarBytes(2) 1054 self.certificate_authorities.append(ca_bytes) 1055 index += len(ca_bytes)+2 1056 p.stopLengthCheck() 1057 return self
1058
1059 - def write(self):
1060 w = Writer() 1061 w.addVarSeq(self.certificate_types, 1, 1) 1062 if self.version >= (3, 3): 1063 w.addVarTupleSeq(self.supported_signature_algs, 1, 2) 1064 caLength = 0 1065 # determine length 1066 for ca_dn in self.certificate_authorities: 1067 caLength += len(ca_dn)+2 1068 w.add(caLength, 2) 1069 # add bytes 1070 for ca_dn in self.certificate_authorities: 1071 w.addVarSeq(ca_dn, 1, 2) 1072 return self.postWrite(w)
1073
1074 1075 -class ServerKeyExchange(HandshakeMsg):
1076 """ 1077 Handling TLS Handshake protocol Server Key Exchange messages. 1078 1079 @type cipherSuite: int 1080 @cvar cipherSuite: id of ciphersuite selected in Server Hello message 1081 @type srp_N: int 1082 @cvar srp_N: SRP protocol prime 1083 @type srp_g: int 1084 @cvar srp_g: SRP protocol generator 1085 @type srp_s: bytearray 1086 @cvar srp_s: SRP protocol salt value 1087 @type srp_B: int 1088 @cvar srp_B: SRP protocol server public value 1089 @type dh_p: int 1090 @cvar dh_p: FFDHE protocol prime 1091 @type dh_g: int 1092 @cvar dh_g: FFDHE protocol generator 1093 @type dh_Ys: int 1094 @cvar dh_Ys: FFDH protocol server key share 1095 @type curve_type: int 1096 @cvar curve_type: Type of curve used (explicit, named, etc.) 1097 @type named_curve: int 1098 @cvar named_curve: TLS ID of named curve 1099 @type ecdh_Ys: bytearray 1100 @cvar ecdh_Ys: ECDH protocol encoded point key share 1101 @type signature: bytearray 1102 @cvar signature: signature performed over the parameters by server 1103 @type hashAlg: int 1104 @cvar hashAlg: id of hash algorithm used for signature 1105 @type signAlg: int 1106 @cvar signAlg: id of signature algorithm used for signature 1107 """ 1108
1109 - def __init__(self, cipherSuite, version):
1110 """ 1111 Initialise Server Key Exchange for reading or writing. 1112 1113 @type cipherSuite: int 1114 @param cipherSuite: id of ciphersuite selected by server 1115 """ 1116 HandshakeMsg.__init__(self, HandshakeType.server_key_exchange) 1117 self.cipherSuite = cipherSuite 1118 self.version = version 1119 self.srp_N = 0 1120 self.srp_g = 0 1121 self.srp_s = bytearray(0) 1122 self.srp_B = 0 1123 # Anon DH params: 1124 self.dh_p = 0 1125 self.dh_g = 0 1126 self.dh_Ys = 0 1127 # EC settings 1128 self.curve_type = None 1129 self.named_curve = None 1130 self.ecdh_Ys = bytearray(0) 1131 # signature for certificate authenticated ciphersuites 1132 self.signature = bytearray(0) 1133 # signature hash algorithm and signing algorithm for TLSv1.2 1134 self.hashAlg = 0 1135 self.signAlg = 0
1136
1137 - def __repr__(self):
1138 ret = "ServerKeyExchange(cipherSuite=CipherSuite.{0}, version={1}"\ 1139 "".format(CipherSuite.ietfNames[self.cipherSuite], self.version) 1140 1141 if self.srp_N != 0: 1142 ret += ", srp_N={0}, srp_g={1}, srp_s={2!r}, srp_B={3}".format( 1143 self.srp_N, self.srp_g, self.srp_s, self.srp_B) 1144 if self.dh_p != 0: 1145 ret += ", dh_p={0}, dh_g={1}, dh_Ys={2}".format( 1146 self.dh_p, self.dh_g, self.dh_Ys) 1147 if self.signAlg != 0: 1148 ret += ", hashAlg={0}, signAlg={1}".format( 1149 self.hashAlg, self.signAlg) 1150 if self.signature != bytearray(0): 1151 ret += ", signature={0!r}".format(self.signature) 1152 ret += ")" 1153 1154 return ret
1155
1156 - def createSRP(self, srp_N, srp_g, srp_s, srp_B):
1157 """Set SRP protocol parameters.""" 1158 self.srp_N = srp_N 1159 self.srp_g = srp_g 1160 self.srp_s = srp_s 1161 self.srp_B = srp_B 1162 return self
1163
1164 - def createDH(self, dh_p, dh_g, dh_Ys):
1165 """Set FFDH protocol parameters.""" 1166 self.dh_p = dh_p 1167 self.dh_g = dh_g 1168 self.dh_Ys = dh_Ys 1169 return self
1170
1171 - def createECDH(self, curve_type, named_curve=None, point=None):
1172 """Set ECDH protocol parameters.""" 1173 self.curve_type = curve_type 1174 self.named_curve = named_curve 1175 self.ecdh_Ys = point
1176
1177 - def parse(self, parser):
1178 """ 1179 Deserialise message from L{Parser}. 1180 1181 @type parser: L{Parser} 1182 @param parser: parser to read data from 1183 """ 1184 parser.startLengthCheck(3) 1185 if self.cipherSuite in CipherSuite.srpAllSuites: 1186 self.srp_N = bytesToNumber(parser.getVarBytes(2)) 1187 self.srp_g = bytesToNumber(parser.getVarBytes(2)) 1188 self.srp_s = parser.getVarBytes(1) 1189 self.srp_B = bytesToNumber(parser.getVarBytes(2)) 1190 elif self.cipherSuite in CipherSuite.dhAllSuites: 1191 self.dh_p = bytesToNumber(parser.getVarBytes(2)) 1192 self.dh_g = bytesToNumber(parser.getVarBytes(2)) 1193 self.dh_Ys = bytesToNumber(parser.getVarBytes(2)) 1194 elif self.cipherSuite in CipherSuite.ecdhAllSuites: 1195 self.curve_type = parser.get(1) 1196 # only named curves supported 1197 assert self.curve_type == 3 1198 self.named_curve = parser.get(2) 1199 self.ecdh_Ys = parser.getVarBytes(1) 1200 else: 1201 raise AssertionError() 1202 1203 if self.cipherSuite in CipherSuite.certAllSuites: 1204 if self.version == (3, 3): 1205 self.hashAlg = parser.get(1) 1206 self.signAlg = parser.get(1) 1207 self.signature = parser.getVarBytes(2) 1208 1209 parser.stopLengthCheck() 1210 return self
1211
1212 - def writeParams(self):
1213 """ 1214 Serialise the key exchange parameters. 1215 1216 @rtype: bytearray 1217 """ 1218 writer = Writer() 1219 if self.cipherSuite in CipherSuite.srpAllSuites: 1220 writer.addVarSeq(numberToByteArray(self.srp_N), 1, 2) 1221 writer.addVarSeq(numberToByteArray(self.srp_g), 1, 2) 1222 writer.addVarSeq(self.srp_s, 1, 1) 1223 writer.addVarSeq(numberToByteArray(self.srp_B), 1, 2) 1224 elif self.cipherSuite in CipherSuite.dhAllSuites: 1225 writer.addVarSeq(numberToByteArray(self.dh_p), 1, 2) 1226 writer.addVarSeq(numberToByteArray(self.dh_g), 1, 2) 1227 writer.addVarSeq(numberToByteArray(self.dh_Ys), 1, 2) 1228 elif self.cipherSuite in CipherSuite.ecdhAllSuites: 1229 writer.add(self.curve_type, 1) 1230 assert self.curve_type == 3 1231 writer.add(self.named_curve, 2) 1232 writer.addVarSeq(self.ecdh_Ys, 1, 1) 1233 else: 1234 assert(False) 1235 return writer.bytes
1236
1237 - def write(self):
1238 """ 1239 Serialise complete message. 1240 1241 @rtype: bytearray 1242 """ 1243 writer = Writer() 1244 writer.bytes += self.writeParams() 1245 if self.cipherSuite in CipherSuite.certAllSuites: 1246 if self.version >= (3, 3): 1247 assert self.hashAlg != 0 and self.signAlg != 0 1248 writer.add(self.hashAlg, 1) 1249 writer.add(self.signAlg, 1) 1250 writer.addVarSeq(self.signature, 1, 2) 1251 return self.postWrite(writer)
1252
1253 - def hash(self, clientRandom, serverRandom):
1254 """ 1255 Calculate hash of parameters to sign. 1256 1257 @rtype: bytearray 1258 """ 1259 bytesToHash = clientRandom + serverRandom + self.writeParams() 1260 if self.version >= (3, 3): 1261 hashAlg = HashAlgorithm.toRepr(self.hashAlg) 1262 if hashAlg is None: 1263 raise AssertionError("Unknown hash algorithm: {0}". 1264 format(self.hashAlg)) 1265 return secureHash(bytesToHash, hashAlg) 1266 return MD5(bytesToHash) + SHA1(bytesToHash)
1267
1268 1269 -class ServerHelloDone(HandshakeMsg):
1270 - def __init__(self):
1272
1273 - def create(self):
1274 return self
1275
1276 - def parse(self, p):
1277 p.startLengthCheck(3) 1278 p.stopLengthCheck() 1279 return self
1280
1281 - def write(self):
1282 w = Writer() 1283 return self.postWrite(w)
1284
1285 - def __repr__(self):
1286 """Human readable representation of object.""" 1287 return "ServerHelloDone()"
1288
1289 1290 -class ClientKeyExchange(HandshakeMsg):
1291 """ 1292 Handling of TLS Handshake protocol ClientKeyExchange message. 1293 1294 @type cipherSuite: int 1295 @ivar cipherSuite: the cipher suite id used for the connection 1296 @type version: tuple(int, int) 1297 @ivar version: TLS protocol version used for the connection 1298 @type srp_A: int 1299 @ivar srp_A: SRP protocol client answer value 1300 @type dh_Yc: int 1301 @ivar dh_Yc: client Finite Field Diffie-Hellman protocol key share 1302 @type ecdh_Yc: bytearray 1303 @ivar ecdh_Yc: encoded curve coordinates 1304 @type encryptedPreMasterSecret: bytearray 1305 @ivar encryptedPreMasterSecret: client selected PremMaster secret encrypted 1306 with server public key (from certificate) 1307 """ 1308
1309 - def __init__(self, cipherSuite, version=None):
1310 """ 1311 Initialise ClientKeyExchange for reading or writing. 1312 1313 @type cipherSuite: int 1314 @param cipherSuite: id of the ciphersuite selected by server 1315 @type version: tuple(int, int) 1316 @param version: protocol version selected by server 1317 """ 1318 HandshakeMsg.__init__(self, HandshakeType.client_key_exchange) 1319 self.cipherSuite = cipherSuite 1320 self.version = version 1321 self.srp_A = 0 1322 self.dh_Yc = 0 1323 self.ecdh_Yc = bytearray(0) 1324 self.encryptedPreMasterSecret = bytearray(0)
1325
1326 - def createSRP(self, srp_A):
1327 """ 1328 Set the SRP client answer. 1329 1330 returns self 1331 1332 @type srp_A: int 1333 @param srp_A: client SRP answer 1334 @rtype: L{ClientKeyExchange} 1335 """ 1336 self.srp_A = srp_A 1337 return self
1338
1339 - def createRSA(self, encryptedPreMasterSecret):
1340 """ 1341 Set the encrypted PreMaster Secret. 1342 1343 returns self 1344 1345 @type encryptedPreMasterSecret: bytearray 1346 @rtype: L{ClientKeyExchange} 1347 """ 1348 self.encryptedPreMasterSecret = encryptedPreMasterSecret 1349 return self
1350
1351 - def createDH(self, dh_Yc):
1352 """ 1353 Set the client FFDH key share. 1354 1355 returns self 1356 1357 @type dh_Yc: int 1358 @rtype: L{ClientKeyExchange} 1359 """ 1360 self.dh_Yc = dh_Yc 1361 return self
1362
1363 - def createECDH(self, ecdh_Yc):
1364 """ 1365 Set the client ECDH key share. 1366 1367 returns self 1368 1369 @type ecdh_Yc: bytearray 1370 @rtype: L{ClientKeyExchange} 1371 """ 1372 self.ecdh_Yc = ecdh_Yc 1373 return self
1374
1375 - def parse(self, parser):
1376 """ 1377 Deserialise the message from L{Parser}, 1378 1379 returns self 1380 1381 @type parser: L{Parser} 1382 @rtype: L{ClientKeyExchange} 1383 """ 1384 parser.startLengthCheck(3) 1385 if self.cipherSuite in CipherSuite.srpAllSuites: 1386 self.srp_A = bytesToNumber(parser.getVarBytes(2)) 1387 elif self.cipherSuite in CipherSuite.certSuites: 1388 if self.version in ((3, 1), (3, 2), (3, 3)): 1389 self.encryptedPreMasterSecret = parser.getVarBytes(2) 1390 elif self.version == (3, 0): 1391 self.encryptedPreMasterSecret = \ 1392 parser.getFixBytes(parser.getRemainingLength()) 1393 else: 1394 raise AssertionError() 1395 elif self.cipherSuite in CipherSuite.dhAllSuites: 1396 self.dh_Yc = bytesToNumber(parser.getVarBytes(2)) 1397 elif self.cipherSuite in CipherSuite.ecdhAllSuites: 1398 self.ecdh_Yc = parser.getVarBytes(1) 1399 else: 1400 raise AssertionError() 1401 parser.stopLengthCheck() 1402 return self
1403
1404 - def write(self):
1405 """ 1406 Serialise the object. 1407 1408 @rtype: bytearray 1409 """ 1410 w = Writer() 1411 if self.cipherSuite in CipherSuite.srpAllSuites: 1412 w.addVarSeq(numberToByteArray(self.srp_A), 1, 2) 1413 elif self.cipherSuite in CipherSuite.certSuites: 1414 if self.version in ((3, 1), (3, 2), (3, 3)): 1415 w.addVarSeq(self.encryptedPreMasterSecret, 1, 2) 1416 elif self.version == (3, 0): 1417 w.addFixSeq(self.encryptedPreMasterSecret, 1) 1418 else: 1419 raise AssertionError() 1420 elif self.cipherSuite in CipherSuite.dhAllSuites: 1421 w.addVarSeq(numberToByteArray(self.dh_Yc), 1, 2) 1422 elif self.cipherSuite in CipherSuite.ecdhAllSuites: 1423 w.addVarSeq(self.ecdh_Yc, 1, 1) 1424 else: 1425 raise AssertionError() 1426 return self.postWrite(w)
1427
1428 1429 -class ClientMasterKey(HandshakeMsg):
1430 """ 1431 Handling of SSLv2 CLIENT-MASTER-KEY message. 1432 1433 @type cipher: int 1434 @ivar cipher: negotiated cipher 1435 1436 @type clear_key: bytearray 1437 @ivar clear_key: the part of master secret key that is sent in clear for 1438 export cipher suites 1439 1440 @type encrypted_key: bytearray 1441 @ivar encrypted_key: (part of) master secret encrypted using server key 1442 1443 @type key_argument: bytearray 1444 @ivar key_argument: additional key argument for block ciphers 1445 """ 1446
1447 - def __init__(self):
1448 super(ClientMasterKey, 1449 self).__init__(SSL2HandshakeType.client_master_key) 1450 self.cipher = 0 1451 self.clear_key = bytearray(0) 1452 self.encrypted_key = bytearray(0) 1453 self.key_argument = bytearray(0)
1454
1455 - def create(self, cipher, clear_key, encrypted_key, key_argument):
1456 """Set values of the CLIENT-MASTER-KEY object.""" 1457 self.cipher = cipher 1458 self.clear_key = clear_key 1459 self.encrypted_key = encrypted_key 1460 self.key_argument = key_argument 1461 return self
1462
1463 - def write(self):
1464 """Serialise the object to on the wire data.""" 1465 writer = Writer() 1466 writer.add(self.handshakeType, 1) 1467 writer.add(self.cipher, 3) 1468 writer.add(len(self.clear_key), 2) 1469 writer.add(len(self.encrypted_key), 2) 1470 writer.add(len(self.key_argument), 2) 1471 writer.bytes += self.clear_key 1472 writer.bytes += self.encrypted_key 1473 writer.bytes += self.key_argument 1474 return writer.bytes
1475
1476 - def parse(self, parser):
1477 """Deserialise object from on the wire data.""" 1478 self.cipher = parser.get(3) 1479 clear_key_length = parser.get(2) 1480 encrypted_key_length = parser.get(2) 1481 key_argument_length = parser.get(2) 1482 parser.setLengthCheck(clear_key_length + 1483 encrypted_key_length + 1484 key_argument_length) 1485 self.clear_key = parser.getFixBytes(clear_key_length) 1486 self.encrypted_key = parser.getFixBytes(encrypted_key_length) 1487 self.key_argument = parser.getFixBytes(key_argument_length) 1488 parser.stopLengthCheck() 1489 return self
1490
1491 1492 -class CertificateVerify(HandshakeMsg):
1493 """Serializer for TLS handshake protocol Certificate Verify message.""" 1494
1495 - def __init__(self, version):
1496 """ 1497 Create message. 1498 1499 @param version: TLS protocol version in use 1500 """ 1501 HandshakeMsg.__init__(self, HandshakeType.certificate_verify) 1502 self.version = version 1503 self.signatureAlgorithm = None 1504 self.signature = bytearray(0)
1505
1506 - def create(self, signature, signatureAlgorithm=None):
1507 """ 1508 Provide data for serialisation of message. 1509 1510 @param signature: signature carried in the message 1511 @param signatureAlgorithm: signature algorithm used to make the 1512 signature (TLSv1.2 only) 1513 """ 1514 self.signatureAlgorithm = signatureAlgorithm 1515 self.signature = signature 1516 return self
1517
1518 - def parse(self, parser):
1519 """ 1520 Deserialize message from parser. 1521 1522 @param parser: parser with data to read 1523 """ 1524 parser.startLengthCheck(3) 1525 if self.version >= (3, 3): 1526 self.signatureAlgorithm = (parser.get(1), parser.get(1)) 1527 self.signature = parser.getVarBytes(2) 1528 parser.stopLengthCheck() 1529 return self
1530
1531 - def write(self):
1532 """ 1533 Serialize the data to bytearray. 1534 1535 @rtype: bytearray 1536 """ 1537 writer = Writer() 1538 if self.version >= (3, 3): 1539 writer.add(self.signatureAlgorithm[0], 1) 1540 writer.add(self.signatureAlgorithm[1], 1) 1541 writer.addVarSeq(self.signature, 1, 2) 1542 return self.postWrite(writer)
1543
1544 1545 -class ChangeCipherSpec(object):
1546 - def __init__(self):
1547 self.contentType = ContentType.change_cipher_spec 1548 self.type = 1
1549
1550 - def create(self):
1551 self.type = 1 1552 return self
1553
1554 - def parse(self, p):
1555 p.setLengthCheck(1) 1556 self.type = p.get(1) 1557 p.stopLengthCheck() 1558 return self
1559
1560 - def write(self):
1561 w = Writer() 1562 w.add(self.type, 1) 1563 return w.bytes
1564
1565 1566 -class NextProtocol(HandshakeMsg):
1567 - def __init__(self):
1568 HandshakeMsg.__init__(self, HandshakeType.next_protocol) 1569 self.next_proto = None
1570
1571 - def create(self, next_proto):
1572 self.next_proto = next_proto 1573 return self
1574
1575 - def parse(self, p):
1576 p.startLengthCheck(3) 1577 self.next_proto = p.getVarBytes(1) 1578 _ = p.getVarBytes(1) 1579 p.stopLengthCheck() 1580 return self
1581
1582 - def write(self, trial=False):
1583 w = Writer() 1584 w.addVarSeq(self.next_proto, 1, 1) 1585 paddingLen = 32 - ((len(self.next_proto) + 2) % 32) 1586 w.addVarSeq(bytearray(paddingLen), 1, 1) 1587 return self.postWrite(w)
1588
1589 1590 -class Finished(HandshakeMsg):
1591 - def __init__(self, version):
1592 HandshakeMsg.__init__(self, HandshakeType.finished) 1593 self.version = version 1594 self.verify_data = bytearray(0)
1595
1596 - def create(self, verify_data):
1597 self.verify_data = verify_data 1598 return self
1599
1600 - def parse(self, p):
1601 p.startLengthCheck(3) 1602 if self.version == (3, 0): 1603 self.verify_data = p.getFixBytes(36) 1604 elif self.version in ((3, 1), (3, 2), (3, 3)): 1605 self.verify_data = p.getFixBytes(12) 1606 else: 1607 raise AssertionError() 1608 p.stopLengthCheck() 1609 return self
1610
1611 - def write(self):
1612 w = Writer() 1613 w.addFixSeq(self.verify_data, 1) 1614 return self.postWrite(w)
1615
1616 1617 -class SSL2Finished(HandshakeMsg):
1618 """Handling of the SSL2 FINISHED messages.""" 1619
1620 - def __init__(self, msg_type):
1621 super(SSL2Finished, self).__init__(msg_type) 1622 self.verify_data = bytearray(0)
1623
1624 - def create(self, verify_data):
1625 """Set the message payload.""" 1626 self.verify_data = verify_data 1627 return self
1628
1629 - def parse(self, parser):
1630 """Deserialise the message from on the wire data.""" 1631 self.verify_data = parser.getFixBytes(parser.getRemainingLength()) 1632 return self
1633
1634 - def write(self):
1635 """Serialise the message to on the wire data.""" 1636 writer = Writer() 1637 writer.add(self.handshakeType, 1) 1638 writer.addFixSeq(self.verify_data, 1) 1639 # does not use postWrite() as it's a SSLv2 message 1640 return writer.bytes
1641
1642 1643 -class ClientFinished(SSL2Finished):
1644 """ 1645 Handling of SSLv2 CLIENT-FINISHED message. 1646 1647 @type verify_data: bytearray 1648 @ivar verify_data: payload of the message, should be the CONNECTION-ID 1649 """ 1650
1651 - def __init__(self):
1653
1654 1655 -class ServerFinished(SSL2Finished):
1656 """ 1657 Handling of SSLv2 SERVER-FINISHED message. 1658 1659 @type verify_data: bytearray 1660 @ivar verify_data: payload of the message, should be SESSION-ID 1661 """ 1662
1663 - def __init__(self):
1665
1666 1667 -class ApplicationData(object):
1668 - def __init__(self):
1669 self.contentType = ContentType.application_data 1670 self.bytes = bytearray(0)
1671
1672 - def create(self, bytes):
1673 self.bytes = bytes 1674 return self
1675
1676 - def splitFirstByte(self):
1677 newMsg = ApplicationData().create(self.bytes[:1]) 1678 self.bytes = self.bytes[1:] 1679 return newMsg
1680
1681 - def parse(self, p):
1682 self.bytes = p.bytes 1683 return self
1684
1685 - def write(self):
1686 return self.bytes
1687