1
2
3
4
5 """ Helper package for handling TLS extensions encountered in ClientHello
6 and ServerHello messages.
7 """
8
9 from __future__ import generators
10 from .utils.codec import Writer, Parser
11 from collections import namedtuple
12 from .constants import NameType, ExtensionType, CertificateStatusType
13 from .errors import TLSInternalError
16 """
17 Base class for handling handshake protocol hello messages extensions.
18
19 This class handles the generic information about TLS extensions used by
20 both sides of connection in Client Hello and Server Hello messages.
21 See U{RFC 4366<https://tools.ietf.org/html/rfc4366>} for more info.
22
23 It is used as a base class for specific users and as a way to store
24 extensions that are not implemented in library.
25
26 To implement a new extension you will need to create a new class which
27 calls this class contructor (__init__), usually specifying just the
28 extType parameter. The other methods which need to be implemented are:
29 L{extData}, L{create}, L{parse} and L{__repr__}. If the parser can be used
30 for client and optionally server extensions, the extension constructor
31 should be added to L{_universalExtensions}. Otherwise, when the client and
32 server extensions have completely different forms, you should add client
33 form to the L{_universalExtensions} and the server form to
34 L{_serverExtensions}. Since the server MUST NOT send extensions not
35 advertised by client, there are no purely server-side extensions. But
36 if the client side extension is just marked by presence and has no payload,
37 the client side (thus the L{_universalExtensions} may be skipped, then
38 the L{TLSExtension} class will be used for implementing it. See
39 end of the file for type-to-constructor bindings.
40
41 Though please note that subclassing for the purpose of parsing extensions
42 is not an officially supported part of API (just as underscores in their
43 names would indicate.
44
45 @type extType: int
46 @ivar extType: a 2^16-1 limited integer specifying the type of the
47 extension that it contains, e.g. 0 indicates server name extension
48
49 @type extData: bytearray
50 @ivar extData: a byte array containing the value of the extension as
51 to be written on the wire
52
53 @type serverType: boolean
54 @ivar serverType: indicates that the extension was parsed with ServerHello
55 specific parser, otherwise it used universal or ClientHello specific
56 parser
57
58 @type _universalExtensions: dict
59 @cvar _universalExtensions: dictionary with concrete implementations of
60 specific TLS extensions where key is the numeric value of the extension
61 ID. Contains ClientHello version of extensions or universal
62 implementations
63
64 @type _serverExtensions: dict
65 @cvar _serverExtensions: dictionary with concrete implementations of
66 specific TLS extensions where key is the numeric value of the extension
67 ID. Includes only those extensions that require special handlers for
68 ServerHello versions.
69 """
70
71 _universalExtensions = {}
72 _serverExtensions = {}
73
74 - def __init__(self, server=False, extType=None):
75 """
76 Creates a generic TLS extension.
77
78 You'll need to use L{create} or L{parse} methods to create an extension
79 that is actually usable.
80
81 @type server: boolean
82 @param server: whether to select ClientHello or ServerHello version
83 for parsing
84 @type extType: int
85 @param extType: type of extension encoded as an integer, to be used
86 by subclasses
87 """
88 self.extType = extType
89 self._extData = bytearray(0)
90 self.serverType = server
91
92 @property
94 """
95 Return the on the wire encoding of extension
96
97 Child classes need to override this property so that it returns just
98 the payload of an extension, that is, without the 4 byte generic header
99 common to all extension. In other words, without the extension ID and
100 overall extension length.
101
102 @rtype: bytearray
103 """
104 return self._extData
105
107 """Legacy handling of create method"""
108 self.extType = extType
109 self._extData = data
110
112 """New format for create method"""
113 self._extData = data
114
115 - def create(self, *args, **kwargs):
116 """
117 Initializes a generic TLS extension.
118
119 The extension can carry arbitrary data and have arbitrary payload, can
120 be used in client hello or server hello messages.
121
122 The legacy calling method uses two arguments - the extType and data.
123 If the new calling method is used, only one argument is passed in -
124 data.
125
126 Child classes need to override this method so that it is possible
127 to set values for all fields used by the extension.
128
129 @type extType: int
130 @param extType: if int: type of the extension encoded as an integer
131 between M{0} and M{2^16-1}
132 @type data: bytearray
133 @param data: raw data representing extension on the wire
134 @rtype: L{TLSExtension}
135 """
136
137 if len(args) + len(kwargs) == 2:
138 self._oldCreate(*args, **kwargs)
139
140 elif len(args) + len(kwargs) == 1:
141 self._newCreate(*args, **kwargs)
142 else:
143 raise TypeError("Invalid number of arguments")
144
145 return self
146
148 """Returns encoded extension, as encoded on the wire
149
150 Note that child classes in general don't need to override this method.
151
152 @rtype: bytearray
153 @return: An array of bytes formatted as is supposed to be written on
154 the wire, including the extension_type, length and the extension
155 data
156
157 @raise AssertionError: when the object was not initialized
158 """
159 assert self.extType is not None
160
161 w = Writer()
162 w.addTwo(self.extType)
163 data = self.extData
164 w.addTwo(len(data))
165 w.bytes += data
166 return w.bytes
167
168 @staticmethod
169 - def _parseExt(parser, extType, extLength, extList):
170 """Parse a extension using a predefined constructor"""
171 ext = extList[extType]()
172 extParser = Parser(parser.getFixBytes(extLength))
173 ext = ext.parse(extParser)
174 return ext
175
177 """Parses extension from on the wire format
178
179 Child classes should override this method so that it parses the
180 extension from on the wire data. Note that child class parsers will
181 not receive the generic header of the extension, but just a parser
182 with the payload. In other words, the method should be the exact
183 reverse of the L{extData} property.
184
185 @type p: L{tlslite.util.codec.Parser}
186 @param p: data to be parsed
187
188 @raise SyntaxError: when the size of the passed element doesn't match
189 the internal representation
190
191 @rtype: L{TLSExtension}
192 """
193 extType = p.get(2)
194 extLength = p.get(2)
195
196
197 if self.serverType and extType in self._serverExtensions:
198 return self._parseExt(p, extType, extLength,
199 self._serverExtensions)
200
201
202 if extType in self._universalExtensions:
203 return self._parseExt(p, extType, extLength,
204 self._universalExtensions)
205
206
207
208 self.extType = extType
209 self._extData = p.getFixBytes(extLength)
210 assert len(self._extData) == extLength
211 return self
212
214 """Test if two TLS extensions are effectively the same
215
216 Will check if encoding them will result in the same on the wire
217 representation.
218
219 Will return False for every object that's not an extension.
220 """
221 if hasattr(that, 'extType') and hasattr(that, 'extData'):
222 return self.extType == that.extType and \
223 self.extData == that.extData
224 else:
225 return False
226
228 """Output human readable representation of object
229
230 Child classes should override this method to support more appropriate
231 string rendering of the extension.
232
233 @rtype: str
234 """
235 return "TLSExtension(extType={0!r}, extData={1!r},"\
236 " serverType={2!r})".format(self.extType, self.extData,
237 self.serverType)
238
239 -class VarListExtension(TLSExtension):
240 """
241 Abstract extension for handling extensions comprised only of a value list
242
243 Extension for handling arbitrary extensions comprising of just a list
244 of same-sized elementes inside an array
245 """
246
247 - def __init__(self, elemLength, lengthLength, fieldName, extType):
248 super(VarListExtension, self).__init__(extType=extType)
249 self._fieldName = fieldName
250 self._internalList = None
251 self._elemLength = elemLength
252 self._lengthLength = lengthLength
253
254 @property
256 """Return raw data encoding of the extension
257
258 @rtype: bytearray
259 """
260 if self._internalList is None:
261 return bytearray(0)
262
263 writer = Writer()
264 writer.addVarSeq(self._internalList,
265 self._elemLength,
266 self._lengthLength)
267 return writer.bytes
268
269 - def create(self, values):
270 """Set the list to specified values
271
272 @type values: list of int
273 @param values: list of values to save
274 """
275 self._internalList = values
276 return self
277
278 - def parse(self, parser):
279 """
280 Deserialise extension from on-the-wire data
281
282 @type parser: L{Parser}
283 @rtype: Extension
284 """
285 if parser.getRemainingLength() == 0:
286 self._internalList = None
287 return self
288
289 self._internalList = parser.getVarList(self._elemLength,
290 self._lengthLength)
291 return self
292
293 - def __getattr__(self, name):
294 """Return the special field name value"""
295 if name == '_fieldName':
296 raise AttributeError("type object '{0}' has no attribute '{1}'"\
297 .format(self.__class__.__name__, name))
298 if name == self._fieldName:
299 return self._internalList
300 raise AttributeError("type object '{0}' has no attribute '{1}'"\
301 .format(self.__class__.__name__, name))
302
303 - def __setattr__(self, name, value):
304 """Set the special field value"""
305 if name == '_fieldName':
306 super(VarListExtension, self).__setattr__(name, value)
307 return
308 if hasattr(self, '_fieldName') and name == self._fieldName:
309 self._internalList = value
310 return
311 super(VarListExtension, self).__setattr__(name, value)
312
313 - def __repr__(self):
314 return "{0}({1}={2!r})".format(self.__class__.__name__,
315 self._fieldName,
316 self._internalList)
317
319 """
320 Class for handling Server Name Indication (server_name) extension from
321 RFC 4366.
322
323 Note that while usually the client does advertise just one name, it is
324 possible to provide a list of names, each of different type.
325 The type is a single byte value (represented by ints), the names are
326 opaque byte strings, in case of DNS host names (records of type 0) they
327 are UTF-8 encoded domain names (without the ending dot).
328
329 @type hostNames: tuple of bytearrays
330 @ivar hostNames: tuple of hostnames (server name records of type 0)
331 advertised in the extension. Note that it may not include all names
332 from client hello as the client can advertise other types. Also note
333 that while it's not possible to change the returned array in place, it
334 is possible to assign a new set of names. IOW, this won't work::
335
336 sni_extension.hostNames[0] = bytearray(b'example.com')
337
338 while this will work::
339
340 names = list(sni_extension.hostNames)
341 names[0] = bytearray(b'example.com')
342 sni_extension.hostNames = names
343
344
345 @type serverNames: list of L{ServerName}
346 @ivar serverNames: list of all names advertised in extension.
347 L{ServerName} is a namedtuple with two elements, the first
348 element (type) defines the type of the name (encoded as int)
349 while the other (name) is a bytearray that carries the value.
350 Known types are defined in L{tlslite.constants.NameType}.
351 The list will be empty if the on the wire extension had and empty
352 list while it will be None if the extension was empty.
353
354 @type extType: int
355 @ivar extType: numeric type of SNIExtension, i.e. 0
356
357 @type extData: bytearray
358 @ivar extData: raw representation of the extension
359 """
360
361 ServerName = namedtuple('ServerName', 'name_type name')
362
371
373 """
374 Return programmer-readable representation of extension
375
376 @rtype: str
377 """
378 return "SNIExtension(serverNames={0!r})".format(self.serverNames)
379
380 - def create(self, hostname=None, hostNames=None, serverNames=None):
381 """
382 Initializes an instance with provided hostname, host names or
383 raw server names.
384
385 Any of the parameters may be None, in that case the list inside the
386 extension won't be defined, if either hostNames or serverNames is
387 an empty list, then the extension will define a list of lenght 0.
388
389 If multiple parameters are specified at the same time, then the
390 resulting list of names will be concatenated in order of hostname,
391 hostNames and serverNames last.
392
393 @type hostname: bytearray
394 @param hostname: raw UTF-8 encoding of the host name
395
396 @type hostNames: list of bytearrays
397 @param hostNames: list of raw UTF-8 encoded host names
398
399 @type serverNames: list of L{ServerName}
400 @param serverNames: pairs of name_type and name encoded as a namedtuple
401
402 @rtype: L{SNIExtension}
403 """
404 if hostname is None and hostNames is None and serverNames is None:
405 self.serverNames = None
406 return self
407 else:
408 self.serverNames = []
409
410 if hostname:
411 self.serverNames += [SNIExtension.ServerName(NameType.host_name,\
412 hostname)]
413
414 if hostNames:
415 self.serverNames +=\
416 [SNIExtension.ServerName(NameType.host_name, x) for x in\
417 hostNames]
418
419 if serverNames:
420 self.serverNames += serverNames
421
422 return self
423
424 @property
426 """ Returns a simulated list of hostNames from the extension.
427
428 @rtype: tuple of bytearrays
429 """
430
431
432 if self.serverNames is None:
433 return tuple()
434 else:
435 return tuple([x.name for x in self.serverNames if \
436 x.name_type == NameType.host_name])
437
438 @hostNames.setter
440 """ Removes all host names from the extension and replaces them by
441 names in X{hostNames} parameter.
442
443 Newly added parameters will be added at the I{beginning} of the list
444 of extensions.
445
446 @type hostNames: iterable of bytearrays
447 @param hostNames: host names to replace the old server names of type 0
448 """
449
450 self.serverNames = \
451 [SNIExtension.ServerName(NameType.host_name, x) for x in \
452 hostNames] + \
453 [x for x in self.serverNames if \
454 x.name_type != NameType.host_name]
455
456 @hostNames.deleter
458 """ Remove all host names from extension, leaves other name types
459 unmodified
460 """
461 self.serverNames = [x for x in self.serverNames if \
462 x.name_type != NameType.host_name]
463
464 @property
466 """ raw encoding of extension data, without type and length header
467
468 @rtype: bytearray
469 """
470 if self.serverNames is None:
471 return bytearray(0)
472
473 w2 = Writer()
474 for server_name in self.serverNames:
475 w2.add(server_name.name_type, 1)
476 w2.add(len(server_name.name), 2)
477 w2.bytes += server_name.name
478
479
480 w = Writer()
481 w.add(len(w2.bytes), 2)
482 w.bytes += w2.bytes
483 return w.bytes
484
486 """ Returns encoded extension, as encoded on the wire
487
488 @rtype: bytearray
489 @return: an array of bytes formatted as they are supposed to be written
490 on the wire, including the type, length and extension data
491 """
492
493 raw_data = self.extData
494
495 w = Writer()
496 w.add(self.extType, 2)
497 w.add(len(raw_data), 2)
498 w.bytes += raw_data
499
500 return w.bytes
501
503 """
504 Deserialise the extension from on-the-wire data
505
506 The parser should not include the type or length of extension!
507
508 @type p: L{tlslite.util.codec.Parser}
509 @param p: data to be parsed
510
511 @rtype: L{SNIExtension}
512 @raise SyntaxError: when the internal sizes don't match the attached
513 data
514 """
515 if p.getRemainingLength() == 0:
516 return self
517
518 self.serverNames = []
519
520 p.startLengthCheck(2)
521 while not p.atLengthCheck():
522 sn_type = p.get(1)
523 sn_name = p.getVarBytes(2)
524 self.serverNames += [SNIExtension.ServerName(sn_type, sn_name)]
525 p.stopLengthCheck()
526
527 return self
528
530 """
531 This class handles the (client variant of) Certificate Type extension
532
533 See RFC 6091.
534
535 @type extType: int
536 @ivar extType: numeric type of Certificate Type extension, i.e. 9
537
538 @type extData: bytearray
539 @ivar extData: raw representation of the extension data
540
541 @type certTypes: list of int
542 @ivar certTypes: list of certificate type identifiers (each one byte long)
543 """
544
553
555 """
556 This class handles the Certificate Type extension (variant sent by server)
557 defined in RFC 6091.
558
559 @type extType: int
560 @ivar extType: binary type of Certificate Type extension, i.e. 9
561
562 @type extData: bytearray
563 @ivar extData: raw representation of the extension data
564
565 @type cert_type: int
566 @ivar cert_type: the certificate type selected by server
567 """
568
578
580 """ Return programmer-centric description of object
581
582 @rtype: str
583 """
584 return "ServerCertTypeExtension(cert_type={0!r})".format(self.cert_type)
585
586 @property
588 """
589 Return the raw encoding of the extension data
590
591 @rtype: bytearray
592 """
593 if self.cert_type is None:
594 return bytearray(0)
595
596 w = Writer()
597 w.add(self.cert_type, 1)
598
599 return w.bytes
600
602 """Create an instance for sending the extension to client.
603
604 @type val: int
605 @param val: selected type of certificate
606 """
607 self.cert_type = val
608 return self
609
611 """Parse the extension from on the wire format
612
613 @type p: L{Parser}
614 @param p: parser with data
615 """
616 self.cert_type = p.get(1)
617 if p.getRemainingLength() > 0:
618 raise SyntaxError()
619
620 return self
621
623 """
624 This class handles the Secure Remote Password protocol TLS extension
625 defined in RFC 5054.
626
627 @type extType: int
628 @ivar extType: numeric type of SRPExtension, i.e. 12
629
630 @type extData: bytearray
631 @ivar extData: raw representation of extension data
632
633 @type identity: bytearray
634 @ivar identity: UTF-8 encoding of user name
635 """
636
638 """
639 Create an instance of SRPExtension
640
641 See also: L{create} and L{parse}
642 """
643 super(SRPExtension, self).__init__(extType=ExtensionType.srp)
644
645 self.identity = None
646
648 """
649 Return programmer-centric description of extension
650
651 @rtype: str
652 """
653 return "SRPExtension(identity={0!r})".format(self.identity)
654
655 @property
657 """
658 Return raw data encoding of the extension
659
660 @rtype: bytearray
661 """
662
663 if self.identity is None:
664 return bytearray(0)
665
666 w = Writer()
667 w.add(len(self.identity), 1)
668 w.addFixSeq(self.identity, 1)
669
670 return w.bytes
671
672 - def create(self, identity=None):
673 """ Create and instance of SRPExtension with specified protocols
674
675 @type identity: bytearray
676 @param identity: UTF-8 encoded identity (user name) to be provided
677 to user. MUST be shorter than 2^8-1.
678
679 @raise ValueError: when the identity lenght is longer than 2^8-1
680 """
681
682 if identity is None:
683 return self
684
685 if len(identity) >= 2**8:
686 raise ValueError()
687
688 self.identity = identity
689 return self
690
692 """
693 Parse the extension from on the wire format
694
695 @type p: L{tlslite.util.codec.Parser}
696 @param p: data to be parsed
697
698 @raise SyntaxError: when the data is internally inconsistent
699
700 @rtype: L{SRPExtension}
701 """
702
703 self.identity = p.getVarBytes(1)
704
705 return self
706
708 """
709 This class handles the unofficial Next Protocol Negotiation TLS extension.
710
711 @type protocols: list of bytearrays
712 @ivar protocols: list of protocol names supported by the server
713
714 @type extType: int
715 @ivar extType: numeric type of NPNExtension, i.e. 13172
716
717 @type extData: bytearray
718 @ivar extData: raw representation of extension data
719 """
720
730
732 """
733 Create programmer-readable version of representation
734
735 @rtype: str
736 """
737 return "NPNExtension(protocols={0!r})".format(self.protocols)
738
739 @property
741 """ Return the raw data encoding of the extension
742
743 @rtype: bytearray
744 """
745 if self.protocols is None:
746 return bytearray(0)
747
748 w = Writer()
749 for prot in self.protocols:
750 w.add(len(prot), 1)
751 w.addFixSeq(prot, 1)
752
753 return w.bytes
754
755 - def create(self, protocols=None):
756 """ Create an instance of NPNExtension with specified protocols
757
758 @type protocols: list of bytearray
759 @param protocols: list of protocol names that are supported
760 """
761 self.protocols = protocols
762 return self
763
765 """ Parse the extension from on the wire format
766
767 @type p: L{tlslite.util.codec.Parser}
768 @param p: data to be parsed
769
770 @raise SyntaxError: when the size of the passed element doesn't match
771 the internal representation
772
773 @rtype: L{NPNExtension}
774 """
775 self.protocols = []
776
777 while p.getRemainingLength() > 0:
778 self.protocols += [p.getVarBytes(1)]
779
780 return self
781
783 """
784 This class handles the server side TACK extension (see
785 draft-perrin-tls-tack-02).
786
787 @type tacks: list
788 @ivar tacks: list of L{TACK}'s supported by server
789
790 @type activation_flags: int
791 @ivar activation_flags: activation flags for the tacks
792 """
793
794 - class TACK(object):
795 """
796 Implementation of the single TACK
797 """
799 """
800 Create a single TACK object
801 """
802 self.public_key = bytearray(64)
803 self.min_generation = 0
804 self.generation = 0
805 self.expiration = 0
806 self.target_hash = bytearray(32)
807 self.signature = bytearray(64)
808
810 """
811 Return programmmer readable representation of TACK object
812
813 @rtype: str
814 """
815 return "TACK(public_key={0!r}, min_generation={1!r}, "\
816 "generation={2!r}, expiration={3!r}, target_hash={4!r}, "\
817 "signature={5!r})".format(
818 self.public_key, self.min_generation,
819 self.generation, self.expiration, self.target_hash,
820 self.signature)
821
822 - def create(self, public_key, min_generation, generation, expiration,
823 target_hash, signature):
824 """
825 Initialise the TACK with data
826 """
827 self.public_key = public_key
828 self.min_generation = min_generation
829 self.generation = generation
830 self.expiration = expiration
831 self.target_hash = target_hash
832 self.signature = signature
833 return self
834
836 """
837 Convert the TACK into on the wire format
838
839 @rtype: bytearray
840 """
841 w = Writer()
842 if len(self.public_key) != 64:
843 raise TLSInternalError("Public_key must be 64 bytes long")
844 w.bytes += self.public_key
845 w.add(self.min_generation, 1)
846 w.add(self.generation, 1)
847 w.add(self.expiration, 4)
848 if len(self.target_hash) != 32:
849 raise TLSInternalError("Target_hash must be 32 bytes long")
850 w.bytes += self.target_hash
851 if len(self.signature) != 64:
852 raise TLSInternalError("Signature must be 64 bytes long")
853 w.bytes += self.signature
854 return w.bytes
855
857 """
858 Parse the TACK from on the wire format
859
860 @type p: L{tlslite.util.codec.Parser}
861 @param p: data to be parsed
862
863 @rtype: L{TACK}
864 @raise SyntaxError: when the internal sizes don't match the
865 provided data
866 """
867
868 self.public_key = p.getFixBytes(64)
869 self.min_generation = p.get(1)
870 self.generation = p.get(1)
871 self.expiration = p.get(4)
872 self.target_hash = p.getFixBytes(32)
873 self.signature = p.getFixBytes(64)
874 return self
875
877 """
878 Tests if the other object is equivalent to this TACK
879
880 Returns False for every object that's not a TACK
881 """
882 if hasattr(other, 'public_key') and\
883 hasattr(other, 'min_generation') and\
884 hasattr(other, 'generation') and\
885 hasattr(other, 'expiration') and\
886 hasattr(other, 'target_hash') and\
887 hasattr(other, 'signature'):
888 if self.public_key == other.public_key and\
889 self.min_generation == other.min_generation and\
890 self.generation == other.generation and\
891 self.expiration == other.expiration and\
892 self.target_hash == other.target_hash and\
893 self.signature == other.signature:
894 return True
895 else:
896 return False
897 else:
898 return False
899
901 """
902 Create an instance of TACKExtension
903
904 See also: L{create} and L{parse}
905 """
906 super(TACKExtension, self).__init__(extType=ExtensionType.tack)
907
908 self.tacks = []
909 self.activation_flags = 0
910
912 """
913 Create a programmer readable representation of TACK extension
914
915 @rtype: str
916 """
917 return "TACKExtension(activation_flags={0!r}, tacks={1!r})".format(
918 self.activation_flags, self.tacks)
919
920 @property
922 """
923 Return the raw data encoding of the extension
924
925 @rtype: bytearray
926 """
927 w2 = Writer()
928 for t in self.tacks:
929 w2.bytes += t.write()
930
931 w = Writer()
932 w.add(len(w2.bytes), 2)
933 w.bytes += w2.bytes
934 w.add(self.activation_flags, 1)
935 return w.bytes
936
937 - def create(self, tacks, activation_flags):
938 """
939 Initialize the instance of TACKExtension
940
941 @rtype: TACKExtension
942 """
943
944 self.tacks = tacks
945 self.activation_flags = activation_flags
946 return self
947
949 """
950 Parse the extension from on the wire format
951
952 @type p: L{tlslite.util.codec.Parser}
953 @param p: data to be parsed
954
955 @rtype: L{TACKExtension}
956 """
957 self.tacks = []
958
959 p.startLengthCheck(2)
960 while not p.atLengthCheck():
961 tack = TACKExtension.TACK().parse(p)
962 self.tacks += [tack]
963 p.stopLengthCheck()
964 self.activation_flags = p.get(1)
965
966 return self
967
969 """
970 Client side list of supported groups of (EC)DHE key exchage.
971
972 See RFC4492, RFC7027 and RFC-ietf-tls-negotiated-ff-dhe-10
973
974 @type groups: int
975 @ivar groups: list of groups that the client supports
976 """
977
982
997
999
1000 """
1001 Client side list of supported signature algorithms.
1002
1003 Should be used by server to select certificate and signing method for
1004 Server Key Exchange messages. In practice used only for the latter.
1005
1006 See RFC5246.
1007 """
1008
1015
1016 @property
1018 """
1019 Return raw encoding of the extension
1020
1021 @rtype: bytearray
1022 """
1023 if self.sigalgs is None:
1024 return bytearray(0)
1025
1026 writer = Writer()
1027
1028 writer.addVarTupleSeq(self.sigalgs, 1, 2)
1029 return writer.bytes
1030
1032 """
1033 Set the list of supported algorithm types
1034
1035 @type sigalgs: list of tuples
1036 @param sigalgs: list of pairs of a hash algorithm and signature
1037 algorithm
1038 """
1039 self.sigalgs = sigalgs
1040 return self
1041
1042 - def parse(self, parser):
1043 """
1044 Deserialise extension from on the wire data
1045
1046 @type parser: L{Parser}
1047 @rtype: SignatureAlgorithmsExtension
1048 """
1049 if parser.getRemainingLength() == 0:
1050 self.sigalgs = None
1051 return self
1052
1053 self.sigalgs = parser.getVarTupleList(1, 2, 2)
1054
1055 if parser.getRemainingLength() != 0:
1056 raise SyntaxError()
1057
1058 return self
1059
1062 """
1063 ClientHello message padding with a desired size.
1064
1065 Can be used to pad ClientHello messages to a desired size
1066 in order to avoid implementation bugs caused by certain
1067 ClientHello sizes.
1068
1069 See RFC7685.
1070 """
1071
1077
1078 @property
1080 """
1081 Return raw encoding of the extension.
1082
1083 @rtype: bytearray
1084 """
1085 return self.paddingData
1086
1088 """
1089 Set the padding size and create null byte padding of defined size.
1090
1091 @type size: int
1092 @param size: required padding size in bytes
1093 """
1094 self.paddingData = bytearray(size)
1095 return self
1096
1098 """
1099 Deserialise extension from on the wire data.
1100
1101 @type p: L{tlslite.util.codec.Parser}
1102 @param p: data to be parsed
1103
1104 @raise SyntaxError: when the size of the passed element doesn't match
1105 the internal representation
1106
1107 @rtype: L{TLSExtension}
1108 """
1109 self.paddingData = p.getFixBytes(p.getRemainingLength())
1110 return self
1111
1113 """
1114 Client and Server Hello secure renegotiation extension from RFC 5746
1115
1116 Should have an empty renegotiated_connection field in case of initial
1117 connection
1118 """
1119
1125
1126 @property
1128 """
1129 Return raw encoding of the extension.
1130
1131 @rtype: bytearray
1132 """
1133 if self.renegotiated_connection is None:
1134 return bytearray(0)
1135 writer = Writer()
1136 writer.add(len(self.renegotiated_connection), 1)
1137 writer.bytes += self.renegotiated_connection
1138 return writer.bytes
1139
1140 - def create(self, renegotiated_connection):
1141 """
1142 Set the finished message payload from previous connection.
1143
1144 @type renegotiated_connection: bytearray
1145 """
1146 self.renegotiated_connection = renegotiated_connection
1147 return self
1148
1149 - def parse(self, parser):
1150 """
1151 Deserialise extension from on the wire data.
1152
1153 @type parser: L{tlslite.util.codec.Parser}
1154 @param parser: data to be parsed
1155
1156 @rtype: L{RenegotiationInfoExtension}
1157 """
1158 if parser.getRemainingLength() == 0:
1159 self.renegotiated_connection = None
1160 else:
1161 self.renegotiated_connection = parser.getVarBytes(1)
1162
1163 return self
1164
1167 """
1168 Handling of Application Layer Protocol Negotiation extension from RFC 7301.
1169
1170 @type protocol_names: list of bytearrays
1171 @ivar protocol_names: list of protocol names acceptable or selected by peer
1172
1173 @type extType: int
1174 @ivar extType: numberic type of ALPNExtension, i.e. 16
1175
1176 @type extData: bytearray
1177 @ivar extData: raw encoding of the extension data
1178 """
1179
1181 """
1182 Create instance of ALPNExtension
1183
1184 See also: L{create} and L{parse}
1185 """
1186 super(ALPNExtension, self).__init__(extType=ExtensionType.alpn)
1187
1188 self.protocol_names = None
1189
1191 """
1192 Create programmer-readable representation of object
1193
1194 @rtype: str
1195 """
1196 return "ALPNExtension(protocol_names={0!r})".format(self.protocol_names)
1197
1198 @property
1200 """
1201 Return encoded payload of the extension
1202
1203 @rtype: bytearray
1204 """
1205 if self.protocol_names is None:
1206 return bytearray(0)
1207
1208 writer = Writer()
1209 for prot in self.protocol_names:
1210 writer.add(len(prot), 1)
1211 writer.bytes += prot
1212
1213 writer2 = Writer()
1214 writer2.add(len(writer.bytes), 2)
1215 writer2.bytes += writer.bytes
1216
1217 return writer2.bytes
1218
1219 - def create(self, protocol_names=None):
1220 """
1221 Create an instance of ALPNExtension with specified protocols
1222
1223 @type protocols: list of bytearray
1224 @param protocols: list of protocol names that are to be sent
1225 """
1226 self.protocol_names = protocol_names
1227 return self
1228
1229 - def parse(self, parser):
1230 """
1231 Parse the extension from on the wire format
1232
1233 @type parser: L{tlslite.util.codec.Parser}
1234 @param parser: data to be parsed as extension
1235
1236 @raise SyntaxError: when the encoding of the extension is self
1237 inconsistent
1238
1239 @rtype: L{ALPNExtension}
1240 """
1241 self.protocol_names = []
1242 parser.startLengthCheck(2)
1243 while not parser.atLengthCheck():
1244 name_len = parser.get(1)
1245 self.protocol_names.append(parser.getFixBytes(name_len))
1246 parser.stopLengthCheck()
1247 if parser.getRemainingLength() != 0:
1248 raise SyntaxError("Trailing data after protocol_name_list")
1249 return self
1250
1251
1252 -class StatusRequestExtension(TLSExtension):
1253 """
1254 Handling of the Certificate Status Request extension from RFC 6066.
1255
1256 @type status_type: int
1257 @ivar status_type: type of the status request
1258
1259 @type responder_id_list: list of bytearray
1260 @ivar responder_id_list: list of DER encoded OCSP responder identifiers
1261 that the client trusts
1262
1263 @type request_extensions: bytearray
1264 @ivar request_extensions: DER encoded list of OCSP extensions, as defined
1265 in RFC 2560
1266 """
1267
1268 - def __init__(self):
1269 super(StatusRequestExtension, self).__init__(
1270 extType=ExtensionType.status_request)
1271 """Create instance of StatusRequestExtension."""
1272 self.status_type = None
1273 self.responder_id_list = []
1274 self.request_extensions = bytearray()
1275
1276 - def __repr__(self):
1277 """
1278 Create programmer-readable representation of object
1279
1280 @rtype: str
1281 """
1282 return ("StatusRequestExtension(status_type={0}, "
1283 "responder_id_list={1!r}, "
1284 "request_extensions={2!r})").format(
1285 self.status_type, self.responder_id_list,
1286 self.request_extensions)
1287
1288 @property
1289 - def extData(self):
1290 """
1291 Return encoded payload of the extension.
1292
1293 @rtype: bytearray
1294 """
1295 if self.status_type is None:
1296 return bytearray()
1297
1298 writer = Writer()
1299 writer.add(self.status_type, 1)
1300 writer2 = Writer()
1301 for i in self.responder_id_list:
1302 writer2.add(len(i), 2)
1303 writer2.bytes += i
1304 writer.add(len(writer2.bytes), 2)
1305 writer.bytes += writer2.bytes
1306 writer.add(len(self.request_extensions), 2)
1307 writer.bytes += self.request_extensions
1308
1309 return writer.bytes
1310
1311 - def create(self, status_type=CertificateStatusType.ocsp,
1312 responder_id_list=tuple(),
1313 request_extensions=b''):
1314 """
1315 Create an instance of StatusRequestExtension with specified options.
1316
1317 @type status_type: int
1318 @param status_type: type of status returned
1319
1320 @type responder_id_list: list
1321 @param responder_id_list: list of encoded OCSP responder identifiers
1322 that the client trusts
1323
1324 @type request_extensions: bytearray
1325 @param request_extensions: DER encoding of requested OCSP extensions
1326 """
1327 self.status_type = status_type
1328 self.responder_id_list = list(responder_id_list)
1329 self.request_extensions = bytearray(request_extensions)
1330 return self
1331
1332 - def parse(self, parser):
1333 """
1334 Parse the extension from on the wire format.
1335
1336 @type parser: L{tlslite.util.codec.Parser}
1337 @param parser: data to be parsed as extension
1338
1339 @rtype: L{StatusRequestExtension}
1340 """
1341
1342 if parser.getRemainingLength() == 0:
1343 self.status_type = None
1344 self.responder_id_list = []
1345 self.request_extensions = bytearray()
1346 return self
1347
1348 self.status_type = parser.get(1)
1349 self.responder_id_list = []
1350 parser.startLengthCheck(2)
1351 while not parser.atLengthCheck():
1352 self.responder_id_list.append(parser.getVarBytes(2))
1353 parser.stopLengthCheck()
1354 self.request_extensions = parser.getVarBytes(2)
1355 if parser.getRemainingLength() != 0:
1356 raise SyntaxError("Trailing data after CertificateStatusRequest")
1357 return self
1358
1359
1360 TLSExtension._universalExtensions = \
1361 {
1362 ExtensionType.server_name: SNIExtension,
1363 ExtensionType.status_request: StatusRequestExtension,
1364 ExtensionType.cert_type: ClientCertTypeExtension,
1365 ExtensionType.supported_groups: SupportedGroupsExtension,
1366 ExtensionType.ec_point_formats: ECPointFormatsExtension,
1367 ExtensionType.srp: SRPExtension,
1368 ExtensionType.signature_algorithms: SignatureAlgorithmsExtension,
1369 ExtensionType.alpn: ALPNExtension,
1370 ExtensionType.supports_npn: NPNExtension,
1371 ExtensionType.client_hello_padding: PaddingExtension,
1372 ExtensionType.renegotiation_info: RenegotiationInfoExtension}
1373
1374 TLSExtension._serverExtensions = \
1375 {
1376 ExtensionType.cert_type: ServerCertTypeExtension,
1377 ExtensionType.tack: TACKExtension}
1378