1
2
3
4
5
6
7
8
9
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 *
24
25 """Generic interface to SSLv2 and SSLv3 (and later) record headers"""
26
28 """define instance variables"""
29 self.type = 0
30 self.version = (0, 0)
31 self.length = 0
32 self.ssl2 = ssl2
33
35
36 """SSLv3 (and later) TLS record header"""
37
41
43 """Set object values for writing (serialisation)"""
44 self.type = type
45 self.version = version
46 self.length = length
47 return self
48
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
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
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
76 return "SSLv3 record,version({0[0]}.{0[1]}),"\
77 "content type({1}),length({2})".format(self.version,
78 self.typeName, self.length)
79
81 return "RecordHeader3(type={0}, version=({1[0]}.{1[1]}), length={2})".\
82 format(self.type, self.version, self.length)
83
85
86 """SSLv2 record header (just reading)"""
87
91
93 """Deserialise object from Parser"""
94 if parser.get(1) != 128:
95 raise SyntaxError()
96 self.type = ContentType.handshake
97 self.version = (2, 0)
98
99 self.length = parser.get(1)
100 return self
101
103
104 """Generic TLS message"""
105
107 """
108 Initialize object with specified contentType and data
109
110 @type contentType: int
111 @param contentType: TLS record layer content type of associated data
112 @type data: bytearray
113 @param data: data
114 """
115 self.contentType = contentType
116 self.data = data
117
119 """Return serialised object data"""
120 return self.data
121
124 self.contentType = ContentType.alert
125 self.level = 0
126 self.description = 0
127
129 self.level = level
130 self.description = description
131 return self
132
139
141 w = Writer()
142 w.add(self.level, 1)
143 w.add(self.description, 1)
144 return w.bytes
145
146 @property
148 matching = [x[0] for x in AlertLevel.__dict__.items()
149 if x[1] == self.level]
150 if len(matching) == 0:
151 return "unknown({0})".format(self.level)
152 else:
153 return str(matching[0])
154
155 @property
157 matching = [x[0] for x in AlertDescription.__dict__.items()
158 if x[1] == self.description]
159 if len(matching) == 0:
160 return "unknown({0})".format(self.description)
161 else:
162 return str(matching[0])
163
167
169 return "Alert(level={0}, description={1})".format(self.level,
170 self.description)
171
176
177 - def postWrite(self, w):
178 headerWriter = Writer()
179 headerWriter.add(self.handshakeType, 1)
180 headerWriter.add(len(w.bytes), 3)
181 return headerWriter.bytes + w.bytes
182
184 """
185 Class for handling the ClientHello TLS message, supports both the SSLv2
186 and SSLv3 style messages.
187
188 @type certificate_types: list
189 @ivar certificate_types: list of supported certificate types (deprecated)
190
191 @type srp_username: bytearray
192 @ivar srp_username: name of the user in SRP extension (deprecated)
193
194 @type supports_npn: boolean
195 @ivar supports_npn: NPN extension presence (deprecated)
196
197 @type tack: boolean
198 @ivar tack: TACK extension presence (deprecated)
199
200 @type server_name: bytearray
201 @ivar server_name: first host_name (type 0) present in SNI extension
202 (deprecated)
203
204 @type extensions: list of L{TLSExtension}
205 @ivar extensions: list of TLS extensions parsed from wire or to send, see
206 L{TLSExtension} and child classes for exact examples
207 """
217
219 """
220 Return human readable representation of Client Hello
221
222 @rtype: str
223 """
224
225 if self.session_id.count(bytearray(b'\x00')) == len(self.session_id)\
226 and len(self.session_id) != 0:
227 session = "bytearray(b'\\x00'*{0})".format(len(self.session_id))
228 else:
229 session = repr(self.session_id)
230 ret = "client_hello,version({0[0]}.{0[1]}),random(...),"\
231 "session ID({1!s}),cipher suites({2!r}),"\
232 "compression methods({3!r})".format(
233 self.client_version, session,
234 self.cipher_suites, self.compression_methods)
235
236 if self.extensions is not None:
237 ret += ",extensions({0!r})".format(self.extensions)
238
239 return ret
240
242 """
243 Return machine readable representation of Client Hello
244
245 @rtype: str
246 """
247 return "ClientHello(ssl2={0}, client_version=({1[0]}.{1[1]}), "\
248 "random={2!r}, session_id={3!r}, cipher_suites={4!r}, "\
249 "compression_methods={5}, extensions={6})".format(\
250 self.ssl2, self.client_version, self.random, self.session_id,
251 self.cipher_suites, self.compression_methods, self.extensions)
252
253 - def getExtension(self, extType):
254 """
255 Returns extension of given type if present, None otherwise
256
257 @rtype: L{tlslite.extensions.TLSExtension}
258 @raise TLSInternalError: when there are multiple extensions of the
259 same type
260 """
261 if self.extensions is None:
262 return None
263
264 exts = [ext for ext in self.extensions if ext.extType == extType]
265 if len(exts) > 1:
266 raise TLSInternalError(
267 "Multiple extensions of the same type present")
268 elif len(exts) == 1:
269 return exts[0]
270 else:
271 return None
272
274 """
275 Adds extension to internal list of extensions
276
277 @type ext: TLSExtension
278 @param ext: extension object to add to list
279 """
280 if self.extensions is None:
281 self.extensions = []
282
283 self.extensions.append(ext)
284
285 @property
299
300 @certificate_types.setter
302 """
303 Sets the list of supported types to list given in L{val} if the
304 cert_type extension is present. Creates the extension and places it
305 last in the list otherwise.
306
307 @type val: list
308 @param val: list of supported certificate types by client encoded as
309 single byte integers
310 """
311 cert_type = self.getExtension(ExtensionType.cert_type)
312
313 if cert_type is None:
314 ext = ClientCertTypeExtension().create(val)
315 self.addExtension(ext)
316 else:
317 cert_type.certTypes = val
318
319 @property
321 """
322 Returns username for the SRP.
323
324 @deprecated: use extensions field to get the extension for inspection
325 """
326 srp_ext = self.getExtension(ExtensionType.srp)
327
328 if srp_ext is None:
329 return None
330 else:
331 return srp_ext.identity
332
333 @srp_username.setter
348
349 @property
351 """
352 Returns whatever the client supports TACK
353
354 @rtype: boolean
355 @deprecated: use extensions field to get the extension for inspection
356 """
357 tack_ext = self.getExtension(ExtensionType.tack)
358
359 if tack_ext is None:
360 return False
361 else:
362 return True
363
364 @tack.setter
365 - def tack(self, present):
386
387 @property
389 """
390 Returns whatever client supports NPN extension
391
392 @rtype: boolean
393 @deprecated: use extensions field to get the extension for inspection
394 """
395 npn_ext = self.getExtension(ExtensionType.supports_npn)
396
397 if npn_ext is None:
398 return False
399 else:
400 return True
401
402 @supports_npn.setter
426
427 @property
429 """
430 Returns first host_name present in SNI extension
431
432 @rtype: bytearray
433 @deprecated: use extensions field to get the extension for inspection
434 """
435 sni_ext = self.getExtension(ExtensionType.server_name)
436 if sni_ext is None:
437 return bytearray(0)
438 else:
439 if len(sni_ext.hostNames) > 0:
440 return sni_ext.hostNames[0]
441 else:
442 return bytearray(0)
443
444 @server_name.setter
460
461 - def create(self, version, random, session_id, cipher_suites,
462 certificate_types=None, srpUsername=None,
463 tack=False, supports_npn=False, serverName=None,
464 extensions=None):
465 """
466 Create a ClientHello message for sending.
467
468 @type version: tuple
469 @param version: the highest supported TLS version encoded as two int
470 tuple
471
472 @type random: bytearray
473 @param random: client provided random value, in old versions of TLS
474 (before 1.2) the first 32 bits should include system time
475
476 @type session_id: bytearray
477 @param session_id: ID of session, set when doing session resumption
478
479 @type cipher_suites: list
480 @param cipher_suites: list of ciphersuites advertised as supported
481
482 @type certificate_types: list
483 @param certificate_types: list of supported certificate types, uses
484 TLS extension for signalling, as such requires TLS1.0 to work
485
486 @type srpUsername: bytearray
487 @param srpUsername: utf-8 encoded username for SRP, TLS extension
488
489 @type tack: boolean
490 @param tack: whatever to advertise support for TACK, TLS extension
491
492 @type supports_npn: boolean
493 @param supports_npn: whatever to advertise support for NPN, TLS
494 extension
495
496 @type serverName: bytearray
497 @param serverName: the hostname to request in server name indication
498 extension, TLS extension. Note that SNI allows to set multiple
499 hostnames and values that are not hostnames, use L{SNIExtension}
500 together with L{extensions} to use it.
501
502 @type extensions: list of L{TLSExtension}
503 @param extensions: list of extensions to advertise
504 """
505 self.client_version = version
506 self.random = random
507 self.session_id = session_id
508 self.cipher_suites = cipher_suites
509 self.compression_methods = [0]
510 if not extensions is None:
511 self.extensions = extensions
512 if not certificate_types is None:
513 self.certificate_types = certificate_types
514 if not srpUsername is None:
515 self.srp_username = bytearray(srpUsername, "utf-8")
516 self.tack = tack
517 self.supports_npn = supports_npn
518 if not serverName is None:
519 self.server_name = bytearray(serverName, "utf-8")
520 return self
521
552
554 w = Writer()
555 w.add(self.client_version[0], 1)
556 w.add(self.client_version[1], 1)
557 w.addFixSeq(self.random, 1)
558 w.addVarSeq(self.session_id, 1, 1)
559 w.addVarSeq(self.cipher_suites, 2, 2)
560 w.addVarSeq(self.compression_methods, 1, 1)
561
562 if not self.extensions is None:
563 w2 = Writer()
564 for ext in self.extensions:
565 w2.bytes += ext.write()
566
567 w.add(len(w2.bytes), 2)
568 w.bytes += w2.bytes
569 return self.postWrite(w)
570
572 """server_hello message
573
574 @type server_version: tuple
575 @ivar server_version: protocol version encoded as two int tuple
576
577 @type random: bytearray
578 @ivar random: server random value
579
580 @type session_id: bytearray
581 @ivar session_id: session identifier for resumption
582
583 @type cipher_suite: int
584 @ivar cipher_suite: server selected cipher_suite
585
586 @type compression_method: int
587 @ivar compression_method: server selected compression method
588
589 @type next_protos: list of bytearray
590 @ivar next_protos: list of advertised protocols in NPN extension
591
592 @type next_protos_advertised: list of bytearray
593 @ivar next_protos_advertised: list of protocols advertised in NPN extension
594
595 @type certificate_type: int
596 @ivar certificate_type: certificate type selected by server
597
598 @type extensions: list
599 @ivar extensions: list of TLS extensions present in server_hello message,
600 see L{TLSExtension} and child classes for exact examples
601 """
603 """Initialise ServerHello object"""
604
605 HandshakeMsg.__init__(self, HandshakeType.server_hello)
606 self.server_version = (0,0)
607 self.random = bytearray(32)
608 self.session_id = bytearray(0)
609 self.cipher_suite = 0
610 self.compression_method = 0
611 self._tack_ext = None
612 self.extensions = None
613
615 base = "server_hello,length({0}),version({1[0]}.{1[1]}),random(...),"\
616 "session ID({2!r}),cipher({3:#x}),compression method({4})"\
617 .format(len(self.write())-4, self.server_version,
618 self.session_id, self.cipher_suite,
619 self.compression_method)
620
621 if self.extensions is None:
622 return base
623
624 ret = ",extensions["
625 ret += ",".join(repr(x) for x in self.extensions)
626 ret += "]"
627 return base + ret
628
630 return "ServerHello(server_version=({0[0]}.{0[1]}), random={1!r}, "\
631 "session_id={2!r}, cipher_suite={3}, compression_method={4}, "\
632 "_tack_ext={5}, extensions={6!r})".format(\
633 self.server_version, self.random, self.session_id,
634 self.cipher_suite, self.compression_method, self._tack_ext,
635 self.extensions)
636
637 - def getExtension(self, extType):
638 """Return extension of a given type, None if extension of given type
639 is not present
640
641 @rtype: L{TLSExtension}
642 @raise TLSInternalError: multiple extensions of the same type present
643 """
644 if self.extensions is None:
645 return None
646
647 exts = [ext for ext in self.extensions if ext.extType == extType]
648 if len(exts) > 1:
649 raise TLSInternalError(
650 "Multiple extensions of the same type present")
651 elif len(exts) == 1:
652 return exts[0]
653 else:
654 return None
655
657 """
658 Add extension to internal list of extensions
659
660 @type ext: TLSExtension
661 @param ext: extension to add to list
662 """
663 if self.extensions is None:
664 self.extensions = []
665 self.extensions.append(ext)
666
667 @property
669 """ Returns the TACK extension
670 """
671 if self._tack_ext is None:
672 ext = self.getExtension(ExtensionType.tack)
673 if ext is None or not tackpyLoaded:
674 return None
675 else:
676 self._tack_ext = TackExtension(ext.extData)
677 return self._tack_ext
678
679 @tackExt.setter
681 """ Set the TACK extension
682 """
683 self._tack_ext = val
684
685 if not val is None:
686 if self.extensions is None:
687 self.extensions = []
688
689 @property
701
702 @certificate_type.setter
719
720 @property
722 """Returns the advertised protocols in NPN extension
723
724 @rtype: list of bytearrays
725 """
726 npn_ext = self.getExtension(ExtensionType.supports_npn)
727
728 if npn_ext is None:
729 return None
730 else:
731 return npn_ext.protocols
732
733 @next_protos.setter
735 """Sets the advertised protocols in NPN extension
736
737 @type val: list
738 @param val: list of protocols to advertise as UTF-8 encoded names
739 """
740 if val is None:
741 return
742 else:
743
744 val = [ bytearray(x) for x in val ]
745
746 npn_ext = self.getExtension(ExtensionType.supports_npn)
747
748 if npn_ext is None:
749 ext = NPNExtension().create(val)
750 self.addExtension(ext)
751 else:
752 npn_ext.protocols = val
753
754 @property
756 """Returns the advertised protocols in NPN extension
757
758 @rtype: list of bytearrays
759 """
760 return self.next_protos
761
762 @next_protos_advertised.setter
764 """Sets the advertised protocols in NPN extension
765
766 @type val: list
767 @param val: list of protocols to advertise as UTF-8 encoded names
768 """
769 self.next_protos = val
770
771 - def create(self, version, random, session_id, cipher_suite,
772 certificate_type=None, tackExt=None, next_protos_advertised=None,
773 extensions=None):
786
803
805 w = Writer()
806 w.add(self.server_version[0], 1)
807 w.add(self.server_version[1], 1)
808 w.addFixSeq(self.random, 1)
809 w.addVarSeq(self.session_id, 1, 1)
810 w.add(self.cipher_suite, 2)
811 w.add(self.compression_method, 1)
812
813 if not self.extensions is None:
814 w2 = Writer()
815 for ext in self.extensions:
816 w2.bytes += ext.write()
817
818 if self.tackExt:
819 b = self.tackExt.serialize()
820 w2.add(ExtensionType.tack, 2)
821 w2.add(len(b), 2)
822 w2.bytes += b
823
824 w.add(len(w2.bytes), 2)
825 w.bytes += w2.bytes
826 return self.postWrite(w)
827
833
835 self.certChain = certChain
836 return self
837
857
859 w = Writer()
860 if self.certificateType == CertificateType.x509:
861 chainLength = 0
862 if self.certChain:
863 certificate_list = self.certChain.x509List
864 else:
865 certificate_list = []
866
867 for cert in certificate_list:
868 bytes = cert.writeBytes()
869 chainLength += len(bytes)+3
870
871 w.add(chainLength, 3)
872 for cert in certificate_list:
873 bytes = cert.writeBytes()
874 w.addVarSeq(bytes, 1, 3)
875 else:
876 raise AssertionError()
877 return self.postWrite(w)
878
886
887 - def create(self, certificate_types, certificate_authorities, sig_algs=()):
892
907
909 w = Writer()
910 w.addVarSeq(self.certificate_types, 1, 1)
911 if self.version >= (3,3):
912 w.addVarTupleSeq(self.supported_signature_algs, 1, 2)
913 caLength = 0
914
915 for ca_dn in self.certificate_authorities:
916 caLength += len(ca_dn)+2
917 w.add(caLength, 2)
918
919 for ca_dn in self.certificate_authorities:
920 w.addVarSeq(ca_dn, 1, 2)
921 return self.postWrite(w)
922
924
925 """
926 Handling TLS Handshake protocol Server Key Exchange messages
927
928 @type cipherSuite: int
929 @cvar cipherSuite: id of ciphersuite selected in Server Hello message
930 @type srp_N: int
931 @cvar srp_N: SRP protocol prime
932 @type srp_g: int
933 @cvar srp_g: SRP protocol generator
934 @type srp_s: bytearray
935 @cvar srp_s: SRP protocol salt value
936 @type srp_B: int
937 @cvar srp_B: SRP protocol server public value
938 @type dh_p: int
939 @cvar dh_p: FFDHE protocol prime
940 @type dh_g: int
941 @cvar dh_g: FFDHE protocol generator
942 @type dh_Ys: int
943 @cvar dh_Ys: FFDH protocol server key share
944 @type signature: bytearray
945 @cvar signature: signature performed over the parameters by server
946 @type hashAlg: int
947 @cvar hashAlg: id of hash algorithm used for signature
948 @type signAlg: int
949 @cvar signAlg: id of signature algorithm used for signature
950 """
951
952 - def __init__(self, cipherSuite, version):
953 """
954 Initialise Server Key Exchange for reading or writing
955
956 @type cipherSuite: int
957 @param cipherSuite: id of ciphersuite selected by server
958 """
959 HandshakeMsg.__init__(self, HandshakeType.server_key_exchange)
960 self.cipherSuite = cipherSuite
961 self.version = version
962 self.srp_N = 0
963 self.srp_g = 0
964 self.srp_s = bytearray(0)
965 self.srp_B = 0
966
967 self.dh_p = 0
968 self.dh_g = 0
969 self.dh_Ys = 0
970
971 self.signature = bytearray(0)
972
973 self.hashAlg = 0
974 self.signAlg = 0
975
977
978 ret = "ServerKeyExchange(cipherSuite=CipherSuite.{0}, version={1}"\
979 "".format(CipherSuite.ietfNames[self.cipherSuite], self.version)
980
981 if self.srp_N != 0:
982 ret += ", srp_N={0}, srp_g={1}, srp_s={2!r}, srp_B={3}".format(\
983 self.srp_N, self.srp_g, self.srp_s, self.srp_B)
984 if self.dh_p != 0:
985 ret += ", dh_p={0}, dh_g={1}, dh_Ys={2}".format(\
986 self.dh_p, self.dh_g, self.dh_Ys)
987 if self.signAlg != 0:
988 ret += ", hashAlg={0}, signAlg={1}".format(\
989 self.hashAlg, self.signAlg)
990 if self.signature != bytearray(0):
991 ret += ", signature={0!r}".format(self.signature)
992 ret += ")"
993
994 return ret
995
996
997 - def createSRP(self, srp_N, srp_g, srp_s, srp_B):
998 """Set SRP protocol parameters"""
999 self.srp_N = srp_N
1000 self.srp_g = srp_g
1001 self.srp_s = srp_s
1002 self.srp_B = srp_B
1003 return self
1004
1005 - def createDH(self, dh_p, dh_g, dh_Ys):
1006 """Set FFDH protocol parameters"""
1007 self.dh_p = dh_p
1008 self.dh_g = dh_g
1009 self.dh_Ys = dh_Ys
1010 return self
1011
1012 - def parse(self, parser):
1039
1041 """Serialise the key exchange parameters
1042
1043 @rtype: bytearray
1044 """
1045 writer = Writer()
1046 if self.cipherSuite in CipherSuite.srpAllSuites:
1047 writer.addVarSeq(numberToByteArray(self.srp_N), 1, 2)
1048 writer.addVarSeq(numberToByteArray(self.srp_g), 1, 2)
1049 writer.addVarSeq(self.srp_s, 1, 1)
1050 writer.addVarSeq(numberToByteArray(self.srp_B), 1, 2)
1051 elif self.cipherSuite in CipherSuite.dhAllSuites:
1052 writer.addVarSeq(numberToByteArray(self.dh_p), 1, 2)
1053 writer.addVarSeq(numberToByteArray(self.dh_g), 1, 2)
1054 writer.addVarSeq(numberToByteArray(self.dh_Ys), 1, 2)
1055 else:
1056 assert(False)
1057 return writer.bytes
1058
1060 """
1061 Serialise complete message
1062
1063 @rtype: bytearray
1064 """
1065 writer = Writer()
1066 writer.bytes += self.writeParams()
1067 if self.cipherSuite in CipherSuite.certAllSuites:
1068 if self.version >= (3, 3):
1069 assert self.hashAlg != 0 and self.signAlg != 0
1070 writer.add(self.hashAlg, 1)
1071 writer.add(self.signAlg, 1)
1072 writer.addVarSeq(self.signature, 1, 2)
1073 return self.postWrite(writer)
1074
1075 - def hash(self, clientRandom, serverRandom):
1076 """
1077 Calculate hash of paramters to sign
1078
1079 @rtype: bytearray
1080 """
1081 bytesToHash = clientRandom + serverRandom + self.writeParams()
1082 if self.version >= (3, 3):
1083
1084 return SHA1(bytesToHash)
1085 return MD5(bytesToHash) + SHA1(bytesToHash)
1086
1102
1104
1105 """
1106 Handling of TLS Handshake protocol ClientKeyExchange message
1107
1108 @type cipherSuite: int
1109 @ivar cipherSuite: the cipher suite id used for the connection
1110 @type version: tuple(int, int)
1111 @ivar version: TLS protocol version used for the connection
1112 @type srp_A: int
1113 @ivar srp_A: SRP protocol client answer value
1114 @type dh_Yc: int
1115 @ivar dh_Yc: client Finite Field Diffie-Hellman protocol key share
1116 @type encryptedPreMasterSecret: bytearray
1117 @ivar encryptedPreMasterSecret: client selected PremMaster secret encrypted
1118 with server public key (from certificate)
1119 """
1120
1121 - def __init__(self, cipherSuite, version=None):
1122 """
1123 Initialise ClientKeyExchange for reading or writing
1124
1125 @type cipherSuite: int
1126 @param cipherSuite: id of the ciphersuite selected by server
1127 @type version: tuple(int, int)
1128 @param version: protocol version selected by server
1129 """
1130 HandshakeMsg.__init__(self, HandshakeType.client_key_exchange)
1131 self.cipherSuite = cipherSuite
1132 self.version = version
1133 self.srp_A = 0
1134 self.dh_Yc = 0
1135 self.encryptedPreMasterSecret = bytearray(0)
1136
1138 """
1139 Set the SRP client answer
1140
1141 returns self
1142
1143 @type srp_A: int
1144 @param srp_A: client SRP answer
1145 @rtype: L{ClientKeyExchange}
1146 """
1147 self.srp_A = srp_A
1148 return self
1149
1150 - def createRSA(self, encryptedPreMasterSecret):
1151 """
1152 Set the encrypted PreMaster Secret
1153
1154 returns self
1155
1156 @type encryptedPreMasterSecret: bytearray
1157 @rtype: L{ClientKeyExchange}
1158 """
1159 self.encryptedPreMasterSecret = encryptedPreMasterSecret
1160 return self
1161
1163 """
1164 Set the client FFDH key share
1165
1166 returns self
1167
1168 @type dh_Yc: int
1169 @rtype: L{ClientKeyExchange}
1170 """
1171 self.dh_Yc = dh_Yc
1172 return self
1173
1174 - def parse(self, parser):
1200
1202 """
1203 Serialise the object
1204
1205 @rtype: bytearray
1206 """
1207 w = Writer()
1208 if self.cipherSuite in CipherSuite.srpAllSuites:
1209 w.addVarSeq(numberToByteArray(self.srp_A), 1, 2)
1210 elif self.cipherSuite in CipherSuite.certSuites:
1211 if self.version in ((3,1), (3,2), (3,3)):
1212 w.addVarSeq(self.encryptedPreMasterSecret, 1, 2)
1213 elif self.version == (3,0):
1214 w.addFixSeq(self.encryptedPreMasterSecret, 1)
1215 else:
1216 raise AssertionError()
1217 elif self.cipherSuite in CipherSuite.dhAllSuites:
1218 w.addVarSeq(numberToByteArray(self.dh_Yc), 1, 2)
1219 else:
1220 raise AssertionError()
1221 return self.postWrite(w)
1222
1224
1225 """Serializer for TLS handshake protocol Certificate Verify message"""
1226
1236
1237 - def create(self, signature, signatureAlgorithm=None):
1238 """
1239 Provide data for serialisation of message
1240
1241 @param signature: signature carried in the message
1242 @param signatureAlgorithm: signature algorithm used to make the
1243 signature (TLSv1.2 only)
1244 """
1245 self.signatureAlgorithm = signatureAlgorithm
1246 self.signature = signature
1247 return self
1248
1249 - def parse(self, parser):
1250 """
1251 Deserialize message from parser
1252
1253 @param parser: parser with data to read
1254 """
1255 parser.startLengthCheck(3)
1256 if self.version >= (3, 3):
1257 self.signatureAlgorithm = (parser.get(1), parser.get(1))
1258 self.signature = parser.getVarBytes(2)
1259 parser.stopLengthCheck()
1260 return self
1261
1263 """
1264 Serialize the data to bytearray
1265
1266 @rtype: bytearray
1267 """
1268 writer = Writer()
1269 if self.version >= (3, 3):
1270 writer.add(self.signatureAlgorithm[0], 1)
1271 writer.add(self.signatureAlgorithm[1], 1)
1272 writer.addVarSeq(self.signature, 1, 2)
1273 return self.postWrite(writer)
1274
1279
1281 self.type = 1
1282 return self
1283
1289
1291 w = Writer()
1292 w.add(self.type,1)
1293 return w.bytes
1294
1300
1301 - def create(self, next_proto):
1302 self.next_proto = next_proto
1303 return self
1304
1311
1312 - def write(self, trial=False):
1313 w = Writer()
1314 w.addVarSeq(self.next_proto, 1, 1)
1315 paddingLen = 32 - ((len(self.next_proto) + 2) % 32)
1316 w.addVarSeq(bytearray(paddingLen), 1, 1)
1317 return self.postWrite(w)
1318
1324
1325 - def create(self, verify_data):
1326 self.verify_data = verify_data
1327 return self
1328
1339
1344
1349
1351 self.bytes = bytes
1352 return self
1353
1355 newMsg = ApplicationData().create(self.bytes[:1])
1356 self.bytes = self.bytes[1:]
1357 return newMsg
1358
1360 self.bytes = p.bytes
1361 return self
1362
1365