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 if p.getRemainingLength():
528 raise SyntaxError()
529
530 return self
531
533 """
534 This class handles the (client variant of) Certificate Type extension
535
536 See RFC 6091.
537
538 @type extType: int
539 @ivar extType: numeric type of Certificate Type extension, i.e. 9
540
541 @type extData: bytearray
542 @ivar extData: raw representation of the extension data
543
544 @type certTypes: list of int
545 @ivar certTypes: list of certificate type identifiers (each one byte long)
546 """
547
556
558 """
559 This class handles the Certificate Type extension (variant sent by server)
560 defined in RFC 6091.
561
562 @type extType: int
563 @ivar extType: binary type of Certificate Type extension, i.e. 9
564
565 @type extData: bytearray
566 @ivar extData: raw representation of the extension data
567
568 @type cert_type: int
569 @ivar cert_type: the certificate type selected by server
570 """
571
581
583 """ Return programmer-centric description of object
584
585 @rtype: str
586 """
587 return "ServerCertTypeExtension(cert_type={0!r})".format(self.cert_type)
588
589 @property
591 """
592 Return the raw encoding of the extension data
593
594 @rtype: bytearray
595 """
596 if self.cert_type is None:
597 return bytearray(0)
598
599 w = Writer()
600 w.add(self.cert_type, 1)
601
602 return w.bytes
603
605 """Create an instance for sending the extension to client.
606
607 @type val: int
608 @param val: selected type of certificate
609 """
610 self.cert_type = val
611 return self
612
614 """Parse the extension from on the wire format
615
616 @type p: L{Parser}
617 @param p: parser with data
618 """
619 self.cert_type = p.get(1)
620 if p.getRemainingLength() > 0:
621 raise SyntaxError()
622
623 return self
624
626 """
627 This class handles the Secure Remote Password protocol TLS extension
628 defined in RFC 5054.
629
630 @type extType: int
631 @ivar extType: numeric type of SRPExtension, i.e. 12
632
633 @type extData: bytearray
634 @ivar extData: raw representation of extension data
635
636 @type identity: bytearray
637 @ivar identity: UTF-8 encoding of user name
638 """
639
641 """
642 Create an instance of SRPExtension
643
644 See also: L{create} and L{parse}
645 """
646 super(SRPExtension, self).__init__(extType=ExtensionType.srp)
647
648 self.identity = None
649
651 """
652 Return programmer-centric description of extension
653
654 @rtype: str
655 """
656 return "SRPExtension(identity={0!r})".format(self.identity)
657
658 @property
660 """
661 Return raw data encoding of the extension
662
663 @rtype: bytearray
664 """
665
666 if self.identity is None:
667 return bytearray(0)
668
669 w = Writer()
670 w.add(len(self.identity), 1)
671 w.addFixSeq(self.identity, 1)
672
673 return w.bytes
674
675 - def create(self, identity=None):
676 """ Create and instance of SRPExtension with specified protocols
677
678 @type identity: bytearray
679 @param identity: UTF-8 encoded identity (user name) to be provided
680 to user. MUST be shorter than 2^8-1.
681
682 @raise ValueError: when the identity lenght is longer than 2^8-1
683 """
684
685 if identity is None:
686 return self
687
688 if len(identity) >= 2**8:
689 raise ValueError()
690
691 self.identity = identity
692 return self
693
695 """
696 Parse the extension from on the wire format
697
698 @type p: L{tlslite.util.codec.Parser}
699 @param p: data to be parsed
700
701 @raise SyntaxError: when the data is internally inconsistent
702
703 @rtype: L{SRPExtension}
704 """
705
706 self.identity = p.getVarBytes(1)
707
708 return self
709
711 """
712 This class handles the unofficial Next Protocol Negotiation TLS extension.
713
714 @type protocols: list of bytearrays
715 @ivar protocols: list of protocol names supported by the server
716
717 @type extType: int
718 @ivar extType: numeric type of NPNExtension, i.e. 13172
719
720 @type extData: bytearray
721 @ivar extData: raw representation of extension data
722 """
723
733
735 """
736 Create programmer-readable version of representation
737
738 @rtype: str
739 """
740 return "NPNExtension(protocols={0!r})".format(self.protocols)
741
742 @property
744 """ Return the raw data encoding of the extension
745
746 @rtype: bytearray
747 """
748 if self.protocols is None:
749 return bytearray(0)
750
751 w = Writer()
752 for prot in self.protocols:
753 w.add(len(prot), 1)
754 w.addFixSeq(prot, 1)
755
756 return w.bytes
757
758 - def create(self, protocols=None):
759 """ Create an instance of NPNExtension with specified protocols
760
761 @type protocols: list of bytearray
762 @param protocols: list of protocol names that are supported
763 """
764 self.protocols = protocols
765 return self
766
768 """ Parse the extension from on the wire format
769
770 @type p: L{tlslite.util.codec.Parser}
771 @param p: data to be parsed
772
773 @raise SyntaxError: when the size of the passed element doesn't match
774 the internal representation
775
776 @rtype: L{NPNExtension}
777 """
778 self.protocols = []
779
780 while p.getRemainingLength() > 0:
781 self.protocols += [p.getVarBytes(1)]
782
783 return self
784
786 """
787 This class handles the server side TACK extension (see
788 draft-perrin-tls-tack-02).
789
790 @type tacks: list
791 @ivar tacks: list of L{TACK}'s supported by server
792
793 @type activation_flags: int
794 @ivar activation_flags: activation flags for the tacks
795 """
796
797 - class TACK(object):
798 """
799 Implementation of the single TACK
800 """
802 """
803 Create a single TACK object
804 """
805 self.public_key = bytearray(64)
806 self.min_generation = 0
807 self.generation = 0
808 self.expiration = 0
809 self.target_hash = bytearray(32)
810 self.signature = bytearray(64)
811
813 """
814 Return programmmer readable representation of TACK object
815
816 @rtype: str
817 """
818 return "TACK(public_key={0!r}, min_generation={1!r}, "\
819 "generation={2!r}, expiration={3!r}, target_hash={4!r}, "\
820 "signature={5!r})".format(
821 self.public_key, self.min_generation,
822 self.generation, self.expiration, self.target_hash,
823 self.signature)
824
825 - def create(self, public_key, min_generation, generation, expiration,
826 target_hash, signature):
827 """
828 Initialise the TACK with data
829 """
830 self.public_key = public_key
831 self.min_generation = min_generation
832 self.generation = generation
833 self.expiration = expiration
834 self.target_hash = target_hash
835 self.signature = signature
836 return self
837
839 """
840 Convert the TACK into on the wire format
841
842 @rtype: bytearray
843 """
844 w = Writer()
845 if len(self.public_key) != 64:
846 raise TLSInternalError("Public_key must be 64 bytes long")
847 w.bytes += self.public_key
848 w.add(self.min_generation, 1)
849 w.add(self.generation, 1)
850 w.add(self.expiration, 4)
851 if len(self.target_hash) != 32:
852 raise TLSInternalError("Target_hash must be 32 bytes long")
853 w.bytes += self.target_hash
854 if len(self.signature) != 64:
855 raise TLSInternalError("Signature must be 64 bytes long")
856 w.bytes += self.signature
857 return w.bytes
858
860 """
861 Parse the TACK from on the wire format
862
863 @type p: L{tlslite.util.codec.Parser}
864 @param p: data to be parsed
865
866 @rtype: L{TACK}
867 @raise SyntaxError: when the internal sizes don't match the
868 provided data
869 """
870
871 self.public_key = p.getFixBytes(64)
872 self.min_generation = p.get(1)
873 self.generation = p.get(1)
874 self.expiration = p.get(4)
875 self.target_hash = p.getFixBytes(32)
876 self.signature = p.getFixBytes(64)
877 return self
878
880 """
881 Tests if the other object is equivalent to this TACK
882
883 Returns False for every object that's not a TACK
884 """
885 if hasattr(other, 'public_key') and\
886 hasattr(other, 'min_generation') and\
887 hasattr(other, 'generation') and\
888 hasattr(other, 'expiration') and\
889 hasattr(other, 'target_hash') and\
890 hasattr(other, 'signature'):
891 if self.public_key == other.public_key and\
892 self.min_generation == other.min_generation and\
893 self.generation == other.generation and\
894 self.expiration == other.expiration and\
895 self.target_hash == other.target_hash and\
896 self.signature == other.signature:
897 return True
898 else:
899 return False
900 else:
901 return False
902
904 """
905 Create an instance of TACKExtension
906
907 See also: L{create} and L{parse}
908 """
909 super(TACKExtension, self).__init__(extType=ExtensionType.tack)
910
911 self.tacks = []
912 self.activation_flags = 0
913
915 """
916 Create a programmer readable representation of TACK extension
917
918 @rtype: str
919 """
920 return "TACKExtension(activation_flags={0!r}, tacks={1!r})".format(
921 self.activation_flags, self.tacks)
922
923 @property
925 """
926 Return the raw data encoding of the extension
927
928 @rtype: bytearray
929 """
930 w2 = Writer()
931 for t in self.tacks:
932 w2.bytes += t.write()
933
934 w = Writer()
935 w.add(len(w2.bytes), 2)
936 w.bytes += w2.bytes
937 w.add(self.activation_flags, 1)
938 return w.bytes
939
940 - def create(self, tacks, activation_flags):
941 """
942 Initialize the instance of TACKExtension
943
944 @rtype: TACKExtension
945 """
946
947 self.tacks = tacks
948 self.activation_flags = activation_flags
949 return self
950
952 """
953 Parse the extension from on the wire format
954
955 @type p: L{tlslite.util.codec.Parser}
956 @param p: data to be parsed
957
958 @rtype: L{TACKExtension}
959 """
960 self.tacks = []
961
962 p.startLengthCheck(2)
963 while not p.atLengthCheck():
964 tack = TACKExtension.TACK().parse(p)
965 self.tacks += [tack]
966 p.stopLengthCheck()
967 self.activation_flags = p.get(1)
968
969 return self
970
972 """
973 Client side list of supported groups of (EC)DHE key exchage.
974
975 See RFC4492, RFC7027 and RFC-ietf-tls-negotiated-ff-dhe-10
976
977 @type groups: int
978 @ivar groups: list of groups that the client supports
979 """
980
985
1000
1002
1003 """
1004 Client side list of supported signature algorithms.
1005
1006 Should be used by server to select certificate and signing method for
1007 Server Key Exchange messages. In practice used only for the latter.
1008
1009 See RFC5246.
1010 """
1011
1018
1019 @property
1021 """
1022 Return raw encoding of the extension
1023
1024 @rtype: bytearray
1025 """
1026 if self.sigalgs is None:
1027 return bytearray(0)
1028
1029 writer = Writer()
1030
1031 writer.addVarTupleSeq(self.sigalgs, 1, 2)
1032 return writer.bytes
1033
1035 """
1036 Set the list of supported algorithm types
1037
1038 @type sigalgs: list of tuples
1039 @param sigalgs: list of pairs of a hash algorithm and signature
1040 algorithm
1041 """
1042 self.sigalgs = sigalgs
1043 return self
1044
1045 - def parse(self, parser):
1046 """
1047 Deserialise extension from on the wire data
1048
1049 @type parser: L{Parser}
1050 @rtype: SignatureAlgorithmsExtension
1051 """
1052 if parser.getRemainingLength() == 0:
1053 self.sigalgs = None
1054 return self
1055
1056 self.sigalgs = parser.getVarTupleList(1, 2, 2)
1057
1058 if parser.getRemainingLength() != 0:
1059 raise SyntaxError()
1060
1061 return self
1062
1065 """
1066 ClientHello message padding with a desired size.
1067
1068 Can be used to pad ClientHello messages to a desired size
1069 in order to avoid implementation bugs caused by certain
1070 ClientHello sizes.
1071
1072 See RFC7685.
1073 """
1074
1080
1081 @property
1083 """
1084 Return raw encoding of the extension.
1085
1086 @rtype: bytearray
1087 """
1088 return self.paddingData
1089
1091 """
1092 Set the padding size and create null byte padding of defined size.
1093
1094 @type size: int
1095 @param size: required padding size in bytes
1096 """
1097 self.paddingData = bytearray(size)
1098 return self
1099
1101 """
1102 Deserialise extension from on the wire data.
1103
1104 @type p: L{tlslite.util.codec.Parser}
1105 @param p: data to be parsed
1106
1107 @raise SyntaxError: when the size of the passed element doesn't match
1108 the internal representation
1109
1110 @rtype: L{TLSExtension}
1111 """
1112 self.paddingData = p.getFixBytes(p.getRemainingLength())
1113 return self
1114
1116 """
1117 Client and Server Hello secure renegotiation extension from RFC 5746
1118
1119 Should have an empty renegotiated_connection field in case of initial
1120 connection
1121 """
1122
1128
1129 @property
1131 """
1132 Return raw encoding of the extension.
1133
1134 @rtype: bytearray
1135 """
1136 if self.renegotiated_connection is None:
1137 return bytearray(0)
1138 writer = Writer()
1139 writer.add(len(self.renegotiated_connection), 1)
1140 writer.bytes += self.renegotiated_connection
1141 return writer.bytes
1142
1143 - def create(self, renegotiated_connection):
1144 """
1145 Set the finished message payload from previous connection.
1146
1147 @type renegotiated_connection: bytearray
1148 """
1149 self.renegotiated_connection = renegotiated_connection
1150 return self
1151
1152 - def parse(self, parser):
1153 """
1154 Deserialise extension from on the wire data.
1155
1156 @type parser: L{tlslite.util.codec.Parser}
1157 @param parser: data to be parsed
1158
1159 @rtype: L{RenegotiationInfoExtension}
1160 """
1161 if parser.getRemainingLength() == 0:
1162 self.renegotiated_connection = None
1163 else:
1164 self.renegotiated_connection = parser.getVarBytes(1)
1165
1166 return self
1167
1170 """
1171 Handling of Application Layer Protocol Negotiation extension from RFC 7301.
1172
1173 @type protocol_names: list of bytearrays
1174 @ivar protocol_names: list of protocol names acceptable or selected by peer
1175
1176 @type extType: int
1177 @ivar extType: numberic type of ALPNExtension, i.e. 16
1178
1179 @type extData: bytearray
1180 @ivar extData: raw encoding of the extension data
1181 """
1182
1184 """
1185 Create instance of ALPNExtension
1186
1187 See also: L{create} and L{parse}
1188 """
1189 super(ALPNExtension, self).__init__(extType=ExtensionType.alpn)
1190
1191 self.protocol_names = None
1192
1194 """
1195 Create programmer-readable representation of object
1196
1197 @rtype: str
1198 """
1199 return "ALPNExtension(protocol_names={0!r})".format(self.protocol_names)
1200
1201 @property
1203 """
1204 Return encoded payload of the extension
1205
1206 @rtype: bytearray
1207 """
1208 if self.protocol_names is None:
1209 return bytearray(0)
1210
1211 writer = Writer()
1212 for prot in self.protocol_names:
1213 writer.add(len(prot), 1)
1214 writer.bytes += prot
1215
1216 writer2 = Writer()
1217 writer2.add(len(writer.bytes), 2)
1218 writer2.bytes += writer.bytes
1219
1220 return writer2.bytes
1221
1222 - def create(self, protocol_names=None):
1223 """
1224 Create an instance of ALPNExtension with specified protocols
1225
1226 @type protocols: list of bytearray
1227 @param protocols: list of protocol names that are to be sent
1228 """
1229 self.protocol_names = protocol_names
1230 return self
1231
1232 - def parse(self, parser):
1233 """
1234 Parse the extension from on the wire format
1235
1236 @type parser: L{tlslite.util.codec.Parser}
1237 @param parser: data to be parsed as extension
1238
1239 @raise SyntaxError: when the encoding of the extension is self
1240 inconsistent
1241
1242 @rtype: L{ALPNExtension}
1243 """
1244 self.protocol_names = []
1245 parser.startLengthCheck(2)
1246 while not parser.atLengthCheck():
1247 name_len = parser.get(1)
1248 self.protocol_names.append(parser.getFixBytes(name_len))
1249 parser.stopLengthCheck()
1250 if parser.getRemainingLength() != 0:
1251 raise SyntaxError("Trailing data after protocol_name_list")
1252 return self
1253
1254
1255 -class StatusRequestExtension(TLSExtension):
1256 """
1257 Handling of the Certificate Status Request extension from RFC 6066.
1258
1259 @type status_type: int
1260 @ivar status_type: type of the status request
1261
1262 @type responder_id_list: list of bytearray
1263 @ivar responder_id_list: list of DER encoded OCSP responder identifiers
1264 that the client trusts
1265
1266 @type request_extensions: bytearray
1267 @ivar request_extensions: DER encoded list of OCSP extensions, as defined
1268 in RFC 2560
1269 """
1270
1271 - def __init__(self):
1272 super(StatusRequestExtension, self).__init__(
1273 extType=ExtensionType.status_request)
1274 """Create instance of StatusRequestExtension."""
1275 self.status_type = None
1276 self.responder_id_list = []
1277 self.request_extensions = bytearray()
1278
1279 - def __repr__(self):
1280 """
1281 Create programmer-readable representation of object
1282
1283 @rtype: str
1284 """
1285 return ("StatusRequestExtension(status_type={0}, "
1286 "responder_id_list={1!r}, "
1287 "request_extensions={2!r})").format(
1288 self.status_type, self.responder_id_list,
1289 self.request_extensions)
1290
1291 @property
1292 - def extData(self):
1293 """
1294 Return encoded payload of the extension.
1295
1296 @rtype: bytearray
1297 """
1298 if self.status_type is None:
1299 return bytearray()
1300
1301 writer = Writer()
1302 writer.add(self.status_type, 1)
1303 writer2 = Writer()
1304 for i in self.responder_id_list:
1305 writer2.add(len(i), 2)
1306 writer2.bytes += i
1307 writer.add(len(writer2.bytes), 2)
1308 writer.bytes += writer2.bytes
1309 writer.add(len(self.request_extensions), 2)
1310 writer.bytes += self.request_extensions
1311
1312 return writer.bytes
1313
1314 - def create(self, status_type=CertificateStatusType.ocsp,
1315 responder_id_list=tuple(),
1316 request_extensions=b''):
1317 """
1318 Create an instance of StatusRequestExtension with specified options.
1319
1320 @type status_type: int
1321 @param status_type: type of status returned
1322
1323 @type responder_id_list: list
1324 @param responder_id_list: list of encoded OCSP responder identifiers
1325 that the client trusts
1326
1327 @type request_extensions: bytearray
1328 @param request_extensions: DER encoding of requested OCSP extensions
1329 """
1330 self.status_type = status_type
1331 self.responder_id_list = list(responder_id_list)
1332 self.request_extensions = bytearray(request_extensions)
1333 return self
1334
1335 - def parse(self, parser):
1336 """
1337 Parse the extension from on the wire format.
1338
1339 @type parser: L{tlslite.util.codec.Parser}
1340 @param parser: data to be parsed as extension
1341
1342 @rtype: L{StatusRequestExtension}
1343 """
1344
1345 if parser.getRemainingLength() == 0:
1346 self.status_type = None
1347 self.responder_id_list = []
1348 self.request_extensions = bytearray()
1349 return self
1350
1351 self.status_type = parser.get(1)
1352 self.responder_id_list = []
1353 parser.startLengthCheck(2)
1354 while not parser.atLengthCheck():
1355 self.responder_id_list.append(parser.getVarBytes(2))
1356 parser.stopLengthCheck()
1357 self.request_extensions = parser.getVarBytes(2)
1358 if parser.getRemainingLength() != 0:
1359 raise SyntaxError("Trailing data after CertificateStatusRequest")
1360 return self
1361
1362
1363 TLSExtension._universalExtensions = \
1364 {
1365 ExtensionType.server_name: SNIExtension,
1366 ExtensionType.status_request: StatusRequestExtension,
1367 ExtensionType.cert_type: ClientCertTypeExtension,
1368 ExtensionType.supported_groups: SupportedGroupsExtension,
1369 ExtensionType.ec_point_formats: ECPointFormatsExtension,
1370 ExtensionType.srp: SRPExtension,
1371 ExtensionType.signature_algorithms: SignatureAlgorithmsExtension,
1372 ExtensionType.alpn: ALPNExtension,
1373 ExtensionType.supports_npn: NPNExtension,
1374 ExtensionType.client_hello_padding: PaddingExtension,
1375 ExtensionType.renegotiation_info: RenegotiationInfoExtension}
1376
1377 TLSExtension._serverExtensions = \
1378 {
1379 ExtensionType.cert_type: ServerCertTypeExtension,
1380 ExtensionType.tack: TACKExtension}
1381