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 curve_type: int
945 @cvar curve_type: Type of curve used (explicit, named, etc.)
946 @type named_curve: int
947 @cvar named_curve: TLS ID of named curve
948 @type ecdh_Ys: bytearray
949 @cvar ecdh_Ys: ECDH protocol encoded point key share
950 @type signature: bytearray
951 @cvar signature: signature performed over the parameters by server
952 @type hashAlg: int
953 @cvar hashAlg: id of hash algorithm used for signature
954 @type signAlg: int
955 @cvar signAlg: id of signature algorithm used for signature
956 """
957
958 - def __init__(self, cipherSuite, version):
959 """
960 Initialise Server Key Exchange for reading or writing
961
962 @type cipherSuite: int
963 @param cipherSuite: id of ciphersuite selected by server
964 """
965 HandshakeMsg.__init__(self, HandshakeType.server_key_exchange)
966 self.cipherSuite = cipherSuite
967 self.version = version
968 self.srp_N = 0
969 self.srp_g = 0
970 self.srp_s = bytearray(0)
971 self.srp_B = 0
972
973 self.dh_p = 0
974 self.dh_g = 0
975 self.dh_Ys = 0
976
977 self.curve_type = None
978 self.named_curve = None
979 self.ecdh_Ys = bytearray(0)
980
981 self.signature = bytearray(0)
982
983 self.hashAlg = 0
984 self.signAlg = 0
985
987
988 ret = "ServerKeyExchange(cipherSuite=CipherSuite.{0}, version={1}"\
989 "".format(CipherSuite.ietfNames[self.cipherSuite], self.version)
990
991 if self.srp_N != 0:
992 ret += ", srp_N={0}, srp_g={1}, srp_s={2!r}, srp_B={3}".format(\
993 self.srp_N, self.srp_g, self.srp_s, self.srp_B)
994 if self.dh_p != 0:
995 ret += ", dh_p={0}, dh_g={1}, dh_Ys={2}".format(\
996 self.dh_p, self.dh_g, self.dh_Ys)
997 if self.signAlg != 0:
998 ret += ", hashAlg={0}, signAlg={1}".format(\
999 self.hashAlg, self.signAlg)
1000 if self.signature != bytearray(0):
1001 ret += ", signature={0!r}".format(self.signature)
1002 ret += ")"
1003
1004 return ret
1005
1006
1007 - def createSRP(self, srp_N, srp_g, srp_s, srp_B):
1008 """Set SRP protocol parameters"""
1009 self.srp_N = srp_N
1010 self.srp_g = srp_g
1011 self.srp_s = srp_s
1012 self.srp_B = srp_B
1013 return self
1014
1015 - def createDH(self, dh_p, dh_g, dh_Ys):
1016 """Set FFDH protocol parameters"""
1017 self.dh_p = dh_p
1018 self.dh_g = dh_g
1019 self.dh_Ys = dh_Ys
1020 return self
1021
1022 - def createECDH(self, curve_type, named_curve=None, point=None):
1023 """Set ECDH protocol parameters"""
1024 self.curve_type = curve_type
1025 self.named_curve = named_curve
1026 self.ecdh_Ys = point
1027
1028 - def parse(self, parser):
1061
1063 """Serialise the key exchange parameters
1064
1065 @rtype: bytearray
1066 """
1067 writer = Writer()
1068 if self.cipherSuite in CipherSuite.srpAllSuites:
1069 writer.addVarSeq(numberToByteArray(self.srp_N), 1, 2)
1070 writer.addVarSeq(numberToByteArray(self.srp_g), 1, 2)
1071 writer.addVarSeq(self.srp_s, 1, 1)
1072 writer.addVarSeq(numberToByteArray(self.srp_B), 1, 2)
1073 elif self.cipherSuite in CipherSuite.dhAllSuites:
1074 writer.addVarSeq(numberToByteArray(self.dh_p), 1, 2)
1075 writer.addVarSeq(numberToByteArray(self.dh_g), 1, 2)
1076 writer.addVarSeq(numberToByteArray(self.dh_Ys), 1, 2)
1077 elif self.cipherSuite in CipherSuite.ecdhAllSuites:
1078 writer.add(self.curve_type, 1)
1079 assert self.curve_type == 3
1080 writer.add(self.named_curve, 2)
1081 writer.addVarSeq(self.ecdh_Ys, 1, 1)
1082 else:
1083 assert(False)
1084 return writer.bytes
1085
1087 """
1088 Serialise complete message
1089
1090 @rtype: bytearray
1091 """
1092 writer = Writer()
1093 writer.bytes += self.writeParams()
1094 if self.cipherSuite in CipherSuite.certAllSuites:
1095 if self.version >= (3, 3):
1096 assert self.hashAlg != 0 and self.signAlg != 0
1097 writer.add(self.hashAlg, 1)
1098 writer.add(self.signAlg, 1)
1099 writer.addVarSeq(self.signature, 1, 2)
1100 return self.postWrite(writer)
1101
1102 - def hash(self, clientRandom, serverRandom):
1103 """
1104 Calculate hash of parameters to sign
1105
1106 @rtype: bytearray
1107 """
1108 bytesToHash = clientRandom + serverRandom + self.writeParams()
1109 if self.version >= (3, 3):
1110 hashAlg = HashAlgorithm.toRepr(self.hashAlg)
1111 if hashAlg is None:
1112 raise AssertionError("Unknown hash algorithm: {0}".\
1113 format(self.hashAlg))
1114 return secureHash(bytesToHash, hashAlg)
1115 return MD5(bytesToHash) + SHA1(bytesToHash)
1116
1132
1134
1135 """
1136 Handling of TLS Handshake protocol ClientKeyExchange message
1137
1138 @type cipherSuite: int
1139 @ivar cipherSuite: the cipher suite id used for the connection
1140 @type version: tuple(int, int)
1141 @ivar version: TLS protocol version used for the connection
1142 @type srp_A: int
1143 @ivar srp_A: SRP protocol client answer value
1144 @type dh_Yc: int
1145 @ivar dh_Yc: client Finite Field Diffie-Hellman protocol key share
1146 @type ecdh_Yc: bytearray
1147 @ivar ecdh_Yc: encoded curve coordinates
1148 @type encryptedPreMasterSecret: bytearray
1149 @ivar encryptedPreMasterSecret: client selected PremMaster secret encrypted
1150 with server public key (from certificate)
1151 """
1152
1153 - def __init__(self, cipherSuite, version=None):
1154 """
1155 Initialise ClientKeyExchange for reading or writing
1156
1157 @type cipherSuite: int
1158 @param cipherSuite: id of the ciphersuite selected by server
1159 @type version: tuple(int, int)
1160 @param version: protocol version selected by server
1161 """
1162 HandshakeMsg.__init__(self, HandshakeType.client_key_exchange)
1163 self.cipherSuite = cipherSuite
1164 self.version = version
1165 self.srp_A = 0
1166 self.dh_Yc = 0
1167 self.ecdh_Yc = bytearray(0)
1168 self.encryptedPreMasterSecret = bytearray(0)
1169
1171 """
1172 Set the SRP client answer
1173
1174 returns self
1175
1176 @type srp_A: int
1177 @param srp_A: client SRP answer
1178 @rtype: L{ClientKeyExchange}
1179 """
1180 self.srp_A = srp_A
1181 return self
1182
1183 - def createRSA(self, encryptedPreMasterSecret):
1184 """
1185 Set the encrypted PreMaster Secret
1186
1187 returns self
1188
1189 @type encryptedPreMasterSecret: bytearray
1190 @rtype: L{ClientKeyExchange}
1191 """
1192 self.encryptedPreMasterSecret = encryptedPreMasterSecret
1193 return self
1194
1196 """
1197 Set the client FFDH key share
1198
1199 returns self
1200
1201 @type dh_Yc: int
1202 @rtype: L{ClientKeyExchange}
1203 """
1204 self.dh_Yc = dh_Yc
1205 return self
1206
1208 """
1209 Set the client ECDH key share
1210
1211 returns self
1212
1213 @type ecdh_Yc: bytearray
1214 @rtype: L{ClientKeyExchange}
1215 """
1216 self.ecdh_Yc = ecdh_Yc
1217 return self
1218
1219 - def parse(self, parser):
1247
1249 """
1250 Serialise the object
1251
1252 @rtype: bytearray
1253 """
1254 w = Writer()
1255 if self.cipherSuite in CipherSuite.srpAllSuites:
1256 w.addVarSeq(numberToByteArray(self.srp_A), 1, 2)
1257 elif self.cipherSuite in CipherSuite.certSuites:
1258 if self.version in ((3,1), (3,2), (3,3)):
1259 w.addVarSeq(self.encryptedPreMasterSecret, 1, 2)
1260 elif self.version == (3,0):
1261 w.addFixSeq(self.encryptedPreMasterSecret, 1)
1262 else:
1263 raise AssertionError()
1264 elif self.cipherSuite in CipherSuite.dhAllSuites:
1265 w.addVarSeq(numberToByteArray(self.dh_Yc), 1, 2)
1266 elif self.cipherSuite in CipherSuite.ecdhAllSuites:
1267 w.addVarSeq(self.ecdh_Yc, 1, 1)
1268 else:
1269 raise AssertionError()
1270 return self.postWrite(w)
1271
1273
1274 """Serializer for TLS handshake protocol Certificate Verify message"""
1275
1285
1286 - def create(self, signature, signatureAlgorithm=None):
1287 """
1288 Provide data for serialisation of message
1289
1290 @param signature: signature carried in the message
1291 @param signatureAlgorithm: signature algorithm used to make the
1292 signature (TLSv1.2 only)
1293 """
1294 self.signatureAlgorithm = signatureAlgorithm
1295 self.signature = signature
1296 return self
1297
1298 - def parse(self, parser):
1299 """
1300 Deserialize message from parser
1301
1302 @param parser: parser with data to read
1303 """
1304 parser.startLengthCheck(3)
1305 if self.version >= (3, 3):
1306 self.signatureAlgorithm = (parser.get(1), parser.get(1))
1307 self.signature = parser.getVarBytes(2)
1308 parser.stopLengthCheck()
1309 return self
1310
1312 """
1313 Serialize the data to bytearray
1314
1315 @rtype: bytearray
1316 """
1317 writer = Writer()
1318 if self.version >= (3, 3):
1319 writer.add(self.signatureAlgorithm[0], 1)
1320 writer.add(self.signatureAlgorithm[1], 1)
1321 writer.addVarSeq(self.signature, 1, 2)
1322 return self.postWrite(writer)
1323
1328
1330 self.type = 1
1331 return self
1332
1338
1340 w = Writer()
1341 w.add(self.type,1)
1342 return w.bytes
1343
1349
1350 - def create(self, next_proto):
1351 self.next_proto = next_proto
1352 return self
1353
1360
1361 - def write(self, trial=False):
1362 w = Writer()
1363 w.addVarSeq(self.next_proto, 1, 1)
1364 paddingLen = 32 - ((len(self.next_proto) + 2) % 32)
1365 w.addVarSeq(bytearray(paddingLen), 1, 1)
1366 return self.postWrite(w)
1367
1373
1374 - def create(self, verify_data):
1375 self.verify_data = verify_data
1376 return self
1377
1388
1393
1398
1400 self.bytes = bytes
1401 return self
1402
1404 newMsg = ApplicationData().create(self.bytes[:1])
1405 self.bytes = self.bytes[1:]
1406 return newMsg
1407
1409 self.bytes = p.bytes
1410 return self
1411
1414