?????????????? ?????????????? ?????????????? ?????????????? __init__.py000064400000002303152572326550006667 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function from .version import __version__, __version_info__ __all__ = [ '__version__', '__version_info__', 'load_order', ] def load_order(): """ Returns a list of the module and sub-module names for asn1crypto in dependency load order, for the sake of live reloading code :return: A list of unicode strings of module names, as they would appear in sys.modules, ordered by which module should be reloaded first """ return [ 'asn1crypto._errors', 'asn1crypto._int', 'asn1crypto._ordereddict', 'asn1crypto._teletex_codec', 'asn1crypto._types', 'asn1crypto._inet', 'asn1crypto._iri', 'asn1crypto.version', 'asn1crypto.pem', 'asn1crypto.util', 'asn1crypto.parser', 'asn1crypto.core', 'asn1crypto.algos', 'asn1crypto.keys', 'asn1crypto.x509', 'asn1crypto.crl', 'asn1crypto.csr', 'asn1crypto.ocsp', 'asn1crypto.cms', 'asn1crypto.pdf', 'asn1crypto.pkcs12', 'asn1crypto.tsp', 'asn1crypto', ] _errors.py000064400000002056152572326550006610 0ustar00# coding: utf-8 """ Exports the following items: - unwrap() - APIException() """ from __future__ import unicode_literals, division, absolute_import, print_function import re import textwrap class APIException(Exception): """ An exception indicating an API has been removed from asn1crypto """ pass def unwrap(string, *params): """ Takes a multi-line string and does the following: - dedents - converts newlines with text before and after into a single line - strips leading and trailing whitespace :param string: The string to format :param *params: Params to interpolate into the string :return: The formatted string """ output = textwrap.dedent(string) # Unwrap lines, taking into account bulleted lists, ordered lists and # underlines consisting of = signs if output.find('\n') != -1: output = re.sub('(?<=\\S)\n(?=[^ \n\t\\d\\*\\-=])', ' ', output) if params: output = output % params output = output.strip() return output _inet.py000064400000011065152572326550006233 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import socket import struct from ._errors import unwrap from ._types import byte_cls, bytes_to_list, str_cls, type_name def inet_ntop(address_family, packed_ip): """ Windows compatibility shim for socket.inet_ntop(). :param address_family: socket.AF_INET for IPv4 or socket.AF_INET6 for IPv6 :param packed_ip: A byte string of the network form of an IP address :return: A unicode string of the IP address """ if address_family not in set([socket.AF_INET, socket.AF_INET6]): raise ValueError(unwrap( ''' address_family must be socket.AF_INET (%s) or socket.AF_INET6 (%s), not %s ''', repr(socket.AF_INET), repr(socket.AF_INET6), repr(address_family) )) if not isinstance(packed_ip, byte_cls): raise TypeError(unwrap( ''' packed_ip must be a byte string, not %s ''', type_name(packed_ip) )) required_len = 4 if address_family == socket.AF_INET else 16 if len(packed_ip) != required_len: raise ValueError(unwrap( ''' packed_ip must be %d bytes long - is %d ''', required_len, len(packed_ip) )) if address_family == socket.AF_INET: return '%d.%d.%d.%d' % tuple(bytes_to_list(packed_ip)) octets = struct.unpack(b'!HHHHHHHH', packed_ip) runs_of_zero = {} longest_run = 0 zero_index = None for i, octet in enumerate(octets + (-1,)): if octet != 0: if zero_index is not None: length = i - zero_index if length not in runs_of_zero: runs_of_zero[length] = zero_index longest_run = max(longest_run, length) zero_index = None elif zero_index is None: zero_index = i hexed = [hex(o)[2:] for o in octets] if longest_run < 2: return ':'.join(hexed) zero_start = runs_of_zero[longest_run] zero_end = zero_start + longest_run return ':'.join(hexed[:zero_start]) + '::' + ':'.join(hexed[zero_end:]) def inet_pton(address_family, ip_string): """ Windows compatibility shim for socket.inet_ntop(). :param address_family: socket.AF_INET for IPv4 or socket.AF_INET6 for IPv6 :param ip_string: A unicode string of an IP address :return: A byte string of the network form of the IP address """ if address_family not in set([socket.AF_INET, socket.AF_INET6]): raise ValueError(unwrap( ''' address_family must be socket.AF_INET (%s) or socket.AF_INET6 (%s), not %s ''', repr(socket.AF_INET), repr(socket.AF_INET6), repr(address_family) )) if not isinstance(ip_string, str_cls): raise TypeError(unwrap( ''' ip_string must be a unicode string, not %s ''', type_name(ip_string) )) if address_family == socket.AF_INET: octets = ip_string.split('.') error = len(octets) != 4 if not error: ints = [] for o in octets: o = int(o) if o > 255 or o < 0: error = True break ints.append(o) if error: raise ValueError(unwrap( ''' ip_string must be a dotted string with four integers in the range of 0 to 255, got %s ''', repr(ip_string) )) return struct.pack(b'!BBBB', *ints) error = False omitted = ip_string.count('::') if omitted > 1: error = True elif omitted == 0: octets = ip_string.split(':') error = len(octets) != 8 else: begin, end = ip_string.split('::') begin_octets = begin.split(':') end_octets = end.split(':') missing = 8 - len(begin_octets) - len(end_octets) octets = begin_octets + (['0'] * missing) + end_octets if not error: ints = [] for o in octets: o = int(o, 16) if o > 65535 or o < 0: error = True break ints.append(o) return struct.pack(b'!HHHHHHHH', *ints) raise ValueError(unwrap( ''' ip_string must be a valid ipv6 string, got %s ''', repr(ip_string) )) _int.py000064400000000756152572326550006073 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function def fill_width(bytes_, width): """ Ensure a byte string representing a positive integer is a specific width (in bytes) :param bytes_: The integer byte string :param width: The desired width as an integer :return: A byte string of the width specified """ while len(bytes_) < width: bytes_ = b'\x00' + bytes_ return bytes_ _iri.py000064400000021035152572326550006055 0ustar00# coding: utf-8 """ Functions to convert unicode IRIs into ASCII byte string URIs and back. Exports the following items: - iri_to_uri() - uri_to_iri() """ from __future__ import unicode_literals, division, absolute_import, print_function from encodings import idna # noqa import codecs import re import sys from ._errors import unwrap from ._types import byte_cls, str_cls, type_name, bytes_to_list, int_types if sys.version_info < (3,): from urlparse import urlsplit, urlunsplit from urllib import ( quote as urlquote, unquote as unquote_to_bytes, ) else: from urllib.parse import ( quote as urlquote, unquote_to_bytes, urlsplit, urlunsplit, ) def iri_to_uri(value, normalize=False): """ Encodes a unicode IRI into an ASCII byte string URI :param value: A unicode string of an IRI :param normalize: A bool that controls URI normalization :return: A byte string of the ASCII-encoded URI """ if not isinstance(value, str_cls): raise TypeError(unwrap( ''' value must be a unicode string, not %s ''', type_name(value) )) scheme = None # Python 2.6 doesn't split properly is the URL doesn't start with http:// or https:// if sys.version_info < (2, 7) and not value.startswith('http://') and not value.startswith('https://'): real_prefix = None prefix_match = re.match('^[^:]*://', value) if prefix_match: real_prefix = prefix_match.group(0) value = 'http://' + value[len(real_prefix):] parsed = urlsplit(value) if real_prefix: value = real_prefix + value[7:] scheme = _urlquote(real_prefix[:-3]) else: parsed = urlsplit(value) if scheme is None: scheme = _urlquote(parsed.scheme) hostname = parsed.hostname if hostname is not None: hostname = hostname.encode('idna') # RFC 3986 allows userinfo to contain sub-delims username = _urlquote(parsed.username, safe='!$&\'()*+,;=') password = _urlquote(parsed.password, safe='!$&\'()*+,;=') port = parsed.port if port is not None: port = str_cls(port).encode('ascii') netloc = b'' if username is not None: netloc += username if password: netloc += b':' + password netloc += b'@' if hostname is not None: netloc += hostname if port is not None: default_http = scheme == b'http' and port == b'80' default_https = scheme == b'https' and port == b'443' if not normalize or (not default_http and not default_https): netloc += b':' + port # RFC 3986 allows a path to contain sub-delims, plus "@" and ":" path = _urlquote(parsed.path, safe='/!$&\'()*+,;=@:') # RFC 3986 allows the query to contain sub-delims, plus "@", ":" , "/" and "?" query = _urlquote(parsed.query, safe='/?!$&\'()*+,;=@:') # RFC 3986 allows the fragment to contain sub-delims, plus "@", ":" , "/" and "?" fragment = _urlquote(parsed.fragment, safe='/?!$&\'()*+,;=@:') if normalize and query is None and fragment is None and path == b'/': path = None # Python 2.7 compat if path is None: path = '' output = urlunsplit((scheme, netloc, path, query, fragment)) if isinstance(output, str_cls): output = output.encode('latin1') return output def uri_to_iri(value): """ Converts an ASCII URI byte string into a unicode IRI :param value: An ASCII-encoded byte string of the URI :return: A unicode string of the IRI """ if not isinstance(value, byte_cls): raise TypeError(unwrap( ''' value must be a byte string, not %s ''', type_name(value) )) parsed = urlsplit(value) scheme = parsed.scheme if scheme is not None: scheme = scheme.decode('ascii') username = _urlunquote(parsed.username, remap=[':', '@']) password = _urlunquote(parsed.password, remap=[':', '@']) hostname = parsed.hostname if hostname: hostname = hostname.decode('idna') port = parsed.port if port and not isinstance(port, int_types): port = port.decode('ascii') netloc = '' if username is not None: netloc += username if password: netloc += ':' + password netloc += '@' if hostname is not None: netloc += hostname if port is not None: netloc += ':' + str_cls(port) path = _urlunquote(parsed.path, remap=['/'], preserve=True) query = _urlunquote(parsed.query, remap=['&', '='], preserve=True) fragment = _urlunquote(parsed.fragment) return urlunsplit((scheme, netloc, path, query, fragment)) def _iri_utf8_errors_handler(exc): """ Error handler for decoding UTF-8 parts of a URI into an IRI. Leaves byte sequences encoded in %XX format, but as part of a unicode string. :param exc: The UnicodeDecodeError exception :return: A 2-element tuple of (replacement unicode string, integer index to resume at) """ bytes_as_ints = bytes_to_list(exc.object[exc.start:exc.end]) replacements = ['%%%02x' % num for num in bytes_as_ints] return (''.join(replacements), exc.end) codecs.register_error('iriutf8', _iri_utf8_errors_handler) def _urlquote(string, safe=''): """ Quotes a unicode string for use in a URL :param string: A unicode string :param safe: A unicode string of character to not encode :return: None (if string is None) or an ASCII byte string of the quoted string """ if string is None or string == '': return None # Anything already hex quoted is pulled out of the URL and unquoted if # possible escapes = [] if re.search('%[0-9a-fA-F]{2}', string): # Try to unquote any percent values, restoring them if they are not # valid UTF-8. Also, requote any safe chars since encoded versions of # those are functionally different than the unquoted ones. def _try_unescape(match): byte_string = unquote_to_bytes(match.group(0)) unicode_string = byte_string.decode('utf-8', 'iriutf8') for safe_char in list(safe): unicode_string = unicode_string.replace(safe_char, '%%%02x' % ord(safe_char)) return unicode_string string = re.sub('(?:%[0-9a-fA-F]{2})+', _try_unescape, string) # Once we have the minimal set of hex quoted values, removed them from # the string so that they are not double quoted def _extract_escape(match): escapes.append(match.group(0).encode('ascii')) return '\x00' string = re.sub('%[0-9a-fA-F]{2}', _extract_escape, string) output = urlquote(string.encode('utf-8'), safe=safe.encode('utf-8')) if not isinstance(output, byte_cls): output = output.encode('ascii') # Restore the existing quoted values that we extracted if len(escapes) > 0: def _return_escape(_): return escapes.pop(0) output = re.sub(b'%00', _return_escape, output) return output def _urlunquote(byte_string, remap=None, preserve=None): """ Unquotes a URI portion from a byte string into unicode using UTF-8 :param byte_string: A byte string of the data to unquote :param remap: A list of characters (as unicode) that should be re-mapped to a %XX encoding. This is used when characters are not valid in part of a URL. :param preserve: A bool - indicates that the chars to be remapped if they occur in non-hex form, should be preserved. E.g. / for URL path. :return: A unicode string """ if byte_string is None: return byte_string if byte_string == b'': return '' if preserve: replacements = ['\x1A', '\x1C', '\x1D', '\x1E', '\x1F'] preserve_unmap = {} for char in remap: replacement = replacements.pop(0) preserve_unmap[replacement] = char byte_string = byte_string.replace(char.encode('ascii'), replacement.encode('ascii')) byte_string = unquote_to_bytes(byte_string) if remap: for char in remap: byte_string = byte_string.replace(char.encode('ascii'), ('%%%02x' % ord(char)).encode('ascii')) output = byte_string.decode('utf-8', 'iriutf8') if preserve: for replacement, original in preserve_unmap.items(): output = output.replace(replacement, original) return output _ordereddict.py000064400000010665152572326550007571 0ustar00# Copyright (c) 2009 Raymond Hettinger # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation files # (the "Software"), to deal in the Software without restriction, # including without limitation the rights to use, copy, modify, merge, # publish, distribute, sublicense, and/or sell copies of the Software, # and to permit persons to whom the Software is furnished to do so, # subject to the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. import sys if not sys.version_info < (2, 7): from collections import OrderedDict else: from UserDict import DictMixin class OrderedDict(dict, DictMixin): def __init__(self, *args, **kwds): if len(args) > 1: raise TypeError('expected at most 1 arguments, got %d' % len(args)) try: self.__end except AttributeError: self.clear() self.update(*args, **kwds) def clear(self): self.__end = end = [] end += [None, end, end] # sentinel node for doubly linked list self.__map = {} # key --> [key, prev, next] dict.clear(self) def __setitem__(self, key, value): if key not in self: end = self.__end curr = end[1] curr[2] = end[1] = self.__map[key] = [key, curr, end] dict.__setitem__(self, key, value) def __delitem__(self, key): dict.__delitem__(self, key) key, prev, next_ = self.__map.pop(key) prev[2] = next_ next_[1] = prev def __iter__(self): end = self.__end curr = end[2] while curr is not end: yield curr[0] curr = curr[2] def __reversed__(self): end = self.__end curr = end[1] while curr is not end: yield curr[0] curr = curr[1] def popitem(self, last=True): if not self: raise KeyError('dictionary is empty') if last: key = reversed(self).next() else: key = iter(self).next() value = self.pop(key) return key, value def __reduce__(self): items = [[k, self[k]] for k in self] tmp = self.__map, self.__end del self.__map, self.__end inst_dict = vars(self).copy() self.__map, self.__end = tmp if inst_dict: return (self.__class__, (items,), inst_dict) return self.__class__, (items,) def keys(self): return list(self) setdefault = DictMixin.setdefault update = DictMixin.update pop = DictMixin.pop values = DictMixin.values items = DictMixin.items iterkeys = DictMixin.iterkeys itervalues = DictMixin.itervalues iteritems = DictMixin.iteritems def __repr__(self): if not self: return '%s()' % (self.__class__.__name__,) return '%s(%r)' % (self.__class__.__name__, self.items()) def copy(self): return self.__class__(self) @classmethod def fromkeys(cls, iterable, value=None): d = cls() for key in iterable: d[key] = value return d def __eq__(self, other): if isinstance(other, OrderedDict): if len(self) != len(other): return False for p, q in zip(self.items(), other.items()): if p != q: return False return True return dict.__eq__(self, other) def __ne__(self, other): return not self == other _teletex_codec.py000064400000011675152572326550010112 0ustar00# coding: utf-8 """ Implementation of the teletex T.61 codec. Exports the following items: - register() """ from __future__ import unicode_literals, division, absolute_import, print_function import codecs class TeletexCodec(codecs.Codec): def encode(self, input_, errors='strict'): return codecs.charmap_encode(input_, errors, ENCODING_TABLE) def decode(self, input_, errors='strict'): return codecs.charmap_decode(input_, errors, DECODING_TABLE) class TeletexIncrementalEncoder(codecs.IncrementalEncoder): def encode(self, input_, final=False): return codecs.charmap_encode(input_, self.errors, ENCODING_TABLE)[0] class TeletexIncrementalDecoder(codecs.IncrementalDecoder): def decode(self, input_, final=False): return codecs.charmap_decode(input_, self.errors, DECODING_TABLE)[0] class TeletexStreamWriter(TeletexCodec, codecs.StreamWriter): pass class TeletexStreamReader(TeletexCodec, codecs.StreamReader): pass def teletex_search_function(name): """ Search function for teletex codec that is passed to codecs.register() """ if name != 'teletex': return None return codecs.CodecInfo( name='teletex', encode=TeletexCodec().encode, decode=TeletexCodec().decode, incrementalencoder=TeletexIncrementalEncoder, incrementaldecoder=TeletexIncrementalDecoder, streamreader=TeletexStreamReader, streamwriter=TeletexStreamWriter, ) def register(): """ Registers the teletex codec """ codecs.register(teletex_search_function) # http://en.wikipedia.org/wiki/ITU_T.61 DECODING_TABLE = ( '\u0000' '\u0001' '\u0002' '\u0003' '\u0004' '\u0005' '\u0006' '\u0007' '\u0008' '\u0009' '\u000A' '\u000B' '\u000C' '\u000D' '\u000E' '\u000F' '\u0010' '\u0011' '\u0012' '\u0013' '\u0014' '\u0015' '\u0016' '\u0017' '\u0018' '\u0019' '\u001A' '\u001B' '\u001C' '\u001D' '\u001E' '\u001F' '\u0020' '\u0021' '\u0022' '\ufffe' '\ufffe' '\u0025' '\u0026' '\u0027' '\u0028' '\u0029' '\u002A' '\u002B' '\u002C' '\u002D' '\u002E' '\u002F' '\u0030' '\u0031' '\u0032' '\u0033' '\u0034' '\u0035' '\u0036' '\u0037' '\u0038' '\u0039' '\u003A' '\u003B' '\u003C' '\u003D' '\u003E' '\u003F' '\u0040' '\u0041' '\u0042' '\u0043' '\u0044' '\u0045' '\u0046' '\u0047' '\u0048' '\u0049' '\u004A' '\u004B' '\u004C' '\u004D' '\u004E' '\u004F' '\u0050' '\u0051' '\u0052' '\u0053' '\u0054' '\u0055' '\u0056' '\u0057' '\u0058' '\u0059' '\u005A' '\u005B' '\ufffe' '\u005D' '\ufffe' '\u005F' '\ufffe' '\u0061' '\u0062' '\u0063' '\u0064' '\u0065' '\u0066' '\u0067' '\u0068' '\u0069' '\u006A' '\u006B' '\u006C' '\u006D' '\u006E' '\u006F' '\u0070' '\u0071' '\u0072' '\u0073' '\u0074' '\u0075' '\u0076' '\u0077' '\u0078' '\u0079' '\u007A' '\ufffe' '\u007C' '\ufffe' '\ufffe' '\u007F' '\u0080' '\u0081' '\u0082' '\u0083' '\u0084' '\u0085' '\u0086' '\u0087' '\u0088' '\u0089' '\u008A' '\u008B' '\u008C' '\u008D' '\u008E' '\u008F' '\u0090' '\u0091' '\u0092' '\u0093' '\u0094' '\u0095' '\u0096' '\u0097' '\u0098' '\u0099' '\u009A' '\u009B' '\u009C' '\u009D' '\u009E' '\u009F' '\u00A0' '\u00A1' '\u00A2' '\u00A3' '\u0024' '\u00A5' '\u0023' '\u00A7' '\u00A4' '\ufffe' '\ufffe' '\u00AB' '\ufffe' '\ufffe' '\ufffe' '\ufffe' '\u00B0' '\u00B1' '\u00B2' '\u00B3' '\u00D7' '\u00B5' '\u00B6' '\u00B7' '\u00F7' '\ufffe' '\ufffe' '\u00BB' '\u00BC' '\u00BD' '\u00BE' '\u00BF' '\ufffe' '\u0300' '\u0301' '\u0302' '\u0303' '\u0304' '\u0306' '\u0307' '\u0308' '\ufffe' '\u030A' '\u0327' '\u0332' '\u030B' '\u0328' '\u030C' '\ufffe' '\ufffe' '\ufffe' '\ufffe' '\ufffe' '\ufffe' '\ufffe' '\ufffe' '\ufffe' '\ufffe' '\ufffe' '\ufffe' '\ufffe' '\ufffe' '\ufffe' '\ufffe' '\u2126' '\u00C6' '\u00D0' '\u00AA' '\u0126' '\ufffe' '\u0132' '\u013F' '\u0141' '\u00D8' '\u0152' '\u00BA' '\u00DE' '\u0166' '\u014A' '\u0149' '\u0138' '\u00E6' '\u0111' '\u00F0' '\u0127' '\u0131' '\u0133' '\u0140' '\u0142' '\u00F8' '\u0153' '\u00DF' '\u00FE' '\u0167' '\u014B' '\ufffe' ) ENCODING_TABLE = codecs.charmap_build(DECODING_TABLE) _types.py000064400000001653152572326550006442 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function import inspect import sys if sys.version_info < (3,): str_cls = unicode # noqa byte_cls = str int_types = (int, long) # noqa def bytes_to_list(byte_string): return [ord(b) for b in byte_string] chr_cls = chr else: str_cls = str byte_cls = bytes int_types = int bytes_to_list = list def chr_cls(num): return bytes([num]) def type_name(value): """ Returns a user-readable name for the type of an object :param value: A value to get the type name of :return: A unicode string of the object's type name """ if inspect.isclass(value): cls = value else: cls = value.__class__ if cls.__module__ in set(['builtins', '__builtin__']): return cls.__name__ return '%s.%s' % (cls.__module__, cls.__name__) algos.py000064400000106033152572326550006242 0ustar00# coding: utf-8 """ ASN.1 type classes for various algorithms using in various aspects of public key cryptography. Exports the following items: - AlgorithmIdentifier() - AnyAlgorithmIdentifier() - DigestAlgorithm() - DigestInfo() - DSASignature() - EncryptionAlgorithm() - HmacAlgorithm() - KdfAlgorithm() - Pkcs5MacAlgorithm() - SignedDigestAlgorithm() Other type classes are defined that help compose the types listed above. """ from __future__ import unicode_literals, division, absolute_import, print_function from ._errors import unwrap from ._int import fill_width from .util import int_from_bytes, int_to_bytes from .core import ( Any, Choice, Integer, Null, ObjectIdentifier, OctetString, Sequence, Void, ) # Structures and OIDs in this file are pulled from # https://tools.ietf.org/html/rfc3279, https://tools.ietf.org/html/rfc4055, # https://tools.ietf.org/html/rfc5758, https://tools.ietf.org/html/rfc7292, # http://www.emc.com/collateral/white-papers/h11302-pkcs5v2-1-password-based-cryptography-standard-wp.pdf class AlgorithmIdentifier(Sequence): _fields = [ ('algorithm', ObjectIdentifier), ('parameters', Any, {'optional': True}), ] class _ForceNullParameters(object): """ Various structures based on AlgorithmIdentifier require that the parameters field be core.Null() for certain OIDs. This mixin ensures that happens. """ # The following attribute, plus the parameters spec callback and custom # __setitem__ are all to handle a situation where parameters should not be # optional and must be Null for certain OIDs. More info at # https://tools.ietf.org/html/rfc4055#page-15 and # https://tools.ietf.org/html/rfc4055#section-2.1 _null_algos = set([ '1.2.840.113549.1.1.1', # rsassa_pkcs1v15 / rsaes_pkcs1v15 / rsa '1.2.840.113549.1.1.11', # sha256_rsa '1.2.840.113549.1.1.12', # sha384_rsa '1.2.840.113549.1.1.13', # sha512_rsa '1.2.840.113549.1.1.14', # sha224_rsa '1.3.14.3.2.26', # sha1 '2.16.840.1.101.3.4.2.4', # sha224 '2.16.840.1.101.3.4.2.1', # sha256 '2.16.840.1.101.3.4.2.2', # sha384 '2.16.840.1.101.3.4.2.3', # sha512 ]) def _parameters_spec(self): if self._oid_pair == ('algorithm', 'parameters'): algo = self['algorithm'].native if algo in self._oid_specs: return self._oid_specs[algo] if self['algorithm'].dotted in self._null_algos: return Null return None _spec_callbacks = { 'parameters': _parameters_spec } # We have to override this since the spec callback uses the value of # algorithm to determine the parameter spec, however default values are # assigned before setting a field, so a default value can't be based on # another field value (unless it is a default also). Thus we have to # manually check to see if the algorithm was set and parameters is unset, # and then fix the value as appropriate. def __setitem__(self, key, value): res = super(_ForceNullParameters, self).__setitem__(key, value) if key != 'algorithm': return res if self['algorithm'].dotted not in self._null_algos: return res if self['parameters'].__class__ != Void: return res self['parameters'] = Null() return res class HmacAlgorithmId(ObjectIdentifier): _map = { '1.3.14.3.2.10': 'des_mac', '1.2.840.113549.2.7': 'sha1', '1.2.840.113549.2.8': 'sha224', '1.2.840.113549.2.9': 'sha256', '1.2.840.113549.2.10': 'sha384', '1.2.840.113549.2.11': 'sha512', '1.2.840.113549.2.12': 'sha512_224', '1.2.840.113549.2.13': 'sha512_256', '2.16.840.1.101.3.4.2.13': 'sha3_224', '2.16.840.1.101.3.4.2.14': 'sha3_256', '2.16.840.1.101.3.4.2.15': 'sha3_384', '2.16.840.1.101.3.4.2.16': 'sha3_512', } class HmacAlgorithm(Sequence): _fields = [ ('algorithm', HmacAlgorithmId), ('parameters', Any, {'optional': True}), ] class DigestAlgorithmId(ObjectIdentifier): _map = { '1.2.840.113549.2.2': 'md2', '1.2.840.113549.2.5': 'md5', '1.3.14.3.2.26': 'sha1', '2.16.840.1.101.3.4.2.4': 'sha224', '2.16.840.1.101.3.4.2.1': 'sha256', '2.16.840.1.101.3.4.2.2': 'sha384', '2.16.840.1.101.3.4.2.3': 'sha512', '2.16.840.1.101.3.4.2.5': 'sha512_224', '2.16.840.1.101.3.4.2.6': 'sha512_256', '2.16.840.1.101.3.4.2.7': 'sha3_224', '2.16.840.1.101.3.4.2.8': 'sha3_256', '2.16.840.1.101.3.4.2.9': 'sha3_384', '2.16.840.1.101.3.4.2.10': 'sha3_512', '2.16.840.1.101.3.4.2.11': 'shake128', '2.16.840.1.101.3.4.2.12': 'shake256', '2.16.840.1.101.3.4.2.17': 'shake128_len', '2.16.840.1.101.3.4.2.18': 'shake256_len', } class DigestAlgorithm(_ForceNullParameters, Sequence): _fields = [ ('algorithm', DigestAlgorithmId), ('parameters', Any, {'optional': True}), ] # This structure is what is signed with a SignedDigestAlgorithm class DigestInfo(Sequence): _fields = [ ('digest_algorithm', DigestAlgorithm), ('digest', OctetString), ] class MaskGenAlgorithmId(ObjectIdentifier): _map = { '1.2.840.113549.1.1.8': 'mgf1', } class MaskGenAlgorithm(Sequence): _fields = [ ('algorithm', MaskGenAlgorithmId), ('parameters', Any, {'optional': True}), ] _oid_pair = ('algorithm', 'parameters') _oid_specs = { 'mgf1': DigestAlgorithm } class TrailerField(Integer): _map = { 1: 'trailer_field_bc', } class RSASSAPSSParams(Sequence): _fields = [ ( 'hash_algorithm', DigestAlgorithm, { 'explicit': 0, 'default': {'algorithm': 'sha1'}, } ), ( 'mask_gen_algorithm', MaskGenAlgorithm, { 'explicit': 1, 'default': { 'algorithm': 'mgf1', 'parameters': {'algorithm': 'sha1'}, }, } ), ( 'salt_length', Integer, { 'explicit': 2, 'default': 20, } ), ( 'trailer_field', TrailerField, { 'explicit': 3, 'default': 'trailer_field_bc', } ), ] class SignedDigestAlgorithmId(ObjectIdentifier): _map = { '1.3.14.3.2.3': 'md5_rsa', '1.3.14.3.2.29': 'sha1_rsa', '1.3.14.7.2.3.1': 'md2_rsa', '1.2.840.113549.1.1.2': 'md2_rsa', '1.2.840.113549.1.1.4': 'md5_rsa', '1.2.840.113549.1.1.5': 'sha1_rsa', '1.2.840.113549.1.1.14': 'sha224_rsa', '1.2.840.113549.1.1.11': 'sha256_rsa', '1.2.840.113549.1.1.12': 'sha384_rsa', '1.2.840.113549.1.1.13': 'sha512_rsa', '1.2.840.113549.1.1.10': 'rsassa_pss', '1.2.840.10040.4.3': 'sha1_dsa', '1.3.14.3.2.13': 'sha1_dsa', '1.3.14.3.2.27': 'sha1_dsa', '2.16.840.1.101.3.4.3.1': 'sha224_dsa', '2.16.840.1.101.3.4.3.2': 'sha256_dsa', '1.2.840.10045.4.1': 'sha1_ecdsa', '1.2.840.10045.4.3.1': 'sha224_ecdsa', '1.2.840.10045.4.3.2': 'sha256_ecdsa', '1.2.840.10045.4.3.3': 'sha384_ecdsa', '1.2.840.10045.4.3.4': 'sha512_ecdsa', '2.16.840.1.101.3.4.3.9': 'sha3_224_ecdsa', '2.16.840.1.101.3.4.3.10': 'sha3_256_ecdsa', '2.16.840.1.101.3.4.3.11': 'sha3_384_ecdsa', '2.16.840.1.101.3.4.3.12': 'sha3_512_ecdsa', # For when the digest is specified elsewhere in a Sequence '1.2.840.113549.1.1.1': 'rsassa_pkcs1v15', '1.2.840.10040.4.1': 'dsa', '1.2.840.10045.4': 'ecdsa', # RFC 8410 -- https://tools.ietf.org/html/rfc8410 '1.3.101.112': 'ed25519', '1.3.101.113': 'ed448', } _reverse_map = { 'dsa': '1.2.840.10040.4.1', 'ecdsa': '1.2.840.10045.4', 'md2_rsa': '1.2.840.113549.1.1.2', 'md5_rsa': '1.2.840.113549.1.1.4', 'rsassa_pkcs1v15': '1.2.840.113549.1.1.1', 'rsassa_pss': '1.2.840.113549.1.1.10', 'sha1_dsa': '1.2.840.10040.4.3', 'sha1_ecdsa': '1.2.840.10045.4.1', 'sha1_rsa': '1.2.840.113549.1.1.5', 'sha224_dsa': '2.16.840.1.101.3.4.3.1', 'sha224_ecdsa': '1.2.840.10045.4.3.1', 'sha224_rsa': '1.2.840.113549.1.1.14', 'sha256_dsa': '2.16.840.1.101.3.4.3.2', 'sha256_ecdsa': '1.2.840.10045.4.3.2', 'sha256_rsa': '1.2.840.113549.1.1.11', 'sha384_ecdsa': '1.2.840.10045.4.3.3', 'sha384_rsa': '1.2.840.113549.1.1.12', 'sha512_ecdsa': '1.2.840.10045.4.3.4', 'sha512_rsa': '1.2.840.113549.1.1.13', 'sha3_224_ecdsa': '2.16.840.1.101.3.4.3.9', 'sha3_256_ecdsa': '2.16.840.1.101.3.4.3.10', 'sha3_384_ecdsa': '2.16.840.1.101.3.4.3.11', 'sha3_512_ecdsa': '2.16.840.1.101.3.4.3.12', 'ed25519': '1.3.101.112', 'ed448': '1.3.101.113', } class SignedDigestAlgorithm(_ForceNullParameters, Sequence): _fields = [ ('algorithm', SignedDigestAlgorithmId), ('parameters', Any, {'optional': True}), ] _oid_pair = ('algorithm', 'parameters') _oid_specs = { 'rsassa_pss': RSASSAPSSParams, } @property def signature_algo(self): """ :return: A unicode string of "rsassa_pkcs1v15", "rsassa_pss", "dsa", "ecdsa", "ed25519" or "ed448" """ algorithm = self['algorithm'].native algo_map = { 'md2_rsa': 'rsassa_pkcs1v15', 'md5_rsa': 'rsassa_pkcs1v15', 'sha1_rsa': 'rsassa_pkcs1v15', 'sha224_rsa': 'rsassa_pkcs1v15', 'sha256_rsa': 'rsassa_pkcs1v15', 'sha384_rsa': 'rsassa_pkcs1v15', 'sha512_rsa': 'rsassa_pkcs1v15', 'rsassa_pkcs1v15': 'rsassa_pkcs1v15', 'rsassa_pss': 'rsassa_pss', 'sha1_dsa': 'dsa', 'sha224_dsa': 'dsa', 'sha256_dsa': 'dsa', 'dsa': 'dsa', 'sha1_ecdsa': 'ecdsa', 'sha224_ecdsa': 'ecdsa', 'sha256_ecdsa': 'ecdsa', 'sha384_ecdsa': 'ecdsa', 'sha512_ecdsa': 'ecdsa', 'sha3_224_ecdsa': 'ecdsa', 'sha3_256_ecdsa': 'ecdsa', 'sha3_384_ecdsa': 'ecdsa', 'sha3_512_ecdsa': 'ecdsa', 'ecdsa': 'ecdsa', 'ed25519': 'ed25519', 'ed448': 'ed448', } if algorithm in algo_map: return algo_map[algorithm] raise ValueError(unwrap( ''' Signature algorithm not known for %s ''', algorithm )) @property def hash_algo(self): """ :return: A unicode string of "md2", "md5", "sha1", "sha224", "sha256", "sha384", "sha512", "sha512_224", "sha512_256" or "shake256" """ algorithm = self['algorithm'].native algo_map = { 'md2_rsa': 'md2', 'md5_rsa': 'md5', 'sha1_rsa': 'sha1', 'sha224_rsa': 'sha224', 'sha256_rsa': 'sha256', 'sha384_rsa': 'sha384', 'sha512_rsa': 'sha512', 'sha1_dsa': 'sha1', 'sha224_dsa': 'sha224', 'sha256_dsa': 'sha256', 'sha1_ecdsa': 'sha1', 'sha224_ecdsa': 'sha224', 'sha256_ecdsa': 'sha256', 'sha384_ecdsa': 'sha384', 'sha512_ecdsa': 'sha512', 'ed25519': 'sha512', 'ed448': 'shake256', } if algorithm in algo_map: return algo_map[algorithm] if algorithm == 'rsassa_pss': return self['parameters']['hash_algorithm']['algorithm'].native raise ValueError(unwrap( ''' Hash algorithm not known for %s ''', algorithm )) class Pbkdf2Salt(Choice): _alternatives = [ ('specified', OctetString), ('other_source', AlgorithmIdentifier), ] class Pbkdf2Params(Sequence): _fields = [ ('salt', Pbkdf2Salt), ('iteration_count', Integer), ('key_length', Integer, {'optional': True}), ('prf', HmacAlgorithm, {'default': {'algorithm': 'sha1'}}), ] class KdfAlgorithmId(ObjectIdentifier): _map = { '1.2.840.113549.1.5.12': 'pbkdf2' } class KdfAlgorithm(Sequence): _fields = [ ('algorithm', KdfAlgorithmId), ('parameters', Any, {'optional': True}), ] _oid_pair = ('algorithm', 'parameters') _oid_specs = { 'pbkdf2': Pbkdf2Params } class DHParameters(Sequence): """ Original Name: DHParameter Source: ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-3.asc section 9 """ _fields = [ ('p', Integer), ('g', Integer), ('private_value_length', Integer, {'optional': True}), ] class KeyExchangeAlgorithmId(ObjectIdentifier): _map = { '1.2.840.113549.1.3.1': 'dh', } class KeyExchangeAlgorithm(Sequence): _fields = [ ('algorithm', KeyExchangeAlgorithmId), ('parameters', Any, {'optional': True}), ] _oid_pair = ('algorithm', 'parameters') _oid_specs = { 'dh': DHParameters, } class Rc2Params(Sequence): _fields = [ ('rc2_parameter_version', Integer, {'optional': True}), ('iv', OctetString), ] class Rc5ParamVersion(Integer): _map = { 16: 'v1-0' } class Rc5Params(Sequence): _fields = [ ('version', Rc5ParamVersion), ('rounds', Integer), ('block_size_in_bits', Integer), ('iv', OctetString, {'optional': True}), ] class Pbes1Params(Sequence): _fields = [ ('salt', OctetString), ('iterations', Integer), ] class CcmParams(Sequence): # https://tools.ietf.org/html/rfc5084 # aes_ICVlen: 4 | 6 | 8 | 10 | 12 | 14 | 16 _fields = [ ('aes_nonce', OctetString), ('aes_icvlen', Integer), ] class PSourceAlgorithmId(ObjectIdentifier): _map = { '1.2.840.113549.1.1.9': 'p_specified', } class PSourceAlgorithm(Sequence): _fields = [ ('algorithm', PSourceAlgorithmId), ('parameters', Any, {'optional': True}), ] _oid_pair = ('algorithm', 'parameters') _oid_specs = { 'p_specified': OctetString } class RSAESOAEPParams(Sequence): _fields = [ ( 'hash_algorithm', DigestAlgorithm, { 'explicit': 0, 'default': {'algorithm': 'sha1'} } ), ( 'mask_gen_algorithm', MaskGenAlgorithm, { 'explicit': 1, 'default': { 'algorithm': 'mgf1', 'parameters': {'algorithm': 'sha1'} } } ), ( 'p_source_algorithm', PSourceAlgorithm, { 'explicit': 2, 'default': { 'algorithm': 'p_specified', 'parameters': b'' } } ), ] class DSASignature(Sequence): """ An ASN.1 class for translating between the OS crypto library's representation of an (EC)DSA signature and the ASN.1 structure that is part of various RFCs. Original Name: DSS-Sig-Value Source: https://tools.ietf.org/html/rfc3279#section-2.2.2 """ _fields = [ ('r', Integer), ('s', Integer), ] @classmethod def from_p1363(cls, data): """ Reads a signature from a byte string encoding accordint to IEEE P1363, which is used by Microsoft's BCryptSignHash() function. :param data: A byte string from BCryptSignHash() :return: A DSASignature object """ r = int_from_bytes(data[0:len(data) // 2]) s = int_from_bytes(data[len(data) // 2:]) return cls({'r': r, 's': s}) def to_p1363(self): """ Dumps a signature to a byte string compatible with Microsoft's BCryptVerifySignature() function. :return: A byte string compatible with BCryptVerifySignature() """ r_bytes = int_to_bytes(self['r'].native) s_bytes = int_to_bytes(self['s'].native) int_byte_length = max(len(r_bytes), len(s_bytes)) r_bytes = fill_width(r_bytes, int_byte_length) s_bytes = fill_width(s_bytes, int_byte_length) return r_bytes + s_bytes class EncryptionAlgorithmId(ObjectIdentifier): _map = { '1.3.14.3.2.7': 'des', '1.2.840.113549.3.7': 'tripledes_3key', '1.2.840.113549.3.2': 'rc2', '1.2.840.113549.3.4': 'rc4', '1.2.840.113549.3.9': 'rc5', # From http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html#AES '2.16.840.1.101.3.4.1.1': 'aes128_ecb', '2.16.840.1.101.3.4.1.2': 'aes128_cbc', '2.16.840.1.101.3.4.1.3': 'aes128_ofb', '2.16.840.1.101.3.4.1.4': 'aes128_cfb', '2.16.840.1.101.3.4.1.5': 'aes128_wrap', '2.16.840.1.101.3.4.1.6': 'aes128_gcm', '2.16.840.1.101.3.4.1.7': 'aes128_ccm', '2.16.840.1.101.3.4.1.8': 'aes128_wrap_pad', '2.16.840.1.101.3.4.1.21': 'aes192_ecb', '2.16.840.1.101.3.4.1.22': 'aes192_cbc', '2.16.840.1.101.3.4.1.23': 'aes192_ofb', '2.16.840.1.101.3.4.1.24': 'aes192_cfb', '2.16.840.1.101.3.4.1.25': 'aes192_wrap', '2.16.840.1.101.3.4.1.26': 'aes192_gcm', '2.16.840.1.101.3.4.1.27': 'aes192_ccm', '2.16.840.1.101.3.4.1.28': 'aes192_wrap_pad', '2.16.840.1.101.3.4.1.41': 'aes256_ecb', '2.16.840.1.101.3.4.1.42': 'aes256_cbc', '2.16.840.1.101.3.4.1.43': 'aes256_ofb', '2.16.840.1.101.3.4.1.44': 'aes256_cfb', '2.16.840.1.101.3.4.1.45': 'aes256_wrap', '2.16.840.1.101.3.4.1.46': 'aes256_gcm', '2.16.840.1.101.3.4.1.47': 'aes256_ccm', '2.16.840.1.101.3.4.1.48': 'aes256_wrap_pad', # From PKCS#5 '1.2.840.113549.1.5.13': 'pbes2', '1.2.840.113549.1.5.1': 'pbes1_md2_des', '1.2.840.113549.1.5.3': 'pbes1_md5_des', '1.2.840.113549.1.5.4': 'pbes1_md2_rc2', '1.2.840.113549.1.5.6': 'pbes1_md5_rc2', '1.2.840.113549.1.5.10': 'pbes1_sha1_des', '1.2.840.113549.1.5.11': 'pbes1_sha1_rc2', # From PKCS#12 '1.2.840.113549.1.12.1.1': 'pkcs12_sha1_rc4_128', '1.2.840.113549.1.12.1.2': 'pkcs12_sha1_rc4_40', '1.2.840.113549.1.12.1.3': 'pkcs12_sha1_tripledes_3key', '1.2.840.113549.1.12.1.4': 'pkcs12_sha1_tripledes_2key', '1.2.840.113549.1.12.1.5': 'pkcs12_sha1_rc2_128', '1.2.840.113549.1.12.1.6': 'pkcs12_sha1_rc2_40', # PKCS#1 v2.2 '1.2.840.113549.1.1.1': 'rsaes_pkcs1v15', '1.2.840.113549.1.1.7': 'rsaes_oaep', } class EncryptionAlgorithm(_ForceNullParameters, Sequence): _fields = [ ('algorithm', EncryptionAlgorithmId), ('parameters', Any, {'optional': True}), ] _oid_pair = ('algorithm', 'parameters') _oid_specs = { 'des': OctetString, 'tripledes_3key': OctetString, 'rc2': Rc2Params, 'rc5': Rc5Params, 'aes128_cbc': OctetString, 'aes192_cbc': OctetString, 'aes256_cbc': OctetString, 'aes128_ofb': OctetString, 'aes192_ofb': OctetString, 'aes256_ofb': OctetString, # From RFC5084 'aes128_ccm': CcmParams, 'aes192_ccm': CcmParams, 'aes256_ccm': CcmParams, # From PKCS#5 'pbes1_md2_des': Pbes1Params, 'pbes1_md5_des': Pbes1Params, 'pbes1_md2_rc2': Pbes1Params, 'pbes1_md5_rc2': Pbes1Params, 'pbes1_sha1_des': Pbes1Params, 'pbes1_sha1_rc2': Pbes1Params, # From PKCS#12 'pkcs12_sha1_rc4_128': Pbes1Params, 'pkcs12_sha1_rc4_40': Pbes1Params, 'pkcs12_sha1_tripledes_3key': Pbes1Params, 'pkcs12_sha1_tripledes_2key': Pbes1Params, 'pkcs12_sha1_rc2_128': Pbes1Params, 'pkcs12_sha1_rc2_40': Pbes1Params, # PKCS#1 v2.2 'rsaes_oaep': RSAESOAEPParams, } @property def kdf(self): """ Returns the name of the key derivation function to use. :return: A unicode from of one of the following: "pbkdf1", "pbkdf2", "pkcs12_kdf" """ encryption_algo = self['algorithm'].native if encryption_algo == 'pbes2': return self['parameters']['key_derivation_func']['algorithm'].native if encryption_algo.find('.') == -1: if encryption_algo.find('_') != -1: encryption_algo, _ = encryption_algo.split('_', 1) if encryption_algo == 'pbes1': return 'pbkdf1' if encryption_algo == 'pkcs12': return 'pkcs12_kdf' raise ValueError(unwrap( ''' Encryption algorithm "%s" does not have a registered key derivation function ''', encryption_algo )) raise ValueError(unwrap( ''' Unrecognized encryption algorithm "%s", can not determine key derivation function ''', encryption_algo )) @property def kdf_hmac(self): """ Returns the HMAC algorithm to use with the KDF. :return: A unicode string of one of the following: "md2", "md5", "sha1", "sha224", "sha256", "sha384", "sha512" """ encryption_algo = self['algorithm'].native if encryption_algo == 'pbes2': return self['parameters']['key_derivation_func']['parameters']['prf']['algorithm'].native if encryption_algo.find('.') == -1: if encryption_algo.find('_') != -1: _, hmac_algo, _ = encryption_algo.split('_', 2) return hmac_algo raise ValueError(unwrap( ''' Encryption algorithm "%s" does not have a registered key derivation function ''', encryption_algo )) raise ValueError(unwrap( ''' Unrecognized encryption algorithm "%s", can not determine key derivation hmac algorithm ''', encryption_algo )) @property def kdf_salt(self): """ Returns the byte string to use as the salt for the KDF. :return: A byte string """ encryption_algo = self['algorithm'].native if encryption_algo == 'pbes2': salt = self['parameters']['key_derivation_func']['parameters']['salt'] if salt.name == 'other_source': raise ValueError(unwrap( ''' Can not determine key derivation salt - the reserved-for-future-use other source salt choice was specified in the PBKDF2 params structure ''' )) return salt.native if encryption_algo.find('.') == -1: if encryption_algo.find('_') != -1: return self['parameters']['salt'].native raise ValueError(unwrap( ''' Encryption algorithm "%s" does not have a registered key derivation function ''', encryption_algo )) raise ValueError(unwrap( ''' Unrecognized encryption algorithm "%s", can not determine key derivation salt ''', encryption_algo )) @property def kdf_iterations(self): """ Returns the number of iterations that should be run via the KDF. :return: An integer """ encryption_algo = self['algorithm'].native if encryption_algo == 'pbes2': return self['parameters']['key_derivation_func']['parameters']['iteration_count'].native if encryption_algo.find('.') == -1: if encryption_algo.find('_') != -1: return self['parameters']['iterations'].native raise ValueError(unwrap( ''' Encryption algorithm "%s" does not have a registered key derivation function ''', encryption_algo )) raise ValueError(unwrap( ''' Unrecognized encryption algorithm "%s", can not determine key derivation iterations ''', encryption_algo )) @property def key_length(self): """ Returns the key length to pass to the cipher/kdf. The PKCS#5 spec does not specify a way to store the RC5 key length, however this tends not to be a problem since OpenSSL does not support RC5 in PKCS#8 and OS X does not provide an RC5 cipher for use in the Security Transforms library. :raises: ValueError - when the key length can not be determined :return: An integer representing the length in bytes """ encryption_algo = self['algorithm'].native if encryption_algo[0:3] == 'aes': return { 'aes128_': 16, 'aes192_': 24, 'aes256_': 32, }[encryption_algo[0:7]] cipher_lengths = { 'des': 8, 'tripledes_3key': 24, } if encryption_algo in cipher_lengths: return cipher_lengths[encryption_algo] if encryption_algo == 'rc2': rc2_parameter_version = self['parameters']['rc2_parameter_version'].native # See page 24 of # http://www.emc.com/collateral/white-papers/h11302-pkcs5v2-1-password-based-cryptography-standard-wp.pdf encoded_key_bits_map = { 160: 5, # 40-bit 120: 8, # 64-bit 58: 16, # 128-bit } if rc2_parameter_version in encoded_key_bits_map: return encoded_key_bits_map[rc2_parameter_version] if rc2_parameter_version >= 256: return rc2_parameter_version if rc2_parameter_version is None: return 4 # 32-bit default raise ValueError(unwrap( ''' Invalid RC2 parameter version found in EncryptionAlgorithm parameters ''' )) if encryption_algo == 'pbes2': key_length = self['parameters']['key_derivation_func']['parameters']['key_length'].native if key_length is not None: return key_length # If the KDF params don't specify the key size, we can infer it from # the encryption scheme for all schemes except for RC5. However, in # practical terms, neither OpenSSL or OS X support RC5 for PKCS#8 # so it is unlikely to be an issue that is run into. return self['parameters']['encryption_scheme'].key_length if encryption_algo.find('.') == -1: return { 'pbes1_md2_des': 8, 'pbes1_md5_des': 8, 'pbes1_md2_rc2': 8, 'pbes1_md5_rc2': 8, 'pbes1_sha1_des': 8, 'pbes1_sha1_rc2': 8, 'pkcs12_sha1_rc4_128': 16, 'pkcs12_sha1_rc4_40': 5, 'pkcs12_sha1_tripledes_3key': 24, 'pkcs12_sha1_tripledes_2key': 16, 'pkcs12_sha1_rc2_128': 16, 'pkcs12_sha1_rc2_40': 5, }[encryption_algo] raise ValueError(unwrap( ''' Unrecognized encryption algorithm "%s" ''', encryption_algo )) @property def encryption_mode(self): """ Returns the name of the encryption mode to use. :return: A unicode string from one of the following: "cbc", "ecb", "ofb", "cfb", "wrap", "gcm", "ccm", "wrap_pad" """ encryption_algo = self['algorithm'].native if encryption_algo[0:7] in set(['aes128_', 'aes192_', 'aes256_']): return encryption_algo[7:] if encryption_algo[0:6] == 'pbes1_': return 'cbc' if encryption_algo[0:7] == 'pkcs12_': return 'cbc' if encryption_algo in set(['des', 'tripledes_3key', 'rc2', 'rc5']): return 'cbc' if encryption_algo == 'pbes2': return self['parameters']['encryption_scheme'].encryption_mode raise ValueError(unwrap( ''' Unrecognized encryption algorithm "%s" ''', encryption_algo )) @property def encryption_cipher(self): """ Returns the name of the symmetric encryption cipher to use. The key length can be retrieved via the .key_length property to disabiguate between different variations of TripleDES, AES, and the RC* ciphers. :return: A unicode string from one of the following: "rc2", "rc5", "des", "tripledes", "aes" """ encryption_algo = self['algorithm'].native if encryption_algo[0:7] in set(['aes128_', 'aes192_', 'aes256_']): return 'aes' if encryption_algo in set(['des', 'rc2', 'rc5']): return encryption_algo if encryption_algo == 'tripledes_3key': return 'tripledes' if encryption_algo == 'pbes2': return self['parameters']['encryption_scheme'].encryption_cipher if encryption_algo.find('.') == -1: return { 'pbes1_md2_des': 'des', 'pbes1_md5_des': 'des', 'pbes1_md2_rc2': 'rc2', 'pbes1_md5_rc2': 'rc2', 'pbes1_sha1_des': 'des', 'pbes1_sha1_rc2': 'rc2', 'pkcs12_sha1_rc4_128': 'rc4', 'pkcs12_sha1_rc4_40': 'rc4', 'pkcs12_sha1_tripledes_3key': 'tripledes', 'pkcs12_sha1_tripledes_2key': 'tripledes', 'pkcs12_sha1_rc2_128': 'rc2', 'pkcs12_sha1_rc2_40': 'rc2', }[encryption_algo] raise ValueError(unwrap( ''' Unrecognized encryption algorithm "%s" ''', encryption_algo )) @property def encryption_block_size(self): """ Returns the block size of the encryption cipher, in bytes. :return: An integer that is the block size in bytes """ encryption_algo = self['algorithm'].native if encryption_algo[0:7] in set(['aes128_', 'aes192_', 'aes256_']): return 16 cipher_map = { 'des': 8, 'tripledes_3key': 8, 'rc2': 8, } if encryption_algo in cipher_map: return cipher_map[encryption_algo] if encryption_algo == 'rc5': return self['parameters']['block_size_in_bits'].native // 8 if encryption_algo == 'pbes2': return self['parameters']['encryption_scheme'].encryption_block_size if encryption_algo.find('.') == -1: return { 'pbes1_md2_des': 8, 'pbes1_md5_des': 8, 'pbes1_md2_rc2': 8, 'pbes1_md5_rc2': 8, 'pbes1_sha1_des': 8, 'pbes1_sha1_rc2': 8, 'pkcs12_sha1_rc4_128': 0, 'pkcs12_sha1_rc4_40': 0, 'pkcs12_sha1_tripledes_3key': 8, 'pkcs12_sha1_tripledes_2key': 8, 'pkcs12_sha1_rc2_128': 8, 'pkcs12_sha1_rc2_40': 8, }[encryption_algo] raise ValueError(unwrap( ''' Unrecognized encryption algorithm "%s" ''', encryption_algo )) @property def encryption_iv(self): """ Returns the byte string of the initialization vector for the encryption scheme. Only the PBES2 stores the IV in the params. For PBES1, the IV is derived from the KDF and this property will return None. :return: A byte string or None """ encryption_algo = self['algorithm'].native if encryption_algo in set(['rc2', 'rc5']): return self['parameters']['iv'].native # For DES/Triple DES and AES the IV is the entirety of the parameters octet_string_iv_oids = set([ 'des', 'tripledes_3key', 'aes128_cbc', 'aes192_cbc', 'aes256_cbc', 'aes128_ofb', 'aes192_ofb', 'aes256_ofb', ]) if encryption_algo in octet_string_iv_oids: return self['parameters'].native if encryption_algo == 'pbes2': return self['parameters']['encryption_scheme'].encryption_iv # All of the PBES1 algos use their KDF to create the IV. For the pbkdf1, # the KDF is told to generate a key that is an extra 8 bytes long, and # that is used for the IV. For the PKCS#12 KDF, it is called with an id # of 2 to generate the IV. In either case, we can't return the IV # without knowing the user's password. if encryption_algo.find('.') == -1: return None raise ValueError(unwrap( ''' Unrecognized encryption algorithm "%s" ''', encryption_algo )) class Pbes2Params(Sequence): _fields = [ ('key_derivation_func', KdfAlgorithm), ('encryption_scheme', EncryptionAlgorithm), ] class Pbmac1Params(Sequence): _fields = [ ('key_derivation_func', KdfAlgorithm), ('message_auth_scheme', HmacAlgorithm), ] class Pkcs5MacId(ObjectIdentifier): _map = { '1.2.840.113549.1.5.14': 'pbmac1', } class Pkcs5MacAlgorithm(Sequence): _fields = [ ('algorithm', Pkcs5MacId), ('parameters', Any), ] _oid_pair = ('algorithm', 'parameters') _oid_specs = { 'pbmac1': Pbmac1Params, } EncryptionAlgorithm._oid_specs['pbes2'] = Pbes2Params class AnyAlgorithmId(ObjectIdentifier): _map = {} def _setup(self): _map = self.__class__._map for other_cls in (EncryptionAlgorithmId, SignedDigestAlgorithmId, DigestAlgorithmId): for oid, name in other_cls._map.items(): _map[oid] = name class AnyAlgorithmIdentifier(_ForceNullParameters, Sequence): _fields = [ ('algorithm', AnyAlgorithmId), ('parameters', Any, {'optional': True}), ] _oid_pair = ('algorithm', 'parameters') _oid_specs = {} def _setup(self): Sequence._setup(self) specs = self.__class__._oid_specs for other_cls in (EncryptionAlgorithm, SignedDigestAlgorithm): for oid, spec in other_cls._oid_specs.items(): specs[oid] = spec cms.py000064400000066200152572326550005720 0ustar00# coding: utf-8 """ ASN.1 type classes for cryptographic message syntax (CMS). Structures are also compatible with PKCS#7. Exports the following items: - AuthenticatedData() - AuthEnvelopedData() - CompressedData() - ContentInfo() - DigestedData() - EncryptedData() - EnvelopedData() - SignedAndEnvelopedData() - SignedData() Other type classes are defined that help compose the types listed above. Most CMS structures in the wild are formatted as ContentInfo encapsulating one of the other types. """ from __future__ import unicode_literals, division, absolute_import, print_function try: import zlib except (ImportError): zlib = None from .algos import ( _ForceNullParameters, DigestAlgorithm, EncryptionAlgorithm, EncryptionAlgorithmId, HmacAlgorithm, KdfAlgorithm, RSAESOAEPParams, SignedDigestAlgorithm, ) from .core import ( Any, BitString, Choice, Enumerated, GeneralizedTime, Integer, ObjectIdentifier, OctetBitString, OctetString, ParsableOctetString, Sequence, SequenceOf, SetOf, UTCTime, UTF8String, ) from .crl import CertificateList from .keys import PublicKeyInfo from .ocsp import OCSPResponse from .x509 import Attributes, Certificate, Extensions, GeneralName, GeneralNames, Name # These structures are taken from # ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-6.asc class ExtendedCertificateInfo(Sequence): _fields = [ ('version', Integer), ('certificate', Certificate), ('attributes', Attributes), ] class ExtendedCertificate(Sequence): _fields = [ ('extended_certificate_info', ExtendedCertificateInfo), ('signature_algorithm', SignedDigestAlgorithm), ('signature', OctetBitString), ] # These structures are taken from https://tools.ietf.org/html/rfc5652, # https://tools.ietf.org/html/rfc5083, http://tools.ietf.org/html/rfc2315, # https://tools.ietf.org/html/rfc5940, https://tools.ietf.org/html/rfc3274, # https://tools.ietf.org/html/rfc3281 class CMSVersion(Integer): _map = { 0: 'v0', 1: 'v1', 2: 'v2', 3: 'v3', 4: 'v4', 5: 'v5', } class CMSAttributeType(ObjectIdentifier): _map = { '1.2.840.113549.1.9.3': 'content_type', '1.2.840.113549.1.9.4': 'message_digest', '1.2.840.113549.1.9.5': 'signing_time', '1.2.840.113549.1.9.6': 'counter_signature', # https://datatracker.ietf.org/doc/html/rfc2633#section-2.5.2 '1.2.840.113549.1.9.15': 'smime_capabilities', # https://tools.ietf.org/html/rfc2633#page-26 '1.2.840.113549.1.9.16.2.11': 'encrypt_key_pref', # https://tools.ietf.org/html/rfc3161#page-20 '1.2.840.113549.1.9.16.2.14': 'signature_time_stamp_token', # https://tools.ietf.org/html/rfc6211#page-5 '1.2.840.113549.1.9.52': 'cms_algorithm_protection', # https://docs.microsoft.com/en-us/previous-versions/hh968145(v%3Dvs.85) '1.3.6.1.4.1.311.2.4.1': 'microsoft_nested_signature', # Some places refer to this as SPC_RFC3161_OBJID, others szOID_RFC3161_counterSign. # https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-crypt_algorithm_identifier # refers to szOID_RFC3161_counterSign as "1.2.840.113549.1.9.16.1.4", # but that OID is also called szOID_TIMESTAMP_TOKEN. Because of there being # no canonical source for this OID, we give it our own name '1.3.6.1.4.1.311.3.3.1': 'microsoft_time_stamp_token', } class Time(Choice): _alternatives = [ ('utc_time', UTCTime), ('generalized_time', GeneralizedTime), ] class ContentType(ObjectIdentifier): _map = { '1.2.840.113549.1.7.1': 'data', '1.2.840.113549.1.7.2': 'signed_data', '1.2.840.113549.1.7.3': 'enveloped_data', '1.2.840.113549.1.7.4': 'signed_and_enveloped_data', '1.2.840.113549.1.7.5': 'digested_data', '1.2.840.113549.1.7.6': 'encrypted_data', '1.2.840.113549.1.9.16.1.2': 'authenticated_data', '1.2.840.113549.1.9.16.1.9': 'compressed_data', '1.2.840.113549.1.9.16.1.23': 'authenticated_enveloped_data', } class CMSAlgorithmProtection(Sequence): _fields = [ ('digest_algorithm', DigestAlgorithm), ('signature_algorithm', SignedDigestAlgorithm, {'implicit': 1, 'optional': True}), ('mac_algorithm', HmacAlgorithm, {'implicit': 2, 'optional': True}), ] class SetOfContentType(SetOf): _child_spec = ContentType class SetOfOctetString(SetOf): _child_spec = OctetString class SetOfTime(SetOf): _child_spec = Time class SetOfAny(SetOf): _child_spec = Any class SetOfCMSAlgorithmProtection(SetOf): _child_spec = CMSAlgorithmProtection class CMSAttribute(Sequence): _fields = [ ('type', CMSAttributeType), ('values', None), ] _oid_specs = {} def _values_spec(self): return self._oid_specs.get(self['type'].native, SetOfAny) _spec_callbacks = { 'values': _values_spec } class CMSAttributes(SetOf): _child_spec = CMSAttribute class IssuerSerial(Sequence): _fields = [ ('issuer', GeneralNames), ('serial', Integer), ('issuer_uid', OctetBitString, {'optional': True}), ] class AttCertVersion(Integer): _map = { 0: 'v1', 1: 'v2', } class AttCertSubject(Choice): _alternatives = [ ('base_certificate_id', IssuerSerial, {'explicit': 0}), ('subject_name', GeneralNames, {'explicit': 1}), ] class AttCertValidityPeriod(Sequence): _fields = [ ('not_before_time', GeneralizedTime), ('not_after_time', GeneralizedTime), ] class AttributeCertificateInfoV1(Sequence): _fields = [ ('version', AttCertVersion, {'default': 'v1'}), ('subject', AttCertSubject), ('issuer', GeneralNames), ('signature', SignedDigestAlgorithm), ('serial_number', Integer), ('att_cert_validity_period', AttCertValidityPeriod), ('attributes', Attributes), ('issuer_unique_id', OctetBitString, {'optional': True}), ('extensions', Extensions, {'optional': True}), ] class AttributeCertificateV1(Sequence): _fields = [ ('ac_info', AttributeCertificateInfoV1), ('signature_algorithm', SignedDigestAlgorithm), ('signature', OctetBitString), ] class DigestedObjectType(Enumerated): _map = { 0: 'public_key', 1: 'public_key_cert', 2: 'other_objy_types', } class ObjectDigestInfo(Sequence): _fields = [ ('digested_object_type', DigestedObjectType), ('other_object_type_id', ObjectIdentifier, {'optional': True}), ('digest_algorithm', DigestAlgorithm), ('object_digest', OctetBitString), ] class Holder(Sequence): _fields = [ ('base_certificate_id', IssuerSerial, {'implicit': 0, 'optional': True}), ('entity_name', GeneralNames, {'implicit': 1, 'optional': True}), ('object_digest_info', ObjectDigestInfo, {'implicit': 2, 'optional': True}), ] class V2Form(Sequence): _fields = [ ('issuer_name', GeneralNames, {'optional': True}), ('base_certificate_id', IssuerSerial, {'explicit': 0, 'optional': True}), ('object_digest_info', ObjectDigestInfo, {'explicit': 1, 'optional': True}), ] class AttCertIssuer(Choice): _alternatives = [ ('v1_form', GeneralNames), ('v2_form', V2Form, {'implicit': 0}), ] class IetfAttrValue(Choice): _alternatives = [ ('octets', OctetString), ('oid', ObjectIdentifier), ('string', UTF8String), ] class IetfAttrValues(SequenceOf): _child_spec = IetfAttrValue class IetfAttrSyntax(Sequence): _fields = [ ('policy_authority', GeneralNames, {'implicit': 0, 'optional': True}), ('values', IetfAttrValues), ] class SetOfIetfAttrSyntax(SetOf): _child_spec = IetfAttrSyntax class SvceAuthInfo(Sequence): _fields = [ ('service', GeneralName), ('ident', GeneralName), ('auth_info', OctetString, {'optional': True}), ] class SetOfSvceAuthInfo(SetOf): _child_spec = SvceAuthInfo class RoleSyntax(Sequence): _fields = [ ('role_authority', GeneralNames, {'implicit': 0, 'optional': True}), ('role_name', GeneralName, {'explicit': 1}), ] class SetOfRoleSyntax(SetOf): _child_spec = RoleSyntax class ClassList(BitString): _map = { 0: 'unmarked', 1: 'unclassified', 2: 'restricted', 3: 'confidential', 4: 'secret', 5: 'top_secret', } class SecurityCategory(Sequence): _fields = [ ('type', ObjectIdentifier, {'implicit': 0}), ('value', Any, {'explicit': 1}), ] class SetOfSecurityCategory(SetOf): _child_spec = SecurityCategory class Clearance(Sequence): _fields = [ ('policy_id', ObjectIdentifier), ('class_list', ClassList, {'default': set(['unclassified'])}), ('security_categories', SetOfSecurityCategory, {'optional': True}), ] class SetOfClearance(SetOf): _child_spec = Clearance class BigTime(Sequence): _fields = [ ('major', Integer), ('fractional_seconds', Integer), ('sign', Integer, {'optional': True}), ] class LeapData(Sequence): _fields = [ ('leap_time', BigTime), ('action', Integer), ] class SetOfLeapData(SetOf): _child_spec = LeapData class TimingMetrics(Sequence): _fields = [ ('ntp_time', BigTime), ('offset', BigTime), ('delay', BigTime), ('expiration', BigTime), ('leap_event', SetOfLeapData, {'optional': True}), ] class SetOfTimingMetrics(SetOf): _child_spec = TimingMetrics class TimingPolicy(Sequence): _fields = [ ('policy_id', SequenceOf, {'spec': ObjectIdentifier}), ('max_offset', BigTime, {'explicit': 0, 'optional': True}), ('max_delay', BigTime, {'explicit': 1, 'optional': True}), ] class SetOfTimingPolicy(SetOf): _child_spec = TimingPolicy class AttCertAttributeType(ObjectIdentifier): _map = { '1.3.6.1.5.5.7.10.1': 'authentication_info', '1.3.6.1.5.5.7.10.2': 'access_identity', '1.3.6.1.5.5.7.10.3': 'charging_identity', '1.3.6.1.5.5.7.10.4': 'group', '2.5.4.72': 'role', '2.5.4.55': 'clearance', '1.3.6.1.4.1.601.10.4.1': 'timing_metrics', '1.3.6.1.4.1.601.10.4.2': 'timing_policy', } class AttCertAttribute(Sequence): _fields = [ ('type', AttCertAttributeType), ('values', None), ] _oid_specs = { 'authentication_info': SetOfSvceAuthInfo, 'access_identity': SetOfSvceAuthInfo, 'charging_identity': SetOfIetfAttrSyntax, 'group': SetOfIetfAttrSyntax, 'role': SetOfRoleSyntax, 'clearance': SetOfClearance, 'timing_metrics': SetOfTimingMetrics, 'timing_policy': SetOfTimingPolicy, } def _values_spec(self): return self._oid_specs.get(self['type'].native, SetOfAny) _spec_callbacks = { 'values': _values_spec } class AttCertAttributes(SequenceOf): _child_spec = AttCertAttribute class AttributeCertificateInfoV2(Sequence): _fields = [ ('version', AttCertVersion), ('holder', Holder), ('issuer', AttCertIssuer), ('signature', SignedDigestAlgorithm), ('serial_number', Integer), ('att_cert_validity_period', AttCertValidityPeriod), ('attributes', AttCertAttributes), ('issuer_unique_id', OctetBitString, {'optional': True}), ('extensions', Extensions, {'optional': True}), ] class AttributeCertificateV2(Sequence): # Handle the situation where a V2 cert is encoded as V1 _bad_tag = 1 _fields = [ ('ac_info', AttributeCertificateInfoV2), ('signature_algorithm', SignedDigestAlgorithm), ('signature', OctetBitString), ] class OtherCertificateFormat(Sequence): _fields = [ ('other_cert_format', ObjectIdentifier), ('other_cert', Any), ] class CertificateChoices(Choice): _alternatives = [ ('certificate', Certificate), ('extended_certificate', ExtendedCertificate, {'implicit': 0}), ('v1_attr_cert', AttributeCertificateV1, {'implicit': 1}), ('v2_attr_cert', AttributeCertificateV2, {'implicit': 2}), ('other', OtherCertificateFormat, {'implicit': 3}), ] def validate(self, class_, tag, contents): """ Ensures that the class and tag specified exist as an alternative. This custom version fixes parsing broken encodings there a V2 attribute # certificate is encoded as a V1 :param class_: The integer class_ from the encoded value header :param tag: The integer tag from the encoded value header :param contents: A byte string of the contents of the value - used when the object is explicitly tagged :raises: ValueError - when value is not a valid alternative """ super(CertificateChoices, self).validate(class_, tag, contents) if self._choice == 2: if AttCertVersion.load(Sequence.load(contents)[0].dump()).native == 'v2': self._choice = 3 class CertificateSet(SetOf): _child_spec = CertificateChoices class ContentInfo(Sequence): _fields = [ ('content_type', ContentType), ('content', Any, {'explicit': 0, 'optional': True}), ] _oid_pair = ('content_type', 'content') _oid_specs = {} class SetOfContentInfo(SetOf): _child_spec = ContentInfo class EncapsulatedContentInfo(Sequence): _fields = [ ('content_type', ContentType), ('content', ParsableOctetString, {'explicit': 0, 'optional': True}), ] _oid_pair = ('content_type', 'content') _oid_specs = {} class IssuerAndSerialNumber(Sequence): _fields = [ ('issuer', Name), ('serial_number', Integer), ] class SignerIdentifier(Choice): _alternatives = [ ('issuer_and_serial_number', IssuerAndSerialNumber), ('subject_key_identifier', OctetString, {'implicit': 0}), ] class DigestAlgorithms(SetOf): _child_spec = DigestAlgorithm class CertificateRevocationLists(SetOf): _child_spec = CertificateList class SCVPReqRes(Sequence): _fields = [ ('request', ContentInfo, {'explicit': 0, 'optional': True}), ('response', ContentInfo), ] class OtherRevInfoFormatId(ObjectIdentifier): _map = { '1.3.6.1.5.5.7.16.2': 'ocsp_response', '1.3.6.1.5.5.7.16.4': 'scvp', } class OtherRevocationInfoFormat(Sequence): _fields = [ ('other_rev_info_format', OtherRevInfoFormatId), ('other_rev_info', Any), ] _oid_pair = ('other_rev_info_format', 'other_rev_info') _oid_specs = { 'ocsp_response': OCSPResponse, 'scvp': SCVPReqRes, } class RevocationInfoChoice(Choice): _alternatives = [ ('crl', CertificateList), ('other', OtherRevocationInfoFormat, {'implicit': 1}), ] class RevocationInfoChoices(SetOf): _child_spec = RevocationInfoChoice class SignerInfo(Sequence): _fields = [ ('version', CMSVersion), ('sid', SignerIdentifier), ('digest_algorithm', DigestAlgorithm), ('signed_attrs', CMSAttributes, {'implicit': 0, 'optional': True}), ('signature_algorithm', SignedDigestAlgorithm), ('signature', OctetString), ('unsigned_attrs', CMSAttributes, {'implicit': 1, 'optional': True}), ] class SignerInfos(SetOf): _child_spec = SignerInfo class SignedData(Sequence): _fields = [ ('version', CMSVersion), ('digest_algorithms', DigestAlgorithms), ('encap_content_info', None), ('certificates', CertificateSet, {'implicit': 0, 'optional': True}), ('crls', RevocationInfoChoices, {'implicit': 1, 'optional': True}), ('signer_infos', SignerInfos), ] def _encap_content_info_spec(self): # If the encap_content_info is version v1, then this could be a PKCS#7 # structure, or a CMS structure. CMS wraps the encoded value in an # Octet String tag. # If the version is greater than 1, it is definite CMS if self['version'].native != 'v1': return EncapsulatedContentInfo # Otherwise, the ContentInfo spec from PKCS#7 will be compatible with # CMS v1 (which only allows Data, an Octet String) and PKCS#7, which # allows Any return ContentInfo _spec_callbacks = { 'encap_content_info': _encap_content_info_spec } class OriginatorInfo(Sequence): _fields = [ ('certs', CertificateSet, {'implicit': 0, 'optional': True}), ('crls', RevocationInfoChoices, {'implicit': 1, 'optional': True}), ] class RecipientIdentifier(Choice): _alternatives = [ ('issuer_and_serial_number', IssuerAndSerialNumber), ('subject_key_identifier', OctetString, {'implicit': 0}), ] class KeyEncryptionAlgorithmId(ObjectIdentifier): _map = { '1.2.840.113549.1.1.1': 'rsaes_pkcs1v15', '1.2.840.113549.1.1.7': 'rsaes_oaep', '2.16.840.1.101.3.4.1.5': 'aes128_wrap', '2.16.840.1.101.3.4.1.8': 'aes128_wrap_pad', '2.16.840.1.101.3.4.1.25': 'aes192_wrap', '2.16.840.1.101.3.4.1.28': 'aes192_wrap_pad', '2.16.840.1.101.3.4.1.45': 'aes256_wrap', '2.16.840.1.101.3.4.1.48': 'aes256_wrap_pad', } _reverse_map = { 'rsa': '1.2.840.113549.1.1.1', 'rsaes_pkcs1v15': '1.2.840.113549.1.1.1', 'rsaes_oaep': '1.2.840.113549.1.1.7', 'aes128_wrap': '2.16.840.1.101.3.4.1.5', 'aes128_wrap_pad': '2.16.840.1.101.3.4.1.8', 'aes192_wrap': '2.16.840.1.101.3.4.1.25', 'aes192_wrap_pad': '2.16.840.1.101.3.4.1.28', 'aes256_wrap': '2.16.840.1.101.3.4.1.45', 'aes256_wrap_pad': '2.16.840.1.101.3.4.1.48', } class KeyEncryptionAlgorithm(_ForceNullParameters, Sequence): _fields = [ ('algorithm', KeyEncryptionAlgorithmId), ('parameters', Any, {'optional': True}), ] _oid_pair = ('algorithm', 'parameters') _oid_specs = { 'rsaes_oaep': RSAESOAEPParams, } class KeyTransRecipientInfo(Sequence): _fields = [ ('version', CMSVersion), ('rid', RecipientIdentifier), ('key_encryption_algorithm', KeyEncryptionAlgorithm), ('encrypted_key', OctetString), ] class OriginatorIdentifierOrKey(Choice): _alternatives = [ ('issuer_and_serial_number', IssuerAndSerialNumber), ('subject_key_identifier', OctetString, {'implicit': 0}), ('originator_key', PublicKeyInfo, {'implicit': 1}), ] class OtherKeyAttribute(Sequence): _fields = [ ('key_attr_id', ObjectIdentifier), ('key_attr', Any), ] class RecipientKeyIdentifier(Sequence): _fields = [ ('subject_key_identifier', OctetString), ('date', GeneralizedTime, {'optional': True}), ('other', OtherKeyAttribute, {'optional': True}), ] class KeyAgreementRecipientIdentifier(Choice): _alternatives = [ ('issuer_and_serial_number', IssuerAndSerialNumber), ('r_key_id', RecipientKeyIdentifier, {'implicit': 0}), ] class RecipientEncryptedKey(Sequence): _fields = [ ('rid', KeyAgreementRecipientIdentifier), ('encrypted_key', OctetString), ] class RecipientEncryptedKeys(SequenceOf): _child_spec = RecipientEncryptedKey class KeyAgreeRecipientInfo(Sequence): _fields = [ ('version', CMSVersion), ('originator', OriginatorIdentifierOrKey, {'explicit': 0}), ('ukm', OctetString, {'explicit': 1, 'optional': True}), ('key_encryption_algorithm', KeyEncryptionAlgorithm), ('recipient_encrypted_keys', RecipientEncryptedKeys), ] class KEKIdentifier(Sequence): _fields = [ ('key_identifier', OctetString), ('date', GeneralizedTime, {'optional': True}), ('other', OtherKeyAttribute, {'optional': True}), ] class KEKRecipientInfo(Sequence): _fields = [ ('version', CMSVersion), ('kekid', KEKIdentifier), ('key_encryption_algorithm', KeyEncryptionAlgorithm), ('encrypted_key', OctetString), ] class PasswordRecipientInfo(Sequence): _fields = [ ('version', CMSVersion), ('key_derivation_algorithm', KdfAlgorithm, {'implicit': 0, 'optional': True}), ('key_encryption_algorithm', KeyEncryptionAlgorithm), ('encrypted_key', OctetString), ] class OtherRecipientInfo(Sequence): _fields = [ ('ori_type', ObjectIdentifier), ('ori_value', Any), ] class RecipientInfo(Choice): _alternatives = [ ('ktri', KeyTransRecipientInfo), ('kari', KeyAgreeRecipientInfo, {'implicit': 1}), ('kekri', KEKRecipientInfo, {'implicit': 2}), ('pwri', PasswordRecipientInfo, {'implicit': 3}), ('ori', OtherRecipientInfo, {'implicit': 4}), ] class RecipientInfos(SetOf): _child_spec = RecipientInfo class EncryptedContentInfo(Sequence): _fields = [ ('content_type', ContentType), ('content_encryption_algorithm', EncryptionAlgorithm), ('encrypted_content', OctetString, {'implicit': 0, 'optional': True}), ] class EnvelopedData(Sequence): _fields = [ ('version', CMSVersion), ('originator_info', OriginatorInfo, {'implicit': 0, 'optional': True}), ('recipient_infos', RecipientInfos), ('encrypted_content_info', EncryptedContentInfo), ('unprotected_attrs', CMSAttributes, {'implicit': 1, 'optional': True}), ] class SignedAndEnvelopedData(Sequence): _fields = [ ('version', CMSVersion), ('recipient_infos', RecipientInfos), ('digest_algorithms', DigestAlgorithms), ('encrypted_content_info', EncryptedContentInfo), ('certificates', CertificateSet, {'implicit': 0, 'optional': True}), ('crls', CertificateRevocationLists, {'implicit': 1, 'optional': True}), ('signer_infos', SignerInfos), ] class DigestedData(Sequence): _fields = [ ('version', CMSVersion), ('digest_algorithm', DigestAlgorithm), ('encap_content_info', None), ('digest', OctetString), ] def _encap_content_info_spec(self): # If the encap_content_info is version v1, then this could be a PKCS#7 # structure, or a CMS structure. CMS wraps the encoded value in an # Octet String tag. # If the version is greater than 1, it is definite CMS if self['version'].native != 'v1': return EncapsulatedContentInfo # Otherwise, the ContentInfo spec from PKCS#7 will be compatible with # CMS v1 (which only allows Data, an Octet String) and PKCS#7, which # allows Any return ContentInfo _spec_callbacks = { 'encap_content_info': _encap_content_info_spec } class EncryptedData(Sequence): _fields = [ ('version', CMSVersion), ('encrypted_content_info', EncryptedContentInfo), ('unprotected_attrs', CMSAttributes, {'implicit': 1, 'optional': True}), ] class AuthenticatedData(Sequence): _fields = [ ('version', CMSVersion), ('originator_info', OriginatorInfo, {'implicit': 0, 'optional': True}), ('recipient_infos', RecipientInfos), ('mac_algorithm', HmacAlgorithm), ('digest_algorithm', DigestAlgorithm, {'implicit': 1, 'optional': True}), # This does not require the _spec_callbacks approach of SignedData and # DigestedData since AuthenticatedData was not part of PKCS#7 ('encap_content_info', EncapsulatedContentInfo), ('auth_attrs', CMSAttributes, {'implicit': 2, 'optional': True}), ('mac', OctetString), ('unauth_attrs', CMSAttributes, {'implicit': 3, 'optional': True}), ] class AuthEnvelopedData(Sequence): _fields = [ ('version', CMSVersion), ('originator_info', OriginatorInfo, {'implicit': 0, 'optional': True}), ('recipient_infos', RecipientInfos), ('auth_encrypted_content_info', EncryptedContentInfo), ('auth_attrs', CMSAttributes, {'implicit': 1, 'optional': True}), ('mac', OctetString), ('unauth_attrs', CMSAttributes, {'implicit': 2, 'optional': True}), ] class CompressionAlgorithmId(ObjectIdentifier): _map = { '1.2.840.113549.1.9.16.3.8': 'zlib', } class CompressionAlgorithm(Sequence): _fields = [ ('algorithm', CompressionAlgorithmId), ('parameters', Any, {'optional': True}), ] class CompressedData(Sequence): _fields = [ ('version', CMSVersion), ('compression_algorithm', CompressionAlgorithm), ('encap_content_info', EncapsulatedContentInfo), ] _decompressed = None @property def decompressed(self): if self._decompressed is None: if zlib is None: raise SystemError('The zlib module is not available') self._decompressed = zlib.decompress(self['encap_content_info']['content'].native) return self._decompressed class RecipientKeyIdentifier(Sequence): _fields = [ ('subjectKeyIdentifier', OctetString), ('date', GeneralizedTime, {'optional': True}), ('other', OtherKeyAttribute, {'optional': True}), ] class SMIMEEncryptionKeyPreference(Choice): _alternatives = [ ('issuer_and_serial_number', IssuerAndSerialNumber, {'implicit': 0}), ('recipientKeyId', RecipientKeyIdentifier, {'implicit': 1}), ('subjectAltKeyIdentifier', PublicKeyInfo, {'implicit': 2}), ] class SMIMEEncryptionKeyPreferences(SetOf): _child_spec = SMIMEEncryptionKeyPreference class SMIMECapabilityIdentifier(Sequence): _fields = [ ('capability_id', EncryptionAlgorithmId), ('parameters', Any, {'optional': True}), ] class SMIMECapabilites(SequenceOf): _child_spec = SMIMECapabilityIdentifier class SetOfSMIMECapabilites(SetOf): _child_spec = SMIMECapabilites ContentInfo._oid_specs = { 'data': OctetString, 'signed_data': SignedData, 'enveloped_data': EnvelopedData, 'signed_and_enveloped_data': SignedAndEnvelopedData, 'digested_data': DigestedData, 'encrypted_data': EncryptedData, 'authenticated_data': AuthenticatedData, 'compressed_data': CompressedData, 'authenticated_enveloped_data': AuthEnvelopedData, } EncapsulatedContentInfo._oid_specs = { 'signed_data': SignedData, 'enveloped_data': EnvelopedData, 'signed_and_enveloped_data': SignedAndEnvelopedData, 'digested_data': DigestedData, 'encrypted_data': EncryptedData, 'authenticated_data': AuthenticatedData, 'compressed_data': CompressedData, 'authenticated_enveloped_data': AuthEnvelopedData, } CMSAttribute._oid_specs = { 'content_type': SetOfContentType, 'message_digest': SetOfOctetString, 'signing_time': SetOfTime, 'counter_signature': SignerInfos, 'signature_time_stamp_token': SetOfContentInfo, 'cms_algorithm_protection': SetOfCMSAlgorithmProtection, 'microsoft_nested_signature': SetOfContentInfo, 'microsoft_time_stamp_token': SetOfContentInfo, 'encrypt_key_pref': SMIMEEncryptionKeyPreferences, 'smime_capabilities': SetOfSMIMECapabilites, } core.py000064400000515334152572326550006075 0ustar00# coding: utf-8 """ ASN.1 type classes for universal types. Exports the following items: - load() - Any() - Asn1Value() - BitString() - BMPString() - Boolean() - CharacterString() - Choice() - EmbeddedPdv() - Enumerated() - GeneralizedTime() - GeneralString() - GraphicString() - IA5String() - InstanceOf() - Integer() - IntegerBitString() - IntegerOctetString() - Null() - NumericString() - ObjectDescriptor() - ObjectIdentifier() - OctetBitString() - OctetString() - PrintableString() - Real() - RelativeOid() - Sequence() - SequenceOf() - Set() - SetOf() - TeletexString() - UniversalString() - UTCTime() - UTF8String() - VideotexString() - VisibleString() - VOID - Void() Other type classes are defined that help compose the types listed above. """ from __future__ import unicode_literals, division, absolute_import, print_function from datetime import datetime, timedelta from fractions import Fraction import binascii import copy import math import re import sys from . import _teletex_codec from ._errors import unwrap from ._ordereddict import OrderedDict from ._types import type_name, str_cls, byte_cls, int_types, chr_cls from .parser import _parse, _dump_header from .util import int_to_bytes, int_from_bytes, timezone, extended_datetime, create_timezone, utc_with_dst if sys.version_info <= (3,): from cStringIO import StringIO as BytesIO range = xrange # noqa _PY2 = True else: from io import BytesIO _PY2 = False _teletex_codec.register() CLASS_NUM_TO_NAME_MAP = { 0: 'universal', 1: 'application', 2: 'context', 3: 'private', } CLASS_NAME_TO_NUM_MAP = { 'universal': 0, 'application': 1, 'context': 2, 'private': 3, 0: 0, 1: 1, 2: 2, 3: 3, } METHOD_NUM_TO_NAME_MAP = { 0: 'primitive', 1: 'constructed', } _OID_RE = re.compile(r'^\d+(\.\d+)*$') # A global tracker to ensure that _setup() is called for every class, even # if is has been called for a parent class. This allows different _fields # definitions for child classes. Without such a construct, the child classes # would just see the parent class attributes and would use them. _SETUP_CLASSES = {} def load(encoded_data, strict=False): """ Loads a BER/DER-encoded byte string and construct a universal object based on the tag value: - 1: Boolean - 2: Integer - 3: BitString - 4: OctetString - 5: Null - 6: ObjectIdentifier - 7: ObjectDescriptor - 8: InstanceOf - 9: Real - 10: Enumerated - 11: EmbeddedPdv - 12: UTF8String - 13: RelativeOid - 16: Sequence, - 17: Set - 18: NumericString - 19: PrintableString - 20: TeletexString - 21: VideotexString - 22: IA5String - 23: UTCTime - 24: GeneralizedTime - 25: GraphicString - 26: VisibleString - 27: GeneralString - 28: UniversalString - 29: CharacterString - 30: BMPString :param encoded_data: A byte string of BER or DER-encoded data :param strict: A boolean indicating if trailing data should be forbidden - if so, a ValueError will be raised when trailing data exists :raises: ValueError - when strict is True and trailing data is present ValueError - when the encoded value tag a tag other than listed above ValueError - when the ASN.1 header length is longer than the data TypeError - when encoded_data is not a byte string :return: An instance of the one of the universal classes """ return Asn1Value.load(encoded_data, strict=strict) class Asn1Value(object): """ The basis of all ASN.1 values """ # The integer 0 for primitive, 1 for constructed method = None # An integer 0 through 3 - see CLASS_NUM_TO_NAME_MAP for value class_ = None # An integer 1 or greater indicating the tag number tag = None # An alternate tag allowed for this type - used for handling broken # structures where a string value is encoded using an incorrect tag _bad_tag = None # If the value has been implicitly tagged implicit = False # If explicitly tagged, a tuple of 2-element tuples containing the # class int and tag int, from innermost to outermost explicit = None # The BER/DER header bytes _header = None # Raw encoded value bytes not including class, method, tag, length header contents = None # The BER/DER trailer bytes _trailer = b'' # The native python representation of the value - this is not used by # some classes since they utilize _bytes or _unicode _native = None @classmethod def load(cls, encoded_data, strict=False, **kwargs): """ Loads a BER/DER-encoded byte string using the current class as the spec :param encoded_data: A byte string of BER or DER-encoded data :param strict: A boolean indicating if trailing data should be forbidden - if so, a ValueError will be raised when trailing data exists :return: An instance of the current class """ if not isinstance(encoded_data, byte_cls): raise TypeError('encoded_data must be a byte string, not %s' % type_name(encoded_data)) spec = None if cls.tag is not None: spec = cls value, _ = _parse_build(encoded_data, spec=spec, spec_params=kwargs, strict=strict) return value def __init__(self, explicit=None, implicit=None, no_explicit=False, tag_type=None, class_=None, tag=None, optional=None, default=None, contents=None, method=None): """ The optional parameter is not used, but rather included so we don't have to delete it from the parameter dictionary when passing as keyword args :param explicit: An int tag number for explicit tagging, or a 2-element tuple of class and tag. :param implicit: An int tag number for implicit tagging, or a 2-element tuple of class and tag. :param no_explicit: If explicit tagging info should be removed from this instance. Used internally to allow contructing the underlying value that has been wrapped in an explicit tag. :param tag_type: None for normal values, or one of "implicit", "explicit" for tagged values. Deprecated in favor of explicit and implicit params. :param class_: The class for the value - defaults to "universal" if tag_type is None, otherwise defaults to "context". Valid values include: - "universal" - "application" - "context" - "private" Deprecated in favor of explicit and implicit params. :param tag: The integer tag to override - usually this is used with tag_type or class_. Deprecated in favor of explicit and implicit params. :param optional: Dummy parameter that allows "optional" key in spec param dicts :param default: The default value to use if the value is currently None :param contents: A byte string of the encoded contents of the value :param method: The method for the value - no default value since this is normally set on a class. Valid values include: - "primitive" or 0 - "constructed" or 1 :raises: ValueError - when implicit, explicit, tag_type, class_ or tag are invalid values """ try: if self.__class__ not in _SETUP_CLASSES: cls = self.__class__ # Allow explicit to be specified as a simple 2-element tuple # instead of requiring the user make a nested tuple if cls.explicit is not None and isinstance(cls.explicit[0], int_types): cls.explicit = (cls.explicit, ) if hasattr(cls, '_setup'): self._setup() _SETUP_CLASSES[cls] = True # Normalize tagging values if explicit is not None: if isinstance(explicit, int_types): if class_ is None: class_ = 'context' explicit = (class_, explicit) # Prevent both explicit and tag_type == 'explicit' if tag_type == 'explicit': tag_type = None tag = None if implicit is not None: if isinstance(implicit, int_types): if class_ is None: class_ = 'context' implicit = (class_, implicit) # Prevent both implicit and tag_type == 'implicit' if tag_type == 'implicit': tag_type = None tag = None # Convert old tag_type API to explicit/implicit params if tag_type is not None: if class_ is None: class_ = 'context' if tag_type == 'explicit': explicit = (class_, tag) elif tag_type == 'implicit': implicit = (class_, tag) else: raise ValueError(unwrap( ''' tag_type must be one of "implicit", "explicit", not %s ''', repr(tag_type) )) if explicit is not None: # Ensure we have a tuple of 2-element tuples if len(explicit) == 2 and isinstance(explicit[1], int_types): explicit = (explicit, ) for class_, tag in explicit: invalid_class = None if isinstance(class_, int_types): if class_ not in CLASS_NUM_TO_NAME_MAP: invalid_class = class_ else: if class_ not in CLASS_NAME_TO_NUM_MAP: invalid_class = class_ class_ = CLASS_NAME_TO_NUM_MAP[class_] if invalid_class is not None: raise ValueError(unwrap( ''' explicit class must be one of "universal", "application", "context", "private", not %s ''', repr(invalid_class) )) if tag is not None: if not isinstance(tag, int_types): raise TypeError(unwrap( ''' explicit tag must be an integer, not %s ''', type_name(tag) )) if self.explicit is None: self.explicit = ((class_, tag), ) else: self.explicit = self.explicit + ((class_, tag), ) elif implicit is not None: class_, tag = implicit if class_ not in CLASS_NAME_TO_NUM_MAP: raise ValueError(unwrap( ''' implicit class must be one of "universal", "application", "context", "private", not %s ''', repr(class_) )) if tag is not None: if not isinstance(tag, int_types): raise TypeError(unwrap( ''' implicit tag must be an integer, not %s ''', type_name(tag) )) self.class_ = CLASS_NAME_TO_NUM_MAP[class_] self.tag = tag self.implicit = True else: if class_ is not None: if class_ not in CLASS_NAME_TO_NUM_MAP: raise ValueError(unwrap( ''' class_ must be one of "universal", "application", "context", "private", not %s ''', repr(class_) )) self.class_ = CLASS_NAME_TO_NUM_MAP[class_] if self.class_ is None: self.class_ = 0 if tag is not None: self.tag = tag if method is not None: if method not in set(["primitive", 0, "constructed", 1]): raise ValueError(unwrap( ''' method must be one of "primitive" or "constructed", not %s ''', repr(method) )) if method == "primitive": method = 0 elif method == "constructed": method = 1 self.method = method if no_explicit: self.explicit = None if contents is not None: self.contents = contents elif default is not None: self.set(default) except (ValueError, TypeError) as e: args = e.args[1:] e.args = (e.args[0] + '\n while constructing %s' % type_name(self),) + args raise e def __str__(self): """ Since str is different in Python 2 and 3, this calls the appropriate method, __unicode__() or __bytes__() :return: A unicode string """ if _PY2: return self.__bytes__() else: return self.__unicode__() def __repr__(self): """ :return: A unicode string """ if _PY2: return '<%s %s b%s>' % (type_name(self), id(self), repr(self.dump())) else: return '<%s %s %s>' % (type_name(self), id(self), repr(self.dump())) def __bytes__(self): """ A fall-back method for print() in Python 2 :return: A byte string of the output of repr() """ return self.__repr__().encode('utf-8') def __unicode__(self): """ A fall-back method for print() in Python 3 :return: A unicode string of the output of repr() """ return self.__repr__() def _new_instance(self): """ Constructs a new copy of the current object, preserving any tagging :return: An Asn1Value object """ new_obj = self.__class__() new_obj.class_ = self.class_ new_obj.tag = self.tag new_obj.implicit = self.implicit new_obj.explicit = self.explicit return new_obj def __copy__(self): """ Implements the copy.copy() interface :return: A new shallow copy of the current Asn1Value object """ new_obj = self._new_instance() new_obj._copy(self, copy.copy) return new_obj def __deepcopy__(self, memo): """ Implements the copy.deepcopy() interface :param memo: A dict for memoization :return: A new deep copy of the current Asn1Value object """ new_obj = self._new_instance() memo[id(self)] = new_obj new_obj._copy(self, copy.deepcopy) return new_obj def copy(self): """ Copies the object, preserving any special tagging from it :return: An Asn1Value object """ return copy.deepcopy(self) def retag(self, tagging, tag=None): """ Copies the object, applying a new tagging to it :param tagging: A dict containing the keys "explicit" and "implicit". Legacy API allows a unicode string of "implicit" or "explicit". :param tag: A integer tag number. Only used when tagging is a unicode string. :return: An Asn1Value object """ # This is required to preserve the old API if not isinstance(tagging, dict): tagging = {tagging: tag} new_obj = self.__class__(explicit=tagging.get('explicit'), implicit=tagging.get('implicit')) new_obj._copy(self, copy.deepcopy) return new_obj def untag(self): """ Copies the object, removing any special tagging from it :return: An Asn1Value object """ new_obj = self.__class__() new_obj._copy(self, copy.deepcopy) return new_obj def _copy(self, other, copy_func): """ Copies the contents of another Asn1Value object to itself :param object: Another instance of the same class :param copy_func: An reference of copy.copy() or copy.deepcopy() to use when copying lists, dicts and objects """ if self.__class__ != other.__class__: raise TypeError(unwrap( ''' Can not copy values from %s object to %s object ''', type_name(other), type_name(self) )) self.contents = other.contents self._native = copy_func(other._native) def debug(self, nest_level=1): """ Show the binary data and parsed data in a tree structure """ prefix = ' ' * nest_level # This interacts with Any and moves the tag, implicit, explicit, _header, # contents, _footer to the parsed value so duplicate data isn't present has_parsed = hasattr(self, 'parsed') _basic_debug(prefix, self) if has_parsed: self.parsed.debug(nest_level + 2) elif hasattr(self, 'chosen'): self.chosen.debug(nest_level + 2) else: if _PY2 and isinstance(self.native, byte_cls): print('%s Native: b%s' % (prefix, repr(self.native))) else: print('%s Native: %s' % (prefix, self.native)) def dump(self, force=False): """ Encodes the value using DER :param force: If the encoded contents already exist, clear them and regenerate to ensure they are in DER format instead of BER format :return: A byte string of the DER-encoded value """ contents = self.contents # If the length is indefinite, force the re-encoding if self._header is not None and self._header[-1:] == b'\x80': force = True if self._header is None or force: if isinstance(self, Constructable) and self._indefinite: self.method = 0 header = _dump_header(self.class_, self.method, self.tag, self.contents) if self.explicit is not None: for class_, tag in self.explicit: header = _dump_header(class_, 1, tag, header + self.contents) + header self._header = header self._trailer = b'' return self._header + contents + self._trailer class ValueMap(): """ Basic functionality that allows for mapping values from ints or OIDs to python unicode strings """ # A dict from primitive value (int or OID) to unicode string. This needs # to be defined in the source code _map = None # A dict from unicode string to int/OID. This is automatically generated # from _map the first time it is needed _reverse_map = None def _setup(self): """ Generates _reverse_map from _map """ cls = self.__class__ if cls._map is None or cls._reverse_map is not None: return cls._reverse_map = {} for key, value in cls._map.items(): cls._reverse_map[value] = key class Castable(object): """ A mixin to handle converting an object between different classes that represent the same encoded value, but with different rules for converting to and from native Python values """ def cast(self, other_class): """ Converts the current object into an object of a different class. The new class must use the ASN.1 encoding for the value. :param other_class: The class to instantiate the new object from :return: An instance of the type other_class """ if other_class.tag != self.__class__.tag: raise TypeError(unwrap( ''' Can not covert a value from %s object to %s object since they use different tags: %d versus %d ''', type_name(other_class), type_name(self), other_class.tag, self.__class__.tag )) new_obj = other_class() new_obj.class_ = self.class_ new_obj.implicit = self.implicit new_obj.explicit = self.explicit new_obj._header = self._header new_obj.contents = self.contents new_obj._trailer = self._trailer if isinstance(self, Constructable): new_obj.method = self.method new_obj._indefinite = self._indefinite return new_obj class Constructable(object): """ A mixin to handle string types that may be constructed from chunks contained within an indefinite length BER-encoded container """ # Instance attribute indicating if an object was indefinite # length when parsed - affects parsing and dumping _indefinite = False def _merge_chunks(self): """ :return: A concatenation of the native values of the contained chunks """ if not self._indefinite: return self._as_chunk() pointer = 0 contents_len = len(self.contents) output = None while pointer < contents_len: # We pass the current class as the spec so content semantics are preserved sub_value, pointer = _parse_build(self.contents, pointer, spec=self.__class__) if output is None: output = sub_value._merge_chunks() else: output += sub_value._merge_chunks() if output is None: return self._as_chunk() return output def _as_chunk(self): """ A method to return a chunk of data that can be combined for constructed method values :return: A native Python value that can be added together. Examples include byte strings, unicode strings or tuples. """ return self.contents def _setable_native(self): """ Returns a native value that can be round-tripped into .set(), to result in a DER encoding. This differs from .native in that .native is designed for the end use, and may account for the fact that the merged value is further parsed as ASN.1, such as in the case of ParsableOctetString() and ParsableOctetBitString(). :return: A python value that is valid to pass to .set() """ return self.native def _copy(self, other, copy_func): """ Copies the contents of another Constructable object to itself :param object: Another instance of the same class :param copy_func: An reference of copy.copy() or copy.deepcopy() to use when copying lists, dicts and objects """ super(Constructable, self)._copy(other, copy_func) # We really don't want to dump BER encodings, so if we see an # indefinite encoding, let's re-encode it if other._indefinite: self.set(other._setable_native()) class Void(Asn1Value): """ A representation of an optional value that is not present. Has .native property and .dump() method to be compatible with other value classes. """ contents = b'' def __eq__(self, other): """ :param other: The other Primitive to compare to :return: A boolean """ return other.__class__ == self.__class__ def __nonzero__(self): return False def __len__(self): return 0 def __iter__(self): return iter(()) @property def native(self): """ The native Python datatype representation of this value :return: None """ return None def dump(self, force=False): """ Encodes the value using DER :param force: If the encoded contents already exist, clear them and regenerate to ensure they are in DER format instead of BER format :return: A byte string of the DER-encoded value """ return b'' VOID = Void() class Any(Asn1Value): """ A value class that can contain any value, and allows for easy parsing of the underlying encoded value using a spec. This is normally contained in a Structure that has an ObjectIdentifier field and _oid_pair and _oid_specs defined. """ # The parsed value object _parsed = None def __init__(self, value=None, **kwargs): """ Sets the value of the object before passing to Asn1Value.__init__() :param value: An Asn1Value object that will be set as the parsed value """ Asn1Value.__init__(self, **kwargs) try: if value is not None: if not isinstance(value, Asn1Value): raise TypeError(unwrap( ''' value must be an instance of Asn1Value, not %s ''', type_name(value) )) self._parsed = (value, value.__class__, None) self.contents = value.dump() except (ValueError, TypeError) as e: args = e.args[1:] e.args = (e.args[0] + '\n while constructing %s' % type_name(self),) + args raise e @property def native(self): """ The native Python datatype representation of this value :return: The .native value from the parsed value object """ if self._parsed is None: self.parse() return self._parsed[0].native @property def parsed(self): """ Returns the parsed object from .parse() :return: The object returned by .parse() """ if self._parsed is None: self.parse() return self._parsed[0] def parse(self, spec=None, spec_params=None): """ Parses the contents generically, or using a spec with optional params :param spec: A class derived from Asn1Value that defines what class_ and tag the value should have, and the semantics of the encoded value. The return value will be of this type. If omitted, the encoded value will be decoded using the standard universal tag based on the encoded tag number. :param spec_params: A dict of params to pass to the spec object :return: An object of the type spec, or if not present, a child of Asn1Value """ if self._parsed is None or self._parsed[1:3] != (spec, spec_params): try: passed_params = spec_params or {} _tag_type_to_explicit_implicit(passed_params) if self.explicit is not None: if 'explicit' in passed_params: passed_params['explicit'] = self.explicit + passed_params['explicit'] else: passed_params['explicit'] = self.explicit contents = self._header + self.contents + self._trailer parsed_value, _ = _parse_build( contents, spec=spec, spec_params=passed_params ) self._parsed = (parsed_value, spec, spec_params) # Once we've parsed the Any value, clear any attributes from this object # since they are now duplicate self.tag = None self.explicit = None self.implicit = False self._header = b'' self.contents = contents self._trailer = b'' except (ValueError, TypeError) as e: args = e.args[1:] e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args raise e return self._parsed[0] def _copy(self, other, copy_func): """ Copies the contents of another Any object to itself :param object: Another instance of the same class :param copy_func: An reference of copy.copy() or copy.deepcopy() to use when copying lists, dicts and objects """ super(Any, self)._copy(other, copy_func) self._parsed = copy_func(other._parsed) def dump(self, force=False): """ Encodes the value using DER :param force: If the encoded contents already exist, clear them and regenerate to ensure they are in DER format instead of BER format :return: A byte string of the DER-encoded value """ if self._parsed is None: self.parse() return self._parsed[0].dump(force=force) class Choice(Asn1Value): """ A class to handle when a value may be one of several options """ # The index in _alternatives of the validated alternative _choice = None # The name of the chosen alternative _name = None # The Asn1Value object for the chosen alternative _parsed = None # Choice overrides .contents to be a property so that the code expecting # the .contents attribute will get the .contents of the chosen alternative _contents = None # A list of tuples in one of the following forms. # # Option 1, a unicode string field name and a value class # # ("name", Asn1ValueClass) # # Option 2, same as Option 1, but with a dict of class params # # ("name", Asn1ValueClass, {'explicit': 5}) _alternatives = None # A dict that maps tuples of (class_, tag) to an index in _alternatives _id_map = None # A dict that maps alternative names to an index in _alternatives _name_map = None @classmethod def load(cls, encoded_data, strict=False, **kwargs): """ Loads a BER/DER-encoded byte string using the current class as the spec :param encoded_data: A byte string of BER or DER encoded data :param strict: A boolean indicating if trailing data should be forbidden - if so, a ValueError will be raised when trailing data exists :return: A instance of the current class """ if not isinstance(encoded_data, byte_cls): raise TypeError('encoded_data must be a byte string, not %s' % type_name(encoded_data)) value, _ = _parse_build(encoded_data, spec=cls, spec_params=kwargs, strict=strict) return value def _setup(self): """ Generates _id_map from _alternatives to allow validating contents """ cls = self.__class__ cls._id_map = {} cls._name_map = {} for index, info in enumerate(cls._alternatives): if len(info) < 3: info = info + ({},) cls._alternatives[index] = info id_ = _build_id_tuple(info[2], info[1]) cls._id_map[id_] = index cls._name_map[info[0]] = index def __init__(self, name=None, value=None, **kwargs): """ Checks to ensure implicit tagging is not being used since it is incompatible with Choice, then forwards on to Asn1Value.__init__() :param name: The name of the alternative to be set - used with value. Alternatively this may be a dict with a single key being the name and the value being the value, or a two-element tuple of the name and the value. :param value: The alternative value to set - used with name :raises: ValueError - when implicit param is passed (or legacy tag_type param is "implicit") """ _tag_type_to_explicit_implicit(kwargs) Asn1Value.__init__(self, **kwargs) try: if kwargs.get('implicit') is not None: raise ValueError(unwrap( ''' The Choice type can not be implicitly tagged even if in an implicit module - due to its nature any tagging must be explicit ''' )) if name is not None: if isinstance(name, dict): if len(name) != 1: raise ValueError(unwrap( ''' When passing a dict as the "name" argument to %s, it must have a single key/value - however %d were present ''', type_name(self), len(name) )) name, value = list(name.items())[0] if isinstance(name, tuple): if len(name) != 2: raise ValueError(unwrap( ''' When passing a tuple as the "name" argument to %s, it must have two elements, the name and value - however %d were present ''', type_name(self), len(name) )) value = name[1] name = name[0] if name not in self._name_map: raise ValueError(unwrap( ''' The name specified, "%s", is not a valid alternative for %s ''', name, type_name(self) )) self._choice = self._name_map[name] _, spec, params = self._alternatives[self._choice] if not isinstance(value, spec): value = spec(value, **params) else: value = _fix_tagging(value, params) self._parsed = value except (ValueError, TypeError) as e: args = e.args[1:] e.args = (e.args[0] + '\n while constructing %s' % type_name(self),) + args raise e @property def contents(self): """ :return: A byte string of the DER-encoded contents of the chosen alternative """ if self._parsed is not None: return self._parsed.contents return self._contents @contents.setter def contents(self, value): """ :param value: A byte string of the DER-encoded contents of the chosen alternative """ self._contents = value @property def name(self): """ :return: A unicode string of the field name of the chosen alternative """ if not self._name: self._name = self._alternatives[self._choice][0] return self._name def parse(self): """ Parses the detected alternative :return: An Asn1Value object of the chosen alternative """ if self._parsed is None: try: _, spec, params = self._alternatives[self._choice] self._parsed, _ = _parse_build(self._contents, spec=spec, spec_params=params) except (ValueError, TypeError) as e: args = e.args[1:] e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args raise e return self._parsed @property def chosen(self): """ :return: An Asn1Value object of the chosen alternative """ return self.parse() @property def native(self): """ The native Python datatype representation of this value :return: The .native value from the contained value object """ return self.chosen.native def validate(self, class_, tag, contents): """ Ensures that the class and tag specified exist as an alternative :param class_: The integer class_ from the encoded value header :param tag: The integer tag from the encoded value header :param contents: A byte string of the contents of the value - used when the object is explicitly tagged :raises: ValueError - when value is not a valid alternative """ id_ = (class_, tag) if self.explicit is not None: if self.explicit[-1] != id_: raise ValueError(unwrap( ''' %s was explicitly tagged, but the value provided does not match the class and tag ''', type_name(self) )) ((class_, _, tag, _, _, _), _) = _parse(contents, len(contents)) id_ = (class_, tag) if id_ in self._id_map: self._choice = self._id_map[id_] return # This means the Choice was implicitly tagged if self.class_ is not None and self.tag is not None: if len(self._alternatives) > 1: raise ValueError(unwrap( ''' %s was implicitly tagged, but more than one alternative exists ''', type_name(self) )) if id_ == (self.class_, self.tag): self._choice = 0 return asn1 = self._format_class_tag(class_, tag) asn1s = [self._format_class_tag(pair[0], pair[1]) for pair in self._id_map] raise ValueError(unwrap( ''' Value %s did not match the class and tag of any of the alternatives in %s: %s ''', asn1, type_name(self), ', '.join(asn1s) )) def _format_class_tag(self, class_, tag): """ :return: A unicode string of a human-friendly representation of the class and tag """ return '[%s %s]' % (CLASS_NUM_TO_NAME_MAP[class_].upper(), tag) def _copy(self, other, copy_func): """ Copies the contents of another Choice object to itself :param object: Another instance of the same class :param copy_func: An reference of copy.copy() or copy.deepcopy() to use when copying lists, dicts and objects """ super(Choice, self)._copy(other, copy_func) self._choice = other._choice self._name = other._name self._parsed = copy_func(other._parsed) def dump(self, force=False): """ Encodes the value using DER :param force: If the encoded contents already exist, clear them and regenerate to ensure they are in DER format instead of BER format :return: A byte string of the DER-encoded value """ # If the length is indefinite, force the re-encoding if self._header is not None and self._header[-1:] == b'\x80': force = True self._contents = self.chosen.dump(force=force) if self._header is None or force: self._header = b'' if self.explicit is not None: for class_, tag in self.explicit: self._header = _dump_header(class_, 1, tag, self._header + self._contents) + self._header return self._header + self._contents class Concat(object): """ A class that contains two or more encoded child values concatentated together. THIS IS NOT PART OF THE ASN.1 SPECIFICATION! This exists to handle the x509.TrustedCertificate() class for OpenSSL certificates containing extra information. """ # A list of the specs of the concatenated values _child_specs = None _children = None @classmethod def load(cls, encoded_data, strict=False): """ Loads a BER/DER-encoded byte string using the current class as the spec :param encoded_data: A byte string of BER or DER encoded data :param strict: A boolean indicating if trailing data should be forbidden - if so, a ValueError will be raised when trailing data exists :return: A Concat object """ return cls(contents=encoded_data, strict=strict) def __init__(self, value=None, contents=None, strict=False): """ :param value: A native Python datatype to initialize the object value with :param contents: A byte string of the encoded contents of the value :param strict: A boolean indicating if trailing data should be forbidden - if so, a ValueError will be raised when trailing data exists in contents :raises: ValueError - when an error occurs with one of the children TypeError - when an error occurs with one of the children """ if contents is not None: try: contents_len = len(contents) self._children = [] offset = 0 for spec in self._child_specs: if offset < contents_len: child_value, offset = _parse_build(contents, pointer=offset, spec=spec) else: child_value = spec() self._children.append(child_value) if strict and offset != contents_len: extra_bytes = contents_len - offset raise ValueError('Extra data - %d bytes of trailing data were provided' % extra_bytes) except (ValueError, TypeError) as e: args = e.args[1:] e.args = (e.args[0] + '\n while constructing %s' % type_name(self),) + args raise e if value is not None: if self._children is None: self._children = [None] * len(self._child_specs) for index, data in enumerate(value): self.__setitem__(index, data) def __str__(self): """ Since str is different in Python 2 and 3, this calls the appropriate method, __unicode__() or __bytes__() :return: A unicode string """ if _PY2: return self.__bytes__() else: return self.__unicode__() def __bytes__(self): """ A byte string of the DER-encoded contents """ return self.dump() def __unicode__(self): """ :return: A unicode string """ return repr(self) def __repr__(self): """ :return: A unicode string """ return '<%s %s %s>' % (type_name(self), id(self), repr(self.dump())) def __copy__(self): """ Implements the copy.copy() interface :return: A new shallow copy of the Concat object """ new_obj = self.__class__() new_obj._copy(self, copy.copy) return new_obj def __deepcopy__(self, memo): """ Implements the copy.deepcopy() interface :param memo: A dict for memoization :return: A new deep copy of the Concat object and all child objects """ new_obj = self.__class__() memo[id(self)] = new_obj new_obj._copy(self, copy.deepcopy) return new_obj def copy(self): """ Copies the object :return: A Concat object """ return copy.deepcopy(self) def _copy(self, other, copy_func): """ Copies the contents of another Concat object to itself :param object: Another instance of the same class :param copy_func: An reference of copy.copy() or copy.deepcopy() to use when copying lists, dicts and objects """ if self.__class__ != other.__class__: raise TypeError(unwrap( ''' Can not copy values from %s object to %s object ''', type_name(other), type_name(self) )) self._children = copy_func(other._children) def debug(self, nest_level=1): """ Show the binary data and parsed data in a tree structure """ prefix = ' ' * nest_level print('%s%s Object #%s' % (prefix, type_name(self), id(self))) print('%s Children:' % (prefix,)) for child in self._children: child.debug(nest_level + 2) def dump(self, force=False): """ Encodes the value using DER :param force: If the encoded contents already exist, clear them and regenerate to ensure they are in DER format instead of BER format :return: A byte string of the DER-encoded value """ contents = b'' for child in self._children: contents += child.dump(force=force) return contents @property def contents(self): """ :return: A byte string of the DER-encoded contents of the children """ return self.dump() def __len__(self): """ :return: Integer """ return len(self._children) def __getitem__(self, key): """ Allows accessing children by index :param key: An integer of the child index :raises: KeyError - when an index is invalid :return: The Asn1Value object of the child specified """ if key > len(self._child_specs) - 1 or key < 0: raise KeyError(unwrap( ''' No child is definition for position %d of %s ''', key, type_name(self) )) return self._children[key] def __setitem__(self, key, value): """ Allows settings children by index :param key: An integer of the child index :param value: An Asn1Value object to set the child to :raises: KeyError - when an index is invalid ValueError - when the value is not an instance of Asn1Value """ if key > len(self._child_specs) - 1 or key < 0: raise KeyError(unwrap( ''' No child is defined for position %d of %s ''', key, type_name(self) )) if not isinstance(value, Asn1Value): raise ValueError(unwrap( ''' Value for child %s of %s is not an instance of asn1crypto.core.Asn1Value ''', key, type_name(self) )) self._children[key] = value def __iter__(self): """ :return: An iterator of child values """ return iter(self._children) class Primitive(Asn1Value): """ Sets the class_ and method attributes for primitive, universal values """ class_ = 0 method = 0 def __init__(self, value=None, default=None, contents=None, **kwargs): """ Sets the value of the object before passing to Asn1Value.__init__() :param value: A native Python datatype to initialize the object value with :param default: The default value if no value is specified :param contents: A byte string of the encoded contents of the value """ Asn1Value.__init__(self, **kwargs) try: if contents is not None: self.contents = contents elif value is not None: self.set(value) elif default is not None: self.set(default) except (ValueError, TypeError) as e: args = e.args[1:] e.args = (e.args[0] + '\n while constructing %s' % type_name(self),) + args raise e def set(self, value): """ Sets the value of the object :param value: A byte string """ if not isinstance(value, byte_cls): raise TypeError(unwrap( ''' %s value must be a byte string, not %s ''', type_name(self), type_name(value) )) self._native = value self.contents = value self._header = None if self._trailer != b'': self._trailer = b'' def dump(self, force=False): """ Encodes the value using DER :param force: If the encoded contents already exist, clear them and regenerate to ensure they are in DER format instead of BER format :return: A byte string of the DER-encoded value """ # If the length is indefinite, force the re-encoding if self._header is not None and self._header[-1:] == b'\x80': force = True if force: native = self.native self.contents = None self.set(native) return Asn1Value.dump(self) def __ne__(self, other): return not self == other def __eq__(self, other): """ :param other: The other Primitive to compare to :return: A boolean """ if not isinstance(other, Primitive): return False if self.contents != other.contents: return False # We compare class tag numbers since object tag numbers could be # different due to implicit or explicit tagging if self.__class__.tag != other.__class__.tag: return False if self.__class__ == other.__class__ and self.contents == other.contents: return True # If the objects share a common base class that is not too low-level # then we can compare the contents self_bases = (set(self.__class__.__bases__) | set([self.__class__])) - set([Asn1Value, Primitive, ValueMap]) other_bases = (set(other.__class__.__bases__) | set([other.__class__])) - set([Asn1Value, Primitive, ValueMap]) if self_bases | other_bases: return self.contents == other.contents # When tagging is going on, do the extra work of constructing new # objects to see if the dumped representation are the same if self.implicit or self.explicit or other.implicit or other.explicit: return self.untag().dump() == other.untag().dump() return self.dump() == other.dump() class AbstractString(Constructable, Primitive): """ A base class for all strings that have a known encoding. In general, we do not worry ourselves with confirming that the decoded values match a specific set of characters, only that they are decoded into a Python unicode string """ # The Python encoding name to use when decoding or encoded the contents _encoding = 'latin1' # Instance attribute of (possibly-merged) unicode string _unicode = None def set(self, value): """ Sets the value of the string :param value: A unicode string """ if not isinstance(value, str_cls): raise TypeError(unwrap( ''' %s value must be a unicode string, not %s ''', type_name(self), type_name(value) )) self._unicode = value self.contents = value.encode(self._encoding) self._header = None if self._indefinite: self._indefinite = False self.method = 0 if self._trailer != b'': self._trailer = b'' def __unicode__(self): """ :return: A unicode string """ if self.contents is None: return '' if self._unicode is None: self._unicode = self._merge_chunks().decode(self._encoding) return self._unicode def _copy(self, other, copy_func): """ Copies the contents of another AbstractString object to itself :param object: Another instance of the same class :param copy_func: An reference of copy.copy() or copy.deepcopy() to use when copying lists, dicts and objects """ super(AbstractString, self)._copy(other, copy_func) self._unicode = other._unicode @property def native(self): """ The native Python datatype representation of this value :return: A unicode string or None """ if self.contents is None: return None return self.__unicode__() class Boolean(Primitive): """ Represents a boolean in both ASN.1 and Python """ tag = 1 def set(self, value): """ Sets the value of the object :param value: True, False or another value that works with bool() """ self._native = bool(value) self.contents = b'\x00' if not value else b'\xff' self._header = None if self._trailer != b'': self._trailer = b'' # Python 2 def __nonzero__(self): """ :return: True or False """ return self.__bool__() def __bool__(self): """ :return: True or False """ return self.contents != b'\x00' @property def native(self): """ The native Python datatype representation of this value :return: True, False or None """ if self.contents is None: return None if self._native is None: self._native = self.__bool__() return self._native class Integer(Primitive, ValueMap): """ Represents an integer in both ASN.1 and Python """ tag = 2 def set(self, value): """ Sets the value of the object :param value: An integer, or a unicode string if _map is set :raises: ValueError - when an invalid value is passed """ if isinstance(value, str_cls): if self._map is None: raise ValueError(unwrap( ''' %s value is a unicode string, but no _map provided ''', type_name(self) )) if value not in self._reverse_map: raise ValueError(unwrap( ''' %s value, %s, is not present in the _map ''', type_name(self), value )) value = self._reverse_map[value] elif not isinstance(value, int_types): raise TypeError(unwrap( ''' %s value must be an integer or unicode string when a name_map is provided, not %s ''', type_name(self), type_name(value) )) self._native = self._map[value] if self._map and value in self._map else value self.contents = int_to_bytes(value, signed=True) self._header = None if self._trailer != b'': self._trailer = b'' def __int__(self): """ :return: An integer """ return int_from_bytes(self.contents, signed=True) @property def native(self): """ The native Python datatype representation of this value :return: An integer or None """ if self.contents is None: return None if self._native is None: self._native = self.__int__() if self._map is not None and self._native in self._map: self._native = self._map[self._native] return self._native class _IntegerBitString(object): """ A mixin for IntegerBitString and BitString to parse the contents as an integer. """ # Tuple of 1s and 0s; set through native _unused_bits = () def _as_chunk(self): """ Parse the contents of a primitive BitString encoding as an integer value. Allows reconstructing indefinite length values. :raises: ValueError - when an invalid value is passed :return: A list with one tuple (value, bits, unused_bits) where value is an integer with the value of the BitString, bits is the bit count of value and unused_bits is a tuple of 1s and 0s. """ if self._indefinite: # return an empty chunk, for cases like \x23\x80\x00\x00 return [] unused_bits_len = ord(self.contents[0]) if _PY2 else self.contents[0] value = int_from_bytes(self.contents[1:]) bits = (len(self.contents) - 1) * 8 if not unused_bits_len: return [(value, bits, ())] if len(self.contents) == 1: # Disallowed by X.690 §8.6.2.3 raise ValueError('Empty bit string has {0} unused bits'.format(unused_bits_len)) if unused_bits_len > 7: # Disallowed by X.690 §8.6.2.2 raise ValueError('Bit string has {0} unused bits'.format(unused_bits_len)) unused_bits = _int_to_bit_tuple(value & ((1 << unused_bits_len) - 1), unused_bits_len) value >>= unused_bits_len bits -= unused_bits_len return [(value, bits, unused_bits)] def _chunks_to_int(self): """ Combines the chunks into a single value. :raises: ValueError - when an invalid value is passed :return: A tuple (value, bits, unused_bits) where value is an integer with the value of the BitString, bits is the bit count of value and unused_bits is a tuple of 1s and 0s. """ if not self._indefinite: # Fast path return self._as_chunk()[0] value = 0 total_bits = 0 unused_bits = () # X.690 §8.6.3 allows empty indefinite encodings for chunk, bits, unused_bits in self._merge_chunks(): if total_bits & 7: # Disallowed by X.690 §8.6.4 raise ValueError('Only last chunk in a bit string may have unused bits') total_bits += bits value = (value << bits) | chunk return value, total_bits, unused_bits def _copy(self, other, copy_func): """ Copies the contents of another _IntegerBitString object to itself :param object: Another instance of the same class :param copy_func: An reference of copy.copy() or copy.deepcopy() to use when copying lists, dicts and objects """ super(_IntegerBitString, self)._copy(other, copy_func) self._unused_bits = other._unused_bits @property def unused_bits(self): """ The unused bits of the bit string encoding. :return: A tuple of 1s and 0s """ # call native to set _unused_bits self.native return self._unused_bits class BitString(_IntegerBitString, Constructable, Castable, Primitive, ValueMap): """ Represents a bit string from ASN.1 as a Python tuple of 1s and 0s """ tag = 3 _size = None def _setup(self): """ Generates _reverse_map from _map """ ValueMap._setup(self) cls = self.__class__ if cls._map is not None: cls._size = max(self._map.keys()) + 1 def set(self, value): """ Sets the value of the object :param value: An integer or a tuple of integers 0 and 1 :raises: ValueError - when an invalid value is passed """ if isinstance(value, set): if self._map is None: raise ValueError(unwrap( ''' %s._map has not been defined ''', type_name(self) )) bits = [0] * self._size self._native = value for index in range(0, self._size): key = self._map.get(index) if key is None: continue if key in value: bits[index] = 1 value = ''.join(map(str_cls, bits)) elif value.__class__ == tuple: if self._map is None: self._native = value else: self._native = set() for index, bit in enumerate(value): if bit: name = self._map.get(index, index) self._native.add(name) value = ''.join(map(str_cls, value)) else: raise TypeError(unwrap( ''' %s value must be a tuple of ones and zeros or a set of unicode strings, not %s ''', type_name(self), type_name(value) )) if self._map is not None: if len(value) > self._size: raise ValueError(unwrap( ''' %s value must be at most %s bits long, specified was %s long ''', type_name(self), self._size, len(value) )) # A NamedBitList must have trailing zero bit truncated. See # https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf # section 11.2, # https://tools.ietf.org/html/rfc5280#page-134 and # https://www.ietf.org/mail-archive/web/pkix/current/msg10443.html value = value.rstrip('0') size = len(value) size_mod = size % 8 extra_bits = 0 if size_mod != 0: extra_bits = 8 - size_mod value += '0' * extra_bits size_in_bytes = int(math.ceil(size / 8)) if extra_bits: extra_bits_byte = int_to_bytes(extra_bits) else: extra_bits_byte = b'\x00' if value == '': value_bytes = b'' else: value_bytes = int_to_bytes(int(value, 2)) if len(value_bytes) != size_in_bytes: value_bytes = (b'\x00' * (size_in_bytes - len(value_bytes))) + value_bytes self.contents = extra_bits_byte + value_bytes self._unused_bits = (0,) * extra_bits self._header = None if self._indefinite: self._indefinite = False self.method = 0 if self._trailer != b'': self._trailer = b'' def __getitem__(self, key): """ Retrieves a boolean version of one of the bits based on a name from the _map :param key: The unicode string of one of the bit names :raises: ValueError - when _map is not set or the key name is invalid :return: A boolean if the bit is set """ is_int = isinstance(key, int_types) if not is_int: if not isinstance(self._map, dict): raise ValueError(unwrap( ''' %s._map has not been defined ''', type_name(self) )) if key not in self._reverse_map: raise ValueError(unwrap( ''' %s._map does not contain an entry for "%s" ''', type_name(self), key )) if self._native is None: self.native if self._map is None: if len(self._native) >= key + 1: return bool(self._native[key]) return False if is_int: key = self._map.get(key, key) return key in self._native def __setitem__(self, key, value): """ Sets one of the bits based on a name from the _map :param key: The unicode string of one of the bit names :param value: A boolean value :raises: ValueError - when _map is not set or the key name is invalid """ is_int = isinstance(key, int_types) if not is_int: if self._map is None: raise ValueError(unwrap( ''' %s._map has not been defined ''', type_name(self) )) if key not in self._reverse_map: raise ValueError(unwrap( ''' %s._map does not contain an entry for "%s" ''', type_name(self), key )) if self._native is None: self.native if self._map is None: new_native = list(self._native) max_key = len(new_native) - 1 if key > max_key: new_native.extend([0] * (key - max_key)) new_native[key] = 1 if value else 0 self._native = tuple(new_native) else: if is_int: key = self._map.get(key, key) if value: if key not in self._native: self._native.add(key) else: if key in self._native: self._native.remove(key) self.set(self._native) @property def native(self): """ The native Python datatype representation of this value :return: If a _map is set, a set of names, or if no _map is set, a tuple of integers 1 and 0. None if no value. """ # For BitString we default the value to be all zeros if self.contents is None: if self._map is None: self.set(()) else: self.set(set()) if self._native is None: int_value, bit_count, self._unused_bits = self._chunks_to_int() bits = _int_to_bit_tuple(int_value, bit_count) if self._map: self._native = set() for index, bit in enumerate(bits): if bit: name = self._map.get(index, index) self._native.add(name) else: self._native = bits return self._native class OctetBitString(Constructable, Castable, Primitive): """ Represents a bit string in ASN.1 as a Python byte string """ tag = 3 # Instance attribute of (possibly-merged) byte string _bytes = None # Tuple of 1s and 0s; set through native _unused_bits = () def set(self, value): """ Sets the value of the object :param value: A byte string :raises: ValueError - when an invalid value is passed """ if not isinstance(value, byte_cls): raise TypeError(unwrap( ''' %s value must be a byte string, not %s ''', type_name(self), type_name(value) )) self._bytes = value # Set the unused bits to 0 self.contents = b'\x00' + value self._unused_bits = () self._header = None if self._indefinite: self._indefinite = False self.method = 0 if self._trailer != b'': self._trailer = b'' def __bytes__(self): """ :return: A byte string """ if self.contents is None: return b'' if self._bytes is None: if not self._indefinite: self._bytes, self._unused_bits = self._as_chunk()[0] else: chunks = self._merge_chunks() self._unused_bits = () for chunk in chunks: if self._unused_bits: # Disallowed by X.690 §8.6.4 raise ValueError('Only last chunk in a bit string may have unused bits') self._unused_bits = chunk[1] self._bytes = b''.join(chunk[0] for chunk in chunks) return self._bytes def _copy(self, other, copy_func): """ Copies the contents of another OctetBitString object to itself :param object: Another instance of the same class :param copy_func: An reference of copy.copy() or copy.deepcopy() to use when copying lists, dicts and objects """ super(OctetBitString, self)._copy(other, copy_func) self._bytes = other._bytes self._unused_bits = other._unused_bits def _as_chunk(self): """ Allows reconstructing indefinite length values :raises: ValueError - when an invalid value is passed :return: List with one tuple, consisting of a byte string and an integer (unused bits) """ unused_bits_len = ord(self.contents[0]) if _PY2 else self.contents[0] if not unused_bits_len: return [(self.contents[1:], ())] if len(self.contents) == 1: # Disallowed by X.690 §8.6.2.3 raise ValueError('Empty bit string has {0} unused bits'.format(unused_bits_len)) if unused_bits_len > 7: # Disallowed by X.690 §8.6.2.2 raise ValueError('Bit string has {0} unused bits'.format(unused_bits_len)) mask = (1 << unused_bits_len) - 1 last_byte = ord(self.contents[-1]) if _PY2 else self.contents[-1] # zero out the unused bits in the last byte. zeroed_byte = last_byte & ~mask value = self.contents[1:-1] + (chr(zeroed_byte) if _PY2 else bytes((zeroed_byte,))) unused_bits = _int_to_bit_tuple(last_byte & mask, unused_bits_len) return [(value, unused_bits)] @property def native(self): """ The native Python datatype representation of this value :return: A byte string or None """ if self.contents is None: return None return self.__bytes__() @property def unused_bits(self): """ The unused bits of the bit string encoding. :return: A tuple of 1s and 0s """ # call native to set _unused_bits self.native return self._unused_bits class IntegerBitString(_IntegerBitString, Constructable, Castable, Primitive): """ Represents a bit string in ASN.1 as a Python integer """ tag = 3 def set(self, value): """ Sets the value of the object :param value: An integer :raises: ValueError - when an invalid value is passed """ if not isinstance(value, int_types): raise TypeError(unwrap( ''' %s value must be a positive integer, not %s ''', type_name(self), type_name(value) )) if value < 0: raise ValueError(unwrap( ''' %s value must be a positive integer, not %d ''', type_name(self), value )) self._native = value # Set the unused bits to 0 self.contents = b'\x00' + int_to_bytes(value, signed=True) self._unused_bits = () self._header = None if self._indefinite: self._indefinite = False self.method = 0 if self._trailer != b'': self._trailer = b'' @property def native(self): """ The native Python datatype representation of this value :return: An integer or None """ if self.contents is None: return None if self._native is None: self._native, __, self._unused_bits = self._chunks_to_int() return self._native class OctetString(Constructable, Castable, Primitive): """ Represents a byte string in both ASN.1 and Python """ tag = 4 # Instance attribute of (possibly-merged) byte string _bytes = None def set(self, value): """ Sets the value of the object :param value: A byte string """ if not isinstance(value, byte_cls): raise TypeError(unwrap( ''' %s value must be a byte string, not %s ''', type_name(self), type_name(value) )) self._bytes = value self.contents = value self._header = None if self._indefinite: self._indefinite = False self.method = 0 if self._trailer != b'': self._trailer = b'' def __bytes__(self): """ :return: A byte string """ if self.contents is None: return b'' if self._bytes is None: self._bytes = self._merge_chunks() return self._bytes def _copy(self, other, copy_func): """ Copies the contents of another OctetString object to itself :param object: Another instance of the same class :param copy_func: An reference of copy.copy() or copy.deepcopy() to use when copying lists, dicts and objects """ super(OctetString, self)._copy(other, copy_func) self._bytes = other._bytes @property def native(self): """ The native Python datatype representation of this value :return: A byte string or None """ if self.contents is None: return None return self.__bytes__() class IntegerOctetString(Constructable, Castable, Primitive): """ Represents a byte string in ASN.1 as a Python integer """ tag = 4 # An explicit length in bytes the integer should be encoded to. This should # generally not be used since DER defines a canonical encoding, however some # use of this, such as when storing elliptic curve private keys, requires an # exact number of bytes, even if the leading bytes are null. _encoded_width = None def set(self, value): """ Sets the value of the object :param value: An integer :raises: ValueError - when an invalid value is passed """ if not isinstance(value, int_types): raise TypeError(unwrap( ''' %s value must be a positive integer, not %s ''', type_name(self), type_name(value) )) if value < 0: raise ValueError(unwrap( ''' %s value must be a positive integer, not %d ''', type_name(self), value )) self._native = value self.contents = int_to_bytes(value, signed=False, width=self._encoded_width) self._header = None if self._indefinite: self._indefinite = False self.method = 0 if self._trailer != b'': self._trailer = b'' @property def native(self): """ The native Python datatype representation of this value :return: An integer or None """ if self.contents is None: return None if self._native is None: self._native = int_from_bytes(self._merge_chunks()) return self._native def set_encoded_width(self, width): """ Set the explicit enoding width for the integer :param width: An integer byte width to encode the integer to """ self._encoded_width = width # Make sure the encoded value is up-to-date with the proper width if self.contents is not None and len(self.contents) != width: self.set(self.native) class ParsableOctetString(Constructable, Castable, Primitive): tag = 4 _parsed = None # Instance attribute of (possibly-merged) byte string _bytes = None def __init__(self, value=None, parsed=None, **kwargs): """ Allows providing a parsed object that will be serialized to get the byte string value :param value: A native Python datatype to initialize the object value with :param parsed: If value is None and this is an Asn1Value object, this will be set as the parsed value, and the value will be obtained by calling .dump() on this object. """ set_parsed = False if value is None and parsed is not None and isinstance(parsed, Asn1Value): value = parsed.dump() set_parsed = True Primitive.__init__(self, value=value, **kwargs) if set_parsed: self._parsed = (parsed, parsed.__class__, None) def set(self, value): """ Sets the value of the object :param value: A byte string """ if not isinstance(value, byte_cls): raise TypeError(unwrap( ''' %s value must be a byte string, not %s ''', type_name(self), type_name(value) )) self._bytes = value self.contents = value self._header = None if self._indefinite: self._indefinite = False self.method = 0 if self._trailer != b'': self._trailer = b'' def parse(self, spec=None, spec_params=None): """ Parses the contents generically, or using a spec with optional params :param spec: A class derived from Asn1Value that defines what class_ and tag the value should have, and the semantics of the encoded value. The return value will be of this type. If omitted, the encoded value will be decoded using the standard universal tag based on the encoded tag number. :param spec_params: A dict of params to pass to the spec object :return: An object of the type spec, or if not present, a child of Asn1Value """ if self._parsed is None or self._parsed[1:3] != (spec, spec_params): parsed_value, _ = _parse_build(self.__bytes__(), spec=spec, spec_params=spec_params) self._parsed = (parsed_value, spec, spec_params) return self._parsed[0] def __bytes__(self): """ :return: A byte string """ if self.contents is None: return b'' if self._bytes is None: self._bytes = self._merge_chunks() return self._bytes def _setable_native(self): """ Returns a byte string that can be passed into .set() :return: A python value that is valid to pass to .set() """ return self.__bytes__() def _copy(self, other, copy_func): """ Copies the contents of another ParsableOctetString object to itself :param object: Another instance of the same class :param copy_func: An reference of copy.copy() or copy.deepcopy() to use when copying lists, dicts and objects """ super(ParsableOctetString, self)._copy(other, copy_func) self._bytes = other._bytes self._parsed = copy_func(other._parsed) @property def native(self): """ The native Python datatype representation of this value :return: A byte string or None """ if self.contents is None: return None if self._parsed is not None: return self._parsed[0].native else: return self.__bytes__() @property def parsed(self): """ Returns the parsed object from .parse() :return: The object returned by .parse() """ if self._parsed is None: self.parse() return self._parsed[0] def dump(self, force=False): """ Encodes the value using DER :param force: If the encoded contents already exist, clear them and regenerate to ensure they are in DER format instead of BER format :return: A byte string of the DER-encoded value """ # If the length is indefinite, force the re-encoding if self._indefinite: force = True if force: if self._parsed is not None: native = self.parsed.dump(force=force) else: native = self.native self.contents = None self.set(native) return Asn1Value.dump(self) class ParsableOctetBitString(ParsableOctetString): tag = 3 def set(self, value): """ Sets the value of the object :param value: A byte string :raises: ValueError - when an invalid value is passed """ if not isinstance(value, byte_cls): raise TypeError(unwrap( ''' %s value must be a byte string, not %s ''', type_name(self), type_name(value) )) self._bytes = value # Set the unused bits to 0 self.contents = b'\x00' + value self._header = None if self._indefinite: self._indefinite = False self.method = 0 if self._trailer != b'': self._trailer = b'' def _as_chunk(self): """ Allows reconstructing indefinite length values :raises: ValueError - when an invalid value is passed :return: A byte string """ unused_bits_len = ord(self.contents[0]) if _PY2 else self.contents[0] if unused_bits_len: raise ValueError('ParsableOctetBitString should have no unused bits') return self.contents[1:] class Null(Primitive): """ Represents a null value in ASN.1 as None in Python """ tag = 5 contents = b'' def set(self, value): """ Sets the value of the object :param value: None """ self.contents = b'' @property def native(self): """ The native Python datatype representation of this value :return: None """ return None class ObjectIdentifier(Primitive, ValueMap): """ Represents an object identifier in ASN.1 as a Python unicode dotted integer string """ tag = 6 # A unicode string of the dotted form of the object identifier _dotted = None @classmethod def map(cls, value): """ Converts a dotted unicode string OID into a mapped unicode string :param value: A dotted unicode string OID :raises: ValueError - when no _map dict has been defined on the class TypeError - when value is not a unicode string :return: A mapped unicode string """ if cls._map is None: raise ValueError(unwrap( ''' %s._map has not been defined ''', type_name(cls) )) if not isinstance(value, str_cls): raise TypeError(unwrap( ''' value must be a unicode string, not %s ''', type_name(value) )) return cls._map.get(value, value) @classmethod def unmap(cls, value): """ Converts a mapped unicode string value into a dotted unicode string OID :param value: A mapped unicode string OR dotted unicode string OID :raises: ValueError - when no _map dict has been defined on the class or the value can't be unmapped TypeError - when value is not a unicode string :return: A dotted unicode string OID """ if cls not in _SETUP_CLASSES: cls()._setup() _SETUP_CLASSES[cls] = True if cls._map is None: raise ValueError(unwrap( ''' %s._map has not been defined ''', type_name(cls) )) if not isinstance(value, str_cls): raise TypeError(unwrap( ''' value must be a unicode string, not %s ''', type_name(value) )) if value in cls._reverse_map: return cls._reverse_map[value] if not _OID_RE.match(value): raise ValueError(unwrap( ''' %s._map does not contain an entry for "%s" ''', type_name(cls), value )) return value def set(self, value): """ Sets the value of the object :param value: A unicode string. May be a dotted integer string, or if _map is provided, one of the mapped values. :raises: ValueError - when an invalid value is passed """ if not isinstance(value, str_cls): raise TypeError(unwrap( ''' %s value must be a unicode string, not %s ''', type_name(self), type_name(value) )) self._native = value if self._map is not None: if value in self._reverse_map: value = self._reverse_map[value] self.contents = b'' first = None for index, part in enumerate(value.split('.')): part = int(part) # The first two parts are merged into a single byte if index == 0: first = part continue elif index == 1: if first > 2: raise ValueError(unwrap( ''' First arc must be one of 0, 1 or 2, not %s ''', repr(first) )) elif first < 2 and part >= 40: raise ValueError(unwrap( ''' Second arc must be less than 40 if first arc is 0 or 1, not %s ''', repr(part) )) part = (first * 40) + part encoded_part = chr_cls(0x7F & part) part = part >> 7 while part > 0: encoded_part = chr_cls(0x80 | (0x7F & part)) + encoded_part part = part >> 7 self.contents += encoded_part self._header = None if self._trailer != b'': self._trailer = b'' def __unicode__(self): """ :return: A unicode string """ return self.dotted @property def dotted(self): """ :return: A unicode string of the object identifier in dotted notation, thus ignoring any mapped value """ if self._dotted is None: output = [] part = 0 for byte in self.contents: if _PY2: byte = ord(byte) part = part * 128 part += byte & 127 # Last byte in subidentifier has the eighth bit set to 0 if byte & 0x80 == 0: if len(output) == 0: if part >= 80: output.append(str_cls(2)) output.append(str_cls(part - 80)) elif part >= 40: output.append(str_cls(1)) output.append(str_cls(part - 40)) else: output.append(str_cls(0)) output.append(str_cls(part)) else: output.append(str_cls(part)) part = 0 self._dotted = '.'.join(output) return self._dotted @property def native(self): """ The native Python datatype representation of this value :return: A unicode string or None. If _map is not defined, the unicode string is a string of dotted integers. If _map is defined and the dotted string is present in the _map, the mapped value is returned. """ if self.contents is None: return None if self._native is None: self._native = self.dotted if self._map is not None and self._native in self._map: self._native = self._map[self._native] return self._native class ObjectDescriptor(Primitive): """ Represents an object descriptor from ASN.1 - no Python implementation """ tag = 7 class InstanceOf(Primitive): """ Represents an instance from ASN.1 - no Python implementation """ tag = 8 class Real(Primitive): """ Represents a real number from ASN.1 - no Python implementation """ tag = 9 class Enumerated(Integer): """ Represents a enumerated list of integers from ASN.1 as a Python unicode string """ tag = 10 def set(self, value): """ Sets the value of the object :param value: An integer or a unicode string from _map :raises: ValueError - when an invalid value is passed """ if not isinstance(value, int_types) and not isinstance(value, str_cls): raise TypeError(unwrap( ''' %s value must be an integer or a unicode string, not %s ''', type_name(self), type_name(value) )) if isinstance(value, str_cls): if value not in self._reverse_map: raise ValueError(unwrap( ''' %s value "%s" is not a valid value ''', type_name(self), value )) value = self._reverse_map[value] elif value not in self._map: raise ValueError(unwrap( ''' %s value %s is not a valid value ''', type_name(self), value )) Integer.set(self, value) @property def native(self): """ The native Python datatype representation of this value :return: A unicode string or None """ if self.contents is None: return None if self._native is None: self._native = self._map[self.__int__()] return self._native class UTF8String(AbstractString): """ Represents a UTF-8 string from ASN.1 as a Python unicode string """ tag = 12 _encoding = 'utf-8' class RelativeOid(ObjectIdentifier): """ Represents an object identifier in ASN.1 as a Python unicode dotted integer string """ tag = 13 class Sequence(Asn1Value): """ Represents a sequence of fields from ASN.1 as a Python object with a dict-like interface """ tag = 16 class_ = 0 method = 1 # A list of child objects, in order of _fields children = None # Sequence overrides .contents to be a property so that the mutated state # of child objects can be checked to ensure everything is up-to-date _contents = None # Variable to track if the object has been mutated _mutated = False # A list of tuples in one of the following forms. # # Option 1, a unicode string field name and a value class # # ("name", Asn1ValueClass) # # Option 2, same as Option 1, but with a dict of class params # # ("name", Asn1ValueClass, {'explicit': 5}) _fields = [] # A dict with keys being the name of a field and the value being a unicode # string of the method name on self to call to get the spec for that field _spec_callbacks = None # A dict that maps unicode string field names to an index in _fields _field_map = None # A list in the same order as _fields that has tuples in the form (class_, tag) _field_ids = None # An optional 2-element tuple that defines the field names of an OID field # and the field that the OID should be used to help decode. Works with the # _oid_specs attribute. _oid_pair = None # A dict with keys that are unicode string OID values and values that are # Asn1Value classes to use for decoding a variable-type field. _oid_specs = None # A 2-element tuple of the indexes in _fields of the OID and value fields _oid_nums = None # Predetermined field specs to optimize away calls to _determine_spec() _precomputed_specs = None def __init__(self, value=None, default=None, **kwargs): """ Allows setting field values before passing everything else along to Asn1Value.__init__() :param value: A native Python datatype to initialize the object value with :param default: The default value if no value is specified """ Asn1Value.__init__(self, **kwargs) check_existing = False if value is None and default is not None: check_existing = True if self.children is None: if self.contents is None: check_existing = False else: self._parse_children() value = default if value is not None: try: # Fields are iterated in definition order to allow things like # OID-based specs. Otherwise sometimes the value would be processed # before the OID field, resulting in invalid value object creation. if self._fields: keys = [info[0] for info in self._fields] unused_keys = set(value.keys()) else: keys = value.keys() unused_keys = set(keys) for key in keys: # If we are setting defaults, but a real value has already # been set for the field, then skip it if check_existing: index = self._field_map[key] if index < len(self.children) and self.children[index] is not VOID: if key in unused_keys: unused_keys.remove(key) continue if key in value: self.__setitem__(key, value[key]) unused_keys.remove(key) if len(unused_keys): raise ValueError(unwrap( ''' One or more unknown fields was passed to the constructor of %s: %s ''', type_name(self), ', '.join(sorted(list(unused_keys))) )) except (ValueError, TypeError) as e: args = e.args[1:] e.args = (e.args[0] + '\n while constructing %s' % type_name(self),) + args raise e @property def contents(self): """ :return: A byte string of the DER-encoded contents of the sequence """ if self.children is None: return self._contents if self._is_mutated(): self._set_contents() return self._contents @contents.setter def contents(self, value): """ :param value: A byte string of the DER-encoded contents of the sequence """ self._contents = value def _is_mutated(self): """ :return: A boolean - if the sequence or any children (recursively) have been mutated """ mutated = self._mutated if self.children is not None: for child in self.children: if isinstance(child, Sequence) or isinstance(child, SequenceOf): mutated = mutated or child._is_mutated() return mutated def _lazy_child(self, index): """ Builds a child object if the child has only been parsed into a tuple so far """ child = self.children[index] if child.__class__ == tuple: child = self.children[index] = _build(*child) return child def __len__(self): """ :return: Integer """ # We inline this check to prevent method invocation each time if self.children is None: self._parse_children() return len(self.children) def __getitem__(self, key): """ Allows accessing fields by name or index :param key: A unicode string of the field name, or an integer of the field index :raises: KeyError - when a field name or index is invalid :return: The Asn1Value object of the field specified """ # We inline this check to prevent method invocation each time if self.children is None: self._parse_children() if not isinstance(key, int_types): if key not in self._field_map: raise KeyError(unwrap( ''' No field named "%s" defined for %s ''', key, type_name(self) )) key = self._field_map[key] if key >= len(self.children): raise KeyError(unwrap( ''' No field numbered %s is present in this %s ''', key, type_name(self) )) try: return self._lazy_child(key) except (ValueError, TypeError) as e: args = e.args[1:] e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args raise e def __setitem__(self, key, value): """ Allows settings fields by name or index :param key: A unicode string of the field name, or an integer of the field index :param value: A native Python datatype to set the field value to. This method will construct the appropriate Asn1Value object from _fields. :raises: ValueError - when a field name or index is invalid """ # We inline this check to prevent method invocation each time if self.children is None: self._parse_children() if not isinstance(key, int_types): if key not in self._field_map: raise KeyError(unwrap( ''' No field named "%s" defined for %s ''', key, type_name(self) )) key = self._field_map[key] field_name, field_spec, value_spec, field_params, _ = self._determine_spec(key) new_value = self._make_value(field_name, field_spec, value_spec, field_params, value) invalid_value = False if isinstance(new_value, Any): invalid_value = new_value.parsed is None else: invalid_value = new_value.contents is None if invalid_value: raise ValueError(unwrap( ''' Value for field "%s" of %s is not set ''', field_name, type_name(self) )) self.children[key] = new_value if self._native is not None: self._native[self._fields[key][0]] = self.children[key].native self._mutated = True def __delitem__(self, key): """ Allows deleting optional or default fields by name or index :param key: A unicode string of the field name, or an integer of the field index :raises: ValueError - when a field name or index is invalid, or the field is not optional or defaulted """ # We inline this check to prevent method invocation each time if self.children is None: self._parse_children() if not isinstance(key, int_types): if key not in self._field_map: raise KeyError(unwrap( ''' No field named "%s" defined for %s ''', key, type_name(self) )) key = self._field_map[key] name, _, params = self._fields[key] if not params or ('default' not in params and 'optional' not in params): raise ValueError(unwrap( ''' Can not delete the value for the field "%s" of %s since it is not optional or defaulted ''', name, type_name(self) )) if 'optional' in params: self.children[key] = VOID if self._native is not None: self._native[name] = None else: self.__setitem__(key, None) self._mutated = True def __iter__(self): """ :return: An iterator of field key names """ for info in self._fields: yield info[0] def _set_contents(self, force=False): """ Updates the .contents attribute of the value with the encoded value of all of the child objects :param force: Ensure all contents are in DER format instead of possibly using cached BER-encoded data """ if self.children is None: self._parse_children() contents = BytesIO() for index, info in enumerate(self._fields): child = self.children[index] if child is None: child_dump = b'' elif child.__class__ == tuple: if force: child_dump = self._lazy_child(index).dump(force=force) else: child_dump = child[3] + child[4] + child[5] else: child_dump = child.dump(force=force) # Skip values that are the same as the default if info[2] and 'default' in info[2]: default_value = info[1](**info[2]) if default_value.dump() == child_dump: continue contents.write(child_dump) self._contents = contents.getvalue() self._header = None if self._trailer != b'': self._trailer = b'' def _setup(self): """ Generates _field_map, _field_ids and _oid_nums for use in parsing """ cls = self.__class__ cls._field_map = {} cls._field_ids = [] cls._precomputed_specs = [] for index, field in enumerate(cls._fields): if len(field) < 3: field = field + ({},) cls._fields[index] = field cls._field_map[field[0]] = index cls._field_ids.append(_build_id_tuple(field[2], field[1])) if cls._oid_pair is not None: cls._oid_nums = (cls._field_map[cls._oid_pair[0]], cls._field_map[cls._oid_pair[1]]) for index, field in enumerate(cls._fields): has_callback = cls._spec_callbacks is not None and field[0] in cls._spec_callbacks is_mapped_oid = cls._oid_nums is not None and cls._oid_nums[1] == index if has_callback or is_mapped_oid: cls._precomputed_specs.append(None) else: cls._precomputed_specs.append((field[0], field[1], field[1], field[2], None)) def _determine_spec(self, index): """ Determine how a value for a field should be constructed :param index: The field number :return: A tuple containing the following elements: - unicode string of the field name - Asn1Value class of the field spec - Asn1Value class of the value spec - None or dict of params to pass to the field spec - None or Asn1Value class indicating the value spec was derived from an OID or a spec callback """ name, field_spec, field_params = self._fields[index] value_spec = field_spec spec_override = None if self._spec_callbacks is not None and name in self._spec_callbacks: callback = self._spec_callbacks[name] spec_override = callback(self) if spec_override: # Allow a spec callback to specify both the base spec and # the override, for situations such as OctetString and parse_as if spec_override.__class__ == tuple and len(spec_override) == 2: field_spec, value_spec = spec_override if value_spec is None: value_spec = field_spec spec_override = None # When no field spec is specified, use a single return value as that elif field_spec is None: field_spec = spec_override value_spec = field_spec spec_override = None else: value_spec = spec_override elif self._oid_nums is not None and self._oid_nums[1] == index: oid = self._lazy_child(self._oid_nums[0]).native if oid in self._oid_specs: spec_override = self._oid_specs[oid] value_spec = spec_override return (name, field_spec, value_spec, field_params, spec_override) def _make_value(self, field_name, field_spec, value_spec, field_params, value): """ Contructs an appropriate Asn1Value object for a field :param field_name: A unicode string of the field name :param field_spec: An Asn1Value class that is the field spec :param value_spec: An Asn1Value class that is the vaue spec :param field_params: None or a dict of params for the field spec :param value: The value to construct an Asn1Value object from :return: An instance of a child class of Asn1Value """ if value is None and 'optional' in field_params: return VOID specs_different = field_spec != value_spec is_any = issubclass(field_spec, Any) if issubclass(value_spec, Choice): is_asn1value = isinstance(value, Asn1Value) is_tuple = isinstance(value, tuple) and len(value) == 2 is_dict = isinstance(value, dict) and len(value) == 1 if not is_asn1value and not is_tuple and not is_dict: raise ValueError(unwrap( ''' Can not set a native python value to %s, which has the choice type of %s - value must be an instance of Asn1Value ''', field_name, type_name(value_spec) )) if is_tuple or is_dict: value = value_spec(value) if not isinstance(value, value_spec): wrapper = value_spec() wrapper.validate(value.class_, value.tag, value.contents) wrapper._parsed = value new_value = wrapper else: new_value = value elif isinstance(value, field_spec): new_value = value if specs_different: new_value.parse(value_spec) elif (not specs_different or is_any) and not isinstance(value, value_spec): if (not is_any or specs_different) and isinstance(value, Asn1Value): raise TypeError(unwrap( ''' %s value must be %s, not %s ''', field_name, type_name(value_spec), type_name(value) )) new_value = value_spec(value, **field_params) else: if isinstance(value, value_spec): new_value = value else: if isinstance(value, Asn1Value): raise TypeError(unwrap( ''' %s value must be %s, not %s ''', field_name, type_name(value_spec), type_name(value) )) new_value = value_spec(value) # For when the field is OctetString or OctetBitString with embedded # values we need to wrap the value in the field spec to get the # appropriate encoded value. if specs_different and not is_any: wrapper = field_spec(value=new_value.dump(), **field_params) wrapper._parsed = (new_value, new_value.__class__, None) new_value = wrapper new_value = _fix_tagging(new_value, field_params) return new_value def _parse_children(self, recurse=False): """ Parses the contents and generates Asn1Value objects based on the definitions from _fields. :param recurse: If child objects that are Sequence or SequenceOf objects should be recursively parsed :raises: ValueError - when an error occurs parsing child objects """ cls = self.__class__ if self._contents is None: if self._fields: self.children = [VOID] * len(self._fields) for index, (_, _, params) in enumerate(self._fields): if 'default' in params: if cls._precomputed_specs[index]: field_name, field_spec, value_spec, field_params, _ = cls._precomputed_specs[index] else: field_name, field_spec, value_spec, field_params, _ = self._determine_spec(index) self.children[index] = self._make_value(field_name, field_spec, value_spec, field_params, None) return try: self.children = [] contents_length = len(self._contents) child_pointer = 0 field = 0 field_len = len(self._fields) parts = None again = child_pointer < contents_length while again: if parts is None: parts, child_pointer = _parse(self._contents, contents_length, pointer=child_pointer) again = child_pointer < contents_length if field < field_len: _, field_spec, value_spec, field_params, spec_override = ( cls._precomputed_specs[field] or self._determine_spec(field)) # If the next value is optional or default, allow it to be absent if field_params and ('optional' in field_params or 'default' in field_params): if self._field_ids[field] != (parts[0], parts[2]) and field_spec != Any: # See if the value is a valid choice before assuming # that we have a missing optional or default value choice_match = False if issubclass(field_spec, Choice): try: tester = field_spec(**field_params) tester.validate(parts[0], parts[2], parts[4]) choice_match = True except (ValueError): pass if not choice_match: if 'optional' in field_params: self.children.append(VOID) else: self.children.append(field_spec(**field_params)) field += 1 again = True continue if field_spec is None or (spec_override and issubclass(field_spec, Any)): field_spec = value_spec spec_override = None if spec_override: child = parts + (field_spec, field_params, value_spec) else: child = parts + (field_spec, field_params) # Handle situations where an optional or defaulted field definition is incorrect elif field_len > 0 and field + 1 <= field_len: missed_fields = [] prev_field = field - 1 while prev_field >= 0: prev_field_info = self._fields[prev_field] if len(prev_field_info) < 3: break if 'optional' in prev_field_info[2] or 'default' in prev_field_info[2]: missed_fields.append(prev_field_info[0]) prev_field -= 1 plural = 's' if len(missed_fields) > 1 else '' missed_field_names = ', '.join(missed_fields) raise ValueError(unwrap( ''' Data for field %s (%s class, %s method, tag %s) does not match the field definition%s of %s ''', field + 1, CLASS_NUM_TO_NAME_MAP.get(parts[0]), METHOD_NUM_TO_NAME_MAP.get(parts[1]), parts[2], plural, missed_field_names )) else: child = parts if recurse: child = _build(*child) if isinstance(child, (Sequence, SequenceOf)): child._parse_children(recurse=True) self.children.append(child) field += 1 parts = None index = len(self.children) while index < field_len: name, field_spec, field_params = self._fields[index] if 'default' in field_params: self.children.append(field_spec(**field_params)) elif 'optional' in field_params: self.children.append(VOID) else: raise ValueError(unwrap( ''' Field "%s" is missing from structure ''', name )) index += 1 except (ValueError, TypeError) as e: self.children = None args = e.args[1:] e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args raise e def spec(self, field_name): """ Determines the spec to use for the field specified. Depending on how the spec is determined (_oid_pair or _spec_callbacks), it may be necessary to set preceding field values before calling this. Usually specs, if dynamic, are controlled by a preceding ObjectIdentifier field. :param field_name: A unicode string of the field name to get the spec for :return: A child class of asn1crypto.core.Asn1Value that the field must be encoded using """ if not isinstance(field_name, str_cls): raise TypeError(unwrap( ''' field_name must be a unicode string, not %s ''', type_name(field_name) )) if self._fields is None: raise ValueError(unwrap( ''' Unable to retrieve spec for field %s in the class %s because _fields has not been set ''', repr(field_name), type_name(self) )) index = self._field_map[field_name] info = self._determine_spec(index) return info[2] @property def native(self): """ The native Python datatype representation of this value :return: An OrderedDict or None. If an OrderedDict, all child values are recursively converted to native representation also. """ if self.contents is None: return None if self._native is None: if self.children is None: self._parse_children(recurse=True) try: self._native = OrderedDict() for index, child in enumerate(self.children): if child.__class__ == tuple: child = _build(*child) self.children[index] = child try: name = self._fields[index][0] except (IndexError): name = str_cls(index) self._native[name] = child.native except (ValueError, TypeError) as e: self._native = None args = e.args[1:] e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args raise e return self._native def _copy(self, other, copy_func): """ Copies the contents of another Sequence object to itself :param object: Another instance of the same class :param copy_func: An reference of copy.copy() or copy.deepcopy() to use when copying lists, dicts and objects """ super(Sequence, self)._copy(other, copy_func) if self.children is not None: self.children = [] for child in other.children: if child.__class__ == tuple: self.children.append(child) else: self.children.append(child.copy()) def debug(self, nest_level=1): """ Show the binary data and parsed data in a tree structure """ if self.children is None: self._parse_children() prefix = ' ' * nest_level _basic_debug(prefix, self) for field_name in self: child = self._lazy_child(self._field_map[field_name]) if child is not VOID: print('%s Field "%s"' % (prefix, field_name)) child.debug(nest_level + 3) def dump(self, force=False): """ Encodes the value using DER :param force: If the encoded contents already exist, clear them and regenerate to ensure they are in DER format instead of BER format :return: A byte string of the DER-encoded value """ # If the length is indefinite, force the re-encoding if self._header is not None and self._header[-1:] == b'\x80': force = True # We can't force encoding if we don't have a spec if force and self._fields == [] and self.__class__ is Sequence: force = False if force: self._set_contents(force=force) if self._fields and self.children is not None: for index, (field_name, _, params) in enumerate(self._fields): if self.children[index] is not VOID: continue if 'default' in params or 'optional' in params: continue raise ValueError(unwrap( ''' Field "%s" is missing from structure ''', field_name )) return Asn1Value.dump(self) class SequenceOf(Asn1Value): """ Represents a sequence (ordered) of a single type of values from ASN.1 as a Python object with a list-like interface """ tag = 16 class_ = 0 method = 1 # A list of child objects children = None # SequenceOf overrides .contents to be a property so that the mutated state # of child objects can be checked to ensure everything is up-to-date _contents = None # Variable to track if the object has been mutated _mutated = False # An Asn1Value class to use when parsing children _child_spec = None def __init__(self, value=None, default=None, contents=None, spec=None, **kwargs): """ Allows setting child objects and the _child_spec via the spec parameter before passing everything else along to Asn1Value.__init__() :param value: A native Python datatype to initialize the object value with :param default: The default value if no value is specified :param contents: A byte string of the encoded contents of the value :param spec: A class derived from Asn1Value to use to parse children """ if spec: self._child_spec = spec Asn1Value.__init__(self, **kwargs) try: if contents is not None: self.contents = contents else: if value is None and default is not None: value = default if value is not None: for index, child in enumerate(value): self.__setitem__(index, child) # Make sure a blank list is serialized if self.contents is None: self._set_contents() except (ValueError, TypeError) as e: args = e.args[1:] e.args = (e.args[0] + '\n while constructing %s' % type_name(self),) + args raise e @property def contents(self): """ :return: A byte string of the DER-encoded contents of the sequence """ if self.children is None: return self._contents if self._is_mutated(): self._set_contents() return self._contents @contents.setter def contents(self, value): """ :param value: A byte string of the DER-encoded contents of the sequence """ self._contents = value def _is_mutated(self): """ :return: A boolean - if the sequence or any children (recursively) have been mutated """ mutated = self._mutated if self.children is not None: for child in self.children: if isinstance(child, Sequence) or isinstance(child, SequenceOf): mutated = mutated or child._is_mutated() return mutated def _lazy_child(self, index): """ Builds a child object if the child has only been parsed into a tuple so far """ child = self.children[index] if child.__class__ == tuple: child = _build(*child) self.children[index] = child return child def _make_value(self, value): """ Constructs a _child_spec value from a native Python data type, or an appropriate Asn1Value object :param value: A native Python value, or some child of Asn1Value :return: An object of type _child_spec """ if isinstance(value, self._child_spec): new_value = value elif issubclass(self._child_spec, Any): if isinstance(value, Asn1Value): new_value = value else: raise ValueError(unwrap( ''' Can not set a native python value to %s where the _child_spec is Any - value must be an instance of Asn1Value ''', type_name(self) )) elif issubclass(self._child_spec, Choice): if not isinstance(value, Asn1Value): raise ValueError(unwrap( ''' Can not set a native python value to %s where the _child_spec is the choice type %s - value must be an instance of Asn1Value ''', type_name(self), self._child_spec.__name__ )) if not isinstance(value, self._child_spec): wrapper = self._child_spec() wrapper.validate(value.class_, value.tag, value.contents) wrapper._parsed = value value = wrapper new_value = value else: return self._child_spec(value=value) params = {} if self._child_spec.explicit: params['explicit'] = self._child_spec.explicit if self._child_spec.implicit: params['implicit'] = (self._child_spec.class_, self._child_spec.tag) return _fix_tagging(new_value, params) def __len__(self): """ :return: An integer """ # We inline this checks to prevent method invocation each time if self.children is None: self._parse_children() return len(self.children) def __getitem__(self, key): """ Allows accessing children via index :param key: Integer index of child """ # We inline this checks to prevent method invocation each time if self.children is None: self._parse_children() return self._lazy_child(key) def __setitem__(self, key, value): """ Allows overriding a child via index :param key: Integer index of child :param value: Native python datatype that will be passed to _child_spec to create new child object """ # We inline this checks to prevent method invocation each time if self.children is None: self._parse_children() new_value = self._make_value(value) # If adding at the end, create a space for the new value if key == len(self.children): self.children.append(None) if self._native is not None: self._native.append(None) self.children[key] = new_value if self._native is not None: self._native[key] = self.children[key].native self._mutated = True def __delitem__(self, key): """ Allows removing a child via index :param key: Integer index of child """ # We inline this checks to prevent method invocation each time if self.children is None: self._parse_children() self.children.pop(key) if self._native is not None: self._native.pop(key) self._mutated = True def __iter__(self): """ :return: An iter() of child objects """ # We inline this checks to prevent method invocation each time if self.children is None: self._parse_children() for index in range(0, len(self.children)): yield self._lazy_child(index) def __contains__(self, item): """ :param item: An object of the type cls._child_spec :return: A boolean if the item is contained in this SequenceOf """ if item is None or item is VOID: return False if not isinstance(item, self._child_spec): raise TypeError(unwrap( ''' Checking membership in %s is only available for instances of %s, not %s ''', type_name(self), type_name(self._child_spec), type_name(item) )) for child in self: if child == item: return True return False def append(self, value): """ Allows adding a child to the end of the sequence :param value: Native python datatype that will be passed to _child_spec to create new child object """ # We inline this checks to prevent method invocation each time if self.children is None: self._parse_children() self.children.append(self._make_value(value)) if self._native is not None: self._native.append(self.children[-1].native) self._mutated = True def _set_contents(self, force=False): """ Encodes all child objects into the contents for this object :param force: Ensure all contents are in DER format instead of possibly using cached BER-encoded data """ if self.children is None: self._parse_children() contents = BytesIO() for child in self: contents.write(child.dump(force=force)) self._contents = contents.getvalue() self._header = None if self._trailer != b'': self._trailer = b'' def _parse_children(self, recurse=False): """ Parses the contents and generates Asn1Value objects based on the definitions from _child_spec. :param recurse: If child objects that are Sequence or SequenceOf objects should be recursively parsed :raises: ValueError - when an error occurs parsing child objects """ try: self.children = [] if self._contents is None: return contents_length = len(self._contents) child_pointer = 0 while child_pointer < contents_length: parts, child_pointer = _parse(self._contents, contents_length, pointer=child_pointer) if self._child_spec: child = parts + (self._child_spec,) else: child = parts if recurse: child = _build(*child) if isinstance(child, (Sequence, SequenceOf)): child._parse_children(recurse=True) self.children.append(child) except (ValueError, TypeError) as e: self.children = None args = e.args[1:] e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args raise e def spec(self): """ Determines the spec to use for child values. :return: A child class of asn1crypto.core.Asn1Value that child values must be encoded using """ return self._child_spec @property def native(self): """ The native Python datatype representation of this value :return: A list or None. If a list, all child values are recursively converted to native representation also. """ if self.contents is None: return None if self._native is None: if self.children is None: self._parse_children(recurse=True) try: self._native = [child.native for child in self] except (ValueError, TypeError) as e: args = e.args[1:] e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args raise e return self._native def _copy(self, other, copy_func): """ Copies the contents of another SequenceOf object to itself :param object: Another instance of the same class :param copy_func: An reference of copy.copy() or copy.deepcopy() to use when copying lists, dicts and objects """ super(SequenceOf, self)._copy(other, copy_func) if self.children is not None: self.children = [] for child in other.children: if child.__class__ == tuple: self.children.append(child) else: self.children.append(child.copy()) def debug(self, nest_level=1): """ Show the binary data and parsed data in a tree structure """ if self.children is None: self._parse_children() prefix = ' ' * nest_level _basic_debug(prefix, self) for child in self: child.debug(nest_level + 1) def dump(self, force=False): """ Encodes the value using DER :param force: If the encoded contents already exist, clear them and regenerate to ensure they are in DER format instead of BER format :return: A byte string of the DER-encoded value """ # If the length is indefinite, force the re-encoding if self._header is not None and self._header[-1:] == b'\x80': force = True if force: self._set_contents(force=force) return Asn1Value.dump(self) class Set(Sequence): """ Represents a set of fields (unordered) from ASN.1 as a Python object with a dict-like interface """ method = 1 class_ = 0 tag = 17 # A dict of 2-element tuples in the form (class_, tag) as keys and integers # as values that are the index of the field in _fields _field_ids = None def _setup(self): """ Generates _field_map, _field_ids and _oid_nums for use in parsing """ cls = self.__class__ cls._field_map = {} cls._field_ids = {} cls._precomputed_specs = [] for index, field in enumerate(cls._fields): if len(field) < 3: field = field + ({},) cls._fields[index] = field cls._field_map[field[0]] = index cls._field_ids[_build_id_tuple(field[2], field[1])] = index if cls._oid_pair is not None: cls._oid_nums = (cls._field_map[cls._oid_pair[0]], cls._field_map[cls._oid_pair[1]]) for index, field in enumerate(cls._fields): has_callback = cls._spec_callbacks is not None and field[0] in cls._spec_callbacks is_mapped_oid = cls._oid_nums is not None and cls._oid_nums[1] == index if has_callback or is_mapped_oid: cls._precomputed_specs.append(None) else: cls._precomputed_specs.append((field[0], field[1], field[1], field[2], None)) def _parse_children(self, recurse=False): """ Parses the contents and generates Asn1Value objects based on the definitions from _fields. :param recurse: If child objects that are Sequence or SequenceOf objects should be recursively parsed :raises: ValueError - when an error occurs parsing child objects """ cls = self.__class__ if self._contents is None: if self._fields: self.children = [VOID] * len(self._fields) for index, (_, _, params) in enumerate(self._fields): if 'default' in params: if cls._precomputed_specs[index]: field_name, field_spec, value_spec, field_params, _ = cls._precomputed_specs[index] else: field_name, field_spec, value_spec, field_params, _ = self._determine_spec(index) self.children[index] = self._make_value(field_name, field_spec, value_spec, field_params, None) return try: child_map = {} contents_length = len(self.contents) child_pointer = 0 seen_field = 0 while child_pointer < contents_length: parts, child_pointer = _parse(self.contents, contents_length, pointer=child_pointer) id_ = (parts[0], parts[2]) field = self._field_ids.get(id_) if field is None: raise ValueError(unwrap( ''' Data for field %s (%s class, %s method, tag %s) does not match any of the field definitions ''', seen_field, CLASS_NUM_TO_NAME_MAP.get(parts[0]), METHOD_NUM_TO_NAME_MAP.get(parts[1]), parts[2], )) _, field_spec, value_spec, field_params, spec_override = ( cls._precomputed_specs[field] or self._determine_spec(field)) if field_spec is None or (spec_override and issubclass(field_spec, Any)): field_spec = value_spec spec_override = None if spec_override: child = parts + (field_spec, field_params, value_spec) else: child = parts + (field_spec, field_params) if recurse: child = _build(*child) if isinstance(child, (Sequence, SequenceOf)): child._parse_children(recurse=True) child_map[field] = child seen_field += 1 total_fields = len(self._fields) for index in range(0, total_fields): if index in child_map: continue name, field_spec, value_spec, field_params, spec_override = ( cls._precomputed_specs[index] or self._determine_spec(index)) if field_spec is None or (spec_override and issubclass(field_spec, Any)): field_spec = value_spec spec_override = None missing = False if not field_params: missing = True elif 'optional' not in field_params and 'default' not in field_params: missing = True elif 'optional' in field_params: child_map[index] = VOID elif 'default' in field_params: child_map[index] = field_spec(**field_params) if missing: raise ValueError(unwrap( ''' Missing required field "%s" from %s ''', name, type_name(self) )) self.children = [] for index in range(0, total_fields): self.children.append(child_map[index]) except (ValueError, TypeError) as e: args = e.args[1:] e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args raise e def _set_contents(self, force=False): """ Encodes all child objects into the contents for this object. This method is overridden because a Set needs to be encoded by removing defaulted fields and then sorting the fields by tag. :param force: Ensure all contents are in DER format instead of possibly using cached BER-encoded data """ if self.children is None: self._parse_children() child_tag_encodings = [] for index, child in enumerate(self.children): child_encoding = child.dump(force=force) # Skip encoding defaulted children name, spec, field_params = self._fields[index] if 'default' in field_params: if spec(**field_params).dump() == child_encoding: continue child_tag_encodings.append((child.tag, child_encoding)) child_tag_encodings.sort(key=lambda ct: ct[0]) self._contents = b''.join([ct[1] for ct in child_tag_encodings]) self._header = None if self._trailer != b'': self._trailer = b'' class SetOf(SequenceOf): """ Represents a set (unordered) of a single type of values from ASN.1 as a Python object with a list-like interface """ tag = 17 def _set_contents(self, force=False): """ Encodes all child objects into the contents for this object. This method is overridden because a SetOf needs to be encoded by sorting the child encodings. :param force: Ensure all contents are in DER format instead of possibly using cached BER-encoded data """ if self.children is None: self._parse_children() child_encodings = [] for child in self: child_encodings.append(child.dump(force=force)) self._contents = b''.join(sorted(child_encodings)) self._header = None if self._trailer != b'': self._trailer = b'' class EmbeddedPdv(Sequence): """ A sequence structure """ tag = 11 class NumericString(AbstractString): """ Represents a numeric string from ASN.1 as a Python unicode string """ tag = 18 _encoding = 'latin1' class PrintableString(AbstractString): """ Represents a printable string from ASN.1 as a Python unicode string """ tag = 19 _encoding = 'latin1' class TeletexString(AbstractString): """ Represents a teletex string from ASN.1 as a Python unicode string """ tag = 20 _encoding = 'teletex' class VideotexString(OctetString): """ Represents a videotex string from ASN.1 as a Python byte string """ tag = 21 class IA5String(AbstractString): """ Represents an IA5 string from ASN.1 as a Python unicode string """ tag = 22 _encoding = 'ascii' class AbstractTime(AbstractString): """ Represents a time from ASN.1 as a Python datetime.datetime object """ @property def _parsed_time(self): """ The parsed datetime string. :raises: ValueError - when an invalid value is passed :return: A dict with the parsed values """ string = str_cls(self) m = self._TIMESTRING_RE.match(string) if not m: raise ValueError(unwrap( ''' Error parsing %s to a %s ''', string, type_name(self), )) groups = m.groupdict() tz = None if groups['zulu']: tz = timezone.utc elif groups['dsign']: sign = 1 if groups['dsign'] == '+' else -1 tz = create_timezone(sign * timedelta( hours=int(groups['dhour']), minutes=int(groups['dminute'] or 0) )) if groups['fraction']: # Compute fraction in microseconds fract = Fraction( int(groups['fraction']), 10 ** len(groups['fraction']) ) * 1000000 if groups['minute'] is None: fract *= 3600 elif groups['second'] is None: fract *= 60 fract_usec = int(fract.limit_denominator(1)) else: fract_usec = 0 return { 'year': int(groups['year']), 'month': int(groups['month']), 'day': int(groups['day']), 'hour': int(groups['hour']), 'minute': int(groups['minute'] or 0), 'second': int(groups['second'] or 0), 'tzinfo': tz, 'fraction': fract_usec, } @property def native(self): """ The native Python datatype representation of this value :return: A datetime.datetime object, asn1crypto.util.extended_datetime object or None. The datetime object is usually timezone aware. If it's naive, then it's in the sender's local time; see X.680 sect. 42.3 """ if self.contents is None: return None if self._native is None: parsed = self._parsed_time fraction = parsed.pop('fraction', 0) value = self._get_datetime(parsed) if fraction: value += timedelta(microseconds=fraction) self._native = value return self._native class UTCTime(AbstractTime): """ Represents a UTC time from ASN.1 as a timezone aware Python datetime.datetime object """ tag = 23 # Regular expression for UTCTime as described in X.680 sect. 43 and ISO 8601 _TIMESTRING_RE = re.compile(r''' ^ # YYMMDD (?P\d{2}) (?P\d{2}) (?P\d{2}) # hhmm or hhmmss (?P\d{2}) (?P\d{2}) (?P\d{2})? # Matches nothing, needed because GeneralizedTime uses this. (?P) # Z or [-+]hhmm (?: (?PZ) | (?: (?P[-+]) (?P\d{2}) (?P\d{2}) ) ) $ ''', re.X) def set(self, value): """ Sets the value of the object :param value: A unicode string or a datetime.datetime object :raises: ValueError - when an invalid value is passed """ if isinstance(value, datetime): if not value.tzinfo: raise ValueError('Must be timezone aware') # Convert value to UTC. value = value.astimezone(utc_with_dst) if not 1950 <= value.year <= 2049: raise ValueError('Year of the UTCTime is not in range [1950, 2049], use GeneralizedTime instead') value = value.strftime('%y%m%d%H%M%SZ') if _PY2: value = value.decode('ascii') AbstractString.set(self, value) # Set it to None and let the class take care of converting the next # time that .native is called self._native = None def _get_datetime(self, parsed): """ Create a datetime object from the parsed time. :return: An aware datetime.datetime object """ # X.680 only specifies that UTCTime is not using a century. # So "18" could as well mean 2118 or 1318. # X.509 and CMS specify to use UTCTime for years earlier than 2050. # Assume that UTCTime is only used for years [1950, 2049]. if parsed['year'] < 50: parsed['year'] += 2000 else: parsed['year'] += 1900 return datetime(**parsed) class GeneralizedTime(AbstractTime): """ Represents a generalized time from ASN.1 as a Python datetime.datetime object or asn1crypto.util.extended_datetime object in UTC """ tag = 24 # Regular expression for GeneralizedTime as described in X.680 sect. 42 and ISO 8601 _TIMESTRING_RE = re.compile(r''' ^ # YYYYMMDD (?P\d{4}) (?P\d{2}) (?P\d{2}) # hh or hhmm or hhmmss (?P\d{2}) (?: (?P\d{2}) (?P\d{2})? )? # Optional fraction; [.,]dddd (one or more decimals) # If Seconds are given, it's fractions of Seconds. # Else if Minutes are given, it's fractions of Minutes. # Else it's fractions of Hours. (?: [,.] (?P\d+) )? # Optional timezone. If left out, the time is in local time. # Z or [-+]hh or [-+]hhmm (?: (?PZ) | (?: (?P[-+]) (?P\d{2}) (?P\d{2})? ) )? $ ''', re.X) def set(self, value): """ Sets the value of the object :param value: A unicode string, a datetime.datetime object or an asn1crypto.util.extended_datetime object :raises: ValueError - when an invalid value is passed """ if isinstance(value, (datetime, extended_datetime)): if not value.tzinfo: raise ValueError('Must be timezone aware') # Convert value to UTC. value = value.astimezone(utc_with_dst) if value.microsecond: fraction = '.' + str(value.microsecond).zfill(6).rstrip('0') else: fraction = '' value = value.strftime('%Y%m%d%H%M%S') + fraction + 'Z' if _PY2: value = value.decode('ascii') AbstractString.set(self, value) # Set it to None and let the class take care of converting the next # time that .native is called self._native = None def _get_datetime(self, parsed): """ Create a datetime object from the parsed time. :return: A datetime.datetime object or asn1crypto.util.extended_datetime object. It may or may not be aware. """ if parsed['year'] == 0: # datetime does not support year 0. Use extended_datetime instead. return extended_datetime(**parsed) else: return datetime(**parsed) class GraphicString(AbstractString): """ Represents a graphic string from ASN.1 as a Python unicode string """ tag = 25 # This is technically not correct since this type can contain any charset _encoding = 'latin1' class VisibleString(AbstractString): """ Represents a visible string from ASN.1 as a Python unicode string """ tag = 26 _encoding = 'latin1' class GeneralString(AbstractString): """ Represents a general string from ASN.1 as a Python unicode string """ tag = 27 # This is technically not correct since this type can contain any charset _encoding = 'latin1' class UniversalString(AbstractString): """ Represents a universal string from ASN.1 as a Python unicode string """ tag = 28 _encoding = 'utf-32-be' class CharacterString(AbstractString): """ Represents a character string from ASN.1 as a Python unicode string """ tag = 29 # This is technically not correct since this type can contain any charset _encoding = 'latin1' class BMPString(AbstractString): """ Represents a BMP string from ASN.1 as a Python unicode string """ tag = 30 _encoding = 'utf-16-be' def _basic_debug(prefix, self): """ Prints out basic information about an Asn1Value object. Extracted for reuse among different classes that customize the debug information. :param prefix: A unicode string of spaces to prefix output line with :param self: The object to print the debugging information about """ print('%s%s Object #%s' % (prefix, type_name(self), id(self))) if self._header: print('%s Header: 0x%s' % (prefix, binascii.hexlify(self._header or b'').decode('utf-8'))) has_header = self.method is not None and self.class_ is not None and self.tag is not None if has_header: method_name = METHOD_NUM_TO_NAME_MAP.get(self.method) class_name = CLASS_NUM_TO_NAME_MAP.get(self.class_) if self.explicit is not None: for class_, tag in self.explicit: print( '%s %s tag %s (explicitly tagged)' % ( prefix, CLASS_NUM_TO_NAME_MAP.get(class_), tag ) ) if has_header: print('%s %s %s %s' % (prefix, method_name, class_name, self.tag)) elif self.implicit: if has_header: print('%s %s %s tag %s (implicitly tagged)' % (prefix, method_name, class_name, self.tag)) elif has_header: print('%s %s %s tag %s' % (prefix, method_name, class_name, self.tag)) if self._trailer: print('%s Trailer: 0x%s' % (prefix, binascii.hexlify(self._trailer or b'').decode('utf-8'))) print('%s Data: 0x%s' % (prefix, binascii.hexlify(self.contents or b'').decode('utf-8'))) def _tag_type_to_explicit_implicit(params): """ Converts old-style "tag_type" and "tag" params to "explicit" and "implicit" :param params: A dict of parameters to convert from tag_type/tag to explicit/implicit """ if 'tag_type' in params: if params['tag_type'] == 'explicit': params['explicit'] = (params.get('class', 2), params['tag']) elif params['tag_type'] == 'implicit': params['implicit'] = (params.get('class', 2), params['tag']) del params['tag_type'] del params['tag'] if 'class' in params: del params['class'] def _fix_tagging(value, params): """ Checks if a value is properly tagged based on the spec, and re/untags as necessary :param value: An Asn1Value object :param params: A dict of spec params :return: An Asn1Value that is properly tagged """ _tag_type_to_explicit_implicit(params) retag = False if 'implicit' not in params: if value.implicit is not False: retag = True else: if isinstance(params['implicit'], tuple): class_, tag = params['implicit'] else: tag = params['implicit'] class_ = 'context' if value.implicit is False: retag = True elif value.class_ != CLASS_NAME_TO_NUM_MAP[class_] or value.tag != tag: retag = True if params.get('explicit') != value.explicit: retag = True if retag: return value.retag(params) return value def _build_id_tuple(params, spec): """ Builds a 2-element tuple used to identify fields by grabbing the class_ and tag from an Asn1Value class and the params dict being passed to it :param params: A dict of params to pass to spec :param spec: An Asn1Value class :return: A 2-element integer tuple in the form (class_, tag) """ # Handle situations where the spec is not known at setup time if spec is None: return (None, None) required_class = spec.class_ required_tag = spec.tag _tag_type_to_explicit_implicit(params) if 'explicit' in params: if isinstance(params['explicit'], tuple): required_class, required_tag = params['explicit'] else: required_class = 2 required_tag = params['explicit'] elif 'implicit' in params: if isinstance(params['implicit'], tuple): required_class, required_tag = params['implicit'] else: required_class = 2 required_tag = params['implicit'] if required_class is not None and not isinstance(required_class, int_types): required_class = CLASS_NAME_TO_NUM_MAP[required_class] required_class = params.get('class_', required_class) required_tag = params.get('tag', required_tag) return (required_class, required_tag) def _int_to_bit_tuple(value, bits): """ Format value as a tuple of 1s and 0s. :param value: A non-negative integer to format :param bits: Number of bits in the output :return: A tuple of 1s and 0s with bits members. """ if not value and not bits: return () result = tuple(map(int, format(value, '0{0}b'.format(bits)))) if len(result) != bits: raise ValueError('Result too large: {0} > {1}'.format(len(result), bits)) return result _UNIVERSAL_SPECS = { 1: Boolean, 2: Integer, 3: BitString, 4: OctetString, 5: Null, 6: ObjectIdentifier, 7: ObjectDescriptor, 8: InstanceOf, 9: Real, 10: Enumerated, 11: EmbeddedPdv, 12: UTF8String, 13: RelativeOid, 16: Sequence, 17: Set, 18: NumericString, 19: PrintableString, 20: TeletexString, 21: VideotexString, 22: IA5String, 23: UTCTime, 24: GeneralizedTime, 25: GraphicString, 26: VisibleString, 27: GeneralString, 28: UniversalString, 29: CharacterString, 30: BMPString } def _build(class_, method, tag, header, contents, trailer, spec=None, spec_params=None, nested_spec=None): """ Builds an Asn1Value object generically, or using a spec with optional params :param class_: An integer representing the ASN.1 class :param method: An integer representing the ASN.1 method :param tag: An integer representing the ASN.1 tag :param header: A byte string of the ASN.1 header (class, method, tag, length) :param contents: A byte string of the ASN.1 value :param trailer: A byte string of any ASN.1 trailer (only used by indefinite length encodings) :param spec: A class derived from Asn1Value that defines what class_ and tag the value should have, and the semantics of the encoded value. The return value will be of this type. If omitted, the encoded value will be decoded using the standard universal tag based on the encoded tag number. :param spec_params: A dict of params to pass to the spec object :param nested_spec: For certain Asn1Value classes (such as OctetString and BitString), the contents can be further parsed and interpreted as another Asn1Value. This parameter controls the spec for that sub-parsing. :return: An object of the type spec, or if not specified, a child of Asn1Value """ if spec_params is not None: _tag_type_to_explicit_implicit(spec_params) if header is None: return VOID header_set = False # If an explicit specification was passed in, make sure it matches if spec is not None: # If there is explicit tagging and contents, we have to split # the header and trailer off before we do the parsing no_explicit = spec_params and 'no_explicit' in spec_params if not no_explicit and (spec.explicit or (spec_params and 'explicit' in spec_params)): if spec_params: value = spec(**spec_params) else: value = spec() original_explicit = value.explicit explicit_info = reversed(original_explicit) parsed_class = class_ parsed_method = method parsed_tag = tag to_parse = contents explicit_header = header explicit_trailer = trailer or b'' for expected_class, expected_tag in explicit_info: if parsed_class != expected_class: raise ValueError(unwrap( ''' Error parsing %s - explicitly-tagged class should have been %s, but %s was found ''', type_name(value), CLASS_NUM_TO_NAME_MAP.get(expected_class), CLASS_NUM_TO_NAME_MAP.get(parsed_class, parsed_class) )) if parsed_method != 1: raise ValueError(unwrap( ''' Error parsing %s - explicitly-tagged method should have been %s, but %s was found ''', type_name(value), METHOD_NUM_TO_NAME_MAP.get(1), METHOD_NUM_TO_NAME_MAP.get(parsed_method, parsed_method) )) if parsed_tag != expected_tag: raise ValueError(unwrap( ''' Error parsing %s - explicitly-tagged tag should have been %s, but %s was found ''', type_name(value), expected_tag, parsed_tag )) info, _ = _parse(to_parse, len(to_parse)) parsed_class, parsed_method, parsed_tag, parsed_header, to_parse, parsed_trailer = info if not isinstance(value, Choice): explicit_header += parsed_header explicit_trailer = parsed_trailer + explicit_trailer value = _build(*info, spec=spec, spec_params={'no_explicit': True}) value._header = explicit_header value._trailer = explicit_trailer value.explicit = original_explicit header_set = True else: if spec_params: value = spec(contents=contents, **spec_params) else: value = spec(contents=contents) if spec is Any: pass elif isinstance(value, Choice): value.validate(class_, tag, contents) try: # Force parsing the Choice now value.contents = header + value.contents header = b'' value.parse() except (ValueError, TypeError) as e: args = e.args[1:] e.args = (e.args[0] + '\n while parsing %s' % type_name(value),) + args raise e else: if class_ != value.class_: raise ValueError(unwrap( ''' Error parsing %s - class should have been %s, but %s was found ''', type_name(value), CLASS_NUM_TO_NAME_MAP.get(value.class_), CLASS_NUM_TO_NAME_MAP.get(class_, class_) )) if method != value.method: # Allow parsing a primitive method as constructed if the value # is indefinite length. This is to allow parsing BER. ber_indef = method == 1 and value.method == 0 and trailer == b'\x00\x00' if not ber_indef or not isinstance(value, Constructable): raise ValueError(unwrap( ''' Error parsing %s - method should have been %s, but %s was found ''', type_name(value), METHOD_NUM_TO_NAME_MAP.get(value.method), METHOD_NUM_TO_NAME_MAP.get(method, method) )) else: value.method = method value._indefinite = True if tag != value.tag: if isinstance(value._bad_tag, tuple): is_bad_tag = tag in value._bad_tag else: is_bad_tag = tag == value._bad_tag if not is_bad_tag: raise ValueError(unwrap( ''' Error parsing %s - tag should have been %s, but %s was found ''', type_name(value), value.tag, tag )) # For explicitly tagged, un-speced parsings, we use a generic container # since we will be parsing the contents and discarding the outer object # anyway a little further on elif spec_params and 'explicit' in spec_params: original_value = Asn1Value(contents=contents, **spec_params) original_explicit = original_value.explicit to_parse = contents explicit_header = header explicit_trailer = trailer or b'' for expected_class, expected_tag in reversed(original_explicit): info, _ = _parse(to_parse, len(to_parse)) _, _, _, parsed_header, to_parse, parsed_trailer = info explicit_header += parsed_header explicit_trailer = parsed_trailer + explicit_trailer value = _build(*info, spec=spec, spec_params={'no_explicit': True}) value._header = header + value._header value._trailer += trailer or b'' value.explicit = original_explicit header_set = True # If no spec was specified, allow anything and just process what # is in the input data else: if tag not in _UNIVERSAL_SPECS: raise ValueError(unwrap( ''' Unknown element - %s class, %s method, tag %s ''', CLASS_NUM_TO_NAME_MAP.get(class_), METHOD_NUM_TO_NAME_MAP.get(method), tag )) spec = _UNIVERSAL_SPECS[tag] value = spec(contents=contents, class_=class_) ber_indef = method == 1 and value.method == 0 and trailer == b'\x00\x00' if ber_indef and isinstance(value, Constructable): value._indefinite = True value.method = method if not header_set: value._header = header value._trailer = trailer or b'' # Destroy any default value that our contents have overwritten value._native = None if nested_spec: try: value.parse(nested_spec) except (ValueError, TypeError) as e: args = e.args[1:] e.args = (e.args[0] + '\n while parsing %s' % type_name(value),) + args raise e return value def _parse_build(encoded_data, pointer=0, spec=None, spec_params=None, strict=False): """ Parses a byte string generically, or using a spec with optional params :param encoded_data: A byte string that contains BER-encoded data :param pointer: The index in the byte string to parse from :param spec: A class derived from Asn1Value that defines what class_ and tag the value should have, and the semantics of the encoded value. The return value will be of this type. If omitted, the encoded value will be decoded using the standard universal tag based on the encoded tag number. :param spec_params: A dict of params to pass to the spec object :param strict: A boolean indicating if trailing data should be forbidden - if so, a ValueError will be raised when trailing data exists :return: A 2-element tuple: - 0: An object of the type spec, or if not specified, a child of Asn1Value - 1: An integer indicating how many bytes were consumed """ encoded_len = len(encoded_data) info, new_pointer = _parse(encoded_data, encoded_len, pointer) if strict and new_pointer != pointer + encoded_len: extra_bytes = pointer + encoded_len - new_pointer raise ValueError('Extra data - %d bytes of trailing data were provided' % extra_bytes) return (_build(*info, spec=spec, spec_params=spec_params), new_pointer) crl.py000064400000037350152572326550005722 0ustar00# coding: utf-8 """ ASN.1 type classes for certificate revocation lists (CRL). Exports the following items: - CertificateList() Other type classes are defined that help compose the types listed above. """ from __future__ import unicode_literals, division, absolute_import, print_function import hashlib from .algos import SignedDigestAlgorithm from .core import ( Boolean, Enumerated, GeneralizedTime, Integer, ObjectIdentifier, OctetBitString, ParsableOctetString, Sequence, SequenceOf, ) from .x509 import ( AuthorityInfoAccessSyntax, AuthorityKeyIdentifier, CRLDistributionPoints, DistributionPointName, GeneralNames, Name, ReasonFlags, Time, ) # The structures in this file are taken from https://tools.ietf.org/html/rfc5280 class Version(Integer): _map = { 0: 'v1', 1: 'v2', 2: 'v3', } class IssuingDistributionPoint(Sequence): _fields = [ ('distribution_point', DistributionPointName, {'explicit': 0, 'optional': True}), ('only_contains_user_certs', Boolean, {'implicit': 1, 'default': False}), ('only_contains_ca_certs', Boolean, {'implicit': 2, 'default': False}), ('only_some_reasons', ReasonFlags, {'implicit': 3, 'optional': True}), ('indirect_crl', Boolean, {'implicit': 4, 'default': False}), ('only_contains_attribute_certs', Boolean, {'implicit': 5, 'default': False}), ] class TBSCertListExtensionId(ObjectIdentifier): _map = { '2.5.29.18': 'issuer_alt_name', '2.5.29.20': 'crl_number', '2.5.29.27': 'delta_crl_indicator', '2.5.29.28': 'issuing_distribution_point', '2.5.29.35': 'authority_key_identifier', '2.5.29.46': 'freshest_crl', '1.3.6.1.5.5.7.1.1': 'authority_information_access', } class TBSCertListExtension(Sequence): _fields = [ ('extn_id', TBSCertListExtensionId), ('critical', Boolean, {'default': False}), ('extn_value', ParsableOctetString), ] _oid_pair = ('extn_id', 'extn_value') _oid_specs = { 'issuer_alt_name': GeneralNames, 'crl_number': Integer, 'delta_crl_indicator': Integer, 'issuing_distribution_point': IssuingDistributionPoint, 'authority_key_identifier': AuthorityKeyIdentifier, 'freshest_crl': CRLDistributionPoints, 'authority_information_access': AuthorityInfoAccessSyntax, } class TBSCertListExtensions(SequenceOf): _child_spec = TBSCertListExtension class CRLReason(Enumerated): _map = { 0: 'unspecified', 1: 'key_compromise', 2: 'ca_compromise', 3: 'affiliation_changed', 4: 'superseded', 5: 'cessation_of_operation', 6: 'certificate_hold', 8: 'remove_from_crl', 9: 'privilege_withdrawn', 10: 'aa_compromise', } @property def human_friendly(self): """ :return: A unicode string with revocation description that is suitable to show to end-users. Starts with a lower case letter and phrased in such a way that it makes sense after the phrase "because of" or "due to". """ return { 'unspecified': 'an unspecified reason', 'key_compromise': 'a compromised key', 'ca_compromise': 'the CA being compromised', 'affiliation_changed': 'an affiliation change', 'superseded': 'certificate supersession', 'cessation_of_operation': 'a cessation of operation', 'certificate_hold': 'a certificate hold', 'remove_from_crl': 'removal from the CRL', 'privilege_withdrawn': 'privilege withdrawl', 'aa_compromise': 'the AA being compromised', }[self.native] class CRLEntryExtensionId(ObjectIdentifier): _map = { '2.5.29.21': 'crl_reason', '2.5.29.23': 'hold_instruction_code', '2.5.29.24': 'invalidity_date', '2.5.29.29': 'certificate_issuer', } class CRLEntryExtension(Sequence): _fields = [ ('extn_id', CRLEntryExtensionId), ('critical', Boolean, {'default': False}), ('extn_value', ParsableOctetString), ] _oid_pair = ('extn_id', 'extn_value') _oid_specs = { 'crl_reason': CRLReason, 'hold_instruction_code': ObjectIdentifier, 'invalidity_date': GeneralizedTime, 'certificate_issuer': GeneralNames, } class CRLEntryExtensions(SequenceOf): _child_spec = CRLEntryExtension class RevokedCertificate(Sequence): _fields = [ ('user_certificate', Integer), ('revocation_date', Time), ('crl_entry_extensions', CRLEntryExtensions, {'optional': True}), ] _processed_extensions = False _critical_extensions = None _crl_reason_value = None _invalidity_date_value = None _certificate_issuer_value = None _issuer_name = False def _set_extensions(self): """ Sets common named extensions to private attributes and creates a list of critical extensions """ self._critical_extensions = set() for extension in self['crl_entry_extensions']: name = extension['extn_id'].native attribute_name = '_%s_value' % name if hasattr(self, attribute_name): setattr(self, attribute_name, extension['extn_value'].parsed) if extension['critical'].native: self._critical_extensions.add(name) self._processed_extensions = True @property def critical_extensions(self): """ Returns a set of the names (or OID if not a known extension) of the extensions marked as critical :return: A set of unicode strings """ if not self._processed_extensions: self._set_extensions() return self._critical_extensions @property def crl_reason_value(self): """ This extension indicates the reason that a certificate was revoked. :return: None or a CRLReason object """ if self._processed_extensions is False: self._set_extensions() return self._crl_reason_value @property def invalidity_date_value(self): """ This extension indicates the suspected date/time the private key was compromised or the certificate became invalid. This would usually be before the revocation date, which is when the CA processed the revocation. :return: None or a GeneralizedTime object """ if self._processed_extensions is False: self._set_extensions() return self._invalidity_date_value @property def certificate_issuer_value(self): """ This extension indicates the issuer of the certificate in question, and is used in indirect CRLs. CRL entries without this extension are for certificates issued from the last seen issuer. :return: None or an x509.GeneralNames object """ if self._processed_extensions is False: self._set_extensions() return self._certificate_issuer_value @property def issuer_name(self): """ :return: None, or an asn1crypto.x509.Name object for the issuer of the cert """ if self._issuer_name is False: self._issuer_name = None if self.certificate_issuer_value: for general_name in self.certificate_issuer_value: if general_name.name == 'directory_name': self._issuer_name = general_name.chosen break return self._issuer_name class RevokedCertificates(SequenceOf): _child_spec = RevokedCertificate class TbsCertList(Sequence): _fields = [ ('version', Version, {'optional': True}), ('signature', SignedDigestAlgorithm), ('issuer', Name), ('this_update', Time), ('next_update', Time, {'optional': True}), ('revoked_certificates', RevokedCertificates, {'optional': True}), ('crl_extensions', TBSCertListExtensions, {'explicit': 0, 'optional': True}), ] class CertificateList(Sequence): _fields = [ ('tbs_cert_list', TbsCertList), ('signature_algorithm', SignedDigestAlgorithm), ('signature', OctetBitString), ] _processed_extensions = False _critical_extensions = None _issuer_alt_name_value = None _crl_number_value = None _delta_crl_indicator_value = None _issuing_distribution_point_value = None _authority_key_identifier_value = None _freshest_crl_value = None _authority_information_access_value = None _issuer_cert_urls = None _delta_crl_distribution_points = None _sha1 = None _sha256 = None def _set_extensions(self): """ Sets common named extensions to private attributes and creates a list of critical extensions """ self._critical_extensions = set() for extension in self['tbs_cert_list']['crl_extensions']: name = extension['extn_id'].native attribute_name = '_%s_value' % name if hasattr(self, attribute_name): setattr(self, attribute_name, extension['extn_value'].parsed) if extension['critical'].native: self._critical_extensions.add(name) self._processed_extensions = True @property def critical_extensions(self): """ Returns a set of the names (or OID if not a known extension) of the extensions marked as critical :return: A set of unicode strings """ if not self._processed_extensions: self._set_extensions() return self._critical_extensions @property def issuer_alt_name_value(self): """ This extension allows associating one or more alternative names with the issuer of the CRL. :return: None or an x509.GeneralNames object """ if self._processed_extensions is False: self._set_extensions() return self._issuer_alt_name_value @property def crl_number_value(self): """ This extension adds a monotonically increasing number to the CRL and is used to distinguish different versions of the CRL. :return: None or an Integer object """ if self._processed_extensions is False: self._set_extensions() return self._crl_number_value @property def delta_crl_indicator_value(self): """ This extension indicates a CRL is a delta CRL, and contains the CRL number of the base CRL that it is a delta from. :return: None or an Integer object """ if self._processed_extensions is False: self._set_extensions() return self._delta_crl_indicator_value @property def issuing_distribution_point_value(self): """ This extension includes information about what types of revocations and certificates are part of the CRL. :return: None or an IssuingDistributionPoint object """ if self._processed_extensions is False: self._set_extensions() return self._issuing_distribution_point_value @property def authority_key_identifier_value(self): """ This extension helps in identifying the public key with which to validate the authenticity of the CRL. :return: None or an AuthorityKeyIdentifier object """ if self._processed_extensions is False: self._set_extensions() return self._authority_key_identifier_value @property def freshest_crl_value(self): """ This extension is used in complete CRLs to indicate where a delta CRL may be located. :return: None or a CRLDistributionPoints object """ if self._processed_extensions is False: self._set_extensions() return self._freshest_crl_value @property def authority_information_access_value(self): """ This extension is used to provide a URL with which to download the certificate used to sign this CRL. :return: None or an AuthorityInfoAccessSyntax object """ if self._processed_extensions is False: self._set_extensions() return self._authority_information_access_value @property def issuer(self): """ :return: An asn1crypto.x509.Name object for the issuer of the CRL """ return self['tbs_cert_list']['issuer'] @property def authority_key_identifier(self): """ :return: None or a byte string of the key_identifier from the authority key identifier extension """ if not self.authority_key_identifier_value: return None return self.authority_key_identifier_value['key_identifier'].native @property def issuer_cert_urls(self): """ :return: A list of unicode strings that are URLs that should contain either an individual DER-encoded X.509 certificate, or a DER-encoded CMS message containing multiple certificates """ if self._issuer_cert_urls is None: self._issuer_cert_urls = [] if self.authority_information_access_value: for entry in self.authority_information_access_value: if entry['access_method'].native == 'ca_issuers': location = entry['access_location'] if location.name != 'uniform_resource_identifier': continue url = location.native if url.lower()[0:7] == 'http://': self._issuer_cert_urls.append(url) return self._issuer_cert_urls @property def delta_crl_distribution_points(self): """ Returns delta CRL URLs - only applies to complete CRLs :return: A list of zero or more DistributionPoint objects """ if self._delta_crl_distribution_points is None: self._delta_crl_distribution_points = [] if self.freshest_crl_value is not None: for distribution_point in self.freshest_crl_value: distribution_point_name = distribution_point['distribution_point'] # RFC 5280 indicates conforming CA should not use the relative form if distribution_point_name.name == 'name_relative_to_crl_issuer': continue # This library is currently only concerned with HTTP-based CRLs for general_name in distribution_point_name.chosen: if general_name.name == 'uniform_resource_identifier': self._delta_crl_distribution_points.append(distribution_point) return self._delta_crl_distribution_points @property def signature(self): """ :return: A byte string of the signature """ return self['signature'].native @property def sha1(self): """ :return: The SHA1 hash of the DER-encoded bytes of this certificate list """ if self._sha1 is None: self._sha1 = hashlib.sha1(self.dump()).digest() return self._sha1 @property def sha256(self): """ :return: The SHA-256 hash of the DER-encoded bytes of this certificate list """ if self._sha256 is None: self._sha256 = hashlib.sha256(self.dump()).digest() return self._sha256 csr.py000064400000006726152572326550005734 0ustar00# coding: utf-8 """ ASN.1 type classes for certificate signing requests (CSR). Exports the following items: - CertificationRequest() Other type classes are defined that help compose the types listed above. """ from __future__ import unicode_literals, division, absolute_import, print_function from .algos import SignedDigestAlgorithm from .core import ( Any, BitString, BMPString, Integer, ObjectIdentifier, OctetBitString, Sequence, SetOf, UTF8String ) from .keys import PublicKeyInfo from .x509 import DirectoryString, Extensions, Name # The structures in this file are taken from https://tools.ietf.org/html/rfc2986 # and https://tools.ietf.org/html/rfc2985 class Version(Integer): _map = { 0: 'v1', } class CSRAttributeType(ObjectIdentifier): _map = { '1.2.840.113549.1.9.7': 'challenge_password', '1.2.840.113549.1.9.9': 'extended_certificate_attributes', '1.2.840.113549.1.9.14': 'extension_request', # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-wcce/a5eaae36-e9f3-4dc5-a687-bfa7115954f1 '1.3.6.1.4.1.311.13.2.2': 'microsoft_enrollment_csp_provider', # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-wcce/7c677cba-030d-48be-ba2b-01e407705f34 '1.3.6.1.4.1.311.13.2.3': 'microsoft_os_version', # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-wcce/64e5ff6d-c6dd-4578-92f7-b3d895f9b9c7 '1.3.6.1.4.1.311.21.20': 'microsoft_request_client_info', } class SetOfDirectoryString(SetOf): _child_spec = DirectoryString class Attribute(Sequence): _fields = [ ('type', ObjectIdentifier), ('values', SetOf, {'spec': Any}), ] class SetOfAttributes(SetOf): _child_spec = Attribute class SetOfExtensions(SetOf): _child_spec = Extensions class MicrosoftEnrollmentCSProvider(Sequence): _fields = [ ('keyspec', Integer), ('cspname', BMPString), # cryptographic service provider name ('signature', BitString), ] class SetOfMicrosoftEnrollmentCSProvider(SetOf): _child_spec = MicrosoftEnrollmentCSProvider class MicrosoftRequestClientInfo(Sequence): _fields = [ ('clientid', Integer), ('machinename', UTF8String), ('username', UTF8String), ('processname', UTF8String), ] class SetOfMicrosoftRequestClientInfo(SetOf): _child_spec = MicrosoftRequestClientInfo class CRIAttribute(Sequence): _fields = [ ('type', CSRAttributeType), ('values', Any), ] _oid_pair = ('type', 'values') _oid_specs = { 'challenge_password': SetOfDirectoryString, 'extended_certificate_attributes': SetOfAttributes, 'extension_request': SetOfExtensions, 'microsoft_enrollment_csp_provider': SetOfMicrosoftEnrollmentCSProvider, 'microsoft_os_version': SetOfDirectoryString, 'microsoft_request_client_info': SetOfMicrosoftRequestClientInfo, } class CRIAttributes(SetOf): _child_spec = CRIAttribute class CertificationRequestInfo(Sequence): _fields = [ ('version', Version), ('subject', Name), ('subject_pk_info', PublicKeyInfo), ('attributes', CRIAttributes, {'implicit': 0, 'optional': True}), ] class CertificationRequest(Sequence): _fields = [ ('certification_request_info', CertificationRequestInfo), ('signature_algorithm', SignedDigestAlgorithm), ('signature', OctetBitString), ] keys.py000064400000111747152572326550006120 0ustar00# coding: utf-8 """ ASN.1 type classes for public and private keys. Exports the following items: - DSAPrivateKey() - ECPrivateKey() - EncryptedPrivateKeyInfo() - PrivateKeyInfo() - PublicKeyInfo() - RSAPrivateKey() - RSAPublicKey() Other type classes are defined that help compose the types listed above. """ from __future__ import unicode_literals, division, absolute_import, print_function import hashlib import math from ._errors import unwrap, APIException from ._types import type_name, byte_cls from .algos import _ForceNullParameters, DigestAlgorithm, EncryptionAlgorithm, RSAESOAEPParams, RSASSAPSSParams from .core import ( Any, Asn1Value, BitString, Choice, Integer, IntegerOctetString, Null, ObjectIdentifier, OctetBitString, OctetString, ParsableOctetString, ParsableOctetBitString, Sequence, SequenceOf, SetOf, ) from .util import int_from_bytes, int_to_bytes class OtherPrimeInfo(Sequence): """ Source: https://tools.ietf.org/html/rfc3447#page-46 """ _fields = [ ('prime', Integer), ('exponent', Integer), ('coefficient', Integer), ] class OtherPrimeInfos(SequenceOf): """ Source: https://tools.ietf.org/html/rfc3447#page-46 """ _child_spec = OtherPrimeInfo class RSAPrivateKeyVersion(Integer): """ Original Name: Version Source: https://tools.ietf.org/html/rfc3447#page-45 """ _map = { 0: 'two-prime', 1: 'multi', } class RSAPrivateKey(Sequence): """ Source: https://tools.ietf.org/html/rfc3447#page-45 """ _fields = [ ('version', RSAPrivateKeyVersion), ('modulus', Integer), ('public_exponent', Integer), ('private_exponent', Integer), ('prime1', Integer), ('prime2', Integer), ('exponent1', Integer), ('exponent2', Integer), ('coefficient', Integer), ('other_prime_infos', OtherPrimeInfos, {'optional': True}) ] class RSAPublicKey(Sequence): """ Source: https://tools.ietf.org/html/rfc3447#page-44 """ _fields = [ ('modulus', Integer), ('public_exponent', Integer) ] class DSAPrivateKey(Sequence): """ The ASN.1 structure that OpenSSL uses to store a DSA private key that is not part of a PKCS#8 structure. Reversed engineered from english-language description on linked OpenSSL documentation page. Original Name: None Source: https://www.openssl.org/docs/apps/dsa.html """ _fields = [ ('version', Integer), ('p', Integer), ('q', Integer), ('g', Integer), ('public_key', Integer), ('private_key', Integer), ] class _ECPoint(): """ In both PublicKeyInfo and PrivateKeyInfo, the EC public key is a byte string that is encoded as a bit string. This class adds convenience methods for converting to and from the byte string to a pair of integers that are the X and Y coordinates. """ @classmethod def from_coords(cls, x, y): """ Creates an ECPoint object from the X and Y integer coordinates of the point :param x: The X coordinate, as an integer :param y: The Y coordinate, as an integer :return: An ECPoint object """ x_bytes = int(math.ceil(math.log(x, 2) / 8.0)) y_bytes = int(math.ceil(math.log(y, 2) / 8.0)) num_bytes = max(x_bytes, y_bytes) byte_string = b'\x04' byte_string += int_to_bytes(x, width=num_bytes) byte_string += int_to_bytes(y, width=num_bytes) return cls(byte_string) def to_coords(self): """ Returns the X and Y coordinates for this EC point, as native Python integers :return: A 2-element tuple containing integers (X, Y) """ data = self.native first_byte = data[0:1] # Uncompressed if first_byte == b'\x04': remaining = data[1:] field_len = len(remaining) // 2 x = int_from_bytes(remaining[0:field_len]) y = int_from_bytes(remaining[field_len:]) return (x, y) if first_byte not in set([b'\x02', b'\x03']): raise ValueError(unwrap( ''' Invalid EC public key - first byte is incorrect ''' )) raise ValueError(unwrap( ''' Compressed representations of EC public keys are not supported due to patent US6252960 ''' )) class ECPoint(OctetString, _ECPoint): pass class ECPointBitString(OctetBitString, _ECPoint): pass class SpecifiedECDomainVersion(Integer): """ Source: http://www.secg.org/sec1-v2.pdf page 104 """ _map = { 1: 'ecdpVer1', 2: 'ecdpVer2', 3: 'ecdpVer3', } class FieldType(ObjectIdentifier): """ Original Name: None Source: http://www.secg.org/sec1-v2.pdf page 101 """ _map = { '1.2.840.10045.1.1': 'prime_field', '1.2.840.10045.1.2': 'characteristic_two_field', } class CharacteristicTwoBasis(ObjectIdentifier): """ Original Name: None Source: http://www.secg.org/sec1-v2.pdf page 102 """ _map = { '1.2.840.10045.1.2.1.1': 'gn_basis', '1.2.840.10045.1.2.1.2': 'tp_basis', '1.2.840.10045.1.2.1.3': 'pp_basis', } class Pentanomial(Sequence): """ Source: http://www.secg.org/sec1-v2.pdf page 102 """ _fields = [ ('k1', Integer), ('k2', Integer), ('k3', Integer), ] class CharacteristicTwo(Sequence): """ Original Name: Characteristic-two Source: http://www.secg.org/sec1-v2.pdf page 101 """ _fields = [ ('m', Integer), ('basis', CharacteristicTwoBasis), ('parameters', Any), ] _oid_pair = ('basis', 'parameters') _oid_specs = { 'gn_basis': Null, 'tp_basis': Integer, 'pp_basis': Pentanomial, } class FieldID(Sequence): """ Source: http://www.secg.org/sec1-v2.pdf page 100 """ _fields = [ ('field_type', FieldType), ('parameters', Any), ] _oid_pair = ('field_type', 'parameters') _oid_specs = { 'prime_field': Integer, 'characteristic_two_field': CharacteristicTwo, } class Curve(Sequence): """ Source: http://www.secg.org/sec1-v2.pdf page 104 """ _fields = [ ('a', OctetString), ('b', OctetString), ('seed', OctetBitString, {'optional': True}), ] class SpecifiedECDomain(Sequence): """ Source: http://www.secg.org/sec1-v2.pdf page 103 """ _fields = [ ('version', SpecifiedECDomainVersion), ('field_id', FieldID), ('curve', Curve), ('base', ECPoint), ('order', Integer), ('cofactor', Integer, {'optional': True}), ('hash', DigestAlgorithm, {'optional': True}), ] class NamedCurve(ObjectIdentifier): """ Various named curves Original Name: None Source: https://tools.ietf.org/html/rfc3279#page-23, https://tools.ietf.org/html/rfc5480#page-5 """ _map = { # https://tools.ietf.org/html/rfc3279#page-23 '1.2.840.10045.3.0.1': 'c2pnb163v1', '1.2.840.10045.3.0.2': 'c2pnb163v2', '1.2.840.10045.3.0.3': 'c2pnb163v3', '1.2.840.10045.3.0.4': 'c2pnb176w1', '1.2.840.10045.3.0.5': 'c2tnb191v1', '1.2.840.10045.3.0.6': 'c2tnb191v2', '1.2.840.10045.3.0.7': 'c2tnb191v3', '1.2.840.10045.3.0.8': 'c2onb191v4', '1.2.840.10045.3.0.9': 'c2onb191v5', '1.2.840.10045.3.0.10': 'c2pnb208w1', '1.2.840.10045.3.0.11': 'c2tnb239v1', '1.2.840.10045.3.0.12': 'c2tnb239v2', '1.2.840.10045.3.0.13': 'c2tnb239v3', '1.2.840.10045.3.0.14': 'c2onb239v4', '1.2.840.10045.3.0.15': 'c2onb239v5', '1.2.840.10045.3.0.16': 'c2pnb272w1', '1.2.840.10045.3.0.17': 'c2pnb304w1', '1.2.840.10045.3.0.18': 'c2tnb359v1', '1.2.840.10045.3.0.19': 'c2pnb368w1', '1.2.840.10045.3.0.20': 'c2tnb431r1', '1.2.840.10045.3.1.2': 'prime192v2', '1.2.840.10045.3.1.3': 'prime192v3', '1.2.840.10045.3.1.4': 'prime239v1', '1.2.840.10045.3.1.5': 'prime239v2', '1.2.840.10045.3.1.6': 'prime239v3', # https://tools.ietf.org/html/rfc5480#page-5 # http://www.secg.org/SEC2-Ver-1.0.pdf '1.2.840.10045.3.1.1': 'secp192r1', '1.2.840.10045.3.1.7': 'secp256r1', '1.3.132.0.1': 'sect163k1', '1.3.132.0.2': 'sect163r1', '1.3.132.0.3': 'sect239k1', '1.3.132.0.4': 'sect113r1', '1.3.132.0.5': 'sect113r2', '1.3.132.0.6': 'secp112r1', '1.3.132.0.7': 'secp112r2', '1.3.132.0.8': 'secp160r1', '1.3.132.0.9': 'secp160k1', '1.3.132.0.10': 'secp256k1', '1.3.132.0.15': 'sect163r2', '1.3.132.0.16': 'sect283k1', '1.3.132.0.17': 'sect283r1', '1.3.132.0.22': 'sect131r1', '1.3.132.0.23': 'sect131r2', '1.3.132.0.24': 'sect193r1', '1.3.132.0.25': 'sect193r2', '1.3.132.0.26': 'sect233k1', '1.3.132.0.27': 'sect233r1', '1.3.132.0.28': 'secp128r1', '1.3.132.0.29': 'secp128r2', '1.3.132.0.30': 'secp160r2', '1.3.132.0.31': 'secp192k1', '1.3.132.0.32': 'secp224k1', '1.3.132.0.33': 'secp224r1', '1.3.132.0.34': 'secp384r1', '1.3.132.0.35': 'secp521r1', '1.3.132.0.36': 'sect409k1', '1.3.132.0.37': 'sect409r1', '1.3.132.0.38': 'sect571k1', '1.3.132.0.39': 'sect571r1', # https://tools.ietf.org/html/rfc5639#section-4.1 '1.3.36.3.3.2.8.1.1.1': 'brainpoolp160r1', '1.3.36.3.3.2.8.1.1.2': 'brainpoolp160t1', '1.3.36.3.3.2.8.1.1.3': 'brainpoolp192r1', '1.3.36.3.3.2.8.1.1.4': 'brainpoolp192t1', '1.3.36.3.3.2.8.1.1.5': 'brainpoolp224r1', '1.3.36.3.3.2.8.1.1.6': 'brainpoolp224t1', '1.3.36.3.3.2.8.1.1.7': 'brainpoolp256r1', '1.3.36.3.3.2.8.1.1.8': 'brainpoolp256t1', '1.3.36.3.3.2.8.1.1.9': 'brainpoolp320r1', '1.3.36.3.3.2.8.1.1.10': 'brainpoolp320t1', '1.3.36.3.3.2.8.1.1.11': 'brainpoolp384r1', '1.3.36.3.3.2.8.1.1.12': 'brainpoolp384t1', '1.3.36.3.3.2.8.1.1.13': 'brainpoolp512r1', '1.3.36.3.3.2.8.1.1.14': 'brainpoolp512t1', } _key_sizes = { # Order values used to compute these sourced from # http://cr.openjdk.java.net/~vinnie/7194075/webrev-3/src/share/classes/sun/security/ec/CurveDB.java.html '1.2.840.10045.3.0.1': 21, '1.2.840.10045.3.0.2': 21, '1.2.840.10045.3.0.3': 21, '1.2.840.10045.3.0.4': 21, '1.2.840.10045.3.0.5': 24, '1.2.840.10045.3.0.6': 24, '1.2.840.10045.3.0.7': 24, '1.2.840.10045.3.0.8': 24, '1.2.840.10045.3.0.9': 24, '1.2.840.10045.3.0.10': 25, '1.2.840.10045.3.0.11': 30, '1.2.840.10045.3.0.12': 30, '1.2.840.10045.3.0.13': 30, '1.2.840.10045.3.0.14': 30, '1.2.840.10045.3.0.15': 30, '1.2.840.10045.3.0.16': 33, '1.2.840.10045.3.0.17': 37, '1.2.840.10045.3.0.18': 45, '1.2.840.10045.3.0.19': 45, '1.2.840.10045.3.0.20': 53, '1.2.840.10045.3.1.2': 24, '1.2.840.10045.3.1.3': 24, '1.2.840.10045.3.1.4': 30, '1.2.840.10045.3.1.5': 30, '1.2.840.10045.3.1.6': 30, # Order values used to compute these sourced from # http://www.secg.org/SEC2-Ver-1.0.pdf # ceil(n.bit_length() / 8) '1.2.840.10045.3.1.1': 24, '1.2.840.10045.3.1.7': 32, '1.3.132.0.1': 21, '1.3.132.0.2': 21, '1.3.132.0.3': 30, '1.3.132.0.4': 15, '1.3.132.0.5': 15, '1.3.132.0.6': 14, '1.3.132.0.7': 14, '1.3.132.0.8': 21, '1.3.132.0.9': 21, '1.3.132.0.10': 32, '1.3.132.0.15': 21, '1.3.132.0.16': 36, '1.3.132.0.17': 36, '1.3.132.0.22': 17, '1.3.132.0.23': 17, '1.3.132.0.24': 25, '1.3.132.0.25': 25, '1.3.132.0.26': 29, '1.3.132.0.27': 30, '1.3.132.0.28': 16, '1.3.132.0.29': 16, '1.3.132.0.30': 21, '1.3.132.0.31': 24, '1.3.132.0.32': 29, '1.3.132.0.33': 28, '1.3.132.0.34': 48, '1.3.132.0.35': 66, '1.3.132.0.36': 51, '1.3.132.0.37': 52, '1.3.132.0.38': 72, '1.3.132.0.39': 72, # Order values used to compute these sourced from # https://tools.ietf.org/html/rfc5639#section-3 # ceil(q.bit_length() / 8) '1.3.36.3.3.2.8.1.1.1': 20, '1.3.36.3.3.2.8.1.1.2': 20, '1.3.36.3.3.2.8.1.1.3': 24, '1.3.36.3.3.2.8.1.1.4': 24, '1.3.36.3.3.2.8.1.1.5': 28, '1.3.36.3.3.2.8.1.1.6': 28, '1.3.36.3.3.2.8.1.1.7': 32, '1.3.36.3.3.2.8.1.1.8': 32, '1.3.36.3.3.2.8.1.1.9': 40, '1.3.36.3.3.2.8.1.1.10': 40, '1.3.36.3.3.2.8.1.1.11': 48, '1.3.36.3.3.2.8.1.1.12': 48, '1.3.36.3.3.2.8.1.1.13': 64, '1.3.36.3.3.2.8.1.1.14': 64, } @classmethod def register(cls, name, oid, key_size): """ Registers a new named elliptic curve that is not included in the default list of named curves :param name: A unicode string of the curve name :param oid: A unicode string of the dotted format OID :param key_size: An integer of the number of bytes the private key should be encoded to """ cls._map[oid] = name if cls._reverse_map is not None: cls._reverse_map[name] = oid cls._key_sizes[oid] = key_size class ECDomainParameters(Choice): """ Source: http://www.secg.org/sec1-v2.pdf page 102 """ _alternatives = [ ('specified', SpecifiedECDomain), ('named', NamedCurve), ('implicit_ca', Null), ] @property def key_size(self): if self.name == 'implicit_ca': raise ValueError(unwrap( ''' Unable to calculate key_size from ECDomainParameters that are implicitly defined by the CA key ''' )) if self.name == 'specified': order = self.chosen['order'].native return math.ceil(math.log(order, 2.0) / 8.0) oid = self.chosen.dotted if oid not in NamedCurve._key_sizes: raise ValueError(unwrap( ''' The asn1crypto.keys.NamedCurve %s does not have a registered key length, please call asn1crypto.keys.NamedCurve.register() ''', repr(oid) )) return NamedCurve._key_sizes[oid] class ECPrivateKeyVersion(Integer): """ Original Name: None Source: http://www.secg.org/sec1-v2.pdf page 108 """ _map = { 1: 'ecPrivkeyVer1', } class ECPrivateKey(Sequence): """ Source: http://www.secg.org/sec1-v2.pdf page 108 """ _fields = [ ('version', ECPrivateKeyVersion), ('private_key', IntegerOctetString), ('parameters', ECDomainParameters, {'explicit': 0, 'optional': True}), ('public_key', ECPointBitString, {'explicit': 1, 'optional': True}), ] # Ensures the key is set to the correct length when encoding _key_size = None # This is necessary to ensure the private_key IntegerOctetString is encoded properly def __setitem__(self, key, value): res = super(ECPrivateKey, self).__setitem__(key, value) if key == 'private_key': if self._key_size is None: # Infer the key_size from the existing private key if possible pkey_contents = self['private_key'].contents if isinstance(pkey_contents, byte_cls) and len(pkey_contents) > 1: self.set_key_size(len(self['private_key'].contents)) elif self._key_size is not None: self._update_key_size() elif key == 'parameters' and isinstance(self['parameters'], ECDomainParameters) and \ self['parameters'].name != 'implicit_ca': self.set_key_size(self['parameters'].key_size) return res def set_key_size(self, key_size): """ Sets the key_size to ensure the private key is encoded to the proper length :param key_size: An integer byte length to encode the private_key to """ self._key_size = key_size self._update_key_size() def _update_key_size(self): """ Ensure the private_key explicit encoding width is set """ if self._key_size is not None and isinstance(self['private_key'], IntegerOctetString): self['private_key'].set_encoded_width(self._key_size) class DSAParams(Sequence): """ Parameters for a DSA public or private key Original Name: Dss-Parms Source: https://tools.ietf.org/html/rfc3279#page-9 """ _fields = [ ('p', Integer), ('q', Integer), ('g', Integer), ] class Attribute(Sequence): """ Source: https://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-X.501-198811-S!!PDF-E&type=items page 8 """ _fields = [ ('type', ObjectIdentifier), ('values', SetOf, {'spec': Any}), ] class Attributes(SetOf): """ Source: https://tools.ietf.org/html/rfc5208#page-3 """ _child_spec = Attribute class PrivateKeyAlgorithmId(ObjectIdentifier): """ These OIDs for various public keys are reused when storing private keys inside of a PKCS#8 structure Original Name: None Source: https://tools.ietf.org/html/rfc3279 """ _map = { # https://tools.ietf.org/html/rfc3279#page-19 '1.2.840.113549.1.1.1': 'rsa', # https://tools.ietf.org/html/rfc4055#page-8 '1.2.840.113549.1.1.10': 'rsassa_pss', # https://tools.ietf.org/html/rfc3279#page-18 '1.2.840.10040.4.1': 'dsa', # https://tools.ietf.org/html/rfc3279#page-13 '1.2.840.10045.2.1': 'ec', # https://tools.ietf.org/html/rfc8410#section-9 '1.3.101.110': 'x25519', '1.3.101.111': 'x448', '1.3.101.112': 'ed25519', '1.3.101.113': 'ed448', } class PrivateKeyAlgorithm(_ForceNullParameters, Sequence): """ Original Name: PrivateKeyAlgorithmIdentifier Source: https://tools.ietf.org/html/rfc5208#page-3 """ _fields = [ ('algorithm', PrivateKeyAlgorithmId), ('parameters', Any, {'optional': True}), ] _oid_pair = ('algorithm', 'parameters') _oid_specs = { 'dsa': DSAParams, 'ec': ECDomainParameters, 'rsassa_pss': RSASSAPSSParams, } class PrivateKeyInfo(Sequence): """ Source: https://tools.ietf.org/html/rfc5208#page-3 """ _fields = [ ('version', Integer), ('private_key_algorithm', PrivateKeyAlgorithm), ('private_key', ParsableOctetString), ('attributes', Attributes, {'implicit': 0, 'optional': True}), ] def _private_key_spec(self): algorithm = self['private_key_algorithm']['algorithm'].native return { 'rsa': RSAPrivateKey, 'rsassa_pss': RSAPrivateKey, 'dsa': Integer, 'ec': ECPrivateKey, # These should be treated as opaque octet strings according # to RFC 8410 'x25519': OctetString, 'x448': OctetString, 'ed25519': OctetString, 'ed448': OctetString, }[algorithm] _spec_callbacks = { 'private_key': _private_key_spec } _algorithm = None _bit_size = None _public_key = None _fingerprint = None @classmethod def wrap(cls, private_key, algorithm): """ Wraps a private key in a PrivateKeyInfo structure :param private_key: A byte string or Asn1Value object of the private key :param algorithm: A unicode string of "rsa", "dsa" or "ec" :return: A PrivateKeyInfo object """ if not isinstance(private_key, byte_cls) and not isinstance(private_key, Asn1Value): raise TypeError(unwrap( ''' private_key must be a byte string or Asn1Value, not %s ''', type_name(private_key) )) if algorithm == 'rsa' or algorithm == 'rsassa_pss': if not isinstance(private_key, RSAPrivateKey): private_key = RSAPrivateKey.load(private_key) params = Null() elif algorithm == 'dsa': if not isinstance(private_key, DSAPrivateKey): private_key = DSAPrivateKey.load(private_key) params = DSAParams() params['p'] = private_key['p'] params['q'] = private_key['q'] params['g'] = private_key['g'] public_key = private_key['public_key'] private_key = private_key['private_key'] elif algorithm == 'ec': if not isinstance(private_key, ECPrivateKey): private_key = ECPrivateKey.load(private_key) else: private_key = private_key.copy() params = private_key['parameters'] del private_key['parameters'] else: raise ValueError(unwrap( ''' algorithm must be one of "rsa", "dsa", "ec", not %s ''', repr(algorithm) )) private_key_algo = PrivateKeyAlgorithm() private_key_algo['algorithm'] = PrivateKeyAlgorithmId(algorithm) private_key_algo['parameters'] = params container = cls() container._algorithm = algorithm container['version'] = Integer(0) container['private_key_algorithm'] = private_key_algo container['private_key'] = private_key # Here we save the DSA public key if possible since it is not contained # within the PKCS#8 structure for a DSA key if algorithm == 'dsa': container._public_key = public_key return container # This is necessary to ensure any contained ECPrivateKey is the # correct size def __setitem__(self, key, value): res = super(PrivateKeyInfo, self).__setitem__(key, value) algorithm = self['private_key_algorithm'] # When possible, use the parameter info to make sure the private key encoding # retains any necessary leading bytes, instead of them being dropped if (key == 'private_key_algorithm' or key == 'private_key') and \ algorithm['algorithm'].native == 'ec' and \ isinstance(algorithm['parameters'], ECDomainParameters) and \ algorithm['parameters'].name != 'implicit_ca' and \ isinstance(self['private_key'], ParsableOctetString) and \ isinstance(self['private_key'].parsed, ECPrivateKey): self['private_key'].parsed.set_key_size(algorithm['parameters'].key_size) return res def unwrap(self): """ Unwraps the private key into an RSAPrivateKey, DSAPrivateKey or ECPrivateKey object :return: An RSAPrivateKey, DSAPrivateKey or ECPrivateKey object """ raise APIException( 'asn1crypto.keys.PrivateKeyInfo().unwrap() has been removed, ' 'please use oscrypto.asymmetric.PrivateKey().unwrap() instead') @property def curve(self): """ Returns information about the curve used for an EC key :raises: ValueError - when the key is not an EC key :return: A two-element tuple, with the first element being a unicode string of "implicit_ca", "specified" or "named". If the first element is "implicit_ca", the second is None. If "specified", the second is an OrderedDict that is the native version of SpecifiedECDomain. If "named", the second is a unicode string of the curve name. """ if self.algorithm != 'ec': raise ValueError(unwrap( ''' Only EC keys have a curve, this key is %s ''', self.algorithm.upper() )) params = self['private_key_algorithm']['parameters'] chosen = params.chosen if params.name == 'implicit_ca': value = None else: value = chosen.native return (params.name, value) @property def hash_algo(self): """ Returns the name of the family of hash algorithms used to generate a DSA key :raises: ValueError - when the key is not a DSA key :return: A unicode string of "sha1" or "sha2" """ if self.algorithm != 'dsa': raise ValueError(unwrap( ''' Only DSA keys are generated using a hash algorithm, this key is %s ''', self.algorithm.upper() )) byte_len = math.log(self['private_key_algorithm']['parameters']['q'].native, 2) / 8 return 'sha1' if byte_len <= 20 else 'sha2' @property def algorithm(self): """ :return: A unicode string of "rsa", "rsassa_pss", "dsa" or "ec" """ if self._algorithm is None: self._algorithm = self['private_key_algorithm']['algorithm'].native return self._algorithm @property def bit_size(self): """ :return: The bit size of the private key, as an integer """ if self._bit_size is None: if self.algorithm == 'rsa' or self.algorithm == 'rsassa_pss': prime = self['private_key'].parsed['modulus'].native elif self.algorithm == 'dsa': prime = self['private_key_algorithm']['parameters']['p'].native elif self.algorithm == 'ec': prime = self['private_key'].parsed['private_key'].native self._bit_size = int(math.ceil(math.log(prime, 2))) modulus = self._bit_size % 8 if modulus != 0: self._bit_size += 8 - modulus return self._bit_size @property def byte_size(self): """ :return: The byte size of the private key, as an integer """ return int(math.ceil(self.bit_size / 8)) @property def public_key(self): """ :return: If an RSA key, an RSAPublicKey object. If a DSA key, an Integer object. If an EC key, an ECPointBitString object. """ raise APIException( 'asn1crypto.keys.PrivateKeyInfo().public_key has been removed, ' 'please use oscrypto.asymmetric.PrivateKey().public_key.unwrap() instead') @property def public_key_info(self): """ :return: A PublicKeyInfo object derived from this private key. """ raise APIException( 'asn1crypto.keys.PrivateKeyInfo().public_key_info has been removed, ' 'please use oscrypto.asymmetric.PrivateKey().public_key.asn1 instead') @property def fingerprint(self): """ Creates a fingerprint that can be compared with a public key to see if the two form a pair. This fingerprint is not compatible with fingerprints generated by any other software. :return: A byte string that is a sha256 hash of selected components (based on the key type) """ raise APIException( 'asn1crypto.keys.PrivateKeyInfo().fingerprint has been removed, ' 'please use oscrypto.asymmetric.PrivateKey().fingerprint instead') class EncryptedPrivateKeyInfo(Sequence): """ Source: https://tools.ietf.org/html/rfc5208#page-4 """ _fields = [ ('encryption_algorithm', EncryptionAlgorithm), ('encrypted_data', OctetString), ] # These structures are from https://tools.ietf.org/html/rfc3279 class ValidationParms(Sequence): """ Source: https://tools.ietf.org/html/rfc3279#page-10 """ _fields = [ ('seed', BitString), ('pgen_counter', Integer), ] class DomainParameters(Sequence): """ Source: https://tools.ietf.org/html/rfc3279#page-10 """ _fields = [ ('p', Integer), ('g', Integer), ('q', Integer), ('j', Integer, {'optional': True}), ('validation_params', ValidationParms, {'optional': True}), ] class PublicKeyAlgorithmId(ObjectIdentifier): """ Original Name: None Source: https://tools.ietf.org/html/rfc3279 """ _map = { # https://tools.ietf.org/html/rfc3279#page-19 '1.2.840.113549.1.1.1': 'rsa', # https://tools.ietf.org/html/rfc3447#page-47 '1.2.840.113549.1.1.7': 'rsaes_oaep', # https://tools.ietf.org/html/rfc4055#page-8 '1.2.840.113549.1.1.10': 'rsassa_pss', # https://tools.ietf.org/html/rfc3279#page-18 '1.2.840.10040.4.1': 'dsa', # https://tools.ietf.org/html/rfc3279#page-13 '1.2.840.10045.2.1': 'ec', # https://tools.ietf.org/html/rfc3279#page-10 '1.2.840.10046.2.1': 'dh', # https://tools.ietf.org/html/rfc8410#section-9 '1.3.101.110': 'x25519', '1.3.101.111': 'x448', '1.3.101.112': 'ed25519', '1.3.101.113': 'ed448', } class PublicKeyAlgorithm(_ForceNullParameters, Sequence): """ Original Name: AlgorithmIdentifier Source: https://tools.ietf.org/html/rfc5280#page-18 """ _fields = [ ('algorithm', PublicKeyAlgorithmId), ('parameters', Any, {'optional': True}), ] _oid_pair = ('algorithm', 'parameters') _oid_specs = { 'dsa': DSAParams, 'ec': ECDomainParameters, 'dh': DomainParameters, 'rsaes_oaep': RSAESOAEPParams, 'rsassa_pss': RSASSAPSSParams, } class PublicKeyInfo(Sequence): """ Original Name: SubjectPublicKeyInfo Source: https://tools.ietf.org/html/rfc5280#page-17 """ _fields = [ ('algorithm', PublicKeyAlgorithm), ('public_key', ParsableOctetBitString), ] def _public_key_spec(self): algorithm = self['algorithm']['algorithm'].native return { 'rsa': RSAPublicKey, 'rsaes_oaep': RSAPublicKey, 'rsassa_pss': RSAPublicKey, 'dsa': Integer, # We override the field spec with ECPoint so that users can easily # decompose the byte string into the constituent X and Y coords 'ec': (ECPointBitString, None), 'dh': Integer, # These should be treated as opaque bit strings according # to RFC 8410, and need not even be valid ASN.1 'x25519': (OctetBitString, None), 'x448': (OctetBitString, None), 'ed25519': (OctetBitString, None), 'ed448': (OctetBitString, None), }[algorithm] _spec_callbacks = { 'public_key': _public_key_spec } _algorithm = None _bit_size = None _fingerprint = None _sha1 = None _sha256 = None @classmethod def wrap(cls, public_key, algorithm): """ Wraps a public key in a PublicKeyInfo structure :param public_key: A byte string or Asn1Value object of the public key :param algorithm: A unicode string of "rsa" :return: A PublicKeyInfo object """ if not isinstance(public_key, byte_cls) and not isinstance(public_key, Asn1Value): raise TypeError(unwrap( ''' public_key must be a byte string or Asn1Value, not %s ''', type_name(public_key) )) if algorithm != 'rsa' and algorithm != 'rsassa_pss': raise ValueError(unwrap( ''' algorithm must "rsa", not %s ''', repr(algorithm) )) algo = PublicKeyAlgorithm() algo['algorithm'] = PublicKeyAlgorithmId(algorithm) algo['parameters'] = Null() container = cls() container['algorithm'] = algo if isinstance(public_key, Asn1Value): public_key = public_key.untag().dump() container['public_key'] = ParsableOctetBitString(public_key) return container def unwrap(self): """ Unwraps an RSA public key into an RSAPublicKey object. Does not support DSA or EC public keys since they do not have an unwrapped form. :return: An RSAPublicKey object """ raise APIException( 'asn1crypto.keys.PublicKeyInfo().unwrap() has been removed, ' 'please use oscrypto.asymmetric.PublicKey().unwrap() instead') @property def curve(self): """ Returns information about the curve used for an EC key :raises: ValueError - when the key is not an EC key :return: A two-element tuple, with the first element being a unicode string of "implicit_ca", "specified" or "named". If the first element is "implicit_ca", the second is None. If "specified", the second is an OrderedDict that is the native version of SpecifiedECDomain. If "named", the second is a unicode string of the curve name. """ if self.algorithm != 'ec': raise ValueError(unwrap( ''' Only EC keys have a curve, this key is %s ''', self.algorithm.upper() )) params = self['algorithm']['parameters'] chosen = params.chosen if params.name == 'implicit_ca': value = None else: value = chosen.native return (params.name, value) @property def hash_algo(self): """ Returns the name of the family of hash algorithms used to generate a DSA key :raises: ValueError - when the key is not a DSA key :return: A unicode string of "sha1" or "sha2" or None if no parameters are present """ if self.algorithm != 'dsa': raise ValueError(unwrap( ''' Only DSA keys are generated using a hash algorithm, this key is %s ''', self.algorithm.upper() )) parameters = self['algorithm']['parameters'] if parameters.native is None: return None byte_len = math.log(parameters['q'].native, 2) / 8 return 'sha1' if byte_len <= 20 else 'sha2' @property def algorithm(self): """ :return: A unicode string of "rsa", "rsassa_pss", "dsa" or "ec" """ if self._algorithm is None: self._algorithm = self['algorithm']['algorithm'].native return self._algorithm @property def bit_size(self): """ :return: The bit size of the public key, as an integer """ if self._bit_size is None: if self.algorithm == 'ec': self._bit_size = int(((len(self['public_key'].native) - 1) / 2) * 8) else: if self.algorithm == 'rsa' or self.algorithm == 'rsassa_pss': prime = self['public_key'].parsed['modulus'].native elif self.algorithm == 'dsa': prime = self['algorithm']['parameters']['p'].native self._bit_size = int(math.ceil(math.log(prime, 2))) modulus = self._bit_size % 8 if modulus != 0: self._bit_size += 8 - modulus return self._bit_size @property def byte_size(self): """ :return: The byte size of the public key, as an integer """ return int(math.ceil(self.bit_size / 8)) @property def sha1(self): """ :return: The SHA1 hash of the DER-encoded bytes of this public key info """ if self._sha1 is None: self._sha1 = hashlib.sha1(byte_cls(self['public_key'])).digest() return self._sha1 @property def sha256(self): """ :return: The SHA-256 hash of the DER-encoded bytes of this public key info """ if self._sha256 is None: self._sha256 = hashlib.sha256(byte_cls(self['public_key'])).digest() return self._sha256 @property def fingerprint(self): """ Creates a fingerprint that can be compared with a private key to see if the two form a pair. This fingerprint is not compatible with fingerprints generated by any other software. :return: A byte string that is a sha256 hash of selected components (based on the key type) """ raise APIException( 'asn1crypto.keys.PublicKeyInfo().fingerprint has been removed, ' 'please use oscrypto.asymmetric.PublicKey().fingerprint instead') ocsp.py000064400000045120152572326550006100 0ustar00# coding: utf-8 """ ASN.1 type classes for the online certificate status protocol (OCSP). Exports the following items: - OCSPRequest() - OCSPResponse() Other type classes are defined that help compose the types listed above. """ from __future__ import unicode_literals, division, absolute_import, print_function from ._errors import unwrap from .algos import DigestAlgorithm, SignedDigestAlgorithm from .core import ( Boolean, Choice, Enumerated, GeneralizedTime, IA5String, Integer, Null, ObjectIdentifier, OctetBitString, OctetString, ParsableOctetString, Sequence, SequenceOf, ) from .crl import AuthorityInfoAccessSyntax, CRLReason from .keys import PublicKeyAlgorithm from .x509 import Certificate, GeneralName, GeneralNames, Name # The structures in this file are taken from https://tools.ietf.org/html/rfc6960 class Version(Integer): _map = { 0: 'v1' } class CertId(Sequence): _fields = [ ('hash_algorithm', DigestAlgorithm), ('issuer_name_hash', OctetString), ('issuer_key_hash', OctetString), ('serial_number', Integer), ] class ServiceLocator(Sequence): _fields = [ ('issuer', Name), ('locator', AuthorityInfoAccessSyntax), ] class RequestExtensionId(ObjectIdentifier): _map = { '1.3.6.1.5.5.7.48.1.7': 'service_locator', } class RequestExtension(Sequence): _fields = [ ('extn_id', RequestExtensionId), ('critical', Boolean, {'default': False}), ('extn_value', ParsableOctetString), ] _oid_pair = ('extn_id', 'extn_value') _oid_specs = { 'service_locator': ServiceLocator, } class RequestExtensions(SequenceOf): _child_spec = RequestExtension class Request(Sequence): _fields = [ ('req_cert', CertId), ('single_request_extensions', RequestExtensions, {'explicit': 0, 'optional': True}), ] _processed_extensions = False _critical_extensions = None _service_locator_value = None def _set_extensions(self): """ Sets common named extensions to private attributes and creates a list of critical extensions """ self._critical_extensions = set() for extension in self['single_request_extensions']: name = extension['extn_id'].native attribute_name = '_%s_value' % name if hasattr(self, attribute_name): setattr(self, attribute_name, extension['extn_value'].parsed) if extension['critical'].native: self._critical_extensions.add(name) self._processed_extensions = True @property def critical_extensions(self): """ Returns a set of the names (or OID if not a known extension) of the extensions marked as critical :return: A set of unicode strings """ if not self._processed_extensions: self._set_extensions() return self._critical_extensions @property def service_locator_value(self): """ This extension is used when communicating with an OCSP responder that acts as a proxy for OCSP requests :return: None or a ServiceLocator object """ if self._processed_extensions is False: self._set_extensions() return self._service_locator_value class Requests(SequenceOf): _child_spec = Request class ResponseType(ObjectIdentifier): _map = { '1.3.6.1.5.5.7.48.1.1': 'basic_ocsp_response', } class AcceptableResponses(SequenceOf): _child_spec = ResponseType class PreferredSignatureAlgorithm(Sequence): _fields = [ ('sig_identifier', SignedDigestAlgorithm), ('cert_identifier', PublicKeyAlgorithm, {'optional': True}), ] class PreferredSignatureAlgorithms(SequenceOf): _child_spec = PreferredSignatureAlgorithm class TBSRequestExtensionId(ObjectIdentifier): _map = { '1.3.6.1.5.5.7.48.1.2': 'nonce', '1.3.6.1.5.5.7.48.1.4': 'acceptable_responses', '1.3.6.1.5.5.7.48.1.8': 'preferred_signature_algorithms', } class TBSRequestExtension(Sequence): _fields = [ ('extn_id', TBSRequestExtensionId), ('critical', Boolean, {'default': False}), ('extn_value', ParsableOctetString), ] _oid_pair = ('extn_id', 'extn_value') _oid_specs = { 'nonce': OctetString, 'acceptable_responses': AcceptableResponses, 'preferred_signature_algorithms': PreferredSignatureAlgorithms, } class TBSRequestExtensions(SequenceOf): _child_spec = TBSRequestExtension class TBSRequest(Sequence): _fields = [ ('version', Version, {'explicit': 0, 'default': 'v1'}), ('requestor_name', GeneralName, {'explicit': 1, 'optional': True}), ('request_list', Requests), ('request_extensions', TBSRequestExtensions, {'explicit': 2, 'optional': True}), ] class Certificates(SequenceOf): _child_spec = Certificate class Signature(Sequence): _fields = [ ('signature_algorithm', SignedDigestAlgorithm), ('signature', OctetBitString), ('certs', Certificates, {'explicit': 0, 'optional': True}), ] class OCSPRequest(Sequence): _fields = [ ('tbs_request', TBSRequest), ('optional_signature', Signature, {'explicit': 0, 'optional': True}), ] _processed_extensions = False _critical_extensions = None _nonce_value = None _acceptable_responses_value = None _preferred_signature_algorithms_value = None def _set_extensions(self): """ Sets common named extensions to private attributes and creates a list of critical extensions """ self._critical_extensions = set() for extension in self['tbs_request']['request_extensions']: name = extension['extn_id'].native attribute_name = '_%s_value' % name if hasattr(self, attribute_name): setattr(self, attribute_name, extension['extn_value'].parsed) if extension['critical'].native: self._critical_extensions.add(name) self._processed_extensions = True @property def critical_extensions(self): """ Returns a set of the names (or OID if not a known extension) of the extensions marked as critical :return: A set of unicode strings """ if not self._processed_extensions: self._set_extensions() return self._critical_extensions @property def nonce_value(self): """ This extension is used to prevent replay attacks by including a unique, random value with each request/response pair :return: None or an OctetString object """ if self._processed_extensions is False: self._set_extensions() return self._nonce_value @property def acceptable_responses_value(self): """ This extension is used to allow the client and server to communicate with alternative response formats other than just basic_ocsp_response, although no other formats are defined in the standard. :return: None or an AcceptableResponses object """ if self._processed_extensions is False: self._set_extensions() return self._acceptable_responses_value @property def preferred_signature_algorithms_value(self): """ This extension is used by the client to define what signature algorithms are preferred, including both the hash algorithm and the public key algorithm, with a level of detail down to even the public key algorithm parameters, such as curve name. :return: None or a PreferredSignatureAlgorithms object """ if self._processed_extensions is False: self._set_extensions() return self._preferred_signature_algorithms_value class OCSPResponseStatus(Enumerated): _map = { 0: 'successful', 1: 'malformed_request', 2: 'internal_error', 3: 'try_later', 5: 'sign_required', 6: 'unauthorized', } class ResponderId(Choice): _alternatives = [ ('by_name', Name, {'explicit': 1}), ('by_key', OctetString, {'explicit': 2}), ] # Custom class to return a meaningful .native attribute from CertStatus() class StatusGood(Null): def set(self, value): """ Sets the value of the object :param value: None or 'good' """ if value is not None and value != 'good' and not isinstance(value, Null): raise ValueError(unwrap( ''' value must be one of None, "good", not %s ''', repr(value) )) self.contents = b'' @property def native(self): return 'good' # Custom class to return a meaningful .native attribute from CertStatus() class StatusUnknown(Null): def set(self, value): """ Sets the value of the object :param value: None or 'unknown' """ if value is not None and value != 'unknown' and not isinstance(value, Null): raise ValueError(unwrap( ''' value must be one of None, "unknown", not %s ''', repr(value) )) self.contents = b'' @property def native(self): return 'unknown' class RevokedInfo(Sequence): _fields = [ ('revocation_time', GeneralizedTime), ('revocation_reason', CRLReason, {'explicit': 0, 'optional': True}), ] class CertStatus(Choice): _alternatives = [ ('good', StatusGood, {'implicit': 0}), ('revoked', RevokedInfo, {'implicit': 1}), ('unknown', StatusUnknown, {'implicit': 2}), ] class CrlId(Sequence): _fields = [ ('crl_url', IA5String, {'explicit': 0, 'optional': True}), ('crl_num', Integer, {'explicit': 1, 'optional': True}), ('crl_time', GeneralizedTime, {'explicit': 2, 'optional': True}), ] class SingleResponseExtensionId(ObjectIdentifier): _map = { '1.3.6.1.5.5.7.48.1.3': 'crl', '1.3.6.1.5.5.7.48.1.6': 'archive_cutoff', # These are CRLEntryExtension values from # https://tools.ietf.org/html/rfc5280 '2.5.29.21': 'crl_reason', '2.5.29.24': 'invalidity_date', '2.5.29.29': 'certificate_issuer', # https://tools.ietf.org/html/rfc6962.html#page-13 '1.3.6.1.4.1.11129.2.4.5': 'signed_certificate_timestamp_list', } class SingleResponseExtension(Sequence): _fields = [ ('extn_id', SingleResponseExtensionId), ('critical', Boolean, {'default': False}), ('extn_value', ParsableOctetString), ] _oid_pair = ('extn_id', 'extn_value') _oid_specs = { 'crl': CrlId, 'archive_cutoff': GeneralizedTime, 'crl_reason': CRLReason, 'invalidity_date': GeneralizedTime, 'certificate_issuer': GeneralNames, 'signed_certificate_timestamp_list': OctetString, } class SingleResponseExtensions(SequenceOf): _child_spec = SingleResponseExtension class SingleResponse(Sequence): _fields = [ ('cert_id', CertId), ('cert_status', CertStatus), ('this_update', GeneralizedTime), ('next_update', GeneralizedTime, {'explicit': 0, 'optional': True}), ('single_extensions', SingleResponseExtensions, {'explicit': 1, 'optional': True}), ] _processed_extensions = False _critical_extensions = None _crl_value = None _archive_cutoff_value = None _crl_reason_value = None _invalidity_date_value = None _certificate_issuer_value = None def _set_extensions(self): """ Sets common named extensions to private attributes and creates a list of critical extensions """ self._critical_extensions = set() for extension in self['single_extensions']: name = extension['extn_id'].native attribute_name = '_%s_value' % name if hasattr(self, attribute_name): setattr(self, attribute_name, extension['extn_value'].parsed) if extension['critical'].native: self._critical_extensions.add(name) self._processed_extensions = True @property def critical_extensions(self): """ Returns a set of the names (or OID if not a known extension) of the extensions marked as critical :return: A set of unicode strings """ if not self._processed_extensions: self._set_extensions() return self._critical_extensions @property def crl_value(self): """ This extension is used to locate the CRL that a certificate's revocation is contained within. :return: None or a CrlId object """ if self._processed_extensions is False: self._set_extensions() return self._crl_value @property def archive_cutoff_value(self): """ This extension is used to indicate the date at which an archived (historical) certificate status entry will no longer be available. :return: None or a GeneralizedTime object """ if self._processed_extensions is False: self._set_extensions() return self._archive_cutoff_value @property def crl_reason_value(self): """ This extension indicates the reason that a certificate was revoked. :return: None or a CRLReason object """ if self._processed_extensions is False: self._set_extensions() return self._crl_reason_value @property def invalidity_date_value(self): """ This extension indicates the suspected date/time the private key was compromised or the certificate became invalid. This would usually be before the revocation date, which is when the CA processed the revocation. :return: None or a GeneralizedTime object """ if self._processed_extensions is False: self._set_extensions() return self._invalidity_date_value @property def certificate_issuer_value(self): """ This extension indicates the issuer of the certificate in question. :return: None or an x509.GeneralNames object """ if self._processed_extensions is False: self._set_extensions() return self._certificate_issuer_value class Responses(SequenceOf): _child_spec = SingleResponse class ResponseDataExtensionId(ObjectIdentifier): _map = { '1.3.6.1.5.5.7.48.1.2': 'nonce', '1.3.6.1.5.5.7.48.1.9': 'extended_revoke', } class ResponseDataExtension(Sequence): _fields = [ ('extn_id', ResponseDataExtensionId), ('critical', Boolean, {'default': False}), ('extn_value', ParsableOctetString), ] _oid_pair = ('extn_id', 'extn_value') _oid_specs = { 'nonce': OctetString, 'extended_revoke': Null, } class ResponseDataExtensions(SequenceOf): _child_spec = ResponseDataExtension class ResponseData(Sequence): _fields = [ ('version', Version, {'explicit': 0, 'default': 'v1'}), ('responder_id', ResponderId), ('produced_at', GeneralizedTime), ('responses', Responses), ('response_extensions', ResponseDataExtensions, {'explicit': 1, 'optional': True}), ] class BasicOCSPResponse(Sequence): _fields = [ ('tbs_response_data', ResponseData), ('signature_algorithm', SignedDigestAlgorithm), ('signature', OctetBitString), ('certs', Certificates, {'explicit': 0, 'optional': True}), ] class ResponseBytes(Sequence): _fields = [ ('response_type', ResponseType), ('response', ParsableOctetString), ] _oid_pair = ('response_type', 'response') _oid_specs = { 'basic_ocsp_response': BasicOCSPResponse, } class OCSPResponse(Sequence): _fields = [ ('response_status', OCSPResponseStatus), ('response_bytes', ResponseBytes, {'explicit': 0, 'optional': True}), ] _processed_extensions = False _critical_extensions = None _nonce_value = None _extended_revoke_value = None def _set_extensions(self): """ Sets common named extensions to private attributes and creates a list of critical extensions """ self._critical_extensions = set() for extension in self['response_bytes']['response'].parsed['tbs_response_data']['response_extensions']: name = extension['extn_id'].native attribute_name = '_%s_value' % name if hasattr(self, attribute_name): setattr(self, attribute_name, extension['extn_value'].parsed) if extension['critical'].native: self._critical_extensions.add(name) self._processed_extensions = True @property def critical_extensions(self): """ Returns a set of the names (or OID if not a known extension) of the extensions marked as critical :return: A set of unicode strings """ if not self._processed_extensions: self._set_extensions() return self._critical_extensions @property def nonce_value(self): """ This extension is used to prevent replay attacks on the request/response exchange :return: None or an OctetString object """ if self._processed_extensions is False: self._set_extensions() return self._nonce_value @property def extended_revoke_value(self): """ This extension is used to signal that the responder will return a "revoked" status for non-issued certificates. :return: None or a Null object (if present) """ if self._processed_extensions is False: self._set_extensions() return self._extended_revoke_value @property def basic_ocsp_response(self): """ A shortcut into the BasicOCSPResponse sequence :return: None or an asn1crypto.ocsp.BasicOCSPResponse object """ return self['response_bytes']['response'].parsed @property def response_data(self): """ A shortcut into the parsed, ResponseData sequence :return: None or an asn1crypto.ocsp.ResponseData object """ return self['response_bytes']['response'].parsed['tbs_response_data'] parser.py000064400000021723152572326550006433 0ustar00# coding: utf-8 """ Functions for parsing and dumping using the ASN.1 DER encoding. Exports the following items: - emit() - parse() - peek() Other type classes are defined that help compose the types listed above. """ from __future__ import unicode_literals, division, absolute_import, print_function import sys from ._types import byte_cls, chr_cls, type_name from .util import int_from_bytes, int_to_bytes _PY2 = sys.version_info <= (3,) _INSUFFICIENT_DATA_MESSAGE = 'Insufficient data - %s bytes requested but only %s available' _MAX_DEPTH = 10 def emit(class_, method, tag, contents): """ Constructs a byte string of an ASN.1 DER-encoded value This is typically not useful. Instead, use one of the standard classes from asn1crypto.core, or construct a new class with specific fields, and call the .dump() method. :param class_: An integer ASN.1 class value: 0 (universal), 1 (application), 2 (context), 3 (private) :param method: An integer ASN.1 method value: 0 (primitive), 1 (constructed) :param tag: An integer ASN.1 tag value :param contents: A byte string of the encoded byte contents :return: A byte string of the ASN.1 DER value (header and contents) """ if not isinstance(class_, int): raise TypeError('class_ must be an integer, not %s' % type_name(class_)) if class_ < 0 or class_ > 3: raise ValueError('class_ must be one of 0, 1, 2 or 3, not %s' % class_) if not isinstance(method, int): raise TypeError('method must be an integer, not %s' % type_name(method)) if method < 0 or method > 1: raise ValueError('method must be 0 or 1, not %s' % method) if not isinstance(tag, int): raise TypeError('tag must be an integer, not %s' % type_name(tag)) if tag < 0: raise ValueError('tag must be greater than zero, not %s' % tag) if not isinstance(contents, byte_cls): raise TypeError('contents must be a byte string, not %s' % type_name(contents)) return _dump_header(class_, method, tag, contents) + contents def parse(contents, strict=False): """ Parses a byte string of ASN.1 BER/DER-encoded data. This is typically not useful. Instead, use one of the standard classes from asn1crypto.core, or construct a new class with specific fields, and call the .load() class method. :param contents: A byte string of BER/DER-encoded data :param strict: A boolean indicating if trailing data should be forbidden - if so, a ValueError will be raised when trailing data exists :raises: ValueError - when the contents do not contain an ASN.1 header or are truncated in some way TypeError - when contents is not a byte string :return: A 6-element tuple: - 0: integer class (0 to 3) - 1: integer method - 2: integer tag - 3: byte string header - 4: byte string content - 5: byte string trailer """ if not isinstance(contents, byte_cls): raise TypeError('contents must be a byte string, not %s' % type_name(contents)) contents_len = len(contents) info, consumed = _parse(contents, contents_len) if strict and consumed != contents_len: raise ValueError('Extra data - %d bytes of trailing data were provided' % (contents_len - consumed)) return info def peek(contents): """ Parses a byte string of ASN.1 BER/DER-encoded data to find the length This is typically used to look into an encoded value to see how long the next chunk of ASN.1-encoded data is. Primarily it is useful when a value is a concatenation of multiple values. :param contents: A byte string of BER/DER-encoded data :raises: ValueError - when the contents do not contain an ASN.1 header or are truncated in some way TypeError - when contents is not a byte string :return: An integer with the number of bytes occupied by the ASN.1 value """ if not isinstance(contents, byte_cls): raise TypeError('contents must be a byte string, not %s' % type_name(contents)) info, consumed = _parse(contents, len(contents)) return consumed def _parse(encoded_data, data_len, pointer=0, lengths_only=False, depth=0): """ Parses a byte string into component parts :param encoded_data: A byte string that contains BER-encoded data :param data_len: The integer length of the encoded data :param pointer: The index in the byte string to parse from :param lengths_only: A boolean to cause the call to return a 2-element tuple of the integer number of bytes in the header and the integer number of bytes in the contents. Internal use only. :param depth: The recursion depth when evaluating indefinite-length encoding. :return: A 2-element tuple: - 0: A tuple of (class_, method, tag, header, content, trailer) - 1: An integer indicating how many bytes were consumed """ if depth > _MAX_DEPTH: raise ValueError('Indefinite-length recursion limit exceeded') start = pointer if data_len < pointer + 1: raise ValueError(_INSUFFICIENT_DATA_MESSAGE % (1, data_len - pointer)) first_octet = ord(encoded_data[pointer]) if _PY2 else encoded_data[pointer] pointer += 1 tag = first_octet & 31 constructed = (first_octet >> 5) & 1 # Base 128 length using 8th bit as continuation indicator if tag == 31: tag = 0 while True: if data_len < pointer + 1: raise ValueError(_INSUFFICIENT_DATA_MESSAGE % (1, data_len - pointer)) num = ord(encoded_data[pointer]) if _PY2 else encoded_data[pointer] pointer += 1 if num == 0x80 and tag == 0: raise ValueError('Non-minimal tag encoding') tag *= 128 tag += num & 127 if num >> 7 == 0: break if tag < 31: raise ValueError('Non-minimal tag encoding') if data_len < pointer + 1: raise ValueError(_INSUFFICIENT_DATA_MESSAGE % (1, data_len - pointer)) length_octet = ord(encoded_data[pointer]) if _PY2 else encoded_data[pointer] pointer += 1 trailer = b'' if length_octet >> 7 == 0: contents_end = pointer + (length_octet & 127) else: length_octets = length_octet & 127 if length_octets: if data_len < pointer + length_octets: raise ValueError(_INSUFFICIENT_DATA_MESSAGE % (length_octets, data_len - pointer)) pointer += length_octets contents_end = pointer + int_from_bytes(encoded_data[pointer - length_octets:pointer], signed=False) else: # To properly parse indefinite length values, we need to scan forward # parsing headers until we find a value with a length of zero. If we # just scanned looking for \x00\x00, nested indefinite length values # would not work. if not constructed: raise ValueError('Indefinite-length element must be constructed') contents_end = pointer while data_len < contents_end + 2 or encoded_data[contents_end:contents_end+2] != b'\x00\x00': _, contents_end = _parse(encoded_data, data_len, contents_end, lengths_only=True, depth=depth+1) contents_end += 2 trailer = b'\x00\x00' if contents_end > data_len: raise ValueError(_INSUFFICIENT_DATA_MESSAGE % (contents_end - pointer, data_len - pointer)) if lengths_only: return (pointer, contents_end) return ( ( first_octet >> 6, constructed, tag, encoded_data[start:pointer], encoded_data[pointer:contents_end-len(trailer)], trailer ), contents_end ) def _dump_header(class_, method, tag, contents): """ Constructs the header bytes for an ASN.1 object :param class_: An integer ASN.1 class value: 0 (universal), 1 (application), 2 (context), 3 (private) :param method: An integer ASN.1 method value: 0 (primitive), 1 (constructed) :param tag: An integer ASN.1 tag value :param contents: A byte string of the encoded byte contents :return: A byte string of the ASN.1 DER header """ header = b'' id_num = 0 id_num |= class_ << 6 id_num |= method << 5 if tag >= 31: cont_bit = 0 while tag > 0: header = chr_cls(cont_bit | (tag & 0x7f)) + header if not cont_bit: cont_bit = 0x80 tag = tag >> 7 header = chr_cls(id_num | 31) + header else: header += chr_cls(id_num | tag) length = len(contents) if length <= 127: header += chr_cls(length) else: length_bytes = int_to_bytes(length) header += chr_cls(0x80 | len(length_bytes)) header += length_bytes return header pdf.py000064400000004312152572326550005703 0ustar00# coding: utf-8 """ ASN.1 type classes for PDF signature structures. Adds extra oid mapping and value parsing to asn1crypto.x509.Extension() and asn1crypto.xms.CMSAttribute(). """ from __future__ import unicode_literals, division, absolute_import, print_function from .cms import CMSAttributeType, CMSAttribute from .core import ( Boolean, Integer, Null, ObjectIdentifier, OctetString, Sequence, SequenceOf, SetOf, ) from .crl import CertificateList from .ocsp import OCSPResponse from .x509 import ( Extension, ExtensionId, GeneralName, KeyPurposeId, ) class AdobeArchiveRevInfo(Sequence): _fields = [ ('version', Integer) ] class AdobeTimestamp(Sequence): _fields = [ ('version', Integer), ('location', GeneralName), ('requires_auth', Boolean, {'optional': True, 'default': False}), ] class OtherRevInfo(Sequence): _fields = [ ('type', ObjectIdentifier), ('value', OctetString), ] class SequenceOfCertificateList(SequenceOf): _child_spec = CertificateList class SequenceOfOCSPResponse(SequenceOf): _child_spec = OCSPResponse class SequenceOfOtherRevInfo(SequenceOf): _child_spec = OtherRevInfo class RevocationInfoArchival(Sequence): _fields = [ ('crl', SequenceOfCertificateList, {'explicit': 0, 'optional': True}), ('ocsp', SequenceOfOCSPResponse, {'explicit': 1, 'optional': True}), ('other_rev_info', SequenceOfOtherRevInfo, {'explicit': 2, 'optional': True}), ] class SetOfRevocationInfoArchival(SetOf): _child_spec = RevocationInfoArchival ExtensionId._map['1.2.840.113583.1.1.9.2'] = 'adobe_archive_rev_info' ExtensionId._map['1.2.840.113583.1.1.9.1'] = 'adobe_timestamp' ExtensionId._map['1.2.840.113583.1.1.10'] = 'adobe_ppklite_credential' Extension._oid_specs['adobe_archive_rev_info'] = AdobeArchiveRevInfo Extension._oid_specs['adobe_timestamp'] = AdobeTimestamp Extension._oid_specs['adobe_ppklite_credential'] = Null KeyPurposeId._map['1.2.840.113583.1.1.5'] = 'pdf_signing' CMSAttributeType._map['1.2.840.113583.1.1.8'] = 'adobe_revocation_info_archival' CMSAttribute._oid_specs['adobe_revocation_info_archival'] = SetOfRevocationInfoArchival pem.py000064400000014001152572326550005707 0ustar00# coding: utf-8 """ Encoding DER to PEM and decoding PEM to DER. Exports the following items: - armor() - detect() - unarmor() """ from __future__ import unicode_literals, division, absolute_import, print_function import base64 import re import sys from ._errors import unwrap from ._types import type_name as _type_name, str_cls, byte_cls if sys.version_info < (3,): from cStringIO import StringIO as BytesIO else: from io import BytesIO def detect(byte_string): """ Detect if a byte string seems to contain a PEM-encoded block :param byte_string: A byte string to look through :return: A boolean, indicating if a PEM-encoded block is contained in the byte string """ if not isinstance(byte_string, byte_cls): raise TypeError(unwrap( ''' byte_string must be a byte string, not %s ''', _type_name(byte_string) )) return byte_string.find(b'-----BEGIN') != -1 or byte_string.find(b'---- BEGIN') != -1 def armor(type_name, der_bytes, headers=None): """ Armors a DER-encoded byte string in PEM :param type_name: A unicode string that will be capitalized and placed in the header and footer of the block. E.g. "CERTIFICATE", "PRIVATE KEY", etc. This will appear as "-----BEGIN CERTIFICATE-----" and "-----END CERTIFICATE-----". :param der_bytes: A byte string to be armored :param headers: An OrderedDict of the header lines to write after the BEGIN line :return: A byte string of the PEM block """ if not isinstance(der_bytes, byte_cls): raise TypeError(unwrap( ''' der_bytes must be a byte string, not %s ''' % _type_name(der_bytes) )) if not isinstance(type_name, str_cls): raise TypeError(unwrap( ''' type_name must be a unicode string, not %s ''', _type_name(type_name) )) type_name = type_name.upper().encode('ascii') output = BytesIO() output.write(b'-----BEGIN ') output.write(type_name) output.write(b'-----\n') if headers: for key in headers: output.write(key.encode('ascii')) output.write(b': ') output.write(headers[key].encode('ascii')) output.write(b'\n') output.write(b'\n') b64_bytes = base64.b64encode(der_bytes) b64_len = len(b64_bytes) i = 0 while i < b64_len: output.write(b64_bytes[i:i + 64]) output.write(b'\n') i += 64 output.write(b'-----END ') output.write(type_name) output.write(b'-----\n') return output.getvalue() def _unarmor(pem_bytes): """ Convert a PEM-encoded byte string into one or more DER-encoded byte strings :param pem_bytes: A byte string of the PEM-encoded data :raises: ValueError - when the pem_bytes do not appear to be PEM-encoded bytes :return: A generator of 3-element tuples in the format: (object_type, headers, der_bytes). The object_type is a unicode string of what is between "-----BEGIN " and "-----". Examples include: "CERTIFICATE", "PUBLIC KEY", "PRIVATE KEY". The headers is a dict containing any lines in the form "Name: Value" that are right after the begin line. """ if not isinstance(pem_bytes, byte_cls): raise TypeError(unwrap( ''' pem_bytes must be a byte string, not %s ''', _type_name(pem_bytes) )) # Valid states include: "trash", "headers", "body" state = 'trash' headers = {} base64_data = b'' object_type = None found_start = False found_end = False for line in pem_bytes.splitlines(False): if line == b'': continue if state == "trash": # Look for a starting line since some CA cert bundle show the cert # into in a parsed format above each PEM block type_name_match = re.match(b'^(?:---- |-----)BEGIN ([A-Z0-9 ]+)(?: ----|-----)', line) if not type_name_match: continue object_type = type_name_match.group(1).decode('ascii') found_start = True state = 'headers' continue if state == 'headers': if line.find(b':') == -1: state = 'body' else: decoded_line = line.decode('ascii') name, value = decoded_line.split(':', 1) headers[name] = value.strip() continue if state == 'body': if line[0:5] in (b'-----', b'---- '): der_bytes = base64.b64decode(base64_data) yield (object_type, headers, der_bytes) state = 'trash' headers = {} base64_data = b'' object_type = None found_end = True continue base64_data += line if not found_start or not found_end: raise ValueError(unwrap( ''' pem_bytes does not appear to contain PEM-encoded data - no BEGIN/END combination found ''' )) def unarmor(pem_bytes, multiple=False): """ Convert a PEM-encoded byte string into a DER-encoded byte string :param pem_bytes: A byte string of the PEM-encoded data :param multiple: If True, function will return a generator :raises: ValueError - when the pem_bytes do not appear to be PEM-encoded bytes :return: A 3-element tuple (object_name, headers, der_bytes). The object_name is a unicode string of what is between "-----BEGIN " and "-----". Examples include: "CERTIFICATE", "PUBLIC KEY", "PRIVATE KEY". The headers is a dict containing any lines in the form "Name: Value" that are right after the begin line. """ generator = _unarmor(pem_bytes) if not multiple: return next(generator) return generator pkcs12.py000064400000010726152572326550006243 0ustar00# coding: utf-8 """ ASN.1 type classes for PKCS#12 files. Exports the following items: - CertBag() - CrlBag() - Pfx() - SafeBag() - SecretBag() Other type classes are defined that help compose the types listed above. """ from __future__ import unicode_literals, division, absolute_import, print_function from .algos import DigestInfo from .cms import ContentInfo, SignedData from .core import ( Any, BMPString, Integer, ObjectIdentifier, OctetString, ParsableOctetString, Sequence, SequenceOf, SetOf, ) from .keys import PrivateKeyInfo, EncryptedPrivateKeyInfo from .x509 import Certificate, KeyPurposeId # The structures in this file are taken from https://tools.ietf.org/html/rfc7292 class MacData(Sequence): _fields = [ ('mac', DigestInfo), ('mac_salt', OctetString), ('iterations', Integer, {'default': 1}), ] class Version(Integer): _map = { 3: 'v3' } class AttributeType(ObjectIdentifier): _map = { # https://tools.ietf.org/html/rfc2985#page-18 '1.2.840.113549.1.9.20': 'friendly_name', '1.2.840.113549.1.9.21': 'local_key_id', # https://support.microsoft.com/en-us/kb/287547 '1.3.6.1.4.1.311.17.1': 'microsoft_local_machine_keyset', # https://github.com/frohoff/jdk8u-dev-jdk/blob/master/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java # this is a set of OIDs, representing key usage, the usual value is a SET of one element OID 2.5.29.37.0 '2.16.840.1.113894.746875.1.1': 'trusted_key_usage', } class SetOfAny(SetOf): _child_spec = Any class SetOfBMPString(SetOf): _child_spec = BMPString class SetOfOctetString(SetOf): _child_spec = OctetString class SetOfKeyPurposeId(SetOf): _child_spec = KeyPurposeId class Attribute(Sequence): _fields = [ ('type', AttributeType), ('values', None), ] _oid_specs = { 'friendly_name': SetOfBMPString, 'local_key_id': SetOfOctetString, 'microsoft_csp_name': SetOfBMPString, 'trusted_key_usage': SetOfKeyPurposeId, } def _values_spec(self): return self._oid_specs.get(self['type'].native, SetOfAny) _spec_callbacks = { 'values': _values_spec } class Attributes(SetOf): _child_spec = Attribute class Pfx(Sequence): _fields = [ ('version', Version), ('auth_safe', ContentInfo), ('mac_data', MacData, {'optional': True}) ] _authenticated_safe = None @property def authenticated_safe(self): if self._authenticated_safe is None: content = self['auth_safe']['content'] if isinstance(content, SignedData): content = content['content_info']['content'] self._authenticated_safe = AuthenticatedSafe.load(content.native) return self._authenticated_safe class AuthenticatedSafe(SequenceOf): _child_spec = ContentInfo class BagId(ObjectIdentifier): _map = { '1.2.840.113549.1.12.10.1.1': 'key_bag', '1.2.840.113549.1.12.10.1.2': 'pkcs8_shrouded_key_bag', '1.2.840.113549.1.12.10.1.3': 'cert_bag', '1.2.840.113549.1.12.10.1.4': 'crl_bag', '1.2.840.113549.1.12.10.1.5': 'secret_bag', '1.2.840.113549.1.12.10.1.6': 'safe_contents', } class CertId(ObjectIdentifier): _map = { '1.2.840.113549.1.9.22.1': 'x509', '1.2.840.113549.1.9.22.2': 'sdsi', } class CertBag(Sequence): _fields = [ ('cert_id', CertId), ('cert_value', ParsableOctetString, {'explicit': 0}), ] _oid_pair = ('cert_id', 'cert_value') _oid_specs = { 'x509': Certificate, } class CrlBag(Sequence): _fields = [ ('crl_id', ObjectIdentifier), ('crl_value', OctetString, {'explicit': 0}), ] class SecretBag(Sequence): _fields = [ ('secret_type_id', ObjectIdentifier), ('secret_value', OctetString, {'explicit': 0}), ] class SafeContents(SequenceOf): pass class SafeBag(Sequence): _fields = [ ('bag_id', BagId), ('bag_value', Any, {'explicit': 0}), ('bag_attributes', Attributes, {'optional': True}), ] _oid_pair = ('bag_id', 'bag_value') _oid_specs = { 'key_bag': PrivateKeyInfo, 'pkcs8_shrouded_key_bag': EncryptedPrivateKeyInfo, 'cert_bag': CertBag, 'crl_bag': CrlBag, 'secret_bag': SecretBag, 'safe_contents': SafeContents } SafeContents._child_spec = SafeBag tsp.py000064400000017221152572326550005743 0ustar00# coding: utf-8 """ ASN.1 type classes for the time stamp protocol (TSP). Exports the following items: - TimeStampReq() - TimeStampResp() Also adds TimeStampedData() support to asn1crypto.cms.ContentInfo(), TimeStampedData() and TSTInfo() support to asn1crypto.cms.EncapsulatedContentInfo() and some oids and value parsers to asn1crypto.cms.CMSAttribute(). Other type classes are defined that help compose the types listed above. """ from __future__ import unicode_literals, division, absolute_import, print_function from .algos import DigestAlgorithm from .cms import ( CMSAttribute, CMSAttributeType, ContentInfo, ContentType, EncapsulatedContentInfo, ) from .core import ( Any, BitString, Boolean, Choice, GeneralizedTime, IA5String, Integer, ObjectIdentifier, OctetString, Sequence, SequenceOf, SetOf, UTF8String, ) from .crl import CertificateList from .x509 import ( Attributes, CertificatePolicies, GeneralName, GeneralNames, ) # The structures in this file are based on https://tools.ietf.org/html/rfc3161, # https://tools.ietf.org/html/rfc4998, https://tools.ietf.org/html/rfc5544, # https://tools.ietf.org/html/rfc5035, https://tools.ietf.org/html/rfc2634 class Version(Integer): _map = { 0: 'v0', 1: 'v1', 2: 'v2', 3: 'v3', 4: 'v4', 5: 'v5', } class MessageImprint(Sequence): _fields = [ ('hash_algorithm', DigestAlgorithm), ('hashed_message', OctetString), ] class Accuracy(Sequence): _fields = [ ('seconds', Integer, {'optional': True}), ('millis', Integer, {'implicit': 0, 'optional': True}), ('micros', Integer, {'implicit': 1, 'optional': True}), ] class Extension(Sequence): _fields = [ ('extn_id', ObjectIdentifier), ('critical', Boolean, {'default': False}), ('extn_value', OctetString), ] class Extensions(SequenceOf): _child_spec = Extension class TSTInfo(Sequence): _fields = [ ('version', Version), ('policy', ObjectIdentifier), ('message_imprint', MessageImprint), ('serial_number', Integer), ('gen_time', GeneralizedTime), ('accuracy', Accuracy, {'optional': True}), ('ordering', Boolean, {'default': False}), ('nonce', Integer, {'optional': True}), ('tsa', GeneralName, {'explicit': 0, 'optional': True}), ('extensions', Extensions, {'implicit': 1, 'optional': True}), ] class TimeStampReq(Sequence): _fields = [ ('version', Version), ('message_imprint', MessageImprint), ('req_policy', ObjectIdentifier, {'optional': True}), ('nonce', Integer, {'optional': True}), ('cert_req', Boolean, {'default': False}), ('extensions', Extensions, {'implicit': 0, 'optional': True}), ] class PKIStatus(Integer): _map = { 0: 'granted', 1: 'granted_with_mods', 2: 'rejection', 3: 'waiting', 4: 'revocation_warning', 5: 'revocation_notification', } class PKIFreeText(SequenceOf): _child_spec = UTF8String class PKIFailureInfo(BitString): _map = { 0: 'bad_alg', 2: 'bad_request', 5: 'bad_data_format', 14: 'time_not_available', 15: 'unaccepted_policy', 16: 'unaccepted_extensions', 17: 'add_info_not_available', 25: 'system_failure', } class PKIStatusInfo(Sequence): _fields = [ ('status', PKIStatus), ('status_string', PKIFreeText, {'optional': True}), ('fail_info', PKIFailureInfo, {'optional': True}), ] class TimeStampResp(Sequence): _fields = [ ('status', PKIStatusInfo), ('time_stamp_token', ContentInfo), ] class MetaData(Sequence): _fields = [ ('hash_protected', Boolean), ('file_name', UTF8String, {'optional': True}), ('media_type', IA5String, {'optional': True}), ('other_meta_data', Attributes, {'optional': True}), ] class TimeStampAndCRL(Sequence): _fields = [ ('time_stamp', EncapsulatedContentInfo), ('crl', CertificateList, {'optional': True}), ] class TimeStampTokenEvidence(SequenceOf): _child_spec = TimeStampAndCRL class DigestAlgorithms(SequenceOf): _child_spec = DigestAlgorithm class EncryptionInfo(Sequence): _fields = [ ('encryption_info_type', ObjectIdentifier), ('encryption_info_value', Any), ] class PartialHashtree(SequenceOf): _child_spec = OctetString class PartialHashtrees(SequenceOf): _child_spec = PartialHashtree class ArchiveTimeStamp(Sequence): _fields = [ ('digest_algorithm', DigestAlgorithm, {'implicit': 0, 'optional': True}), ('attributes', Attributes, {'implicit': 1, 'optional': True}), ('reduced_hashtree', PartialHashtrees, {'implicit': 2, 'optional': True}), ('time_stamp', ContentInfo), ] class ArchiveTimeStampSequence(SequenceOf): _child_spec = ArchiveTimeStamp class EvidenceRecord(Sequence): _fields = [ ('version', Version), ('digest_algorithms', DigestAlgorithms), ('crypto_infos', Attributes, {'implicit': 0, 'optional': True}), ('encryption_info', EncryptionInfo, {'implicit': 1, 'optional': True}), ('archive_time_stamp_sequence', ArchiveTimeStampSequence), ] class OtherEvidence(Sequence): _fields = [ ('oe_type', ObjectIdentifier), ('oe_value', Any), ] class Evidence(Choice): _alternatives = [ ('tst_evidence', TimeStampTokenEvidence, {'implicit': 0}), ('ers_evidence', EvidenceRecord, {'implicit': 1}), ('other_evidence', OtherEvidence, {'implicit': 2}), ] class TimeStampedData(Sequence): _fields = [ ('version', Version), ('data_uri', IA5String, {'optional': True}), ('meta_data', MetaData, {'optional': True}), ('content', OctetString, {'optional': True}), ('temporal_evidence', Evidence), ] class IssuerSerial(Sequence): _fields = [ ('issuer', GeneralNames), ('serial_number', Integer), ] class ESSCertID(Sequence): _fields = [ ('cert_hash', OctetString), ('issuer_serial', IssuerSerial, {'optional': True}), ] class ESSCertIDs(SequenceOf): _child_spec = ESSCertID class SigningCertificate(Sequence): _fields = [ ('certs', ESSCertIDs), ('policies', CertificatePolicies, {'optional': True}), ] class SetOfSigningCertificates(SetOf): _child_spec = SigningCertificate class ESSCertIDv2(Sequence): _fields = [ ('hash_algorithm', DigestAlgorithm, {'default': {'algorithm': 'sha256'}}), ('cert_hash', OctetString), ('issuer_serial', IssuerSerial, {'optional': True}), ] class ESSCertIDv2s(SequenceOf): _child_spec = ESSCertIDv2 class SigningCertificateV2(Sequence): _fields = [ ('certs', ESSCertIDv2s), ('policies', CertificatePolicies, {'optional': True}), ] class SetOfSigningCertificatesV2(SetOf): _child_spec = SigningCertificateV2 EncapsulatedContentInfo._oid_specs['tst_info'] = TSTInfo EncapsulatedContentInfo._oid_specs['timestamped_data'] = TimeStampedData ContentInfo._oid_specs['timestamped_data'] = TimeStampedData ContentType._map['1.2.840.113549.1.9.16.1.4'] = 'tst_info' ContentType._map['1.2.840.113549.1.9.16.1.31'] = 'timestamped_data' CMSAttributeType._map['1.2.840.113549.1.9.16.2.12'] = 'signing_certificate' CMSAttribute._oid_specs['signing_certificate'] = SetOfSigningCertificates CMSAttributeType._map['1.2.840.113549.1.9.16.2.47'] = 'signing_certificate_v2' CMSAttribute._oid_specs['signing_certificate_v2'] = SetOfSigningCertificatesV2 util.py000064400000052561152572326550006120 0ustar00# coding: utf-8 """ Miscellaneous data helpers, including functions for converting integers to and from bytes and UTC timezone. Exports the following items: - OrderedDict() - int_from_bytes() - int_to_bytes() - timezone.utc - utc_with_dst - create_timezone() - inet_ntop() - inet_pton() - uri_to_iri() - iri_to_uri() """ from __future__ import unicode_literals, division, absolute_import, print_function import math import sys from datetime import datetime, date, timedelta, tzinfo from ._errors import unwrap from ._iri import iri_to_uri, uri_to_iri # noqa from ._ordereddict import OrderedDict # noqa from ._types import type_name if sys.platform == 'win32': from ._inet import inet_ntop, inet_pton else: from socket import inet_ntop, inet_pton # noqa # Python 2 if sys.version_info <= (3,): def int_to_bytes(value, signed=False, width=None): """ Converts an integer to a byte string :param value: The integer to convert :param signed: If the byte string should be encoded using two's complement :param width: If None, the minimal possible size (but at least 1), otherwise an integer of the byte width for the return value :return: A byte string """ if value == 0 and width == 0: return b'' # Handle negatives in two's complement is_neg = False if signed and value < 0: is_neg = True bits = int(math.ceil(len('%x' % abs(value)) / 2.0) * 8) value = (value + (1 << bits)) % (1 << bits) hex_str = '%x' % value if len(hex_str) & 1: hex_str = '0' + hex_str output = hex_str.decode('hex') if signed and not is_neg and ord(output[0:1]) & 0x80: output = b'\x00' + output if width is not None: if len(output) > width: raise OverflowError('int too big to convert') if is_neg: pad_char = b'\xFF' else: pad_char = b'\x00' output = (pad_char * (width - len(output))) + output elif is_neg and ord(output[0:1]) & 0x80 == 0: output = b'\xFF' + output return output def int_from_bytes(value, signed=False): """ Converts a byte string to an integer :param value: The byte string to convert :param signed: If the byte string should be interpreted using two's complement :return: An integer """ if value == b'': return 0 num = long(value.encode("hex"), 16) # noqa if not signed: return num # Check for sign bit and handle two's complement if ord(value[0:1]) & 0x80: bit_len = len(value) * 8 return num - (1 << bit_len) return num class timezone(tzinfo): # noqa """ Implements datetime.timezone for py2. Only full minute offsets are supported. DST is not supported. """ def __init__(self, offset, name=None): """ :param offset: A timedelta with this timezone's offset from UTC :param name: Name of the timezone; if None, generate one. """ if not timedelta(hours=-24) < offset < timedelta(hours=24): raise ValueError('Offset must be in [-23:59, 23:59]') if offset.seconds % 60 or offset.microseconds: raise ValueError('Offset must be full minutes') self._offset = offset if name is not None: self._name = name elif not offset: self._name = 'UTC' else: self._name = 'UTC' + _format_offset(offset) def __eq__(self, other): """ Compare two timezones :param other: The other timezone to compare to :return: A boolean """ if type(other) != timezone: return False return self._offset == other._offset def __getinitargs__(self): """ Called by tzinfo.__reduce__ to support pickle and copy. :return: offset and name, to be used for __init__ """ return self._offset, self._name def tzname(self, dt): """ :param dt: A datetime object; ignored. :return: Name of this timezone """ return self._name def utcoffset(self, dt): """ :param dt: A datetime object; ignored. :return: A timedelta object with the offset from UTC """ return self._offset def dst(self, dt): """ :param dt: A datetime object; ignored. :return: Zero timedelta """ return timedelta(0) timezone.utc = timezone(timedelta(0)) # Python 3 else: from datetime import timezone # noqa def int_to_bytes(value, signed=False, width=None): """ Converts an integer to a byte string :param value: The integer to convert :param signed: If the byte string should be encoded using two's complement :param width: If None, the minimal possible size (but at least 1), otherwise an integer of the byte width for the return value :return: A byte string """ if width is None: if signed: if value < 0: bits_required = abs(value + 1).bit_length() else: bits_required = value.bit_length() if bits_required % 8 == 0: bits_required += 1 else: bits_required = value.bit_length() width = math.ceil(bits_required / 8) or 1 return value.to_bytes(width, byteorder='big', signed=signed) def int_from_bytes(value, signed=False): """ Converts a byte string to an integer :param value: The byte string to convert :param signed: If the byte string should be interpreted using two's complement :return: An integer """ return int.from_bytes(value, 'big', signed=signed) def _format_offset(off): """ Format a timedelta into "[+-]HH:MM" format or "" for None """ if off is None: return '' mins = off.days * 24 * 60 + off.seconds // 60 sign = '-' if mins < 0 else '+' return sign + '%02d:%02d' % divmod(abs(mins), 60) class _UtcWithDst(tzinfo): """ Utc class where dst does not return None; required for astimezone """ def tzname(self, dt): return 'UTC' def utcoffset(self, dt): return timedelta(0) def dst(self, dt): return timedelta(0) utc_with_dst = _UtcWithDst() _timezone_cache = {} def create_timezone(offset): """ Returns a new datetime.timezone object with the given offset. Uses cached objects if possible. :param offset: A datetime.timedelta object; It needs to be in full minutes and between -23:59 and +23:59. :return: A datetime.timezone object """ try: tz = _timezone_cache[offset] except KeyError: tz = _timezone_cache[offset] = timezone(offset) return tz class extended_date(object): """ A datetime.datetime-like object that represents the year 0. This is just to handle 0000-01-01 found in some certificates. Python's datetime does not support year 0. The proleptic gregorian calendar repeats itself every 400 years. Therefore, the simplest way to format is to substitute year 2000. """ def __init__(self, year, month, day): """ :param year: The integer 0 :param month: An integer from 1 to 12 :param day: An integer from 1 to 31 """ if year != 0: raise ValueError('year must be 0') self._y2k = date(2000, month, day) @property def year(self): """ :return: The integer 0 """ return 0 @property def month(self): """ :return: An integer from 1 to 12 """ return self._y2k.month @property def day(self): """ :return: An integer from 1 to 31 """ return self._y2k.day def strftime(self, format): """ Formats the date using strftime() :param format: A strftime() format string :return: A str, the formatted date as a unicode string in Python 3 and a byte string in Python 2 """ # Format the date twice, once with year 2000, once with year 4000. # The only differences in the result will be in the millennium. Find them and replace by zeros. y2k = self._y2k.strftime(format) y4k = self._y2k.replace(year=4000).strftime(format) return ''.join('0' if (c2, c4) == ('2', '4') else c2 for c2, c4 in zip(y2k, y4k)) def isoformat(self): """ Formats the date as %Y-%m-%d :return: The date formatted to %Y-%m-%d as a unicode string in Python 3 and a byte string in Python 2 """ return self.strftime('0000-%m-%d') def replace(self, year=None, month=None, day=None): """ Returns a new datetime.date or asn1crypto.util.extended_date object with the specified components replaced :return: A datetime.date or asn1crypto.util.extended_date object """ if year is None: year = self.year if month is None: month = self.month if day is None: day = self.day if year > 0: cls = date else: cls = extended_date return cls( year, month, day ) def __str__(self): """ :return: A str representing this extended_date, e.g. "0000-01-01" """ return self.strftime('%Y-%m-%d') def __eq__(self, other): """ Compare two extended_date objects :param other: The other extended_date to compare to :return: A boolean """ # datetime.date object wouldn't compare equal because it can't be year 0 if not isinstance(other, self.__class__): return False return self.__cmp__(other) == 0 def __ne__(self, other): """ Compare two extended_date objects :param other: The other extended_date to compare to :return: A boolean """ return not self.__eq__(other) def _comparison_error(self, other): raise TypeError(unwrap( ''' An asn1crypto.util.extended_date object can only be compared to an asn1crypto.util.extended_date or datetime.date object, not %s ''', type_name(other) )) def __cmp__(self, other): """ Compare two extended_date or datetime.date objects :param other: The other extended_date object to compare to :return: An integer smaller than, equal to, or larger than 0 """ # self is year 0, other is >= year 1 if isinstance(other, date): return -1 if not isinstance(other, self.__class__): self._comparison_error(other) if self._y2k < other._y2k: return -1 if self._y2k > other._y2k: return 1 return 0 def __lt__(self, other): return self.__cmp__(other) < 0 def __le__(self, other): return self.__cmp__(other) <= 0 def __gt__(self, other): return self.__cmp__(other) > 0 def __ge__(self, other): return self.__cmp__(other) >= 0 class extended_datetime(object): """ A datetime.datetime-like object that represents the year 0. This is just to handle 0000-01-01 found in some certificates. Python's datetime does not support year 0. The proleptic gregorian calendar repeats itself every 400 years. Therefore, the simplest way to format is to substitute year 2000. """ # There are 97 leap days during 400 years. DAYS_IN_400_YEARS = 400 * 365 + 97 DAYS_IN_2000_YEARS = 5 * DAYS_IN_400_YEARS def __init__(self, year, *args, **kwargs): """ :param year: The integer 0 :param args: Other positional arguments; see datetime.datetime. :param kwargs: Other keyword arguments; see datetime.datetime. """ if year != 0: raise ValueError('year must be 0') self._y2k = datetime(2000, *args, **kwargs) @property def year(self): """ :return: The integer 0 """ return 0 @property def month(self): """ :return: An integer from 1 to 12 """ return self._y2k.month @property def day(self): """ :return: An integer from 1 to 31 """ return self._y2k.day @property def hour(self): """ :return: An integer from 1 to 24 """ return self._y2k.hour @property def minute(self): """ :return: An integer from 1 to 60 """ return self._y2k.minute @property def second(self): """ :return: An integer from 1 to 60 """ return self._y2k.second @property def microsecond(self): """ :return: An integer from 0 to 999999 """ return self._y2k.microsecond @property def tzinfo(self): """ :return: If object is timezone aware, a datetime.tzinfo object, else None. """ return self._y2k.tzinfo def utcoffset(self): """ :return: If object is timezone aware, a datetime.timedelta object, else None. """ return self._y2k.utcoffset() def time(self): """ :return: A datetime.time object """ return self._y2k.time() def date(self): """ :return: An asn1crypto.util.extended_date of the date """ return extended_date(0, self.month, self.day) def strftime(self, format): """ Performs strftime(), always returning a str :param format: A strftime() format string :return: A str of the formatted datetime """ # Format the datetime twice, once with year 2000, once with year 4000. # The only differences in the result will be in the millennium. Find them and replace by zeros. y2k = self._y2k.strftime(format) y4k = self._y2k.replace(year=4000).strftime(format) return ''.join('0' if (c2, c4) == ('2', '4') else c2 for c2, c4 in zip(y2k, y4k)) def isoformat(self, sep='T'): """ Formats the date as "%Y-%m-%d %H:%M:%S" with the sep param between the date and time portions :param set: A single character of the separator to place between the date and time :return: The formatted datetime as a unicode string in Python 3 and a byte string in Python 2 """ s = '0000-%02d-%02d%c%02d:%02d:%02d' % (self.month, self.day, sep, self.hour, self.minute, self.second) if self.microsecond: s += '.%06d' % self.microsecond return s + _format_offset(self.utcoffset()) def replace(self, year=None, *args, **kwargs): """ Returns a new datetime.datetime or asn1crypto.util.extended_datetime object with the specified components replaced :param year: The new year to substitute. None to keep it. :param args: Other positional arguments; see datetime.datetime.replace. :param kwargs: Other keyword arguments; see datetime.datetime.replace. :return: A datetime.datetime or asn1crypto.util.extended_datetime object """ if year: return self._y2k.replace(year, *args, **kwargs) return extended_datetime.from_y2k(self._y2k.replace(2000, *args, **kwargs)) def astimezone(self, tz): """ Convert this extended_datetime to another timezone. :param tz: A datetime.tzinfo object. :return: A new extended_datetime or datetime.datetime object """ return extended_datetime.from_y2k(self._y2k.astimezone(tz)) def timestamp(self): """ Return POSIX timestamp. Only supported in python >= 3.3 :return: A float representing the seconds since 1970-01-01 UTC. This will be a negative value. """ return self._y2k.timestamp() - self.DAYS_IN_2000_YEARS * 86400 def __str__(self): """ :return: A str representing this extended_datetime, e.g. "0000-01-01 00:00:00.000001-10:00" """ return self.isoformat(sep=' ') def __eq__(self, other): """ Compare two extended_datetime objects :param other: The other extended_datetime to compare to :return: A boolean """ # Only compare against other datetime or extended_datetime objects if not isinstance(other, (self.__class__, datetime)): return False # Offset-naive and offset-aware datetimes are never the same if (self.tzinfo is None) != (other.tzinfo is None): return False return self.__cmp__(other) == 0 def __ne__(self, other): """ Compare two extended_datetime objects :param other: The other extended_datetime to compare to :return: A boolean """ return not self.__eq__(other) def _comparison_error(self, other): """ Raises a TypeError about the other object not being suitable for comparison :param other: The object being compared to """ raise TypeError(unwrap( ''' An asn1crypto.util.extended_datetime object can only be compared to an asn1crypto.util.extended_datetime or datetime.datetime object, not %s ''', type_name(other) )) def __cmp__(self, other): """ Compare two extended_datetime or datetime.datetime objects :param other: The other extended_datetime or datetime.datetime object to compare to :return: An integer smaller than, equal to, or larger than 0 """ if not isinstance(other, (self.__class__, datetime)): self._comparison_error(other) if (self.tzinfo is None) != (other.tzinfo is None): raise TypeError("can't compare offset-naive and offset-aware datetimes") diff = self - other zero = timedelta(0) if diff < zero: return -1 if diff > zero: return 1 return 0 def __lt__(self, other): return self.__cmp__(other) < 0 def __le__(self, other): return self.__cmp__(other) <= 0 def __gt__(self, other): return self.__cmp__(other) > 0 def __ge__(self, other): return self.__cmp__(other) >= 0 def __add__(self, other): """ Adds a timedelta :param other: A datetime.timedelta object to add. :return: A new extended_datetime or datetime.datetime object. """ return extended_datetime.from_y2k(self._y2k + other) def __sub__(self, other): """ Subtracts a timedelta or another datetime. :param other: A datetime.timedelta or datetime.datetime or extended_datetime object to subtract. :return: If a timedelta is passed, a new extended_datetime or datetime.datetime object. Else a datetime.timedelta object. """ if isinstance(other, timedelta): return extended_datetime.from_y2k(self._y2k - other) if isinstance(other, extended_datetime): return self._y2k - other._y2k if isinstance(other, datetime): return self._y2k - other - timedelta(days=self.DAYS_IN_2000_YEARS) return NotImplemented def __rsub__(self, other): return -(self - other) @classmethod def from_y2k(cls, value): """ Revert substitution of year 2000. :param value: A datetime.datetime object which is 2000 years in the future. :return: A new extended_datetime or datetime.datetime object. """ year = value.year - 2000 if year > 0: new_cls = datetime else: new_cls = cls return new_cls( year, value.month, value.day, value.hour, value.minute, value.second, value.microsecond, value.tzinfo ) version.py000064400000000230152572326550006612 0ustar00# coding: utf-8 from __future__ import unicode_literals, division, absolute_import, print_function __version__ = '1.5.1' __version_info__ = (1, 5, 1) x509.py000064400000267122152572326550005651 0ustar00# coding: utf-8 """ ASN.1 type classes for X.509 certificates. Exports the following items: - Attributes() - Certificate() - Extensions() - GeneralName() - GeneralNames() - Name() Other type classes are defined that help compose the types listed above. """ from __future__ import unicode_literals, division, absolute_import, print_function from contextlib import contextmanager from encodings import idna # noqa import hashlib import re import socket import stringprep import sys import unicodedata from ._errors import unwrap from ._iri import iri_to_uri, uri_to_iri from ._ordereddict import OrderedDict from ._types import type_name, str_cls, bytes_to_list from .algos import AlgorithmIdentifier, AnyAlgorithmIdentifier, DigestAlgorithm, SignedDigestAlgorithm from .core import ( Any, BitString, BMPString, Boolean, Choice, Concat, Enumerated, GeneralizedTime, GeneralString, IA5String, Integer, Null, NumericString, ObjectIdentifier, OctetBitString, OctetString, ParsableOctetString, PrintableString, Sequence, SequenceOf, Set, SetOf, TeletexString, UniversalString, UTCTime, UTF8String, VisibleString, VOID, ) from .keys import PublicKeyInfo from .util import int_to_bytes, int_from_bytes, inet_ntop, inet_pton # The structures in this file are taken from https://tools.ietf.org/html/rfc5280 # and a few other supplementary sources, mostly due to extra supported # extension and name OIDs class DNSName(IA5String): _encoding = 'idna' _bad_tag = (12, 19) def __ne__(self, other): return not self == other def __eq__(self, other): """ Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.2 :param other: Another DNSName object :return: A boolean """ if not isinstance(other, DNSName): return False return self.__unicode__().lower() == other.__unicode__().lower() def set(self, value): """ Sets the value of the DNS name :param value: A unicode string """ if not isinstance(value, str_cls): raise TypeError(unwrap( ''' %s value must be a unicode string, not %s ''', type_name(self), type_name(value) )) if value.startswith('.'): encoded_value = b'.' + value[1:].encode(self._encoding) else: encoded_value = value.encode(self._encoding) self._unicode = value self.contents = encoded_value self._header = None if self._trailer != b'': self._trailer = b'' class URI(IA5String): def set(self, value): """ Sets the value of the string :param value: A unicode string """ if not isinstance(value, str_cls): raise TypeError(unwrap( ''' %s value must be a unicode string, not %s ''', type_name(self), type_name(value) )) self._unicode = value self.contents = iri_to_uri(value) self._header = None if self._trailer != b'': self._trailer = b'' def __ne__(self, other): return not self == other def __eq__(self, other): """ Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.4 :param other: Another URI object :return: A boolean """ if not isinstance(other, URI): return False return iri_to_uri(self.native, True) == iri_to_uri(other.native, True) def __unicode__(self): """ :return: A unicode string """ if self.contents is None: return '' if self._unicode is None: self._unicode = uri_to_iri(self._merge_chunks()) return self._unicode class EmailAddress(IA5String): _contents = None # If the value has gone through the .set() method, thus normalizing it _normalized = False # In the wild we've seen this encoded as a UTF8String and PrintableString _bad_tag = (12, 19) @property def contents(self): """ :return: A byte string of the DER-encoded contents of the sequence """ return self._contents @contents.setter def contents(self, value): """ :param value: A byte string of the DER-encoded contents of the sequence """ self._normalized = False self._contents = value def set(self, value): """ Sets the value of the string :param value: A unicode string """ if not isinstance(value, str_cls): raise TypeError(unwrap( ''' %s value must be a unicode string, not %s ''', type_name(self), type_name(value) )) if value.find('@') != -1: mailbox, hostname = value.rsplit('@', 1) encoded_value = mailbox.encode('ascii') + b'@' + hostname.encode('idna') else: encoded_value = value.encode('ascii') self._normalized = True self._unicode = value self.contents = encoded_value self._header = None if self._trailer != b'': self._trailer = b'' def __unicode__(self): """ :return: A unicode string """ # We've seen this in the wild as a PrintableString, and since ascii is a # subset of cp1252, we use the later for decoding to be more user friendly if self._unicode is None: contents = self._merge_chunks() if contents.find(b'@') == -1: self._unicode = contents.decode('cp1252') else: mailbox, hostname = contents.rsplit(b'@', 1) self._unicode = mailbox.decode('cp1252') + '@' + hostname.decode('idna') return self._unicode def __ne__(self, other): return not self == other def __eq__(self, other): """ Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.5 :param other: Another EmailAddress object :return: A boolean """ if not isinstance(other, EmailAddress): return False if not self._normalized: self.set(self.native) if not other._normalized: other.set(other.native) if self._contents.find(b'@') == -1 or other._contents.find(b'@') == -1: return self._contents == other._contents other_mailbox, other_hostname = other._contents.rsplit(b'@', 1) mailbox, hostname = self._contents.rsplit(b'@', 1) if mailbox != other_mailbox: return False if hostname.lower() != other_hostname.lower(): return False return True class IPAddress(OctetString): def parse(self, spec=None, spec_params=None): """ This method is not applicable to IP addresses """ raise ValueError(unwrap( ''' IP address values can not be parsed ''' )) def set(self, value): """ Sets the value of the object :param value: A unicode string containing an IPv4 address, IPv4 address with CIDR, an IPv6 address or IPv6 address with CIDR """ if not isinstance(value, str_cls): raise TypeError(unwrap( ''' %s value must be a unicode string, not %s ''', type_name(self), type_name(value) )) original_value = value has_cidr = value.find('/') != -1 cidr = 0 if has_cidr: parts = value.split('/', 1) value = parts[0] cidr = int(parts[1]) if cidr < 0: raise ValueError(unwrap( ''' %s value contains a CIDR range less than 0 ''', type_name(self) )) if value.find(':') != -1: family = socket.AF_INET6 if cidr > 128: raise ValueError(unwrap( ''' %s value contains a CIDR range bigger than 128, the maximum value for an IPv6 address ''', type_name(self) )) cidr_size = 128 else: family = socket.AF_INET if cidr > 32: raise ValueError(unwrap( ''' %s value contains a CIDR range bigger than 32, the maximum value for an IPv4 address ''', type_name(self) )) cidr_size = 32 cidr_bytes = b'' if has_cidr: cidr_mask = '1' * cidr cidr_mask += '0' * (cidr_size - len(cidr_mask)) cidr_bytes = int_to_bytes(int(cidr_mask, 2)) cidr_bytes = (b'\x00' * ((cidr_size // 8) - len(cidr_bytes))) + cidr_bytes self._native = original_value self.contents = inet_pton(family, value) + cidr_bytes self._bytes = self.contents self._header = None if self._trailer != b'': self._trailer = b'' @property def native(self): """ The native Python datatype representation of this value :return: A unicode string or None """ if self.contents is None: return None if self._native is None: byte_string = self.__bytes__() byte_len = len(byte_string) value = None cidr_int = None if byte_len in set([32, 16]): value = inet_ntop(socket.AF_INET6, byte_string[0:16]) if byte_len > 16: cidr_int = int_from_bytes(byte_string[16:]) elif byte_len in set([8, 4]): value = inet_ntop(socket.AF_INET, byte_string[0:4]) if byte_len > 4: cidr_int = int_from_bytes(byte_string[4:]) if cidr_int is not None: cidr_bits = '{0:b}'.format(cidr_int) cidr = len(cidr_bits.rstrip('0')) value = value + '/' + str_cls(cidr) self._native = value return self._native def __ne__(self, other): return not self == other def __eq__(self, other): """ :param other: Another IPAddress object :return: A boolean """ if not isinstance(other, IPAddress): return False return self.__bytes__() == other.__bytes__() class Attribute(Sequence): _fields = [ ('type', ObjectIdentifier), ('values', SetOf, {'spec': Any}), ] class Attributes(SequenceOf): _child_spec = Attribute class KeyUsage(BitString): _map = { 0: 'digital_signature', 1: 'non_repudiation', 2: 'key_encipherment', 3: 'data_encipherment', 4: 'key_agreement', 5: 'key_cert_sign', 6: 'crl_sign', 7: 'encipher_only', 8: 'decipher_only', } class PrivateKeyUsagePeriod(Sequence): _fields = [ ('not_before', GeneralizedTime, {'implicit': 0, 'optional': True}), ('not_after', GeneralizedTime, {'implicit': 1, 'optional': True}), ] class NotReallyTeletexString(TeletexString): """ OpenSSL (and probably some other libraries) puts ISO-8859-1 into TeletexString instead of ITU T.61. We use Windows-1252 when decoding since it is a superset of ISO-8859-1, and less likely to cause encoding issues, but we stay strict with encoding to prevent us from creating bad data. """ _decoding_encoding = 'cp1252' def __unicode__(self): """ :return: A unicode string """ if self.contents is None: return '' if self._unicode is None: self._unicode = self._merge_chunks().decode(self._decoding_encoding) return self._unicode @contextmanager def strict_teletex(): try: NotReallyTeletexString._decoding_encoding = 'teletex' yield finally: NotReallyTeletexString._decoding_encoding = 'cp1252' class DirectoryString(Choice): _alternatives = [ ('teletex_string', NotReallyTeletexString), ('printable_string', PrintableString), ('universal_string', UniversalString), ('utf8_string', UTF8String), ('bmp_string', BMPString), # This is an invalid/bad alternative, but some broken certs use it ('ia5_string', IA5String), ] class NameType(ObjectIdentifier): _map = { '2.5.4.3': 'common_name', '2.5.4.4': 'surname', '2.5.4.5': 'serial_number', '2.5.4.6': 'country_name', '2.5.4.7': 'locality_name', '2.5.4.8': 'state_or_province_name', '2.5.4.9': 'street_address', '2.5.4.10': 'organization_name', '2.5.4.11': 'organizational_unit_name', '2.5.4.12': 'title', '2.5.4.15': 'business_category', '2.5.4.17': 'postal_code', '2.5.4.20': 'telephone_number', '2.5.4.41': 'name', '2.5.4.42': 'given_name', '2.5.4.43': 'initials', '2.5.4.44': 'generation_qualifier', '2.5.4.45': 'unique_identifier', '2.5.4.46': 'dn_qualifier', '2.5.4.65': 'pseudonym', '2.5.4.97': 'organization_identifier', # https://www.trustedcomputinggroup.org/wp-content/uploads/Credential_Profile_EK_V2.0_R14_published.pdf '2.23.133.2.1': 'tpm_manufacturer', '2.23.133.2.2': 'tpm_model', '2.23.133.2.3': 'tpm_version', '2.23.133.2.4': 'platform_manufacturer', '2.23.133.2.5': 'platform_model', '2.23.133.2.6': 'platform_version', # https://tools.ietf.org/html/rfc2985#page-26 '1.2.840.113549.1.9.1': 'email_address', # Page 10 of https://cabforum.org/wp-content/uploads/EV-V1_5_5.pdf '1.3.6.1.4.1.311.60.2.1.1': 'incorporation_locality', '1.3.6.1.4.1.311.60.2.1.2': 'incorporation_state_or_province', '1.3.6.1.4.1.311.60.2.1.3': 'incorporation_country', # https://tools.ietf.org/html/rfc4519#section-2.39 '0.9.2342.19200300.100.1.1': 'user_id', # https://tools.ietf.org/html/rfc2247#section-4 '0.9.2342.19200300.100.1.25': 'domain_component', # http://www.alvestrand.no/objectid/0.2.262.1.10.7.20.html '0.2.262.1.10.7.20': 'name_distinguisher', } # This order is largely based on observed order seen in EV certs from # Symantec and DigiCert. Some of the uncommon name-related fields are # just placed in what seems like a reasonable order. preferred_order = [ 'incorporation_country', 'incorporation_state_or_province', 'incorporation_locality', 'business_category', 'serial_number', 'country_name', 'postal_code', 'state_or_province_name', 'locality_name', 'street_address', 'organization_name', 'organizational_unit_name', 'title', 'common_name', 'user_id', 'initials', 'generation_qualifier', 'surname', 'given_name', 'name', 'pseudonym', 'dn_qualifier', 'telephone_number', 'email_address', 'domain_component', 'name_distinguisher', 'organization_identifier', 'tpm_manufacturer', 'tpm_model', 'tpm_version', 'platform_manufacturer', 'platform_model', 'platform_version', ] @classmethod def preferred_ordinal(cls, attr_name): """ Returns an ordering value for a particular attribute key. Unrecognized attributes and OIDs will be sorted lexically at the end. :return: An orderable value. """ attr_name = cls.map(attr_name) if attr_name in cls.preferred_order: ordinal = cls.preferred_order.index(attr_name) else: ordinal = len(cls.preferred_order) return (ordinal, attr_name) @property def human_friendly(self): """ :return: A human-friendly unicode string to display to users """ return { 'common_name': 'Common Name', 'surname': 'Surname', 'serial_number': 'Serial Number', 'country_name': 'Country', 'locality_name': 'Locality', 'state_or_province_name': 'State/Province', 'street_address': 'Street Address', 'organization_name': 'Organization', 'organizational_unit_name': 'Organizational Unit', 'title': 'Title', 'business_category': 'Business Category', 'postal_code': 'Postal Code', 'telephone_number': 'Telephone Number', 'name': 'Name', 'given_name': 'Given Name', 'initials': 'Initials', 'generation_qualifier': 'Generation Qualifier', 'unique_identifier': 'Unique Identifier', 'dn_qualifier': 'DN Qualifier', 'pseudonym': 'Pseudonym', 'email_address': 'Email Address', 'incorporation_locality': 'Incorporation Locality', 'incorporation_state_or_province': 'Incorporation State/Province', 'incorporation_country': 'Incorporation Country', 'domain_component': 'Domain Component', 'name_distinguisher': 'Name Distinguisher', 'organization_identifier': 'Organization Identifier', 'tpm_manufacturer': 'TPM Manufacturer', 'tpm_model': 'TPM Model', 'tpm_version': 'TPM Version', 'platform_manufacturer': 'Platform Manufacturer', 'platform_model': 'Platform Model', 'platform_version': 'Platform Version', 'user_id': 'User ID', }.get(self.native, self.native) class NameTypeAndValue(Sequence): _fields = [ ('type', NameType), ('value', Any), ] _oid_pair = ('type', 'value') _oid_specs = { 'common_name': DirectoryString, 'surname': DirectoryString, 'serial_number': DirectoryString, 'country_name': DirectoryString, 'locality_name': DirectoryString, 'state_or_province_name': DirectoryString, 'street_address': DirectoryString, 'organization_name': DirectoryString, 'organizational_unit_name': DirectoryString, 'title': DirectoryString, 'business_category': DirectoryString, 'postal_code': DirectoryString, 'telephone_number': PrintableString, 'name': DirectoryString, 'given_name': DirectoryString, 'initials': DirectoryString, 'generation_qualifier': DirectoryString, 'unique_identifier': OctetBitString, 'dn_qualifier': DirectoryString, 'pseudonym': DirectoryString, # https://tools.ietf.org/html/rfc2985#page-26 'email_address': EmailAddress, # Page 10 of https://cabforum.org/wp-content/uploads/EV-V1_5_5.pdf 'incorporation_locality': DirectoryString, 'incorporation_state_or_province': DirectoryString, 'incorporation_country': DirectoryString, 'domain_component': DNSName, 'name_distinguisher': DirectoryString, 'organization_identifier': DirectoryString, 'tpm_manufacturer': UTF8String, 'tpm_model': UTF8String, 'tpm_version': UTF8String, 'platform_manufacturer': UTF8String, 'platform_model': UTF8String, 'platform_version': UTF8String, 'user_id': DirectoryString, } _prepped = None @property def prepped_value(self): """ Returns the value after being processed by the internationalized string preparation as specified by RFC 5280 :return: A unicode string """ if self._prepped is None: self._prepped = self._ldap_string_prep(self['value'].native) return self._prepped def __ne__(self, other): return not self == other def __eq__(self, other): """ Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.1 :param other: Another NameTypeAndValue object :return: A boolean """ if not isinstance(other, NameTypeAndValue): return False if other['type'].native != self['type'].native: return False return other.prepped_value == self.prepped_value def _ldap_string_prep(self, string): """ Implements the internationalized string preparation algorithm from RFC 4518. https://tools.ietf.org/html/rfc4518#section-2 :param string: A unicode string to prepare :return: A prepared unicode string, ready for comparison """ # Map step string = re.sub('[\u00ad\u1806\u034f\u180b-\u180d\ufe0f-\uff00\ufffc]+', '', string) string = re.sub('[\u0009\u000a\u000b\u000c\u000d\u0085]', ' ', string) if sys.maxunicode == 0xffff: # Some installs of Python 2.7 don't support 8-digit unicode escape # ranges, so we have to break them into pieces # Original was: \U0001D173-\U0001D17A and \U000E0020-\U000E007F string = re.sub('\ud834[\udd73-\udd7a]|\udb40[\udc20-\udc7f]|\U000e0001', '', string) else: string = re.sub('[\U0001D173-\U0001D17A\U000E0020-\U000E007F\U000e0001]', '', string) string = re.sub( '[\u0000-\u0008\u000e-\u001f\u007f-\u0084\u0086-\u009f\u06dd\u070f\u180e\u200c-\u200f' '\u202a-\u202e\u2060-\u2063\u206a-\u206f\ufeff\ufff9-\ufffb]+', '', string ) string = string.replace('\u200b', '') string = re.sub('[\u00a0\u1680\u2000-\u200a\u2028-\u2029\u202f\u205f\u3000]', ' ', string) string = ''.join(map(stringprep.map_table_b2, string)) # Normalize step string = unicodedata.normalize('NFKC', string) # Prohibit step for char in string: if stringprep.in_table_a1(char): raise ValueError(unwrap( ''' X.509 Name objects may not contain unassigned code points ''' )) if stringprep.in_table_c8(char): raise ValueError(unwrap( ''' X.509 Name objects may not contain change display or zzzzdeprecated characters ''' )) if stringprep.in_table_c3(char): raise ValueError(unwrap( ''' X.509 Name objects may not contain private use characters ''' )) if stringprep.in_table_c4(char): raise ValueError(unwrap( ''' X.509 Name objects may not contain non-character code points ''' )) if stringprep.in_table_c5(char): raise ValueError(unwrap( ''' X.509 Name objects may not contain surrogate code points ''' )) if char == '\ufffd': raise ValueError(unwrap( ''' X.509 Name objects may not contain the replacement character ''' )) # Check bidirectional step - here we ensure that we are not mixing # left-to-right and right-to-left text in the string has_r_and_al_cat = False has_l_cat = False for char in string: if stringprep.in_table_d1(char): has_r_and_al_cat = True elif stringprep.in_table_d2(char): has_l_cat = True if has_r_and_al_cat: first_is_r_and_al = stringprep.in_table_d1(string[0]) last_is_r_and_al = stringprep.in_table_d1(string[-1]) if has_l_cat or not first_is_r_and_al or not last_is_r_and_al: raise ValueError(unwrap( ''' X.509 Name object contains a malformed bidirectional sequence ''' )) # Insignificant space handling step string = ' ' + re.sub(' +', ' ', string).strip() + ' ' return string class RelativeDistinguishedName(SetOf): _child_spec = NameTypeAndValue @property def hashable(self): """ :return: A unicode string that can be used as a dict key or in a set """ output = [] values = self._get_values(self) for key in sorted(values.keys()): output.append('%s: %s' % (key, values[key])) # Unit separator is used here since the normalization process for # values moves any such character, and the keys are all dotted integers # or under_score_words return '\x1F'.join(output) def __ne__(self, other): return not self == other def __eq__(self, other): """ Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.1 :param other: Another RelativeDistinguishedName object :return: A boolean """ if not isinstance(other, RelativeDistinguishedName): return False if len(self) != len(other): return False self_types = self._get_types(self) other_types = self._get_types(other) if self_types != other_types: return False self_values = self._get_values(self) other_values = self._get_values(other) for type_name_ in self_types: if self_values[type_name_] != other_values[type_name_]: return False return True def _get_types(self, rdn): """ Returns a set of types contained in an RDN :param rdn: A RelativeDistinguishedName object :return: A set object with unicode strings of NameTypeAndValue type field values """ return set([ntv['type'].native for ntv in rdn]) def _get_values(self, rdn): """ Returns a dict of prepped values contained in an RDN :param rdn: A RelativeDistinguishedName object :return: A dict object with unicode strings of NameTypeAndValue value field values that have been prepped for comparison """ output = {} [output.update([(ntv['type'].native, ntv.prepped_value)]) for ntv in rdn] return output class RDNSequence(SequenceOf): _child_spec = RelativeDistinguishedName @property def hashable(self): """ :return: A unicode string that can be used as a dict key or in a set """ # Record separator is used here since the normalization process for # values moves any such character, and the keys are all dotted integers # or under_score_words return '\x1E'.join(rdn.hashable for rdn in self) def __ne__(self, other): return not self == other def __eq__(self, other): """ Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.1 :param other: Another RDNSequence object :return: A boolean """ if not isinstance(other, RDNSequence): return False if len(self) != len(other): return False for index, self_rdn in enumerate(self): if other[index] != self_rdn: return False return True class Name(Choice): _alternatives = [ ('', RDNSequence), ] _human_friendly = None _sha1 = None _sha256 = None @classmethod def build(cls, name_dict, use_printable=False): """ Creates a Name object from a dict of unicode string keys and values. The keys should be from NameType._map, or a dotted-integer OID unicode string. :param name_dict: A dict of name information, e.g. {"common_name": "Will Bond", "country_name": "US", "organization_name": "Codex Non Sufficit LC"} :param use_printable: A bool - if PrintableString should be used for encoding instead of UTF8String. This is for backwards compatibility with old software. :return: An x509.Name object """ rdns = [] if not use_printable: encoding_name = 'utf8_string' encoding_class = UTF8String else: encoding_name = 'printable_string' encoding_class = PrintableString # Sort the attributes according to NameType.preferred_order name_dict = OrderedDict( sorted( name_dict.items(), key=lambda item: NameType.preferred_ordinal(item[0]) ) ) for attribute_name, attribute_value in name_dict.items(): attribute_name = NameType.map(attribute_name) if attribute_name == 'email_address': value = EmailAddress(attribute_value) elif attribute_name == 'domain_component': value = DNSName(attribute_value) elif attribute_name in set(['dn_qualifier', 'country_name', 'serial_number']): value = DirectoryString( name='printable_string', value=PrintableString(attribute_value) ) else: value = DirectoryString( name=encoding_name, value=encoding_class(attribute_value) ) rdns.append(RelativeDistinguishedName([ NameTypeAndValue({ 'type': attribute_name, 'value': value }) ])) return cls(name='', value=RDNSequence(rdns)) @property def hashable(self): """ :return: A unicode string that can be used as a dict key or in a set """ return self.chosen.hashable def __len__(self): return len(self.chosen) def __ne__(self, other): return not self == other def __eq__(self, other): """ Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.1 :param other: Another Name object :return: A boolean """ if not isinstance(other, Name): return False return self.chosen == other.chosen @property def native(self): if self._native is None: self._native = OrderedDict() for rdn in self.chosen.native: for type_val in rdn: field_name = type_val['type'] if field_name in self._native: existing = self._native[field_name] if not isinstance(existing, list): existing = self._native[field_name] = [existing] existing.append(type_val['value']) else: self._native[field_name] = type_val['value'] return self._native @property def human_friendly(self): """ :return: A human-friendly unicode string containing the parts of the name """ if self._human_friendly is None: data = OrderedDict() last_field = None for rdn in self.chosen: for type_val in rdn: field_name = type_val['type'].human_friendly last_field = field_name if field_name in data: data[field_name] = [data[field_name]] data[field_name].append(type_val['value']) else: data[field_name] = type_val['value'] to_join = [] keys = data.keys() if last_field == 'Country': keys = reversed(list(keys)) for key in keys: value = data[key] native_value = self._recursive_humanize(value) to_join.append('%s: %s' % (key, native_value)) has_comma = False for element in to_join: if element.find(',') != -1: has_comma = True break separator = ', ' if not has_comma else '; ' self._human_friendly = separator.join(to_join[::-1]) return self._human_friendly def _recursive_humanize(self, value): """ Recursively serializes data compiled from the RDNSequence :param value: An Asn1Value object, or a list of Asn1Value objects :return: A unicode string """ if isinstance(value, list): return ', '.join( reversed([self._recursive_humanize(sub_value) for sub_value in value]) ) return value.native @property def sha1(self): """ :return: The SHA1 hash of the DER-encoded bytes of this name """ if self._sha1 is None: self._sha1 = hashlib.sha1(self.dump()).digest() return self._sha1 @property def sha256(self): """ :return: The SHA-256 hash of the DER-encoded bytes of this name """ if self._sha256 is None: self._sha256 = hashlib.sha256(self.dump()).digest() return self._sha256 class AnotherName(Sequence): _fields = [ ('type_id', ObjectIdentifier), ('value', Any, {'explicit': 0}), ] class CountryName(Choice): class_ = 1 tag = 1 _alternatives = [ ('x121_dcc_code', NumericString), ('iso_3166_alpha2_code', PrintableString), ] class AdministrationDomainName(Choice): class_ = 1 tag = 2 _alternatives = [ ('numeric', NumericString), ('printable', PrintableString), ] class PrivateDomainName(Choice): _alternatives = [ ('numeric', NumericString), ('printable', PrintableString), ] class PersonalName(Set): _fields = [ ('surname', PrintableString, {'implicit': 0}), ('given_name', PrintableString, {'implicit': 1, 'optional': True}), ('initials', PrintableString, {'implicit': 2, 'optional': True}), ('generation_qualifier', PrintableString, {'implicit': 3, 'optional': True}), ] class TeletexPersonalName(Set): _fields = [ ('surname', TeletexString, {'implicit': 0}), ('given_name', TeletexString, {'implicit': 1, 'optional': True}), ('initials', TeletexString, {'implicit': 2, 'optional': True}), ('generation_qualifier', TeletexString, {'implicit': 3, 'optional': True}), ] class OrganizationalUnitNames(SequenceOf): _child_spec = PrintableString class TeletexOrganizationalUnitNames(SequenceOf): _child_spec = TeletexString class BuiltInStandardAttributes(Sequence): _fields = [ ('country_name', CountryName, {'optional': True}), ('administration_domain_name', AdministrationDomainName, {'optional': True}), ('network_address', NumericString, {'implicit': 0, 'optional': True}), ('terminal_identifier', PrintableString, {'implicit': 1, 'optional': True}), ('private_domain_name', PrivateDomainName, {'explicit': 2, 'optional': True}), ('organization_name', PrintableString, {'implicit': 3, 'optional': True}), ('numeric_user_identifier', NumericString, {'implicit': 4, 'optional': True}), ('personal_name', PersonalName, {'implicit': 5, 'optional': True}), ('organizational_unit_names', OrganizationalUnitNames, {'implicit': 6, 'optional': True}), ] class BuiltInDomainDefinedAttribute(Sequence): _fields = [ ('type', PrintableString), ('value', PrintableString), ] class BuiltInDomainDefinedAttributes(SequenceOf): _child_spec = BuiltInDomainDefinedAttribute class TeletexDomainDefinedAttribute(Sequence): _fields = [ ('type', TeletexString), ('value', TeletexString), ] class TeletexDomainDefinedAttributes(SequenceOf): _child_spec = TeletexDomainDefinedAttribute class PhysicalDeliveryCountryName(Choice): _alternatives = [ ('x121_dcc_code', NumericString), ('iso_3166_alpha2_code', PrintableString), ] class PostalCode(Choice): _alternatives = [ ('numeric_code', NumericString), ('printable_code', PrintableString), ] class PDSParameter(Set): _fields = [ ('printable_string', PrintableString, {'optional': True}), ('teletex_string', TeletexString, {'optional': True}), ] class PrintableAddress(SequenceOf): _child_spec = PrintableString class UnformattedPostalAddress(Set): _fields = [ ('printable_address', PrintableAddress, {'optional': True}), ('teletex_string', TeletexString, {'optional': True}), ] class E1634Address(Sequence): _fields = [ ('number', NumericString, {'implicit': 0}), ('sub_address', NumericString, {'implicit': 1, 'optional': True}), ] class NAddresses(SetOf): _child_spec = OctetString class PresentationAddress(Sequence): _fields = [ ('p_selector', OctetString, {'explicit': 0, 'optional': True}), ('s_selector', OctetString, {'explicit': 1, 'optional': True}), ('t_selector', OctetString, {'explicit': 2, 'optional': True}), ('n_addresses', NAddresses, {'explicit': 3}), ] class ExtendedNetworkAddress(Choice): _alternatives = [ ('e163_4_address', E1634Address), ('psap_address', PresentationAddress, {'implicit': 0}) ] class TerminalType(Integer): _map = { 3: 'telex', 4: 'teletex', 5: 'g3_facsimile', 6: 'g4_facsimile', 7: 'ia5_terminal', 8: 'videotex', } class ExtensionAttributeType(Integer): _map = { 1: 'common_name', 2: 'teletex_common_name', 3: 'teletex_organization_name', 4: 'teletex_personal_name', 5: 'teletex_organization_unit_names', 6: 'teletex_domain_defined_attributes', 7: 'pds_name', 8: 'physical_delivery_country_name', 9: 'postal_code', 10: 'physical_delivery_office_name', 11: 'physical_delivery_office_number', 12: 'extension_of_address_components', 13: 'physical_delivery_personal_name', 14: 'physical_delivery_organization_name', 15: 'extension_physical_delivery_address_components', 16: 'unformatted_postal_address', 17: 'street_address', 18: 'post_office_box_address', 19: 'poste_restante_address', 20: 'unique_postal_name', 21: 'local_postal_attributes', 22: 'extended_network_address', 23: 'terminal_type', } class ExtensionAttribute(Sequence): _fields = [ ('extension_attribute_type', ExtensionAttributeType, {'implicit': 0}), ('extension_attribute_value', Any, {'explicit': 1}), ] _oid_pair = ('extension_attribute_type', 'extension_attribute_value') _oid_specs = { 'common_name': PrintableString, 'teletex_common_name': TeletexString, 'teletex_organization_name': TeletexString, 'teletex_personal_name': TeletexPersonalName, 'teletex_organization_unit_names': TeletexOrganizationalUnitNames, 'teletex_domain_defined_attributes': TeletexDomainDefinedAttributes, 'pds_name': PrintableString, 'physical_delivery_country_name': PhysicalDeliveryCountryName, 'postal_code': PostalCode, 'physical_delivery_office_name': PDSParameter, 'physical_delivery_office_number': PDSParameter, 'extension_of_address_components': PDSParameter, 'physical_delivery_personal_name': PDSParameter, 'physical_delivery_organization_name': PDSParameter, 'extension_physical_delivery_address_components': PDSParameter, 'unformatted_postal_address': UnformattedPostalAddress, 'street_address': PDSParameter, 'post_office_box_address': PDSParameter, 'poste_restante_address': PDSParameter, 'unique_postal_name': PDSParameter, 'local_postal_attributes': PDSParameter, 'extended_network_address': ExtendedNetworkAddress, 'terminal_type': TerminalType, } class ExtensionAttributes(SequenceOf): _child_spec = ExtensionAttribute class ORAddress(Sequence): _fields = [ ('built_in_standard_attributes', BuiltInStandardAttributes), ('built_in_domain_defined_attributes', BuiltInDomainDefinedAttributes, {'optional': True}), ('extension_attributes', ExtensionAttributes, {'optional': True}), ] class EDIPartyName(Sequence): _fields = [ ('name_assigner', DirectoryString, {'implicit': 0, 'optional': True}), ('party_name', DirectoryString, {'implicit': 1}), ] class GeneralName(Choice): _alternatives = [ ('other_name', AnotherName, {'implicit': 0}), ('rfc822_name', EmailAddress, {'implicit': 1}), ('dns_name', DNSName, {'implicit': 2}), ('x400_address', ORAddress, {'implicit': 3}), ('directory_name', Name, {'explicit': 4}), ('edi_party_name', EDIPartyName, {'implicit': 5}), ('uniform_resource_identifier', URI, {'implicit': 6}), ('ip_address', IPAddress, {'implicit': 7}), ('registered_id', ObjectIdentifier, {'implicit': 8}), ] def __ne__(self, other): return not self == other def __eq__(self, other): """ Does not support other_name, x400_address or edi_party_name :param other: The other GeneralName to compare to :return: A boolean """ if self.name in ('other_name', 'x400_address', 'edi_party_name'): raise ValueError(unwrap( ''' Comparison is not supported for GeneralName objects of choice %s ''', self.name )) if other.name in ('other_name', 'x400_address', 'edi_party_name'): raise ValueError(unwrap( ''' Comparison is not supported for GeneralName objects of choice %s''', other.name )) if self.name != other.name: return False return self.chosen == other.chosen class GeneralNames(SequenceOf): _child_spec = GeneralName class Time(Choice): _alternatives = [ ('utc_time', UTCTime), ('general_time', GeneralizedTime), ] class Validity(Sequence): _fields = [ ('not_before', Time), ('not_after', Time), ] class BasicConstraints(Sequence): _fields = [ ('ca', Boolean, {'default': False}), ('path_len_constraint', Integer, {'optional': True}), ] class AuthorityKeyIdentifier(Sequence): _fields = [ ('key_identifier', OctetString, {'implicit': 0, 'optional': True}), ('authority_cert_issuer', GeneralNames, {'implicit': 1, 'optional': True}), ('authority_cert_serial_number', Integer, {'implicit': 2, 'optional': True}), ] class DistributionPointName(Choice): _alternatives = [ ('full_name', GeneralNames, {'implicit': 0}), ('name_relative_to_crl_issuer', RelativeDistinguishedName, {'implicit': 1}), ] class ReasonFlags(BitString): _map = { 0: 'unused', 1: 'key_compromise', 2: 'ca_compromise', 3: 'affiliation_changed', 4: 'superseded', 5: 'cessation_of_operation', 6: 'certificate_hold', 7: 'privilege_withdrawn', 8: 'aa_compromise', } class GeneralSubtree(Sequence): _fields = [ ('base', GeneralName), ('minimum', Integer, {'implicit': 0, 'default': 0}), ('maximum', Integer, {'implicit': 1, 'optional': True}), ] class GeneralSubtrees(SequenceOf): _child_spec = GeneralSubtree class NameConstraints(Sequence): _fields = [ ('permitted_subtrees', GeneralSubtrees, {'implicit': 0, 'optional': True}), ('excluded_subtrees', GeneralSubtrees, {'implicit': 1, 'optional': True}), ] class DistributionPoint(Sequence): _fields = [ ('distribution_point', DistributionPointName, {'explicit': 0, 'optional': True}), ('reasons', ReasonFlags, {'implicit': 1, 'optional': True}), ('crl_issuer', GeneralNames, {'implicit': 2, 'optional': True}), ] _url = False @property def url(self): """ :return: None or a unicode string of the distribution point's URL """ if self._url is False: self._url = None name = self['distribution_point'] if name.name != 'full_name': raise ValueError(unwrap( ''' CRL distribution points that are relative to the issuer are not supported ''' )) for general_name in name.chosen: if general_name.name == 'uniform_resource_identifier': url = general_name.native if url.lower().startswith(('http://', 'https://', 'ldap://', 'ldaps://')): self._url = url break return self._url class CRLDistributionPoints(SequenceOf): _child_spec = DistributionPoint class DisplayText(Choice): _alternatives = [ ('ia5_string', IA5String), ('visible_string', VisibleString), ('bmp_string', BMPString), ('utf8_string', UTF8String), ] class NoticeNumbers(SequenceOf): _child_spec = Integer class NoticeReference(Sequence): _fields = [ ('organization', DisplayText), ('notice_numbers', NoticeNumbers), ] class UserNotice(Sequence): _fields = [ ('notice_ref', NoticeReference, {'optional': True}), ('explicit_text', DisplayText, {'optional': True}), ] class PolicyQualifierId(ObjectIdentifier): _map = { '1.3.6.1.5.5.7.2.1': 'certification_practice_statement', '1.3.6.1.5.5.7.2.2': 'user_notice', } class PolicyQualifierInfo(Sequence): _fields = [ ('policy_qualifier_id', PolicyQualifierId), ('qualifier', Any), ] _oid_pair = ('policy_qualifier_id', 'qualifier') _oid_specs = { 'certification_practice_statement': IA5String, 'user_notice': UserNotice, } class PolicyQualifierInfos(SequenceOf): _child_spec = PolicyQualifierInfo class PolicyIdentifier(ObjectIdentifier): _map = { '2.5.29.32.0': 'any_policy', } class PolicyInformation(Sequence): _fields = [ ('policy_identifier', PolicyIdentifier), ('policy_qualifiers', PolicyQualifierInfos, {'optional': True}) ] class CertificatePolicies(SequenceOf): _child_spec = PolicyInformation class PolicyMapping(Sequence): _fields = [ ('issuer_domain_policy', PolicyIdentifier), ('subject_domain_policy', PolicyIdentifier), ] class PolicyMappings(SequenceOf): _child_spec = PolicyMapping class PolicyConstraints(Sequence): _fields = [ ('require_explicit_policy', Integer, {'implicit': 0, 'optional': True}), ('inhibit_policy_mapping', Integer, {'implicit': 1, 'optional': True}), ] class KeyPurposeId(ObjectIdentifier): _map = { # https://tools.ietf.org/html/rfc5280#page-45 '2.5.29.37.0': 'any_extended_key_usage', '1.3.6.1.5.5.7.3.1': 'server_auth', '1.3.6.1.5.5.7.3.2': 'client_auth', '1.3.6.1.5.5.7.3.3': 'code_signing', '1.3.6.1.5.5.7.3.4': 'email_protection', '1.3.6.1.5.5.7.3.5': 'ipsec_end_system', '1.3.6.1.5.5.7.3.6': 'ipsec_tunnel', '1.3.6.1.5.5.7.3.7': 'ipsec_user', '1.3.6.1.5.5.7.3.8': 'time_stamping', '1.3.6.1.5.5.7.3.9': 'ocsp_signing', # http://tools.ietf.org/html/rfc3029.html#page-9 '1.3.6.1.5.5.7.3.10': 'dvcs', # http://tools.ietf.org/html/rfc6268.html#page-16 '1.3.6.1.5.5.7.3.13': 'eap_over_ppp', '1.3.6.1.5.5.7.3.14': 'eap_over_lan', # https://tools.ietf.org/html/rfc5055#page-76 '1.3.6.1.5.5.7.3.15': 'scvp_server', '1.3.6.1.5.5.7.3.16': 'scvp_client', # https://tools.ietf.org/html/rfc4945#page-31 '1.3.6.1.5.5.7.3.17': 'ipsec_ike', # https://tools.ietf.org/html/rfc5415#page-38 '1.3.6.1.5.5.7.3.18': 'capwap_ac', '1.3.6.1.5.5.7.3.19': 'capwap_wtp', # https://tools.ietf.org/html/rfc5924#page-8 '1.3.6.1.5.5.7.3.20': 'sip_domain', # https://tools.ietf.org/html/rfc6187#page-7 '1.3.6.1.5.5.7.3.21': 'secure_shell_client', '1.3.6.1.5.5.7.3.22': 'secure_shell_server', # https://tools.ietf.org/html/rfc6494#page-7 '1.3.6.1.5.5.7.3.23': 'send_router', '1.3.6.1.5.5.7.3.24': 'send_proxied_router', '1.3.6.1.5.5.7.3.25': 'send_owner', '1.3.6.1.5.5.7.3.26': 'send_proxied_owner', # https://tools.ietf.org/html/rfc6402#page-10 '1.3.6.1.5.5.7.3.27': 'cmc_ca', '1.3.6.1.5.5.7.3.28': 'cmc_ra', '1.3.6.1.5.5.7.3.29': 'cmc_archive', # https://tools.ietf.org/html/draft-ietf-sidr-bgpsec-pki-profiles-15#page-6 '1.3.6.1.5.5.7.3.30': 'bgpspec_router', # https://www.ietf.org/proceedings/44/I-D/draft-ietf-ipsec-pki-req-01.txt '1.3.6.1.5.5.8.2.2': 'ike_intermediate', # https://msdn.microsoft.com/en-us/library/windows/desktop/aa378132(v=vs.85).aspx # and https://support.microsoft.com/en-us/kb/287547 '1.3.6.1.4.1.311.10.3.1': 'microsoft_trust_list_signing', '1.3.6.1.4.1.311.10.3.2': 'microsoft_time_stamp_signing', '1.3.6.1.4.1.311.10.3.3': 'microsoft_server_gated', '1.3.6.1.4.1.311.10.3.3.1': 'microsoft_serialized', '1.3.6.1.4.1.311.10.3.4': 'microsoft_efs', '1.3.6.1.4.1.311.10.3.4.1': 'microsoft_efs_recovery', '1.3.6.1.4.1.311.10.3.5': 'microsoft_whql', '1.3.6.1.4.1.311.10.3.6': 'microsoft_nt5', '1.3.6.1.4.1.311.10.3.7': 'microsoft_oem_whql', '1.3.6.1.4.1.311.10.3.8': 'microsoft_embedded_nt', '1.3.6.1.4.1.311.10.3.9': 'microsoft_root_list_signer', '1.3.6.1.4.1.311.10.3.10': 'microsoft_qualified_subordination', '1.3.6.1.4.1.311.10.3.11': 'microsoft_key_recovery', '1.3.6.1.4.1.311.10.3.12': 'microsoft_document_signing', '1.3.6.1.4.1.311.10.3.13': 'microsoft_lifetime_signing', '1.3.6.1.4.1.311.10.3.14': 'microsoft_mobile_device_software', # https://support.microsoft.com/en-us/help/287547/object-ids-associated-with-microsoft-cryptography '1.3.6.1.4.1.311.20.2.2': 'microsoft_smart_card_logon', # https://opensource.apple.com/source # - /Security/Security-57031.40.6/Security/libsecurity_keychain/lib/SecPolicy.cpp # - /libsecurity_cssm/libsecurity_cssm-36064/lib/oidsalg.c '1.2.840.113635.100.1.2': 'apple_x509_basic', '1.2.840.113635.100.1.3': 'apple_ssl', '1.2.840.113635.100.1.4': 'apple_local_cert_gen', '1.2.840.113635.100.1.5': 'apple_csr_gen', '1.2.840.113635.100.1.6': 'apple_revocation_crl', '1.2.840.113635.100.1.7': 'apple_revocation_ocsp', '1.2.840.113635.100.1.8': 'apple_smime', '1.2.840.113635.100.1.9': 'apple_eap', '1.2.840.113635.100.1.10': 'apple_software_update_signing', '1.2.840.113635.100.1.11': 'apple_ipsec', '1.2.840.113635.100.1.12': 'apple_ichat', '1.2.840.113635.100.1.13': 'apple_resource_signing', '1.2.840.113635.100.1.14': 'apple_pkinit_client', '1.2.840.113635.100.1.15': 'apple_pkinit_server', '1.2.840.113635.100.1.16': 'apple_code_signing', '1.2.840.113635.100.1.17': 'apple_package_signing', '1.2.840.113635.100.1.18': 'apple_id_validation', '1.2.840.113635.100.1.20': 'apple_time_stamping', '1.2.840.113635.100.1.21': 'apple_revocation', '1.2.840.113635.100.1.22': 'apple_passbook_signing', '1.2.840.113635.100.1.23': 'apple_mobile_store', '1.2.840.113635.100.1.24': 'apple_escrow_service', '1.2.840.113635.100.1.25': 'apple_profile_signer', '1.2.840.113635.100.1.26': 'apple_qa_profile_signer', '1.2.840.113635.100.1.27': 'apple_test_mobile_store', '1.2.840.113635.100.1.28': 'apple_otapki_signer', '1.2.840.113635.100.1.29': 'apple_test_otapki_signer', '1.2.840.113625.100.1.30': 'apple_id_validation_record_signing_policy', '1.2.840.113625.100.1.31': 'apple_smp_encryption', '1.2.840.113625.100.1.32': 'apple_test_smp_encryption', '1.2.840.113635.100.1.33': 'apple_server_authentication', '1.2.840.113635.100.1.34': 'apple_pcs_escrow_service', # http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.201-2.pdf '2.16.840.1.101.3.6.8': 'piv_card_authentication', '2.16.840.1.101.3.6.7': 'piv_content_signing', # https://tools.ietf.org/html/rfc4556.html '1.3.6.1.5.2.3.4': 'pkinit_kpclientauth', '1.3.6.1.5.2.3.5': 'pkinit_kpkdc', # https://www.adobe.com/devnet-docs/acrobatetk/tools/DigSig/changes.html '1.2.840.113583.1.1.5': 'adobe_authentic_documents_trust', # https://www.idmanagement.gov/wp-content/uploads/sites/1171/uploads/fpki-pivi-cert-profiles.pdf '2.16.840.1.101.3.8.7': 'fpki_pivi_content_signing' } class ExtKeyUsageSyntax(SequenceOf): _child_spec = KeyPurposeId class AccessMethod(ObjectIdentifier): _map = { '1.3.6.1.5.5.7.48.1': 'ocsp', '1.3.6.1.5.5.7.48.2': 'ca_issuers', '1.3.6.1.5.5.7.48.3': 'time_stamping', '1.3.6.1.5.5.7.48.5': 'ca_repository', } class AccessDescription(Sequence): _fields = [ ('access_method', AccessMethod), ('access_location', GeneralName), ] class AuthorityInfoAccessSyntax(SequenceOf): _child_spec = AccessDescription class SubjectInfoAccessSyntax(SequenceOf): _child_spec = AccessDescription # https://tools.ietf.org/html/rfc7633 class Features(SequenceOf): _child_spec = Integer class EntrustVersionInfo(Sequence): _fields = [ ('entrust_vers', GeneralString), ('entrust_info_flags', BitString) ] class NetscapeCertificateType(BitString): _map = { 0: 'ssl_client', 1: 'ssl_server', 2: 'email', 3: 'object_signing', 4: 'reserved', 5: 'ssl_ca', 6: 'email_ca', 7: 'object_signing_ca', } class Version(Integer): _map = { 0: 'v1', 1: 'v2', 2: 'v3', } class TPMSpecification(Sequence): _fields = [ ('family', UTF8String), ('level', Integer), ('revision', Integer), ] class SetOfTPMSpecification(SetOf): _child_spec = TPMSpecification class TCGSpecificationVersion(Sequence): _fields = [ ('major_version', Integer), ('minor_version', Integer), ('revision', Integer), ] class TCGPlatformSpecification(Sequence): _fields = [ ('version', TCGSpecificationVersion), ('platform_class', OctetString), ] class SetOfTCGPlatformSpecification(SetOf): _child_spec = TCGPlatformSpecification class EKGenerationType(Enumerated): _map = { 0: 'internal', 1: 'injected', 2: 'internal_revocable', 3: 'injected_revocable', } class EKGenerationLocation(Enumerated): _map = { 0: 'tpm_manufacturer', 1: 'platform_manufacturer', 2: 'ek_cert_signer', } class EKCertificateGenerationLocation(Enumerated): _map = { 0: 'tpm_manufacturer', 1: 'platform_manufacturer', 2: 'ek_cert_signer', } class EvaluationAssuranceLevel(Enumerated): _map = { 1: 'level1', 2: 'level2', 3: 'level3', 4: 'level4', 5: 'level5', 6: 'level6', 7: 'level7', } class EvaluationStatus(Enumerated): _map = { 0: 'designed_to_meet', 1: 'evaluation_in_progress', 2: 'evaluation_completed', } class StrengthOfFunction(Enumerated): _map = { 0: 'basic', 1: 'medium', 2: 'high', } class URIReference(Sequence): _fields = [ ('uniform_resource_identifier', IA5String), ('hash_algorithm', DigestAlgorithm, {'optional': True}), ('hash_value', BitString, {'optional': True}), ] class CommonCriteriaMeasures(Sequence): _fields = [ ('version', IA5String), ('assurance_level', EvaluationAssuranceLevel), ('evaluation_status', EvaluationStatus), ('plus', Boolean, {'default': False}), ('strengh_of_function', StrengthOfFunction, {'implicit': 0, 'optional': True}), ('profile_oid', ObjectIdentifier, {'implicit': 1, 'optional': True}), ('profile_url', URIReference, {'implicit': 2, 'optional': True}), ('target_oid', ObjectIdentifier, {'implicit': 3, 'optional': True}), ('target_uri', URIReference, {'implicit': 4, 'optional': True}), ] class SecurityLevel(Enumerated): _map = { 1: 'level1', 2: 'level2', 3: 'level3', 4: 'level4', } class FIPSLevel(Sequence): _fields = [ ('version', IA5String), ('level', SecurityLevel), ('plus', Boolean, {'default': False}), ] class TPMSecurityAssertions(Sequence): _fields = [ ('version', Version, {'default': 'v1'}), ('field_upgradable', Boolean, {'default': False}), ('ek_generation_type', EKGenerationType, {'implicit': 0, 'optional': True}), ('ek_generation_location', EKGenerationLocation, {'implicit': 1, 'optional': True}), ('ek_certificate_generation_location', EKCertificateGenerationLocation, {'implicit': 2, 'optional': True}), ('cc_info', CommonCriteriaMeasures, {'implicit': 3, 'optional': True}), ('fips_level', FIPSLevel, {'implicit': 4, 'optional': True}), ('iso_9000_certified', Boolean, {'implicit': 5, 'default': False}), ('iso_9000_uri', IA5String, {'optional': True}), ] class SetOfTPMSecurityAssertions(SetOf): _child_spec = TPMSecurityAssertions class SubjectDirectoryAttributeId(ObjectIdentifier): _map = { # https://tools.ietf.org/html/rfc2256#page-11 '2.5.4.52': 'supported_algorithms', # https://www.trustedcomputinggroup.org/wp-content/uploads/Credential_Profile_EK_V2.0_R14_published.pdf '2.23.133.2.16': 'tpm_specification', '2.23.133.2.17': 'tcg_platform_specification', '2.23.133.2.18': 'tpm_security_assertions', # https://tools.ietf.org/html/rfc3739#page-18 '1.3.6.1.5.5.7.9.1': 'pda_date_of_birth', '1.3.6.1.5.5.7.9.2': 'pda_place_of_birth', '1.3.6.1.5.5.7.9.3': 'pda_gender', '1.3.6.1.5.5.7.9.4': 'pda_country_of_citizenship', '1.3.6.1.5.5.7.9.5': 'pda_country_of_residence', # https://holtstrom.com/michael/tools/asn1decoder.php '1.2.840.113533.7.68.29': 'entrust_user_role', } class SetOfGeneralizedTime(SetOf): _child_spec = GeneralizedTime class SetOfDirectoryString(SetOf): _child_spec = DirectoryString class SetOfPrintableString(SetOf): _child_spec = PrintableString class SupportedAlgorithm(Sequence): _fields = [ ('algorithm_identifier', AnyAlgorithmIdentifier), ('intended_usage', KeyUsage, {'explicit': 0, 'optional': True}), ('intended_certificate_policies', CertificatePolicies, {'explicit': 1, 'optional': True}), ] class SetOfSupportedAlgorithm(SetOf): _child_spec = SupportedAlgorithm class SubjectDirectoryAttribute(Sequence): _fields = [ ('type', SubjectDirectoryAttributeId), ('values', Any), ] _oid_pair = ('type', 'values') _oid_specs = { 'supported_algorithms': SetOfSupportedAlgorithm, 'tpm_specification': SetOfTPMSpecification, 'tcg_platform_specification': SetOfTCGPlatformSpecification, 'tpm_security_assertions': SetOfTPMSecurityAssertions, 'pda_date_of_birth': SetOfGeneralizedTime, 'pda_place_of_birth': SetOfDirectoryString, 'pda_gender': SetOfPrintableString, 'pda_country_of_citizenship': SetOfPrintableString, 'pda_country_of_residence': SetOfPrintableString, } def _values_spec(self): type_ = self['type'].native if type_ in self._oid_specs: return self._oid_specs[type_] return SetOf _spec_callbacks = { 'values': _values_spec } class SubjectDirectoryAttributes(SequenceOf): _child_spec = SubjectDirectoryAttribute class ExtensionId(ObjectIdentifier): _map = { '2.5.29.9': 'subject_directory_attributes', '2.5.29.14': 'key_identifier', '2.5.29.15': 'key_usage', '2.5.29.16': 'private_key_usage_period', '2.5.29.17': 'subject_alt_name', '2.5.29.18': 'issuer_alt_name', '2.5.29.19': 'basic_constraints', '2.5.29.30': 'name_constraints', '2.5.29.31': 'crl_distribution_points', '2.5.29.32': 'certificate_policies', '2.5.29.33': 'policy_mappings', '2.5.29.35': 'authority_key_identifier', '2.5.29.36': 'policy_constraints', '2.5.29.37': 'extended_key_usage', '2.5.29.46': 'freshest_crl', '2.5.29.54': 'inhibit_any_policy', '1.3.6.1.5.5.7.1.1': 'authority_information_access', '1.3.6.1.5.5.7.1.11': 'subject_information_access', # https://tools.ietf.org/html/rfc7633 '1.3.6.1.5.5.7.1.24': 'tls_feature', '1.3.6.1.5.5.7.48.1.5': 'ocsp_no_check', '1.2.840.113533.7.65.0': 'entrust_version_extension', '2.16.840.1.113730.1.1': 'netscape_certificate_type', # https://tools.ietf.org/html/rfc6962.html#page-14 '1.3.6.1.4.1.11129.2.4.2': 'signed_certificate_timestamp_list', # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-wcce/3aec3e50-511a-42f9-a5d5-240af503e470 '1.3.6.1.4.1.311.20.2': 'microsoft_enroll_certtype', } class Extension(Sequence): _fields = [ ('extn_id', ExtensionId), ('critical', Boolean, {'default': False}), ('extn_value', ParsableOctetString), ] _oid_pair = ('extn_id', 'extn_value') _oid_specs = { 'subject_directory_attributes': SubjectDirectoryAttributes, 'key_identifier': OctetString, 'key_usage': KeyUsage, 'private_key_usage_period': PrivateKeyUsagePeriod, 'subject_alt_name': GeneralNames, 'issuer_alt_name': GeneralNames, 'basic_constraints': BasicConstraints, 'name_constraints': NameConstraints, 'crl_distribution_points': CRLDistributionPoints, 'certificate_policies': CertificatePolicies, 'policy_mappings': PolicyMappings, 'authority_key_identifier': AuthorityKeyIdentifier, 'policy_constraints': PolicyConstraints, 'extended_key_usage': ExtKeyUsageSyntax, 'freshest_crl': CRLDistributionPoints, 'inhibit_any_policy': Integer, 'authority_information_access': AuthorityInfoAccessSyntax, 'subject_information_access': SubjectInfoAccessSyntax, 'tls_feature': Features, 'ocsp_no_check': Null, 'entrust_version_extension': EntrustVersionInfo, 'netscape_certificate_type': NetscapeCertificateType, 'signed_certificate_timestamp_list': OctetString, # Not UTF8String as Microsofts docs claim, see: # https://www.alvestrand.no/objectid/1.3.6.1.4.1.311.20.2.html 'microsoft_enroll_certtype': BMPString, } class Extensions(SequenceOf): _child_spec = Extension class TbsCertificate(Sequence): _fields = [ ('version', Version, {'explicit': 0, 'default': 'v1'}), ('serial_number', Integer), ('signature', SignedDigestAlgorithm), ('issuer', Name), ('validity', Validity), ('subject', Name), ('subject_public_key_info', PublicKeyInfo), ('issuer_unique_id', OctetBitString, {'implicit': 1, 'optional': True}), ('subject_unique_id', OctetBitString, {'implicit': 2, 'optional': True}), ('extensions', Extensions, {'explicit': 3, 'optional': True}), ] class Certificate(Sequence): _fields = [ ('tbs_certificate', TbsCertificate), ('signature_algorithm', SignedDigestAlgorithm), ('signature_value', OctetBitString), ] _processed_extensions = False _critical_extensions = None _subject_directory_attributes_value = None _key_identifier_value = None _key_usage_value = None _subject_alt_name_value = None _issuer_alt_name_value = None _basic_constraints_value = None _name_constraints_value = None _crl_distribution_points_value = None _certificate_policies_value = None _policy_mappings_value = None _authority_key_identifier_value = None _policy_constraints_value = None _freshest_crl_value = None _inhibit_any_policy_value = None _extended_key_usage_value = None _authority_information_access_value = None _subject_information_access_value = None _private_key_usage_period_value = None _tls_feature_value = None _ocsp_no_check_value = None _issuer_serial = None _authority_issuer_serial = False _crl_distribution_points = None _delta_crl_distribution_points = None _valid_domains = None _valid_ips = None _self_issued = None _self_signed = None _sha1 = None _sha256 = None def _set_extensions(self): """ Sets common named extensions to private attributes and creates a list of critical extensions """ self._critical_extensions = set() for extension in self['tbs_certificate']['extensions']: name = extension['extn_id'].native attribute_name = '_%s_value' % name if hasattr(self, attribute_name): setattr(self, attribute_name, extension['extn_value'].parsed) if extension['critical'].native: self._critical_extensions.add(name) self._processed_extensions = True @property def critical_extensions(self): """ Returns a set of the names (or OID if not a known extension) of the extensions marked as critical :return: A set of unicode strings """ if not self._processed_extensions: self._set_extensions() return self._critical_extensions @property def private_key_usage_period_value(self): """ This extension is used to constrain the period over which the subject private key may be used :return: None or a PrivateKeyUsagePeriod object """ if not self._processed_extensions: self._set_extensions() return self._private_key_usage_period_value @property def subject_directory_attributes_value(self): """ This extension is used to contain additional identification attributes about the subject. :return: None or a SubjectDirectoryAttributes object """ if not self._processed_extensions: self._set_extensions() return self._subject_directory_attributes_value @property def key_identifier_value(self): """ This extension is used to help in creating certificate validation paths. It contains an identifier that should generally, but is not guaranteed to, be unique. :return: None or an OctetString object """ if not self._processed_extensions: self._set_extensions() return self._key_identifier_value @property def key_usage_value(self): """ This extension is used to define the purpose of the public key contained within the certificate. :return: None or a KeyUsage """ if not self._processed_extensions: self._set_extensions() return self._key_usage_value @property def subject_alt_name_value(self): """ This extension allows for additional names to be associate with the subject of the certificate. While it may contain a whole host of possible names, it is usually used to allow certificates to be used with multiple different domain names. :return: None or a GeneralNames object """ if not self._processed_extensions: self._set_extensions() return self._subject_alt_name_value @property def issuer_alt_name_value(self): """ This extension allows associating one or more alternative names with the issuer of the certificate. :return: None or an x509.GeneralNames object """ if not self._processed_extensions: self._set_extensions() return self._issuer_alt_name_value @property def basic_constraints_value(self): """ This extension is used to determine if the subject of the certificate is a CA, and if so, what the maximum number of intermediate CA certs after this are, before an end-entity certificate is found. :return: None or a BasicConstraints object """ if not self._processed_extensions: self._set_extensions() return self._basic_constraints_value @property def name_constraints_value(self): """ This extension is used in CA certificates, and is used to limit the possible names of certificates issued. :return: None or a NameConstraints object """ if not self._processed_extensions: self._set_extensions() return self._name_constraints_value @property def crl_distribution_points_value(self): """ This extension is used to help in locating the CRL for this certificate. :return: None or a CRLDistributionPoints object extension """ if not self._processed_extensions: self._set_extensions() return self._crl_distribution_points_value @property def certificate_policies_value(self): """ This extension defines policies in CA certificates under which certificates may be issued. In end-entity certificates, the inclusion of a policy indicates the issuance of the certificate follows the policy. :return: None or a CertificatePolicies object """ if not self._processed_extensions: self._set_extensions() return self._certificate_policies_value @property def policy_mappings_value(self): """ This extension allows mapping policy OIDs to other OIDs. This is used to allow different policies to be treated as equivalent in the process of validation. :return: None or a PolicyMappings object """ if not self._processed_extensions: self._set_extensions() return self._policy_mappings_value @property def authority_key_identifier_value(self): """ This extension helps in identifying the public key with which to validate the authenticity of the certificate. :return: None or an AuthorityKeyIdentifier object """ if not self._processed_extensions: self._set_extensions() return self._authority_key_identifier_value @property def policy_constraints_value(self): """ This extension is used to control if policy mapping is allowed and when policies are required. :return: None or a PolicyConstraints object """ if not self._processed_extensions: self._set_extensions() return self._policy_constraints_value @property def freshest_crl_value(self): """ This extension is used to help locate any available delta CRLs :return: None or an CRLDistributionPoints object """ if not self._processed_extensions: self._set_extensions() return self._freshest_crl_value @property def inhibit_any_policy_value(self): """ This extension is used to prevent mapping of the any policy to specific requirements :return: None or a Integer object """ if not self._processed_extensions: self._set_extensions() return self._inhibit_any_policy_value @property def extended_key_usage_value(self): """ This extension is used to define additional purposes for the public key beyond what is contained in the basic constraints. :return: None or an ExtKeyUsageSyntax object """ if not self._processed_extensions: self._set_extensions() return self._extended_key_usage_value @property def authority_information_access_value(self): """ This extension is used to locate the CA certificate used to sign this certificate, or the OCSP responder for this certificate. :return: None or an AuthorityInfoAccessSyntax object """ if not self._processed_extensions: self._set_extensions() return self._authority_information_access_value @property def subject_information_access_value(self): """ This extension is used to access information about the subject of this certificate. :return: None or a SubjectInfoAccessSyntax object """ if not self._processed_extensions: self._set_extensions() return self._subject_information_access_value @property def tls_feature_value(self): """ This extension is used to list the TLS features a server must respond with if a client initiates a request supporting them. :return: None or a Features object """ if not self._processed_extensions: self._set_extensions() return self._tls_feature_value @property def ocsp_no_check_value(self): """ This extension is used on certificates of OCSP responders, indicating that revocation information for the certificate should never need to be verified, thus preventing possible loops in path validation. :return: None or a Null object (if present) """ if not self._processed_extensions: self._set_extensions() return self._ocsp_no_check_value @property def signature(self): """ :return: A byte string of the signature """ return self['signature_value'].native @property def signature_algo(self): """ :return: A unicode string of "rsassa_pkcs1v15", "rsassa_pss", "dsa", "ecdsa" """ return self['signature_algorithm'].signature_algo @property def hash_algo(self): """ :return: A unicode string of "md2", "md5", "sha1", "sha224", "sha256", "sha384", "sha512", "sha512_224", "sha512_256" """ return self['signature_algorithm'].hash_algo @property def public_key(self): """ :return: The PublicKeyInfo object for this certificate """ return self['tbs_certificate']['subject_public_key_info'] @property def subject(self): """ :return: The Name object for the subject of this certificate """ return self['tbs_certificate']['subject'] @property def issuer(self): """ :return: The Name object for the issuer of this certificate """ return self['tbs_certificate']['issuer'] @property def serial_number(self): """ :return: An integer of the certificate's serial number """ return self['tbs_certificate']['serial_number'].native @property def key_identifier(self): """ :return: None or a byte string of the certificate's key identifier from the key identifier extension """ if not self.key_identifier_value: return None return self.key_identifier_value.native @property def issuer_serial(self): """ :return: A byte string of the SHA-256 hash of the issuer concatenated with the ascii character ":", concatenated with the serial number as an ascii string """ if self._issuer_serial is None: self._issuer_serial = self.issuer.sha256 + b':' + str_cls(self.serial_number).encode('ascii') return self._issuer_serial @property def not_valid_after(self): """ :return: A datetime of latest time when the certificate is still valid """ return self['tbs_certificate']['validity']['not_after'].native @property def not_valid_before(self): """ :return: A datetime of the earliest time when the certificate is valid """ return self['tbs_certificate']['validity']['not_before'].native @property def authority_key_identifier(self): """ :return: None or a byte string of the key_identifier from the authority key identifier extension """ if not self.authority_key_identifier_value: return None return self.authority_key_identifier_value['key_identifier'].native @property def authority_issuer_serial(self): """ :return: None or a byte string of the SHA-256 hash of the isser from the authority key identifier extension concatenated with the ascii character ":", concatenated with the serial number from the authority key identifier extension as an ascii string """ if self._authority_issuer_serial is False: akiv = self.authority_key_identifier_value if akiv and akiv['authority_cert_issuer'].native: issuer = self.authority_key_identifier_value['authority_cert_issuer'][0].chosen # We untag the element since it is tagged via being a choice from GeneralName issuer = issuer.untag() authority_serial = self.authority_key_identifier_value['authority_cert_serial_number'].native self._authority_issuer_serial = issuer.sha256 + b':' + str_cls(authority_serial).encode('ascii') else: self._authority_issuer_serial = None return self._authority_issuer_serial @property def crl_distribution_points(self): """ Returns complete CRL URLs - does not include delta CRLs :return: A list of zero or more DistributionPoint objects """ if self._crl_distribution_points is None: self._crl_distribution_points = self._get_http_crl_distribution_points(self.crl_distribution_points_value) return self._crl_distribution_points @property def delta_crl_distribution_points(self): """ Returns delta CRL URLs - does not include complete CRLs :return: A list of zero or more DistributionPoint objects """ if self._delta_crl_distribution_points is None: self._delta_crl_distribution_points = self._get_http_crl_distribution_points(self.freshest_crl_value) return self._delta_crl_distribution_points def _get_http_crl_distribution_points(self, crl_distribution_points): """ Fetches the DistributionPoint object for non-relative, HTTP CRLs referenced by the certificate :param crl_distribution_points: A CRLDistributionPoints object to grab the DistributionPoints from :return: A list of zero or more DistributionPoint objects """ output = [] if crl_distribution_points is None: return [] for distribution_point in crl_distribution_points: distribution_point_name = distribution_point['distribution_point'] if distribution_point_name is VOID: continue # RFC 5280 indicates conforming CA should not use the relative form if distribution_point_name.name == 'name_relative_to_crl_issuer': continue # This library is currently only concerned with HTTP-based CRLs for general_name in distribution_point_name.chosen: if general_name.name == 'uniform_resource_identifier': output.append(distribution_point) return output @property def ocsp_urls(self): """ :return: A list of zero or more unicode strings of the OCSP URLs for this cert """ if not self.authority_information_access_value: return [] output = [] for entry in self.authority_information_access_value: if entry['access_method'].native == 'ocsp': location = entry['access_location'] if location.name != 'uniform_resource_identifier': continue url = location.native if url.lower().startswith(('http://', 'https://', 'ldap://', 'ldaps://')): output.append(url) return output @property def valid_domains(self): """ :return: A list of unicode strings of valid domain names for the certificate. Wildcard certificates will have a domain in the form: *.example.com """ if self._valid_domains is None: self._valid_domains = [] # For the subject alt name extension, we can look at the name of # the choice selected since it distinguishes between domain names, # email addresses, IPs, etc if self.subject_alt_name_value: for general_name in self.subject_alt_name_value: if general_name.name == 'dns_name' and general_name.native not in self._valid_domains: self._valid_domains.append(general_name.native) # If there was no subject alt name extension, and the common name # in the subject looks like a domain, that is considered the valid # list. This is done because according to # https://tools.ietf.org/html/rfc6125#section-6.4.4, the common # name should not be used if the subject alt name is present. else: pattern = re.compile('^(\\*\\.)?(?:[a-zA-Z0-9](?:[a-zA-Z0-9\\-]*[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,}$') for rdn in self.subject.chosen: for name_type_value in rdn: if name_type_value['type'].native == 'common_name': value = name_type_value['value'].native if pattern.match(value): self._valid_domains.append(value) return self._valid_domains @property def valid_ips(self): """ :return: A list of unicode strings of valid IP addresses for the certificate """ if self._valid_ips is None: self._valid_ips = [] if self.subject_alt_name_value: for general_name in self.subject_alt_name_value: if general_name.name == 'ip_address': self._valid_ips.append(general_name.native) return self._valid_ips @property def ca(self): """ :return; A boolean - if the certificate is marked as a CA """ return self.basic_constraints_value and self.basic_constraints_value['ca'].native @property def max_path_length(self): """ :return; None or an integer of the maximum path length """ if not self.ca: return None return self.basic_constraints_value['path_len_constraint'].native @property def self_issued(self): """ :return: A boolean - if the certificate is self-issued, as defined by RFC 5280 """ if self._self_issued is None: self._self_issued = self.subject == self.issuer return self._self_issued @property def self_signed(self): """ :return: A unicode string of "no" or "maybe". The "maybe" result will be returned if the certificate issuer and subject are the same. If a key identifier and authority key identifier are present, they will need to match otherwise "no" will be returned. To verify is a certificate is truly self-signed, the signature will need to be verified. See the certvalidator package for one possible solution. """ if self._self_signed is None: self._self_signed = 'no' if self.self_issued: if self.key_identifier: if not self.authority_key_identifier: self._self_signed = 'maybe' elif self.authority_key_identifier == self.key_identifier: self._self_signed = 'maybe' else: self._self_signed = 'maybe' return self._self_signed @property def sha1(self): """ :return: The SHA-1 hash of the DER-encoded bytes of this complete certificate """ if self._sha1 is None: self._sha1 = hashlib.sha1(self.dump()).digest() return self._sha1 @property def sha1_fingerprint(self): """ :return: A unicode string of the SHA-1 hash, formatted using hex encoding with a space between each pair of characters, all uppercase """ return ' '.join('%02X' % c for c in bytes_to_list(self.sha1)) @property def sha256(self): """ :return: The SHA-256 hash of the DER-encoded bytes of this complete certificate """ if self._sha256 is None: self._sha256 = hashlib.sha256(self.dump()).digest() return self._sha256 @property def sha256_fingerprint(self): """ :return: A unicode string of the SHA-256 hash, formatted using hex encoding with a space between each pair of characters, all uppercase """ return ' '.join('%02X' % c for c in bytes_to_list(self.sha256)) def is_valid_domain_ip(self, domain_ip): """ Check if a domain name or IP address is valid according to the certificate :param domain_ip: A unicode string of a domain name or IP address :return: A boolean - if the domain or IP is valid for the certificate """ if not isinstance(domain_ip, str_cls): raise TypeError(unwrap( ''' domain_ip must be a unicode string, not %s ''', type_name(domain_ip) )) encoded_domain_ip = domain_ip.encode('idna').decode('ascii').lower() is_ipv6 = encoded_domain_ip.find(':') != -1 is_ipv4 = not is_ipv6 and re.match('^\\d+\\.\\d+\\.\\d+\\.\\d+$', encoded_domain_ip) is_domain = not is_ipv6 and not is_ipv4 # Handle domain name checks if is_domain: if not self.valid_domains: return False domain_labels = encoded_domain_ip.split('.') for valid_domain in self.valid_domains: encoded_valid_domain = valid_domain.encode('idna').decode('ascii').lower() valid_domain_labels = encoded_valid_domain.split('.') # The domain must be equal in label length to match if len(valid_domain_labels) != len(domain_labels): continue if valid_domain_labels == domain_labels: return True is_wildcard = self._is_wildcard_domain(encoded_valid_domain) if is_wildcard and self._is_wildcard_match(domain_labels, valid_domain_labels): return True return False # Handle IP address checks if not self.valid_ips: return False family = socket.AF_INET if is_ipv4 else socket.AF_INET6 normalized_ip = inet_pton(family, encoded_domain_ip) for valid_ip in self.valid_ips: valid_family = socket.AF_INET if valid_ip.find('.') != -1 else socket.AF_INET6 normalized_valid_ip = inet_pton(valid_family, valid_ip) if normalized_valid_ip == normalized_ip: return True return False def _is_wildcard_domain(self, domain): """ Checks if a domain is a valid wildcard according to https://tools.ietf.org/html/rfc6125#section-6.4.3 :param domain: A unicode string of the domain name, where any U-labels from an IDN have been converted to A-labels :return: A boolean - if the domain is a valid wildcard domain """ # The * character must be present for a wildcard match, and if there is # most than one, it is an invalid wildcard specification if domain.count('*') != 1: return False labels = domain.lower().split('.') if not labels: return False # Wildcards may only appear in the left-most label if labels[0].find('*') == -1: return False # Wildcards may not be embedded in an A-label from an IDN if labels[0][0:4] == 'xn--': return False return True def _is_wildcard_match(self, domain_labels, valid_domain_labels): """ Determines if the labels in a domain are a match for labels from a wildcard valid domain name :param domain_labels: A list of unicode strings, with A-label form for IDNs, of the labels in the domain name to check :param valid_domain_labels: A list of unicode strings, with A-label form for IDNs, of the labels in a wildcard domain pattern :return: A boolean - if the domain matches the valid domain """ first_domain_label = domain_labels[0] other_domain_labels = domain_labels[1:] wildcard_label = valid_domain_labels[0] other_valid_domain_labels = valid_domain_labels[1:] # The wildcard is only allowed in the first label, so if # The subsequent labels are not equal, there is no match if other_domain_labels != other_valid_domain_labels: return False if wildcard_label == '*': return True wildcard_regex = re.compile('^' + wildcard_label.replace('*', '.*') + '$') if wildcard_regex.match(first_domain_label): return True return False # The structures are taken from the OpenSSL source file x_x509a.c, and specify # extra information that is added to X.509 certificates to store trust # information about the certificate. class KeyPurposeIdentifiers(SequenceOf): _child_spec = KeyPurposeId class SequenceOfAlgorithmIdentifiers(SequenceOf): _child_spec = AlgorithmIdentifier class CertificateAux(Sequence): _fields = [ ('trust', KeyPurposeIdentifiers, {'optional': True}), ('reject', KeyPurposeIdentifiers, {'implicit': 0, 'optional': True}), ('alias', UTF8String, {'optional': True}), ('keyid', OctetString, {'optional': True}), ('other', SequenceOfAlgorithmIdentifiers, {'implicit': 1, 'optional': True}), ] class TrustedCertificate(Concat): _child_specs = [Certificate, CertificateAux] __pycache__/__init__.cpython-312.pyc000064400000002334152572326550013234 0ustar00Ë uÉþiÃãó:—ddlmZmZmZmZddlmZmZgd¢Zd„Z y)é)Úunicode_literalsÚdivisionÚabsolute_importÚprint_functioné)Ú __version__Ú__version_info__)rr Ú load_ordercó —gd¢S)a+ Returns a list of the module and sub-module names for asn1crypto in dependency load order, for the sake of live reloading code :return: A list of unicode strings of module names, as they would appear in sys.modules, ordered by which module should be reloaded first )zasn1crypto._errorszasn1crypto._intzasn1crypto._ordereddictzasn1crypto._teletex_codeczasn1crypto._typeszasn1crypto._inetzasn1crypto._irizasn1crypto.versionzasn1crypto.pemzasn1crypto.utilzasn1crypto.parserzasn1crypto.corezasn1crypto.algoszasn1crypto.keyszasn1crypto.x509zasn1crypto.crlzasn1crypto.csrzasn1crypto.ocspzasn1crypto.cmszasn1crypto.pdfzasn1crypto.pkcs12zasn1crypto.tspÚ asn1crypto©r óúD/opt/nydus/tmp/pip-target-dhtdbchl/lib/python/asn1crypto/__init__.pyr r s €ò ðrN) Ú __future__rrrrÚversionrr Ú__all__r r rrÚrsðçRÓRç2ò €ó"r__pycache__/_errors.cpython-312.pyc000064400000002734152572326550013154 0ustar00Ë uÉþi.ãóL—dZddlmZmZmZmZddlZddlZGd„de«Z d„Z y)z= Exports the following items: - unwrap() - APIException() é)Úunicode_literalsÚdivisionÚabsolute_importÚprint_functionNcó—eZdZdZy)Ú APIExceptionzI An exception indicating an API has been removed from asn1crypto N)Ú__name__Ú __module__Ú __qualname__Ú__doc__©óúC/opt/nydus/tmp/pip-target-dhtdbchl/lib/python/asn1crypto/_errors.pyrrs „ñð rrcó´—tj|«}|jd«dk7rtjdd|«}|r||z}|j «}|S)a_ Takes a multi-line string and does the following: - dedents - converts newlines with text before and after into a single line - strips leading and trailing whitespace :param string: The string to format :param *params: Params to interpolate into the string :return: The formatted string Ú éÿÿÿÿz(?<=\S) (?=[^ \d\*\-=])Ú )ÚtextwrapÚdedentÚfindÚreÚsubÚstrip)ÚstringÚparamsÚoutputs rÚunwraprsT€ô$�_‰_˜VÓ $€Fð‡{�{�4Ó˜BÒÜ—‘Ð:¸CÀÓHˆá ؘ&‘ˆà �\‰\‹^€Fà €Mr) r Ú __future__rrrrrrÚ Exceptionrrr rrÚr s*ðñ÷SÓRã Ûô �9ô ór__pycache__/_inet.cpython-312.pyc000064400000012725152572326550012600 0ustar00Ë uÉþi5ãó\—ddlmZmZmZmZddlZddlZddlmZddl m Z m Z m Z m Z d„Zd„Zy)é)Úunicode_literalsÚdivisionÚabsolute_importÚprint_functionNé)Úunwrap)Úbyte_clsÚ bytes_to_listÚstr_clsÚ type_namec ó¼—|ttjtjg«vrNt t dt tj«t tj«t |«««‚t|t«stt dt|«««‚|tjk(rdnd}t|«|k7rt t d|t|«««‚|tjk(rdtt|««zStjd|«}i}d}d }t!|d z«D]/\}}|dk7r |€Œ||z } | |vr||| <t#|| «}d }Œ+|�Œ.|}Œ1|D� cgc]} t%| «d d ‘Œ} } |d krd j'| «S||} | |z} d j'| d | «d zd j'| | d «zScc} w)a Windows compatibility shim for socket.inet_ntop(). :param address_family: socket.AF_INET for IPv4 or socket.AF_INET6 for IPv6 :param packed_ip: A byte string of the network form of an IP address :return: A unicode string of the IP address úp address_family must be socket.AF_INET (%s) or socket.AF_INET6 (%s), not %s zA packed_ip must be a byte string, not %s éézA packed_ip must be %d bytes long - is %d z %d.%d.%d.%dó !HHHHHHHHrN)éÿÿÿÿéÚ:ú::)ÚsetÚsocketÚAF_INETÚAF_INET6Ú ValueErrorrÚreprÚ isinstancer Ú TypeErrorr ÚlenÚtupler ÚstructÚunpackÚ enumerateÚmaxÚhexÚjoin)Úaddress_familyÚ packed_ipÚ required_lenÚoctetsÚ runs_of_zeroÚ longest_runÚ zero_indexÚiÚoctetÚlengthÚoÚhexedÚ zero_startÚzero_ends úA/opt/nydus/tmp/pip-target-dhtdbchl/lib/python/asn1crypto/_inet.pyÚ inet_ntopr5 sè€ðœS¤&§.¡.´&·/±/Ð!BÓCÑCÜœð ô ”—‘Ó Ü ”—‘Ó !Ü �Ó ó ó ð ô �i¤Ô *Üœð ô �iÓ ó  ó ð ð'¬&¯.©.Ò8‘1¸b€LÜ ˆ9ƒ~˜Ò%Üœð ð Ü � ‹Nó  ó ð 𜟙Ò'Øœu¤]°9Ó%=Ó>Ñ>Ð>ä �]‰]˜<¨Ó 3€Fà€LØ€KØ€Jܘf u™nÖ-‰ˆˆ5Ø �AŠ:ØÑ%ؘZ™�Ø Ñ-Ø+5�L Ñ(Ü! +¨vÓ6� Ø!‘ Ø Ñ Ø‰Jð.ñ"(Ó (¡˜AŒS�‹V�A�BŠZ €EÐ (à�Q‚Ø�x‰x˜‹Ðà˜kÑ*€JؘKÑ'€Hà �8‰8�E˜+˜:Ð&Ó '¨$Ñ .°·±¸%ÀÀ Ð:JÓ1KÑ KÐKùò )sÅ6Gc ó–—|ttjtjg«vrNt t dt tj«t tj«t |«««‚t|t«stt dt|«««‚|tjk(rŠ|jd«}t|«dk7}|s3g}|D],}t|«}|dkDs|dkrd}n|j|«Œ.|rt t dt |«««‚tj d g¢­ŽSd }|j#d «}|d kDrd}n�|dk(r |jd «}t|«dk7}n\|jd «\}}|jd «} |jd «} dt| «z t| «z } | dg| zz| z}|sJg}D]-}t|d«}|dkDs|dkrd}n|j|«Œ/tj dg|¢­ŽSt t dt |«««‚)a Windows compatibility shim for socket.inet_ntop(). :param address_family: socket.AF_INET for IPv4 or socket.AF_INET6 for IPv6 :param ip_string: A unicode string of an IP address :return: A byte string of the network form of the IP address rzD ip_string must be a unicode string, not %s Ú.réÿrTz‡ ip_string must be a dotted string with four integers in the range of 0 to 255, got %s s!BBBBFrrréÚ0riÿÿrz? ip_string must be a valid ipv6 string, got %s )rrrrrrrrr rr ÚsplitrÚintÚappendr ÚpackÚcount) r&Ú ip_stringr)ÚerrorÚintsr0ÚomittedÚbeginÚendÚ begin_octetsÚ end_octetsÚmissings r4Ú inet_ptonrITs;€ðœS¤&§.¡.´&·/±/Ð!BÓCÑCÜœð ô ”—‘Ó Ü ”—‘Ó !Ü �Ó ó ó ð ô �i¤Ô )Üœð ô �iÓ ó  ó ð 𜟙Ò'Ø—‘ Ó%ˆÜ�F“ ˜qÑ ˆÙ؈DÛ�ܘ“F�Ø�s’7˜a !šeØ �EÙØ— ‘ ˜A•ð ñ ÜœVðô�Y“ó óð ô�{‰{˜8Ð+ dÒ+Ð+à €EØ�o‰o˜dÓ#€GØ�‚{Ø‰Ø �AŠØ—‘ Ó%ˆÜ�F“ ˜qÑ ‰à—_‘_ TÓ*‰ ˆˆsØ—{‘{ 3Ó'ˆ Ø—Y‘Y˜s“^ˆ Ø”c˜,Ó'Ñ'¬#¨j«/Ñ9ˆØ # ¨¡Ñ1°JÑ>ˆá ؈ۈAÜ�A�r“ ˆAØ�5Šy˜A šEØ�ÙØ �K‰K˜�Nð ô�{‰{˜<Ð/¨$Ò/Ð/ä ”Vð ô ˆY‹ó ó ðó)Ú __future__rrrrrr Ú_errorsrÚ_typesr r r r r5rI©rJr4ÚrOs(ðçRÓRã Û åß?Ó?òFLóRVrJ__pycache__/_int.cpython-312.pyc000064400000001434152572326550012426 0ustar00Ë uÉþiîãó"—ddlmZmZmZmZd„Zy)é)Úunicode_literalsÚdivisionÚabsolute_importÚprint_functioncóJ—t|«|krd|z}t|«|krŒ|S)a  Ensure a byte string representing a positive integer is a specific width (in bytes) :param bytes_: The integer byte string :param width: The desired width as an integer :return: A byte string of the width specified ó)Úlen)Úbytes_Úwidths ú@/opt/nydus/tmp/pip-target-dhtdbchl/lib/python/asn1crypto/_int.pyÚ fill_widthr s-€ô ˆf‹+˜Ò ؘ6Ñ!ˆô ˆf‹+˜Ó à €MóN)Ú __future__rrrrr ©rr ÚrsðçRÓRór__pycache__/_iri.cpython-312.pyc000064400000023057152572326550012424 0ustar00Ë uÉþi"ãó—dZddlmZmZmZmZddlmZddlZddl Z ddl Z ddl m Z ddl mZmZmZmZmZe j&dkrdd lmZmZdd lmZmZn dd lmZmZmZmZdd „Zd „Zd„Zej@de«dd„Z!dd„Z"y)z‡ Functions to convert unicode IRIs into ASCII byte string URIs and back. Exports the following items: - iri_to_uri() - uri_to_iri() é)Úunicode_literalsÚdivisionÚabsolute_importÚprint_function)ÚidnaNé)Úunwrap)Úbyte_clsÚstr_clsÚ type_nameÚ bytes_to_listÚ int_types)é)ÚurlsplitÚ urlunsplit)ÚquoteÚunquote)rÚunquote_to_bytesrrcóZ—t|t«sttdt |«««‚d}t j dkr‚|jd«sq|jd«s`d}tjd|«}|r"|jd«}d|t|«dz}t|«}|r"||ddz}t|dd «}n t|«}|€t|j«}|j}|�|j!d «}t|j"d ¬ «}t|j$d ¬ «}|j&} | �t| «j!d «} d} |�| |z } |r| d|zz } | dz } |�| |z } | �&|dk(xr| dk(} |dk(xr| dk(} |r| s | s| d| zz } t|j(d¬ «} t|j*d¬ «}t|j,d¬ «}|r |€ |€| dk(rd} | €d} t/|| | ||f«}t|t«r|j!d«}|S)zö Encodes a unicode IRI into an ASCII byte string URI :param value: A unicode string of an IRI :param normalize: A bool that controls URI normalization :return: A byte string of the ASCII-encoded URI z@ value must be a unicode string, not %s N)éézhttp://zhttps://z ^[^:]*://rréýÿÿÿrz !$&'()*+,;=©ÚsafeÚasciióó:ó@shttps80shttpss443z/!$&'()*+,;=@:z/?!$&'()*+,;=@:ó/ÚÚlatin1)Ú isinstancer Ú TypeErrorr r ÚsysÚ version_infoÚ startswithÚreÚmatchÚgroupÚlenrÚ _urlquoteÚschemeÚhostnameÚencodeÚusernameÚpasswordÚportÚpathÚqueryÚfragmentr)ÚvalueÚ normalizer,Ú real_prefixÚ prefix_matchÚparsedr-r/r0r1ÚnetlocÚ default_httpÚ default_httpsr2r3r4Úoutputs ú@/opt/nydus/tmp/pip-target-dhtdbchl/lib/python/asn1crypto/_iri.pyÚ iri_to_urir?%sS€ô �eœWÔ %Üœð ô �eÓ ó  ó ð ð€Fä ×ј&Ò ¨×)9Ñ)9¸)Ô)DÈU×M]ÑM]Ð^hÔMi؈ Ü—x‘x  ¨UÓ3ˆ Ù Ø&×,Ñ,¨QÓ/ˆKØ ¤c¨+Ó&6Ð&7Ð 8Ñ8ˆEܘ%“ˆÙ Ø %¨¨ )Ñ+ˆEܘ{¨3¨BÐ/Ó0‰Fä˜%“ˆà €~ܘ6Ÿ=™=Ó)ˆØ�‰€HØÐØ—?‘? 6Ó*ˆä˜Ÿ™¨~Ô>€HܘŸ™¨~Ô>€HØ �;‰;€DØ ÐÜ�t‹}×#Ñ# GÓ,ˆà €FØÐØ�(ÑˆÙ Ø �d˜X‘oÑ %ˆFØ�$‰ˆØÐØ�(ÑˆØ ÐØ Ñ(Ò:¨T°U©]ˆ Ø (Ñ*Ò=¨t°v©~ˆ Ù¡±mØ �d˜T‘kÑ !ˆFô �V—[‘[Ð'8Ô 9€Dä �f—l‘lÐ);Ô <€E䘟™Ð/AÔB€Há�U�] xÐ'7¸DÀDºL؈ð €|Øˆä ˜ ¨¨u°hÐ?Ó @€FÜ�&œ'Ô"Ø—‘˜xÓ(ˆØ €MrcóÆ—t|t«sttdt |«««‚t |«}|j }|�|jd«}t|jddg¬«}t|jddg¬«}|j}|r|jd«}|j}|r!t|t«s|jd«}d}|�||z }|r|d|zz }|dz }|�||z }|�|dt|«zz }t|jdgd ¬ «}t|j d d gd ¬ «} t|j"«} t%|||| | f«S) z³ Converts an ASCII URI byte string into a unicode IRI :param value: An ASCII-encoded byte string of the URI :return: A unicode string of the IRI z= value must be a byte string, not %s rÚ:Ú@)Úremaprr Ú/T)rCÚpreserveÚ&Ú=)r"r r#r r rr,ÚdecodeÚ _urlunquoter/r0r-r1rr r2r3r4r) r5r9r,r/r0r-r1r:r2r3r4s r>Ú uri_to_irirJxsd€ô �eœXÔ &Üœð ô �eÓ ó  ó ð ô�e‹_€Fà �]‰]€FØ ÐØ—‘˜wÓ'ˆä˜6Ÿ?™?°3¸°*Ô=€Hܘ6Ÿ?™?°3¸°*Ô=€HØ�‰€HÙØ—?‘? 6Ó*ˆØ �;‰;€DÙ ”J˜t¤YÔ/Ø�{‰{˜7Ó#ˆà €FØÐØ�(ÑˆÙ Ø �c˜H‘nÑ $ˆFØ�#‰ ˆØÐØ�(ÑˆØ ÐØ�#œ › Ñ%Ñ%ˆä �v—{‘{¨3¨%¸$Ô ?€DÜ ˜Ÿ ™ ¨S°#¨JÀÔ F€Eܘ6Ÿ?™?Ó+€Hä �v˜v t¨U°HÐ=Ó >Ð>rcó—t|j|j|j«}|D�cgc]}d|z‘Œ }}dj |«|jfScc}w)a> Error handler for decoding UTF-8 parts of a URI into an IRI. Leaves byte sequences encoded in %XX format, but as part of a unicode string. :param exc: The UnicodeDecodeError exception :return: A 2-element tuple of (replacement unicode string, integer index to resume at) ú%%%02xr )r ÚobjectÚstartÚendÚjoin)ÚexcÚ bytes_as_intsÚnumÚ replacementss r>Ú_iri_utf8_errors_handlerrU¬sV€ô" #§*¡*¨S¯Y©Y°s·w±wÐ"?Ó@€MÙ.;Ó<©m s�H˜s“N¨m€LÐ<Ø �G‰G�LÓ ! 3§7¡7Ð +Ð+ùò=s± AÚiriutf8c󦇇—|�|dk(rygŠtjd|«r8ˆfd„}tjd||«}ˆfd„}tjd||«}t|j d«‰j d«¬«}t |t «s|j d «}t‰«d kDrˆfd „}tjd ||«}|S) a Quotes a unicode string for use in a URL :param string: A unicode string :param safe: A unicode string of character to not encode :return: None (if string is None) or an ASCII byte string of the quoted string Nr z%[0-9a-fA-F]{2}c󼕗t|jd««}|jdd«}t‰«D] }|j |dt |«z«}Œ"|S)Nrúutf-8rVrL)rr)rHÚlistÚreplaceÚord)r(Ú byte_stringÚunicode_stringÚ safe_charrs €r>Ú _try_unescapez _urlquote.._try_unescapeÙsWø€Ü*¨5¯;©;°q«>Ó:ˆKØ(×/Ñ/°¸ÓCˆNÜ! $žZ� Ø!/×!7Ñ!7¸ À8ÌcÐR[ËnÑC\Ó!]‘ð(à!Ð !rz(?:%[0-9a-fA-F]{2})+cód•—‰j|jd«jd««y)NrrÚ)Úappendr)r.)r(Úescapess €r>Ú_extract_escapez"_urlquote.._extract_escapeãs%ø€Ø �N‰N˜5Ÿ;™; q›>×0Ñ0°Ó9Ô :ØrrYrrrcó&•—‰jd«S)Nr)Úpop)Ú_rds €r>Ú_return_escapez!_urlquote.._return_escapeîsø€Ø—;‘;˜q“>Ð !rs%00)r'ÚsearchÚsubÚurlquoter.r"r r*)Ústringrr`rer=rirds ` @r>r+r+Ás½ù€ð€~˜ 2šØð€GÜ ‡y�yÐ" FÔ+ô "ô —‘Ð.° ¸vÓFˆô ô—‘Ð)¨?¸FÓCˆä �f—m‘m GÓ,°4·;±;¸wÓ3GÔ H€FÜ �fœhÔ 'Ø—‘˜wÓ'ˆô ˆ7ƒ|�aÒô "ä—‘˜ °Ó7ˆà €Mrcóà—|€|S|dk(ry|rSgd¢}i}|D]H}|jd«}|||<|j|jd«|jd««}ŒJt|«}|rC|D]>}|j|jd«dt |«zjd««}Œ@|j dd«}|r*j «D]\}}|j||«}Œ|S) a Unquotes a URI portion from a byte string into unicode using UTF-8 :param byte_string: A byte string of the data to unquote :param remap: A list of characters (as unicode) that should be re-mapped to a %XX encoding. This is used when characters are not valid in part of a URL. :param preserve: A bool - indicates that the chars to be remapped if they occur in non-hex form, should be preserved. E.g. / for URL path. :return: A unicode string rr )ÚÚÚÚÚrrrLrYrV)rgr[r.rr\rHÚitems) r]rCrErTÚpreserve_unmapÚcharÚ replacementr=Úoriginals r>rIrIõs€ð(ÐØÐà�cÒØáÚ?ˆ ؈ۈDØ&×*Ñ*¨1Ó-ˆKØ*.ˆN˜;Ñ 'Ø%×-Ñ-¨d¯k©k¸'Ó.BÀK×DVÑDVÐW^ÓD_Ó`‰Kðô # ;Ó/€Ká ÛˆDØ%×-Ñ-¨d¯k©k¸'Ó.BÀXÔPSÐTXÓPYÑEY×DaÑDaÐbiÓDjÓk‰Kðð× Ñ  ¨Ó 3€FáØ%3×%9Ñ%9Ö%;Ñ !ˆK˜Ø—^‘^ K°Ó:‰Fð&<ð €Mr)F)r )NN)#Ú__doc__Ú __future__rrrrÚ encodingsrÚcodecsr'r$Ú_errorsr Ú_typesr r r r rr%ÚurlparserrÚurllibrrlrrÚ urllib.parser?rJrUÚregister_errorr+rI©rr>Úr„sðñ÷SÓRåÛ Û Û åßJÕJà×Ñ�dÒß-÷ð÷ óóPòf1?òh,ð$€×Ñ�iÐ!9Ô:ó1ôh.r__pycache__/_ordereddict.cpython-312.pyc000064400000012663152572326550014132 0ustar00Ë uÉþiµãó\—ddlZejdksddlmZyddlmZGd„dee«Zy)éN)éé)Ú OrderedDict)Ú DictMixincó.—eZdZd„Zd„Zd„Zd„Zd„Zd„Zdd„Z d„Z d „Z e jZ e jZe jZe j Ze j"Ze j$Ze j&Ze j(Zd „Zd „Zedd „«Zd„Zd„Zy )rcóÊ—t|«dkDrtdt|«z«‚ |j|j |i|¤Žy#t$r|j «YŒ.wxYw)Néz$expected at most 1 arguments, got %d)ÚlenÚ TypeErrorÚ_OrderedDict__endÚAttributeErrorÚclearÚupdate)ÚselfÚargsÚkwdss úH/opt/nydus/tmp/pip-target-dhtdbchl/lib/python/asn1crypto/_ordereddict.pyÚ__init__zOrderedDict.__init__#s]€Ü�4‹y˜1Š}ÜÐ FÌÈTËÑ RÓSÐSð Ø— ’ ð ˆD�K‰K˜Ð & Ó &øô"ò Ø— ‘ – ð ús§ AÁA"Á!A"có^—gx|_}|d||gz }i|_tj|«y©N)r Ú_OrderedDict__mapÚdictr)rÚends rrzOrderedDict.clear,s2€Ø!Ð !ˆDŒJ˜Ø �D˜#˜sÐ#Ñ #ˆC؈DŒJÜ �J‰J�tÕ ócó”—||vr-|j}|d}|||gx|d<x|d<|j|<tj|||«y)Nr r)r rrÚ __setitem__)rÚkeyÚvaluerÚcurrs rrzOrderedDict.__setitem__2sS€Ø˜$‰Ø—j‘j�ؘ1‘v�Ø69¸4ÀÐ5EÐE��Q‘ÐE˜#˜a™& 4§:¡:¨c¡?Ü × Ñ ˜T 3¨Õ .rcó‚—tj||«|jj|«\}}}||d<||d<y)Nrr )rÚ __delitem__rÚpop)rrÚprevÚnext_s rr!zOrderedDict.__delitem__9s=€Ü × Ñ ˜T 3Ô 'Ø#Ÿz™zŸ~™~¨cÓ2Ñ ˆC��u؈D�‰G؈E�!ŠHrc#óZK—|j}|d}||ur|d–—|d}||urŒyy­w)Nrr©r ©rrrs rÚ__iter__zOrderedDict.__iter__?ó:èø€Ø—*‘*ˆCØ�q‘6ˆDؘc‘/ؘ1‘g’ ؘA‘w�ð˜c”/ùó‚&+©+c#óZK—|j}|d}||ur|d–—|d}||urŒyy­w)Nr rr&r's rÚ __reversed__zOrderedDict.__reversed__Fr)r*có°—|s td«‚|rt|«j«}nt|«j«}|j |«}||fS)Nzdictionary is empty)ÚKeyErrorÚreversedÚnextÚiterr")rÚlastrrs rÚpopitemzOrderedDict.popitemMsM€ÙÜÐ4Ó5Ð5Ùܘt“n×)Ñ)Ó+‘ä˜4“j—o‘oÓ'�Ø—H‘H˜S“MˆEؘ�:Ð rcóþ—|D�cgc] }|||g‘Œ }}|j|jf}|`|`t|«j«}|\|_|_|r|j|f|fS|j|ffScc}wr)rr ÚvarsÚcopyÚ __class__)rÚkÚitemsÚtmpÚ inst_dicts rÚ __reduce__zOrderedDict.__reduce__Wsƒ€Ù+/Ó0©4 a�a˜˜a™’\¨4ˆEÐ0Ø—*‘*˜dŸj™jÐ(ˆCØ� ˜D˜JܘT› Ÿ™Ó)ˆIØ%(Ñ "ˆDŒJ˜œ ÙØŸ™¨¨°)Ð<Ð<Ø—>‘> E 8Ð+Ð +ùò1s…A:có—t|«Sr)Úlist©rs rÚkeyszOrderedDict.keysas €Ü˜“:Ð rcóŒ—|s|jj›d�S|jj›d|j«›d�S)Nz()Ú(Ú))r7Ú__name__r9r?s rÚ__repr__zOrderedDict.__repr__ms3€ÙØ!%§¡×!8Ó!8Ð:Ð:Ø#Ÿ~™~×6Ó6¸¿ ¹ ½ ÐEÐ Ercó$—|j|«Sr)r7r?s rr6zOrderedDict.copyrs€Ø—>‘> $Ó'Ð 'rNcó,—|«}|D]}|||<Œ |Sr©)ÚclsÚiterablerÚdrs rÚfromkeyszOrderedDict.fromkeysus!€á“ˆAÛ�Ø��#’ð àˆHrcóî—t|t«rPt|«t|«k7ryt|j «|j ««D] \}}||k7sŒ yyt j ||«S)NFT)Ú isinstancerr Úzipr9rÚ__eq__)rÚotherÚpÚqs rrPzOrderedDict.__eq__|s`€Ü˜%¤Ô-Ü�t“9¤ E£ Ò*Ø Ü § ¡ £ ¨e¯k©k«mÖ<‘D�A�qؘA“vÙ$ð=ðÜ—;‘;˜t UÓ+Ð +rcó—||k( SrrH)rrQs rÚ__ne__zOrderedDict.__ne__†s€Ø˜u‘}Ð$Ð $r)Tr)rDÚ __module__Ú __qualname__rrrr!r(r,r3r<r@rÚ setdefaultrr"Úvaluesr9ÚiterkeysÚ itervaluesÚ iteritemsrEr6Ú classmethodrLrPrUrHrrrr!s®„ò 'ò ò  /ò ò  ò ó ò ,ò ð×)Ñ)ˆ Ø×!Ñ!ˆØ�m‰mˆØ×!Ñ!ˆØ—‘ˆØ×%Ñ%ˆØ×)Ñ)ˆ Ø×'Ñ'ˆ ò Fò  (ð ò ó ð ò  ,ó %rr)ÚsysÚ version_infoÚ collectionsrÚUserDictrrrHrrÚrbs0ðó. à ×ј&Ò æ'õ#ôf%�d˜Iõf%r__pycache__/_teletex_codec.cpython-312.pyc000064400000007266152572326550014454 0ustar00Ë uÉþi½ãó2—dZddlmZmZmZmZddlZGd„dej«ZGd„dej«Z Gd„d ej«Z Gd „d eej«ZGd „d eej«Zd„Zd„ZdZej(e«Zy)zW Implementation of the teletex T.61 codec. Exports the following items: - register() é)Úunicode_literalsÚdivisionÚabsolute_importÚprint_functionNcó—eZdZdd„Zdd„Zy)Ú TeletexCodeccó8—tj||t«S©N)ÚcodecsÚcharmap_encodeÚENCODING_TABLE©ÚselfÚinput_Úerrorss úJ/opt/nydus/tmp/pip-target-dhtdbchl/lib/python/asn1crypto/_teletex_codec.pyÚencodezTeletexCodec.encodeó€Ü×$Ñ$ V¨V´^ÓDÐDócó8—tj||t«Sr )r Úcharmap_decodeÚDECODING_TABLErs rÚdecodezTeletexCodec.decoderrN)Ústrict)Ú__name__Ú __module__Ú __qualname__rr©rrrrs„óEôErrcó—eZdZdd„Zy)ÚTeletexIncrementalEncodercóR—tj||jt«dS©Nr)r r rr ©rrÚfinals rrz TeletexIncrementalEncoder.encodeó €Ü×$Ñ$ V¨T¯[©[¼.ÓIÈ!ÑLÐLrN©F)rrrrrrrr r ó„ôMrr có—eZdZdd„Zy)ÚTeletexIncrementalDecodercóR—tj||jt«dSr")r rrrr#s rrz TeletexIncrementalDecoder.decoder%rNr&)rrrrrrrr)r)r'rr)có —eZdZy)ÚTeletexStreamWriterN©rrrrrrr,r,#ó„àrr,có —eZdZy)ÚTeletexStreamReaderNr-rrrr0r0(r.rr0c ó®—|dk7rytjdt«jt«jt t tt¬«S)zO Search function for teletex codec that is passed to codecs.register() ÚteletexN)ÚnamerrÚincrementalencoderÚincrementaldecoderÚ streamreaderÚ streamwriter) r Ú CodecInforrrr r)r0r,)r3s rÚteletex_search_functionr9-sG€ð  ˆyÒØä × Ñ Ø Ü‹~×$Ñ$Ü‹~×$Ñ$Ü4Ü4Ü(Ü(ô ðrcó6—tjt«y)z% Registers the teletex codec N)r Úregisterr9rrrr;r;@s€ô  ‡O�OÔ+Õ,ru«  !"￾￾%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[￾]￾_￾abcdefghijklmnopqrstuvwxyz￾|￾￾€Â�‚ƒ„…†‡ˆ‰Š‹ŒÂ�ÂŽÂ�Â�‘’“”•–—˜™š›œÂ�žŸ ¡¢£$Â¥#§¤￾￾«￾￾￾￾°±²³×µ¶·÷￾￾»¼½¾¿￾̀Ì�̂̃̄̆̇̈￾̧̨̲̊̋̌￾￾￾￾￾￾￾￾￾￾￾￾￾￾￾￾ΩÆÃ�ªĦ￾IJĿÅ�ØŒºÞŦŊʼnĸæđðħıijŀłøœßþŧŋ￾)Ú__doc__Ú __future__rrrrr ÚCodecrÚIncrementalEncoderr ÚIncrementalDecoderr)Ú StreamWriterr,Ú StreamReaderr0r9r;rÚ charmap_buildr rrrÚrDs¢ðñ÷ SÓRã ôE�6—<‘<ôEôM × 9Ñ 9ôMô M × 9Ñ 9ôMô  ˜,¨×(;Ñ(;ô ô  ˜,¨×(;Ñ(;ô ò ò&-ð ððD&�×%Ñ% nÓ5�r__pycache__/_types.cpython-312.pyc000064400000003040152572326550012773 0ustar00Ë uÉþi«ãóˆ—ddlmZmZmZmZddlZddlZejdkreZ e Z e e fZd„ZeZd„Zye Z eZ e ZeZd„Zd„Zy)é)Úunicode_literalsÚdivisionÚabsolute_importÚprint_functionN)écó>—|D�cgc] }t|«‘Œc}Scc}w©N)Úord)Ú byte_stringÚbs úB/opt/nydus/tmp/pip-target-dhtdbchl/lib/python/asn1crypto/_types.pyÚ bytes_to_listr s€Ù +Ó,¡ ˜1”�A•  Ñ,Ð,ùÒ,s…có—t|g«Sr )Úbytes)Únums r Úchr_clsrs€Ü�c�U‹|ÐócóÊ—tj|«r|}n |j}|jt ddg«vr |j S|j›d|j ›�S)z¼ Returns a user-readable name for the type of an object :param value: A value to get the type name of :return: A unicode string of the object's type name ÚbuiltinsÚ __builtin__Ú.)ÚinspectÚisclassÚ __class__Ú __module__ÚsetÚ__name__)ÚvalueÚclss r Ú type_namer sQ€ô‡��uÔØ‰à�o‰oˆØ ‡~�~œ˜j¨-Ð8Ó9Ñ9Ø�|‰|ÐØ—n“n c§l¢lÐ 3Ð3r)Ú __future__rrrrrÚsysÚ version_infoÚunicodeÚstr_clsÚstrÚbyte_clsÚintÚlongÚ int_typesrÚchrrrÚlistr ©rr Úr.seðçRÓRãÛ ð×Ñ�dÒØ€GØ€HØ�d� €Iò-ð€Gó4ð€GØ€HØ€Ià€Mòó4r__pycache__/algos.cpython-312.pyc000064400000100677152572326550012613 0ustar00Ë uÉþiŒãóÄ—dZddlmZmZmZmZddlmZddlm Z ddl m Z m Z ddl mZmZmZmZmZmZmZmZGd„d e«ZGd „d e«ZGd „d e«ZGd„de«ZGd„de«ZGd„dee«ZGd„de«ZGd„de«ZGd„de«ZGd„de«Z Gd„de«Z!Gd„de«Z"Gd „d!ee«Z#Gd"„d#e«Z$Gd$„d%e«Z%Gd&„d'e«Z&Gd(„d)e«Z'Gd*„d+e«Z(Gd,„d-e«Z)Gd.„d/e«Z*Gd0„d1e«Z+Gd2„d3e«Z,Gd4„d5e«Z-Gd6„d7e«Z.Gd8„d9e«Z/Gd:„d;e«Z0Gd<„d=e«Z1Gd>„d?e«Z2Gd@„dAe«Z3GdB„dCe«Z4GdD„dEee«Z5GdF„dGe«Z6GdH„dIe«Z7GdJ„dKe«Z8GdL„dMe«Z9e6e5jtdN<GdO„dPe«Z;GdQ„dRee«Z‰>Ð8Ò 8ؘ Ñ$×+Ñ+ˆDØ�t—‘Ñ&Ø—‘ tÑ,Ð,à � Ñ × #Ñ # t×'7Ñ'7Ñ 7܈Kàrrcó•—tt|� ||«}|dk7r|S|dj|jvr|S|dj t k7r|St«|d<|S)Nrr)Úsuperr!Ú __setitem__r1r2Ú __class__rr)r3ÚkeyÚvalueÚresr9s €rr8z _ForceNullParameters.__setitem___skø€ÜÔ(¨$Ñ;¸CÀÓGˆØ �+Ò ØˆJØ � Ñ × #Ñ #¨4×+;Ñ+;Ñ ;؈JØ � Ñ × 'Ñ '¬4Ò /؈JÜ!›Vˆˆ\ÑØˆ r) rrrÚ__doc__Úsetr2r5Ú_spec_callbacksr8Ú __classcell__)r9s@rr!r!2s7ø„ññò ó €Kò ð Ð&ð€O÷ ð rr!c ó*—eZdZddddddddd d d d d œ Zy)ÚHmacAlgorithmIdÚdes_macÚsha1Úsha224Úsha256Úsha384Úsha512Ú sha512_224Ú sha512_256Úsha3_224Úsha3_256Úsha3_384Úsha3_512) z 1.3.14.3.2.10z1.2.840.113549.2.7z1.2.840.113549.2.8z1.2.840.113549.2.9z1.2.840.113549.2.10z1.2.840.113549.2.11z1.2.840.113549.2.12z1.2.840.113549.2.13z2.16.840.1.101.3.4.2.13z2.16.840.1.101.3.4.2.14z2.16.840.1.101.3.4.2.15z2.16.840.1.101.3.4.2.16N©rrrÚ_maprrrrBrBks-„à"Ø$Ø&Ø&Ø'Ø'Ø+Ø+Ø#-Ø#-Ø#-Ø#-ñ �DrrBcó"—eZdZdefdeddifgZy)Ú HmacAlgorithmrrrTN)rrrrBr rrrrrRrR|s „à �oÐ&Ø �s˜Z¨Ð.Ð/ð�GrrRcóv—eZdZidd“dd“dd“dd“d d “d d “d d“dd“dd“dd“dd“dd“dd“dd“dd“dd “d!d"“Zy#)$ÚDigestAlgorithmIdz1.2.840.113549.2.2Úmd2z1.2.840.113549.2.5Úmd5r'rDr(rEr)rFr*rGr+rHz2.16.840.1.101.3.4.2.5rIz2.16.840.1.101.3.4.2.6rJz2.16.840.1.101.3.4.2.7rKz2.16.840.1.101.3.4.2.8rLz2.16.840.1.101.3.4.2.9rMz2.16.840.1.101.3.4.2.10rNz2.16.840.1.101.3.4.2.11Úshake128z2.16.840.1.101.3.4.2.12Úshake256z2.16.840.1.101.3.4.2.17Ú shake128_lenz2.16.840.1.101.3.4.2.18Ú shake256_lenNrOrrrrTrTƒsÑ„ð Ø˜eð à˜eð ð ˜ð ð ! (ð  ð ! (ð  ð ! (ð  ð ! (ð ð ! ,ð ð ! ,ð ð ! *ð ð ! *ð ð ! *ð ð " :ð ð " :ð ð " :ð ð " >ð! ð" " >ð# �DrrTcó"—eZdZdefdeddifgZy)ÚDigestAlgorithmrrrTN)rrrrTr rrrrr\r\™s!„à Ð'Ð(Ø �s˜Z¨Ð.Ð/ð�Grr\có—eZdZdefdefgZy)Ú DigestInfoÚdigest_algorithmÚdigestN)rrrr\rrrrrr^r^¡s„à ˜_Ð-Ø �;Ðð�Grr^có—eZdZddiZy)ÚMaskGenAlgorithmIdz1.2.840.113549.1.1.8Úmgf1NrOrrrrbrb¨s„à ð �Drrbcó.—eZdZdefdeddifgZdZdeiZy)ÚMaskGenAlgorithmrrrTr-rcN) rrrrbr rr.r\r0rrrrere®s4„à Ð(Ð)Ø �s˜Z¨Ð.Ð/ð€Gð ,€Ià�ð�Jrrecó—eZdZddiZy)Ú TrailerFieldrÚtrailer_field_bcNrOrrrrgrgºs„à Ð ð �DrrgcóV—eZdZdedddidœfdeddddid œdœfd ed d dœfd edddœfgZy)ÚRSASSAPSSParamsÚhash_algorithmrrrD©ÚexplicitÚdefaultÚmask_gen_algorithmrrcr-Ú salt_lengthééÚ trailer_fieldérhN)rrrr\rerrgrrrrrjrjÀs{„ð Ø àØ'¨Ð0ñ ð ð !Ø àà!'Ø#.°Ð"7ññ ð ð Ø àØñ ð ð Ø àØ-ñ ð ð9$�Grrjcó—eZdZidd“dd“dd“dd“dd“d d“d d “d d “dd“dd“dd“dd“dd“dd“dd“dd“dd“ddd d!d"d#d$d%d&d'd(d)d*d+œ ¥Zid'd,“d(d-“dd“dd“d&d.“dd“dd“dd“dd “dd“dd/“d d “dd“dd0“d d “d d1“dd“d2dd3d4d5d6d7d8d9œ¥Zy:);ÚSignedDigestAlgorithmIdz 1.3.14.3.2.3Úmd5_rsaz 1.3.14.3.2.29Úsha1_rsaz1.3.14.7.2.3.1Úmd2_rsaz1.2.840.113549.1.1.2z1.2.840.113549.1.1.4z1.2.840.113549.1.1.5r&Ú sha224_rsar#Ú sha256_rsar$Ú sha384_rsar%Ú sha512_rsaz1.2.840.113549.1.1.10Ú rsassa_pssz1.2.840.10040.4.3Úsha1_dsaz 1.3.14.3.2.13z 1.3.14.3.2.27z2.16.840.1.101.3.4.3.1Ú sha224_dsaz2.16.840.1.101.3.4.3.2Ú sha256_dsaz1.2.840.10045.4.1Ú sha1_ecdsaÚ sha224_ecdsaÚ sha256_ecdsaÚ sha384_ecdsaÚ sha512_ecdsaÚsha3_224_ecdsaÚsha3_256_ecdsaÚsha3_384_ecdsaÚsha3_512_ecdsaÚrsassa_pkcs1v15ÚdsaÚecdsaÚed25519Úed448) ú1.2.840.10045.4.3.1ú1.2.840.10045.4.3.2ú1.2.840.10045.4.3.3ú1.2.840.10045.4.3.4ú2.16.840.1.101.3.4.3.9ú2.16.840.1.101.3.4.3.10ú2.16.840.1.101.3.4.3.11ú2.16.840.1.101.3.4.3.12r"ú1.2.840.10040.4.1ú1.2.840.10045.4ú 1.3.101.112ú 1.3.101.113r˜r™r"r�r‘r’r“r”r•r–r—ršr›)r†r}r‡rˆr‰rŠrŽr�N)rrrrPÚ _reverse_maprrrrvrvès„ð! ؘ ð! à˜ð! ð ˜)ð! ð   ð ! ð   ð ! ð   ð ! ð  ð! ð  ð! ð  ð! ð  ð! ð  ð! ð ˜Zð! ð ˜ð! ð ˜ð! ð ! ,ð! ð ! ,ð!! ð" ˜\ð#! ð$ .Ø-Ø-Ø-Ø"2Ø#3Ø#3Ø#3à 1Ø"Ø"à ØòA! €DðFØ Ð"ðàÐ"ðð Ð)ðð Ð)ð ð Ð1ð ð Ð-ð ð Ð'ðð Ð)ðð Ð*ðð Ð.ðð Ð-ðð Ð-ðð Ð.ðð Ð-ðð Ð-ðð Ð-ð!ð" Ð-ð#ð$.Ø-Ø2Ø3Ø3Ø3Ø Øò3�LrrvcóN—eZdZdefdeddifgZdZdeiZe d„«Z e d„«Z y ) ÚSignedDigestAlgorithmrrrTr-r~c óÜ—|dj}idd“dd“dd“dd“dd“dd“d d“dd“d d “d d “d d “dd “d d “dd“dd“dd“dd“dddddddddœ¥}||vr||Sttd|««‚)zŒ :return: A unicode string of "rsassa_pkcs1v15", "rsassa_pss", "dsa", "ecdsa", "ed25519" or "ed448" rryr‹rwrxrzr{r|r}r~rrŒr€r�r‚r�rƒr„r…rŽr�)r†r‡rˆr‰rŠr�rŽr�z> Signature algorithm not known for %s ©r/Ú ValueErrorr©r3rÚalgo_maps rÚsignature_algoz$SignedDigestAlgorithm.signature_algo4s=€ð˜Ñ%×,Ñ,ˆ ð Ø Ð(ð à Ð(ð ð Ð)ð ð Ð+ð  ð Ð+ð  ð Ð+ð  ð Ð+ð ð Ð0ð ð ˜,ð ð ˜ð ð ˜%ð ð ˜%ð ð �5ð ð ˜'ð ð ˜Gð ð ˜Gð! ð" ˜Gð# ð$$Ø%Ø%Ø%Ø%ØØ Øò3 ˆð6 ˜Ñ ؘIÑ&Ð &äœð ð ó  ó ð rcóú—|dj}idd“dd“dd“dd “d d “d d “dd“dd“dd “dd “dd“dd “dd “dd “dd“dd“dd“}||vr||S|dk(r|dddjSttd|««‚)z­ :return: A unicode string of "md2", "md5", "sha1", "sha224", "sha256", "sha384", "sha512", "sha512_224", "sha512_256" or "shake256" rryrUrwrVrxrDrzrEr{rFr|rGr}rHrr€r�r‚rƒr„r…r†rŽr�rXr~rrkz9 Hash algorithm not known for %s r r¢s rÚ hash_algozSignedDigestAlgorithm.hash_algocs:€ð˜Ñ%×,Ñ,ˆ ð Ø �uð à �uð ð ˜ð ð ˜(ð  ð ˜(ð  ð ˜(ð  ð ˜(ð ð ˜ð ð ˜(ð ð ˜(ð ð ˜&ð ð ˜Hð ð ˜Hð ð ˜Hð ð ˜Hð ð �xð! ð" �Zð# ˆð& ˜Ñ ؘIÑ&Ð &à ˜ Ò $ؘ Ñ%Ð&6Ñ7¸ ÑD×KÑKÐ Käœð ð ó  ó ð rN) rrrrvr rr.rjr0Úpropertyr¤r¦rrrržrž)s]„à Ð-Ð.Ø �s˜Z¨Ð.Ð/ð€Gð ,€Ià�oð€Jðñ, óð, ð\ñ' óñ' rržcó—eZdZdefdefgZy)Ú Pbkdf2SaltÚ specifiedÚ other_sourceN)rrrrrÚ _alternativesrrrr©r©Žs„à �kÐ"Ø Ð,Ð-ð�Mrr©có8—eZdZdefdefdeddifdeddd iifgZy ) Ú Pbkdf2ParamsÚsaltÚiteration_countÚ key_lengthrTÚprfrnrrDN)rrrr©rrRrrrrr®r®•s<„à �ÐØ ˜GÐ$Ø �w ¨TÐ 2Ð3Ø �   ¨K¸Ð+@ÐAÐBð �Grr®có—eZdZddiZy)ÚKdfAlgorithmIdz1.2.840.113549.1.5.12Úpbkdf2NrOrrrr´r´žó„à ð �Drr´có.—eZdZdefdeddifgZdZdeiZy)Ú KdfAlgorithmrrrTr-rµN) rrrr´r rr.r®r0rrrr¸r¸¤s3„à �nÐ%Ø �s˜Z¨Ð.Ð/ð€Gð,€Ià�,ð�Jrr¸có,—eZdZdZdefdefdeddifgZy)Ú DHParameterszn Original Name: DHParameter Source: ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-3.asc section 9 ÚpÚgÚprivate_value_lengthrTN)rrrr=rrrrrrºrº¯s-„ñð ˆgˆØ ˆgˆØ  ¨:°tÐ*<Ð=ð�Grrºcó—eZdZddiZy)ÚKeyExchangeAlgorithmIdz1.2.840.113549.1.3.1ÚdhNrOrrrr¿r¿¼s„à ð �Drr¿có.—eZdZdefdeddifgZdZdeiZy)ÚKeyExchangeAlgorithmrrrTr-rÀN) rrrr¿r rr.rºr0rrrrÂrÂÂs4„à Ð,Ð-Ø �s˜Z¨Ð.Ð/ð€Gð,€Ià ˆlð�JrrÂcó"—eZdZdeddifdefgZy)Ú Rc2ParamsÚrc2_parameter_versionrTÚivN)rrrrrrrrrrÄrÄÍs „à  '¨J¸Ð+=Ð>Ø ˆ{Ðð�GrrÄcó—eZdZddiZy)ÚRc5ParamVersionézv1-0NrOrrrrÈrÈÔs„à ˆFð �DrrÈcó.—eZdZdefdefdefdeddifgZy)Ú Rc5ParamsÚversionÚroundsÚblock_size_in_bitsrÆrTN)rrrrÈrrrrrrrËrËÚs0„à �OÐ$Ø �7ÐØ ˜wÐ'Ø ˆ{˜Z¨Ð.Ð/ð �GrrËcó—eZdZdefdefgZy)Ú Pbes1Paramsr¯Ú iterationsN©rrrrrrrrrrÐrÐãs„à �ÐØ �wÐð�GrrÐcó—eZdZdefdefgZy)Ú CcmParamsÚ aes_nonceÚ aes_icvlenNrÒrrrrÔrÔês„ð �kÐ"Ø �wÐð�GrrÔcó—eZdZddiZy)ÚPSourceAlgorithmIdz1.2.840.113549.1.1.9Ú p_specifiedNrOrrrrØrØós„à  ð �DrrØcó.—eZdZdefdeddifgZdZdeiZy)ÚPSourceAlgorithmrrrTr-rÙN) rrrrØr rr.rr0rrrrÛrÛùs4„à Ð(Ð)Ø �s˜Z¨Ð.Ð/ð€Gð ,€Ià�{ð�JrrÛcóN—eZdZdedddidœfdeddddid œdœfd ed d d d œdœfgZy)ÚRSAESOAEPParamsrkrrrDrlrorrcr-Úp_source_algorithmrqrÙrN)rrrr\rerÛrrrrrÝrÝsk„ð Ø àØ'¨Ð0ñ ð ð !Ø àà!'Ø#.°Ð"7ññ ð ð !Ø àà!.Ø"%ññ ð ð)�GrrÝcó6—eZdZdZdefdefgZed„«Zd„Zy)Ú DSASignaturea  An ASN.1 class for translating between the OS crypto library's representation of an (EC)DSA signature and the ASN.1 structure that is part of various RFCs. Original Name: DSS-Sig-Value Source: https://tools.ietf.org/html/rfc3279#section-2.2.2 ÚrÚscó€—t|dt|«dz«}t|t|«dzd«}|||dœ«S)a Reads a signature from a byte string encoding accordint to IEEE P1363, which is used by Microsoft's BCryptSignHash() function. :param data: A byte string from BCryptSignHash() :return: A DSASignature object rrqN)rárâ)r Úlen)ÚclsÚdatarárâs rÚ from_p1363zDSASignature.from_p13637sF€ô ˜4 ¤# d£)¨q¡.Ð1Ó 2ˆÜ ˜4¤ D£ ¨Q¡ Ð0Ó 1ˆÙ˜ Ñ#Ó$Ð$rcóØ—t|dj«}t|dj«}tt|«t|««}t ||«}t ||«}||zS)zÎ Dumps a signature to a byte string compatible with Microsoft's BCryptVerifySignature() function. :return: A byte string compatible with BCryptVerifySignature() rárâ)r r/Úmaxrär )r3Úr_bytesÚs_bytesÚint_byte_lengths rÚto_p1363zDSASignature.to_p1363Hsc€ô˜t C™y×/Ñ/Ó0ˆÜ˜t C™y×/Ñ/Ó0ˆäœc '›l¬C°«LÓ9ˆÜ˜W oÓ6ˆÜ˜W oÓ6ˆà˜Ñ Ð rN) rrrr=rrÚ classmethodrçrírrrràrà(s7„ñð ˆgˆØ ˆgˆð€Gð ñ%óð%ó !rràc óú—eZdZidd“dd“dd“dd“d d “d d “d d“dd“dd“dd“dd“dd“dd“dd“dd“dd “d!d"“id#d$“d%d&“d'd(“d)d*“d+d,“d-d.“d/d0“d1d2“d3d4“d5d6“d7d8“d9d:“d;d<“d=d>“d?d@“dAdB“dCdD“¥dEdFdGdHdIdJdKdLdMdNdOœ ¥ZyP)QÚEncryptionAlgorithmIdz 1.3.14.3.2.7Údesz1.2.840.113549.3.7Útripledes_3keyz1.2.840.113549.3.2Úrc2z1.2.840.113549.3.4Úrc4z1.2.840.113549.3.9Úrc5z2.16.840.1.101.3.4.1.1Ú aes128_ecbz2.16.840.1.101.3.4.1.2Ú aes128_cbcz2.16.840.1.101.3.4.1.3Ú aes128_ofbz2.16.840.1.101.3.4.1.4Ú aes128_cfbz2.16.840.1.101.3.4.1.5Ú aes128_wrapz2.16.840.1.101.3.4.1.6Ú aes128_gcmz2.16.840.1.101.3.4.1.7Ú aes128_ccmz2.16.840.1.101.3.4.1.8Úaes128_wrap_padz2.16.840.1.101.3.4.1.21Ú aes192_ecbz2.16.840.1.101.3.4.1.22Ú aes192_cbcz2.16.840.1.101.3.4.1.23Ú aes192_ofbz2.16.840.1.101.3.4.1.24Ú aes192_cfbz2.16.840.1.101.3.4.1.25Ú aes192_wrapz2.16.840.1.101.3.4.1.26Ú aes192_gcmz2.16.840.1.101.3.4.1.27Ú aes192_ccmz2.16.840.1.101.3.4.1.28Úaes192_wrap_padz2.16.840.1.101.3.4.1.41Ú aes256_ecbz2.16.840.1.101.3.4.1.42Ú aes256_cbcz2.16.840.1.101.3.4.1.43Ú aes256_ofbz2.16.840.1.101.3.4.1.44Ú aes256_cfbz2.16.840.1.101.3.4.1.45Ú aes256_wrapz2.16.840.1.101.3.4.1.46Ú aes256_gcmz2.16.840.1.101.3.4.1.47Ú aes256_ccmz2.16.840.1.101.3.4.1.48Úaes256_wrap_padz1.2.840.113549.1.5.13Úpbes2z1.2.840.113549.1.5.1Ú pbes1_md2_desz1.2.840.113549.1.5.3Ú pbes1_md5_desz1.2.840.113549.1.5.4Ú pbes1_md2_rc2z1.2.840.113549.1.5.6Ú pbes1_md5_rc2Úpbes1_sha1_desÚpbes1_sha1_rc2Úpkcs12_sha1_rc4_128Úpkcs12_sha1_rc4_40Úpkcs12_sha1_tripledes_3keyÚpkcs12_sha1_tripledes_2keyÚpkcs12_sha1_rc2_128Úpkcs12_sha1_rc2_40Úrsaes_pkcs1v15Ú rsaes_oaep) z1.2.840.113549.1.5.10z1.2.840.113549.1.5.11z1.2.840.113549.1.12.1.1z1.2.840.113549.1.12.1.2z1.2.840.113549.1.12.1.3z1.2.840.113549.1.12.1.4z1.2.840.113549.1.12.1.5z1.2.840.113549.1.12.1.6r"z1.2.840.113549.1.1.7NrOrrrrðrð[sÒ„ð1 ؘð1 àÐ.ð1 ð ˜eð1 ð ˜eð 1 ð ˜eð 1 ð ! ,ð1 ð ! ,ð1 ð ! ,ð1 ð ! ,ð1 ð ! -ð1 ð ! ,ð1 ð ! ,ð1 ð !Ð"3ð1 ð " <ð1 ð " <ð!1 ð" " <ð#1 ð$ " <ñ%1 ð& " =ð'1 ð( " <ð)1 ð* " <ð+1 ð, "Ð#4ð-1 ð. " <ð/1 ð0 " <ð11 ð2 " <ð31 ð4 " <ð51 ð6 " =ð71 ð8 " <ð91 ð: " <ð;1 ð< "Ð#4ð=1 ð@  ðA1 ðB  ðC1 ðD  ðE1 ðF  ðG1 ðH  ñI1 ðJ"2Ø!1à#8Ø#7Ø#?Ø#?Ø#8Ø#7à 0Ø ,òa1 �Drrðc ó8—eZdZdefdeddifgZdZide“de“de“d e “d e“d e“d e“d e“de“de“de “de “de “de “de “de “de “e e e e e e e e e dœ ¥Z ed„«Zed„«Zed„«Zed„«Zed„«Zed„«Zed„«Zed„«Zed „«Zy!)"ÚEncryptionAlgorithmrrrTr-rñròrórõr÷rÿrrørrrürr rrrr) rrrrrrrrrcó:—|dj}|dk(r|dddjS|jd«dk(rJ|jd«dk7r!|jdd«\}}|d k(ry |d k(ry tt d |««‚tt d|««‚)z¼ Returns the name of the key derivation function to use. :return: A unicode from of one of the following: "pbkdf1", "pbkdf2", "pkcs12_kdf" rrrÚkey_derivation_funcÚ.éÿÿÿÿÚ_rÚpbes1Úpbkdf1Úpkcs12Ú pkcs12_kdfú~ Encryption algorithm "%s" does not have a registered key derivation function zw Unrecognized encryption algorithm "%s", can not determine key derivation function ©r/ÚfindÚsplitr¡r)r3Úencryption_algor#s rÚkdfzEncryptionAlgorithm.kdf¸sÉ€ð˜{Ñ+×2Ñ2ˆà ˜gÒ %ؘ Ñ%Ð&;Ñ<¸[ÑI×PÑPÐ Pà × Ñ  Ó $¨Ò *Ø×#Ñ# CÓ(¨BÒ.Ø%4×%:Ñ%:¸3ÀÓ%BÑ"� à" gÒ-Ø#à" hÒ.Ø'äœVðð ó óð ôœð ð ó  ó ð rcó4—|dj}|dk(r|dddddjS|jd«dk(rA|jd«dk7r|jdd «\}}}|Stt d |««‚tt d |««‚) zÒ Returns the HMAC algorithm to use with the KDF. :return: A unicode string of one of the following: "md2", "md5", "sha1", "sha224", "sha256", "sha384", "sha512" rrrr r²r!r"r#rqr(z} Unrecognized encryption algorithm "%s", can not determine key derivation hmac algorithm r))r3r,r#Ú hmac_algos rÚkdf_hmaczEncryptionAlgorithm.kdf_hmacásÅ€ð˜{Ñ+×2Ñ2ˆà ˜gÒ %ؘ Ñ%Ð&;Ñ<¸\ÑJÈ5ÑQÐR]Ñ^×eÑeÐ eà × Ñ  Ó $¨Ò *Ø×#Ñ# CÓ(¨BÒ.Ø"1×"7Ñ"7¸¸QÓ"?‘��9˜aØ Ð äœVðð ó óð ôœð ð ó  ó ð rcól—|dj}|dk(r=|dddd}|jdk(rttd««‚|jS|j d«d k(r;|j d «d k7r|ddjSttd |««‚ttd |««‚) zu Returns the byte string to use as the salt for the KDF. :return: A byte string rrrr r¯r«zÛ Can not determine key derivation salt - the reserved-for-future-use other source salt choice was specified in the PBKDF2 params structure r!r"r#r(zs Unrecognized encryption algorithm "%s", can not determine key derivation salt )r/Únamer¡rr*)r3r,r¯s rÚkdf_saltzEncryptionAlgorithm.kdf_saltsá€ð˜{Ñ+×2Ñ2ˆà ˜gÒ %ؘ Ñ%Ð&;Ñ<¸\ÑJÈ6ÑRˆDà�y‰y˜NÒ*Ü ¤ðó"óðð—;‘;Ð à × Ñ  Ó $¨Ò *Ø×#Ñ# CÓ(¨BÒ.ؘLÑ)¨&Ñ1×8Ñ8Ð8äœVðð ó óð ôœð ð ó  ó ð rcó"—|dj}|dk(r|ddddjS|jd«dk(r;|jd«dk7r|dd jSttd |««‚ttd |««‚) z{ Returns the number of iterations that should be run via the KDF. :return: An integer rrrr r°r!r"r#rÑr(zy Unrecognized encryption algorithm "%s", can not determine key derivation iterations )r/r*r¡r©r3r,s rÚkdf_iterationsz"EncryptionAlgorithm.kdf_iterations2s¸€ð˜{Ñ+×2Ñ2ˆà ˜gÒ %ؘ Ñ%Ð&;Ñ<¸\ÑJÐK\Ñ]×dÑdÐ dà × Ñ  Ó $¨Ò *Ø×#Ñ# CÓ(¨BÒ.ؘLÑ)¨,Ñ7×>Ñ>Ð>äœVðð ó óð ôœð ð ó  ó ð rc óÈ—|dj}|dddk(r ddddœ|dd Sd dd œ}||vr||S|d k(r?|d dj}dd ddœ}||vr||S|dk\r|S|€yttd««‚|dk(r.|d dd dj}|�|S|d djS|j d«dk(rd d d d d d dddddddœ |Sttd|««‚)aî Returns the key length to pass to the cipher/kdf. The PKCS#5 spec does not specify a way to store the RC5 key length, however this tends not to be a problem since OpenSSL does not support RC5 in PKCS#8 and OS X does not provide an RC5 cipher for use in the Security Transforms library. :raises: ValueError - when the key length can not be determined :return: An integer representing the length in bytes rrrtÚaesrÉéé ©Úaes128_Úaes192_Úaes256_éé)rñròrórrÅé)é éxé:éézw Invalid RC2 parameter version found in EncryptionAlgorithm parameters rr r±Úencryption_schemer!r"© rrrrrrrrrrrrú@ Unrecognized encryption algorithm "%s" )r/r¡rr±r*)r3r,Úcipher_lengthsrÅÚencoded_key_bits_mapr±s rr±zEncryptionAlgorithm.key_lengthTsŸ€ð ˜{Ñ+×2Ñ2ˆà ˜1˜QÐ  5Ò (àØØñð˜a Ð"ñ $ð $ðØ ñ ˆð ˜nÑ ,Ø! /Ñ2Ð 2à ˜eÒ #Ø$(¨Ñ$6Ð7NÑ$O×$VÑ$VÐ !ð ØØñ$Ð ð %Ð(<Ñ<Ø+Ð,AÑBÐBà$¨Ò+Ø,Ð,à$Ð,ØäœVðóóð ð ˜gÒ %ؘlÑ+Ð,AÑBÀ<ÑPÐQ]Ñ^×eÑeˆJØÐ%Ø!Ð!ð˜ Ñ%Ð&9Ñ:×EÑEÐ Eà × Ñ  Ó $¨Ò *à!"Ø!"Ø!"Ø!"Ø"#Ø"#Ø')Ø&'Ø.0Ø.0Ø')Ø&'ñ ðñ ð ôœð ð ó  ó ð rcóê—|dj}|ddtgd¢«vr|ddS|dddk(ry|ddd k(ry|tgd ¢«vry|d k(r|d d jStt d|««‚)zÔ Returns the name of the encryption mode to use. :return: A unicode string from one of the following: "cbc", "ecb", "ofb", "cfb", "wrap", "gcm", "ccm", "wrap_pad" rrr?r;NéÚpbes1_ÚcbcÚpkcs12_)rñròrórõrrrGrI)r/r>Úencryption_moder¡rr5s rrQz#EncryptionAlgorithm.encryption_mode³s¨€ð˜{Ñ+×2Ñ2ˆà ˜1˜QÐ ¤3Ò'HÓ#IÑ IØ" 1 2Ð&Ð &à ˜1˜QÐ  8Ò +Øà ˜1˜QÐ  9Ò ,Øà œcÒ"IÓJÑ JØà ˜gÒ %ؘ Ñ%Ð&9Ñ:×JÑJÐ Jäœð ð ó  ó ð rc ó—|dj}|ddtgd¢«vry|tgd¢«vr|S|dk(ry|d k(r|d d jS|jd «d k(rdddddddddddddœ |St t d|««‚)al Returns the name of the symmetric encryption cipher to use. The key length can be retrieved via the .key_length property to disabiguate between different variations of TripleDES, AES, and the RC* ciphers. :return: A unicode string from one of the following: "rc2", "rc5", "des", "tripledes", "aes" rrr?r;r8)rñrórõròÚ tripledesrrrGr!r"rñrórôrHrI)r/r>Úencryption_cipherr*r¡rr5s rrTz%EncryptionAlgorithm.encryption_cipherÕsÖ€ð˜{Ñ+×2Ñ2ˆà ˜1˜QÐ ¤3Ò'HÓ#IÑ IØà œcÒ"7Ó8Ñ 8Ø"Ð "à Ð.Ò .Øà ˜gÒ %ؘ Ñ%Ð&9Ñ:×LÑLÐ Là × Ñ  Ó $¨Ò *à!&Ø!&Ø!&Ø!&Ø"'Ø"'Ø',Ø&+Ø.9Ø.9Ø',Ø&+ñ ðñ ð ôœð ð ó  ó ð rc ó<—|dj}|ddtgd¢«vryddddœ}||vr||S|dk(r|d d jdzS|d k(r|d d jS|jd «dk(rdddddddddddddœ |St t d|««‚)z• Returns the block size of the encryption cipher, in bytes. :return: An integer that is the block size in bytes rrr?r;rÉr@)rñròrórõrrÎrrGr!r"rHrI)r/r>Úencryption_block_sizer*r¡r)r3r,Ú cipher_maps rrVz)EncryptionAlgorithm.encryption_block_sizes€ð˜{Ñ+×2Ñ2ˆà ˜1˜QÐ ¤3Ò'HÓ#IÑ IØðØØñ ˆ ð ˜jÑ (ؘoÑ.Ð .à ˜eÒ #ؘ Ñ%Ð&:Ñ;×BÑBÀaÑGÐ Gà ˜gÒ %ؘ Ñ%Ð&9Ñ:×PÑPÐ Pà × Ñ  Ó $¨Ò *à!"Ø!"Ø!"Ø!"Ø"#Ø"#Ø'(Ø&'Ø./Ø./Ø'(Ø&'ñ ðñ ð ôœð ð ó  ó ð rcó$—|dj}|tddg«vr|ddjStgd¢«}||vr|djS|dk(r|ddjS|jd «d k(ry t t d |««‚) a Returns the byte string of the initialization vector for the encryption scheme. Only the PBES2 stores the IV in the params. For PBES1, the IV is derived from the KDF and this property will return None. :return: A byte string or None rrórõrrÆ)rñròr÷rÿrrørrrrGr!r"NrI)r/r>Ú encryption_ivr*r¡r)r3r,Úoctet_string_iv_oidss rrYz!EncryptionAlgorithm.encryption_iv9s¾€ð˜{Ñ+×2Ñ2ˆà œc 5¨% .Ó1Ñ 1ؘ Ñ% dÑ+×2Ñ2Ð 2ô #ò $ ó Ðð Ð2Ñ 2ؘ Ñ%×,Ñ,Ð ,à ˜gÒ %ؘ Ñ%Ð&9Ñ:×HÑHÐ Hð × Ñ  Ó $¨Ò *Øäœð ð ó  ó ð rN)rrrrðr rr.rrÄrËrÔrÐrÝr0r§r-r0r3r6r±rQrTrVrYrrrrr�sØ„à Ð+Ð,Ø �s˜Z¨Ð.Ð/ð€Gð ,€IðØ ˆ{ðà˜+ðð ˆyðð ˆyð ð �kð ð �kð ð �kðð �kðð �kðð �kðð �iðð �iðð �iðð ˜ð!ð" ˜ð#ð$ ˜ð%ð& ˜ð'ð(&Ø%à*Ø)Ø&1Ø&1Ø*Ø)à%ò=€JðBñ& óð& ðPñ! óð! ðFñ* óð* ðXñ óð ðBñ\ óð\ ð|ñ óð ðBñ. óð. ð`ñ0 óð0 ðdñ- óñ- rrcó—eZdZdefdefgZy)Ú Pbes2Paramsr rGN)rrrr¸rrrrrr\r\js„à   Ð-Ø Ð1Ð2ð�Grr\có—eZdZdefdefgZy)Ú Pbmac1Paramsr Úmessage_auth_schemeN)rrrr¸rRrrrrr^r^qs„à   Ð-Ø   Ð.ð�Grr^có—eZdZddiZy)Ú Pkcs5MacIdz1.2.840.113549.1.5.14Úpbmac1NrOrrrraraxr¶rracó(—eZdZdefdefgZdZdeiZy)ÚPkcs5MacAlgorithmrrr-rbN) rrrrar rr.r^r0rrrrdrd~s,„à �jÐ!Ø �sÐð€Gð ,€Ià�,ð�Jrrdrcó—eZdZiZd„Zy)ÚAnyAlgorithmIdcóª—|jj}tttfD])}|jj «D] \}}|||<Œ Œ+y©N)r9rPrðrvrTÚitems)r3rPÚ other_clsÚoidr2s rÚ_setupzAnyAlgorithmId._setup�sI€Ø�~‰~×"Ñ"ˆÜ/Ô1HÔJ[Ó\ˆIØ&Ÿ^™^×1Ñ1Ö3‘ ��TØ ��S’ ñ4ñ]rN)rrrrPrlrrrrfrf�s „Ø €Dó!rrfcó0—eZdZdefdeddifgZdZiZd„Zy)ÚAnyAlgorithmIdentifierrrrTr-cóÊ—tj|«|jj}tt fD])}|jj «D] \}}|||<Œ Œ+yrh)rrlr9r0rržri)r3ÚspecsrjrkÚspecs rrlzAnyAlgorithmIdentifier._setup sT€Ü�‰˜ÔØ—‘×)Ñ)ˆÜ-Ô/DÓEˆIØ&×1Ñ1×7Ñ7Ö9‘ ��TØ!��c’ ñ:ñFrN) rrrrfr rr.r0rlrrrrnrn—s1„à �nÐ%Ø �s˜Z¨Ð.Ð/ð€Gð ,€IØ€Jó"rrnN)=r=Ú __future__rrrrÚ_errorsrÚ_intr Úutilr r Úcorer r rrrrrrrÚobjectr!rBrRrTr\r^rbrergrjrvržr©r®r´r¸rºr¿rÂrÄrÈrËrÐrÔrØrÛrÝràrðrr\r^rardr0rfrnrrrÚrxsðñ÷$SÓRåÝß.÷ ÷ ó ô"˜(ôô6˜6ô6ôrÐ&ôô"�HôôÐ(ôô,Ð*¨Hôô�ôôÐ)ôô �xô ô�7ôô %�hô%ôP>Ð.ô>ôBb Ð0°(ôb ôJ�ôô�8ôôÐ%ôô �8ôô �8ô ôÐ-ôô ˜8ôô�ôô�gôô �ôô�(ôô�ôôÐ)ôô �xô ô �hô ôF0!�8ô0!ôf2Ð,ô2ôjW Ð.°ôW ôt�(ôô�8ôôÐ!ôô ˜ô ð+6Ð×јwÑ'ô!Ð%ô!ô"Ð1°8õ"r__pycache__/cms.cpython-312.pyc000064400000101064152572326550012257 0ustar00Ë uÉþi€lã ó" —dZddlmZmZmZmZ ddlZddlm Z m Z m Z m Z m Z mZmZmZddlmZmZmZmZmZmZmZmZmZmZmZmZmZmZm Z ddl!m"Z"ddl#m$Z$dd l%m&Z&dd l'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-Gd „d e«Z.Gd „de«Z/Gd„de«Z0Gd„de«Z1Gd„de«Z2Gd„de«Z3Gd„de«Z4Gd„de«Z5Gd„de«Z6Gd„de«Z7Gd„d e«Z8Gd!„d"e«Z9Gd#„d$e«Z:Gd%„d&e«Z;Gd'„d(e«Z<Gd)„d*e«Z=Gd+„d,e«Z>Gd-„d.e«Z?Gd/„d0e«Z@Gd1„d2e«ZAGd3„d4e«ZBGd5„d6e«ZCGd7„d8e«ZDGd9„d:e«ZEGd;„de«ZGGd?„d@e«ZHGdA„dBe«ZIGdC„dDe«ZJGdE„dFe«ZKGdG„dHe«ZLGdI„dJe«ZMGdK„dLe«ZNGdM„dNe«ZOGdO„dPe«ZPGdQ„dRe«ZQGdS„dTe«ZRGdU„dVe«ZSGdW„dXe«ZTGdY„dZe«ZUGd[„d\e«ZVGd]„d^e«ZWGd_„d`e«ZXGda„dbe«ZYGdc„dde«ZZGde„dfe«Z[Gdg„dhe«Z\Gdi„dje«Z]Gdk„dle«Z^Gdm„dne«Z_Gdo„dpe«Z`Gdq„dre«ZaGds„dte«ZbGdu„dve«ZcGdw„dxe«ZdGdy„dze«ZeGd{„d|e«ZfGd}„d~e«ZgGd„d€e«ZhGd�„d‚e«ZiGdƒ„d„e«ZjGd…„d†e«ZkGd‡„dˆe«ZlGd‰„dŠe«ZmGd‹„dŒe«ZnGd�„dŽe«ZoGd�„d�e«ZpGd‘„d’e«ZqGd“„d”e«ZrGd•„d–e«ZsGd—„d˜e«ZtGd™„dše e«ZuGd›„dœe«ZvGd�„dže«ZwGdŸ„d e«ZxGd¡„d¢e«ZyGd£„d¤e«ZzGd¥„d¦e«Z{Gd§„d¨e«Z|Gd©„dªe«Z}Gd«„d¬e«Z~Gd­„d®e«ZGd¯„d°e«Z€Gd±„d²e«Z�Gd³„d´e«Z‚Gdµ„d¶e«ZƒGd·„d¸e«Z„Gd¹„dºe«Z…Gd»„d¼e«Z†Gd½„d¾e«Z‡Gd¿„dÀe«ZˆGdÁ„dÂe«Z‰GdÄdÄe«ZŠGdÅ„dÆe«Z‹GdÇ„dÈe«ZŒGdÉ„dÊe«Z�GdË„d¢e«ZyGdÌ„dÍe«ZŽGd΄dÏe«Z�GdЄdÑe«Z�GdÒ„dÓe«Z‘GdÔ„dÕe«Z’eeqe…e†e‡eˆe‰e�eŠdÖœ ec_“eqe…e†e‡eˆe‰e�eŠdלee_“e5e6e7epede9edede�e’dØœ e:_“y#e$rdZY�ŒùwxYw)Ùaë ASN.1 type classes for cryptographic message syntax (CMS). Structures are also compatible with PKCS#7. Exports the following items: - AuthenticatedData() - AuthEnvelopedData() - CompressedData() - ContentInfo() - DigestedData() - EncryptedData() - EnvelopedData() - SignedAndEnvelopedData() - SignedData() Other type classes are defined that help compose the types listed above. Most CMS structures in the wild are formatted as ContentInfo encapsulating one of the other types. é)Úunicode_literalsÚdivisionÚabsolute_importÚprint_functionNé)Ú_ForceNullParametersÚDigestAlgorithmÚEncryptionAlgorithmÚEncryptionAlgorithmIdÚ HmacAlgorithmÚ KdfAlgorithmÚRSAESOAEPParamsÚSignedDigestAlgorithm)ÚAnyÚ BitStringÚChoiceÚ EnumeratedÚGeneralizedTimeÚIntegerÚObjectIdentifierÚOctetBitStringÚ OctetStringÚParsableOctetStringÚSequenceÚ SequenceOfÚSetOfÚUTCTimeÚ UTF8String)ÚCertificateList)Ú PublicKeyInfo)Ú OCSPResponse)Ú AttributesÚ CertificateÚ ExtensionsÚ GeneralNameÚ GeneralNamesÚNamecó"—eZdZdefdefdefgZy)ÚExtendedCertificateInfoÚversionÚ certificateÚ attributesN)Ú__name__Ú __module__Ú __qualname__rr#r"Ú_fields©óú?/opt/nydus/tmp/pip-target-dhtdbchl/lib/python/asn1crypto/cms.pyr)r)As!„à �GÐØ ˜ Ð$Ø �zÐ"ð�Gr2r)có"—eZdZdefdefdefgZy)ÚExtendedCertificateÚextended_certificate_infoÚsignature_algorithmÚ signatureN)r-r.r/r)rrr0r1r2r3r5r5Is#„à $Ð&=Ð>Ø Ð 5Ð6Ø �nÐ%ð�Gr2r5có—eZdZdddddddœZy) Ú CMSVersionÚv0Úv1Úv2Úv3Úv4Úv5©rrééééN©r-r.r/Ú_mapr1r2r3r:r:Ws„à Ø Ø Ø Ø Ø ñ  �Dr2r:c ó&—eZdZddddddddd d d œ Zy ) ÚCMSAttributeTypeÚ content_typeÚmessage_digestÚ signing_timeÚcounter_signatureÚsmime_capabilitiesÚencrypt_key_prefÚsignature_time_stamp_tokenÚcms_algorithm_protectionÚmicrosoft_nested_signatureÚmicrosoft_time_stamp_token) z1.2.840.113549.1.9.3z1.2.840.113549.1.9.4z1.2.840.113549.1.9.5z1.2.840.113549.1.9.6z1.2.840.113549.1.9.15z1.2.840.113549.1.9.16.2.11z1.2.840.113549.1.9.16.2.14z1.2.840.113549.1.9.52z1.3.6.1.4.1.311.2.4.1z1.3.6.1.4.1.311.3.3.1NrFr1r2r3rIrIbs)„à .Ø 0Ø .Ø 3à!5à&8à&Bà!;à!=ð ">ñ) �Dr2rIcó—eZdZdefdefgZy)ÚTimeÚutc_timeÚgeneralized_timeN)r-r.r/rrÚ _alternativesr1r2r3rUrU{s„à �WÐØ ˜_Ð-ð�Mr2rUc ó$—eZdZddddddddd d œ Zy ) Ú ContentTypeÚdataÚ signed_dataÚenveloped_dataÚsigned_and_enveloped_dataÚ digested_dataÚencrypted_dataÚauthenticated_dataÚcompressed_dataÚauthenticated_enveloped_data) z1.2.840.113549.1.7.1z1.2.840.113549.1.7.2z1.2.840.113549.1.7.3z1.2.840.113549.1.7.4z1.2.840.113549.1.7.5z1.2.840.113549.1.7.6z1.2.840.113549.1.9.16.1.2z1.2.840.113549.1.9.16.1.9z1.2.840.113549.1.9.16.1.23NrFr1r2r3rZrZ‚s$„à &Ø -Ø 0Ø ;Ø /Ø 0Ø%9Ø%6Ø&Dñ �Dr2rZcó2—eZdZdefdedddœfdedddœfgZy) ÚCMSAlgorithmProtectionÚdigest_algorithmr7rT©ÚimplicitÚoptionalÚ mac_algorithmrBN)r-r.r/r rr r0r1r2r3rere�s1„à ˜_Ð-Ø Ð 5ÀAÐSWÑ7XÐYØ ˜-°aÀTÑ)JÐKð�Gr2recó—eZdZeZy)ÚSetOfContentTypeN)r-r.r/rZÚ _child_specr1r2r3rlrl˜ó„Ø�Kr2rlcó—eZdZeZy)ÚSetOfOctetStringN)r-r.r/rrmr1r2r3rprpœrnr2rpcó—eZdZeZy)Ú SetOfTimeN)r-r.r/rUrmr1r2r3rrrr s„Ø�Kr2rrcó—eZdZeZy)ÚSetOfAnyN)r-r.r/rrmr1r2r3rtrt¤s„Ø�Kr2rtcó—eZdZeZy)ÚSetOfCMSAlgorithmProtectionN)r-r.r/rermr1r2r3rvrv¨s„Ø(�Kr2rvcó*—eZdZdefdgZiZd„ZdeiZy)Ú CMSAttributeÚtype©ÚvaluesNcó\—|jj|djt«S©Nry©Ú _oid_specsÚgetÚnativert©Úselfs r3Ú _values_speczCMSAttribute._values_spec´ó#€Ø�‰×"Ñ" 4¨¡<×#6Ñ#6¼ÓAÐAr2r{N)r-r.r/rIr0rr„Ú_spec_callbacksr1r2r3rxrx¬s0„à Ð!Ð"Øð€Gð €JòBð �,ð�Or2rxcó—eZdZeZy)Ú CMSAttributesN)r-r.r/rxrmr1r2r3rˆrˆ¼ó„Ø�Kr2rˆcó(—eZdZdefdefdeddifgZy)Ú IssuerSerialÚissuerÚserialÚ issuer_uidriTN)r-r.r/r&rrr0r1r2r3r‹r‹Às(„à �<Ð Ø �7ÐØ �~¨ °DÐ'9Ð:ð�Gr2r‹có—eZdZdddœZy)ÚAttCertVersionr<r=)rrNrFr1r2r3r�r�Ès„à Ø ñ �Dr2r�có(—eZdZdeddifdeddifgZy)ÚAttCertSubjectÚbase_certificate_idÚexplicitrÚ subject_namerN)r-r.r/r‹r&rXr1r2r3r’r’Ïs%„à   ¨z¸1¨oÐ>Ø ˜¨ °A Ð7ð�Mr2r’có—eZdZdefdefgZy)ÚAttCertValidityPeriodÚnot_before_timeÚnot_after_timeN)r-r.r/rr0r1r2r3r—r—Ös„à ˜OÐ,Ø ˜?Ð+ð�Gr2r—c óX—eZdZdeddifdefdefdefdefdefd e fd e d d ifd e d d ifg Z y)ÚAttributeCertificateInfoV1r*Údefaultr<ÚsubjectrŒr8Ú serial_numberÚatt_cert_validity_periodr,Úissuer_unique_idriTÚ extensionsN) r-r.r/r�r’r&rrr—r"rr$r0r1r2r3r›r›Ýsh„à �N Y°Ð$5Ð6Ø �NÐ#Ø �<Ð Ø Ð+Ð,Ø ˜'Ð"Ø #Ð%:Ð;Ø �zÐ"Ø ˜^¨j¸$Ð-?Ð@Ø �z J°Ð#5Ð6ð �Gr2r›có"—eZdZdefdefdefgZy)ÚAttributeCertificateV1Úac_infor7r8N)r-r.r/r›rrr0r1r2r3r£r£ës#„à Ð.Ð/Ø Ð 5Ð6Ø �nÐ%ð�Gr2r£có—eZdZddddœZy)ÚDigestedObjectTypeÚ public_keyÚpublic_key_certÚother_objy_types)rrrBNrFr1r2r3r¦r¦ós„à Ø Ø ñ �Dr2r¦có.—eZdZdefdeddifdefdefgZy)ÚObjectDigestInfoÚdigested_object_typeÚother_object_type_idriTrfÚ object_digestN)r-r.r/r¦rr rr0r1r2r3r«r«ûs2„à Ð!3Ð4Ø Ð!1°JÀÐ3EÐFØ ˜_Ð-Ø ˜.Ð)ð �Gr2r«có:—eZdZdedddœfdedddœfdedddœfgZy ) ÚHolderr“rTrgÚ entity_namerÚobject_digest_inforBN)r-r.r/r‹r&r«r0r1r2r3r°r°s7„à   ¸1È$Ñ.OÐPØ ˜ °1À$Ñ&GÐHØ Ð/¸aÈTÑ1RÐSð�Gr2r°có8—eZdZdeddifdedddœfdedddœfgZy ) ÚV2FormÚ issuer_nameriTr“r©r”rir²rN)r-r.r/r&r‹r«r0r1r2r3r´r´ s7„à ˜  z°4Ð&8Ð9Ø   ¸1È$Ñ.OÐPØ Ð/¸aÈTÑ1RÐSð�Gr2r´có"—eZdZdefdeddifgZy)Ú AttCertIssuerÚv1_formÚv2_formrhrN)r-r.r/r&r´rXr1r2r3r¸r¸s„à �LÐ!Ø �F˜Z¨˜OÐ,ð�Mr2r¸có"—eZdZdefdefdefgZy)Ú IetfAttrValueÚoctetsÚoidÚstringN)r-r.r/rrrrXr1r2r3r¼r¼s"„à �;ÐØ Ð Ð!Ø �:Ðð�Mr2r¼có—eZdZeZy)ÚIetfAttrValuesN)r-r.r/r¼rmr1r2r3rÁrÁ#ó„Ø�Kr2rÁcó$—eZdZdedddœfdefgZy)ÚIetfAttrSyntaxÚpolicy_authorityrTrgr{N)r-r.r/r&rÁr0r1r2r3rÄrÄ's „à ˜\¸ÀtÑ+LÐMØ �>Ð"ð�Gr2rÄcó—eZdZeZy)ÚSetOfIetfAttrSyntaxN)r-r.r/rÄrmr1r2r3rÇrÇ.s„Ø �Kr2rÇcó(—eZdZdefdefdeddifgZy)Ú SvceAuthInfoÚserviceÚidentÚ auth_inforiTN)r-r.r/r%rr0r1r2r3rÉrÉ2s(„à �KÐ Ø �+ÐØ �k J°Ð#5Ð6ð�Gr2rÉcó—eZdZeZy)ÚSetOfSvceAuthInfoN)r-r.r/rÉrmr1r2r3rÎrÎ:r‰r2rÎcó*—eZdZdedddœfdeddifgZy) Ú RoleSyntaxÚrole_authorityrTrgÚ role_namer”rN)r-r.r/r&r%r0r1r2r3rÐrÐ>s&„à ˜<°aÀTÑ)JÐKØ �k J° ?Ð3ð�Gr2rÐcó—eZdZeZy)ÚSetOfRoleSyntaxN)r-r.r/rÐrmr1r2r3rÔrÔEó„Ø�Kr2rÔcó—eZdZdddddddœZy) Ú ClassListÚunmarkedÚ unclassifiedÚ restrictedÚ confidentialÚsecretÚ top_secretrANrFr1r2r3r×r×Is„à Ø Ø Ø Ø Ø ñ  �Dr2r×có(—eZdZdeddifdeddifgZy)ÚSecurityCategoryryrhrÚvaluer”rN©r-r.r/rrr0r1r2r3rßrßTs&„à Ð! J° ?Ð3Ø �#˜  A�Ð'ð�Gr2rßcó—eZdZeZy)ÚSetOfSecurityCategoryN)r-r.r/rßrmr1r2r3rãrã[ó„Ø"�Kr2rãcó<—eZdZdefdededg«ifdeddifgZy) Ú ClearanceÚ policy_idÚ class_listrœrÙÚsecurity_categoriesriTN)r-r.r/rr×Úsetrãr0r1r2r3ræræ_s9„à Ð&Ð'Ø �y 9©c°>Ð2BÓ.CÐ"DÐEØ Ð 5¸ ÀDÐ7IÐJð�Gr2ræcó—eZdZeZy)ÚSetOfClearanceN)r-r.r/rærmr1r2r3rìrìgs„Ø�Kr2rìcó(—eZdZdefdefdeddifgZy)ÚBigTimeÚmajorÚfractional_secondsÚsignriTN)r-r.r/rr0r1r2r3rîrîks(„à �'ÐØ ˜wÐ'Ø �˜: tÐ,Ð-ð�Gr2rîcó—eZdZdefdefgZy)ÚLeapDataÚ leap_timeÚactionN)r-r.r/rîrr0r1r2r3róróss„à �gÐØ �7Ðð�Gr2rócó—eZdZeZy)Ú SetOfLeapDataN)r-r.r/rórmr1r2r3r÷r÷zs„Ø�Kr2r÷có4—eZdZdefdefdefdefdeddifgZy) Ú TimingMetricsÚntp_timeÚoffsetÚdelayÚ expirationÚ leap_eventriTN)r-r.r/rîr÷r0r1r2r3rùrù~s8„à �WÐØ �7ÐØ �'ÐØ �wÐØ �} z°4Ð&8Ð9ð �Gr2rùcó—eZdZeZy)ÚSetOfTimingMetricsN)r-r.r/rùrmr1r2r3rrˆrÂr2rcó8—eZdZdedeifdedddœfdedddœfgZy ) Ú TimingPolicyrçÚspecÚ max_offsetrTr¶Ú max_delayrN)r-r.r/rrrîr0r1r2r3rrŒs7„à �j 6Ð+;Ð"<Ð=Ø �w¨Q¸DÑ AÐBØ �g¨A¸4Ñ@ÐAð�Gr2rcó—eZdZeZy)ÚSetOfTimingPolicyN)r-r.r/rrmr1r2r3rr”r‰r2rc ó"—eZdZddddddddd œZy ) ÚAttCertAttributeTypeÚauthentication_infoÚaccess_identityÚcharging_identityÚgroupÚroleÚ clearanceÚtiming_metricsÚ timing_policy)z1.3.6.1.5.5.7.10.1z1.3.6.1.5.5.7.10.2z1.3.6.1.5.5.7.10.3z1.3.6.1.5.5.7.10.4z2.5.4.72z2.5.4.55z1.3.6.1.4.1.601.10.4.1z1.3.6.1.4.1.601.10.4.2NrFr1r2r3r r ˜s!„à3Ø/Ø1Ø%ØØØ"2Ø"1ñ �Dr2r c ó<—eZdZdefdgZeeeeeee e dœZ d„Z de iZ y)ÚAttCertAttributeryrz)r r r r rrrrcó\—|jj|djt«Sr}r~r‚s r3r„zAttCertAttribute._values_spec¶r…r2r{N)r-r.r/r r0rÎrÇrÔrìrrrr„r†r1r2r3rr¥sJ„à Ð%Ð&Øð€Gð 1Ø,Ø0Ø$ØØ#Ø,Ø*ñ €JòBð �,ð�Or2rcó—eZdZeZy)ÚAttCertAttributesN)r-r.r/rrmr1r2r3rr¾rär2rc óR—eZdZdefdefdefdefdefdefde fde d d ifd e d d ifg Z y ) ÚAttributeCertificateInfoV2r*ÚholderrŒr8ržrŸr,r riTr¡N) r-r.r/r�r°r¸rrr—rrr$r0r1r2r3rrÂsb„à �NÐ#Ø �6ÐØ �=Ð!Ø Ð+Ð,Ø ˜'Ð"Ø #Ð%:Ð;Ø Ð(Ð)Ø ˜^¨j¸$Ð-?Ð@Ø �z J°Ð#5Ð6ð �Gr2rcó&—eZdZdZdefdefdefgZy)ÚAttributeCertificateV2rr¤r7r8N)r-r.r/Ú_bad_tagrrrr0r1r2r3rrÐs*„à€Hð Ð.Ð/Ø Ð 5Ð6Ø �nÐ%ð�Gr2rcó—eZdZdefdefgZy)ÚOtherCertificateFormatÚother_cert_formatÚ other_certNrár1r2r3rrÛs„à Ð.Ð/Ø �sÐð�Gr2rcóX‡—eZdZdefdeddifdeddifdeddifd edd ifgZˆfd „Z ˆxZ S) ÚCertificateChoicesr+Úextended_certificaterhrÚ v1_attr_certrÚ v2_attr_certrBÚotherrCcóì•—tt|� |||«|jdk(rOtj t j |«dj««jdk(rd|_yyy)aJ Ensures that the class and tag specified exist as an alternative. This custom version fixes parsing broken encodings there a V2 attribute # certificate is encoded as a V1 :param class_: The integer class_ from the encoded value header :param tag: The integer tag from the encoded value header :param contents: A byte string of the contents of the value - used when the object is explicitly tagged :raises: ValueError - when value is not a valid alternative rBrr=rCN) Úsuperr"ÚvalidateÚ_choicer�ÚloadrÚdumpr�)rƒÚclass_ÚtagÚcontentsÚ __class__s €r3r)zCertificateChoices.validateëshø€ô( Ô  $Ñ0°¸¸hÔGØ �<‰<˜1Ò Ü×"Ñ"¤8§=¡=°Ó#:¸1Ñ#=×#BÑ#BÓ#DÓE×LÑLÐPTÒTØ �• ðUð r2) r-r.r/r#r5r£rrrXr)Ú __classcell__)r0s@r3r"r"âsXø„à ˜ Ð$Ø Ð!4°zÀ1°oÐFØ Ð/°*¸a°ÐAØ Ð/°*¸a°ÐAØ Ð(¨:°q¨/Ð:ð €M÷!ð!r2r"có—eZdZeZy)ÚCertificateSetN)r-r.r/r"rmr1r2r3r3r3s„Ø$�Kr2r3có,—eZdZdefdedddœfgZdZiZy)Ú ContentInforJÚcontentrTr¶©rJr6N)r-r.r/rZrr0Ú _oid_pairrr1r2r3r5r5 s,„à ˜Ð%Ø �C a°TÑ:Ð;ð€Gð ,€IØ�Jr2r5có—eZdZeZy)ÚSetOfContentInfoN)r-r.r/r5rmr1r2r3r:r:rnr2r:có,—eZdZdefdedddœfgZdZiZy)ÚEncapsulatedContentInforJr6rTr¶r7N)r-r.r/rZrr0r8rr1r2r3r<r<s-„à ˜Ð%Ø Ð'°aÀTÑ)JÐKð€Gð ,€IØ�Jr2r<có—eZdZdefdefgZy)ÚIssuerAndSerialNumberrŒržN)r-r.r/r'rr0r1r2r3r>r>!s„à �4ÐØ ˜'Ð"ð�Gr2r>có"—eZdZdefdeddifgZy)ÚSignerIdentifierÚissuer_and_serial_numberÚsubject_key_identifierrhrN©r-r.r/r>rrXr1r2r3r@r@(ó „à #Ð%:Ð;Ø ! ;°¸Q°Ð@ð�Mr2r@có—eZdZeZy)ÚDigestAlgorithmsN)r-r.r/r rmr1r2r3rFrF/ó„Ø!�Kr2rFcó—eZdZeZy)ÚCertificateRevocationListsN)r-r.r/rrmr1r2r3rIrI3rGr2rIcó$—eZdZdedddœfdefgZy)Ú SCVPReqResÚrequestrTr¶ÚresponseN)r-r.r/r5r0r1r2r3rKrK7s „à �K¨a¸TÑ!BÐCØ �[Ð!ð�Gr2rKcó—eZdZdddœZy)ÚOtherRevInfoFormatIdÚ ocsp_responseÚscvp)z1.3.6.1.5.5.7.16.2z1.3.6.1.5.5.7.16.4NrFr1r2r3rOrO>s„à-Ø$ñ �Dr2rOcó*—eZdZdefdefgZdZeedœZ y)ÚOtherRevocationInfoFormatÚother_rev_info_formatÚother_rev_info)rTrU)rPrQN) r-r.r/rOrr0r8r!rKrr1r2r3rSrSEs.„à Ð"6Ð7Ø ˜3Ðð€Gð <€Ià%Øñ�Jr2rScó"—eZdZdefdeddifgZy)ÚRevocationInfoChoiceÚcrlr&rhrN)r-r.r/rrSrXr1r2r3rWrWRs „à �Ð Ø Ð+¨j¸!¨_Ð=ð�Mr2rWcó—eZdZeZy)ÚRevocationInfoChoicesN)r-r.r/rWrmr1r2r3rZrZYs„Ø&�Kr2rZc óJ—eZdZdefdefdefdedddœfdefd efd ed ddœfgZ y ) Ú SignerInfor*ÚsidrfÚ signed_attrsrTrgr7r8Úunsigned_attrsrN) r-r.r/r:r@r rˆrrr0r1r2r3r\r\]sQ„à �JÐØ Ð Ð!Ø ˜_Ð-Ø ˜°QÀDÑ(IÐJØ Ð 5Ð6Ø �kÐ"Ø ˜=°qÀdÑ*KÐLð�Gr2r\có—eZdZeZy)Ú SignerInfosN)r-r.r/r\rmr1r2r3rarairÕr2rac óN—eZdZdefdefddedddœfded ddœfd efgZd „Z d e iZ y )Ú SignedDatar*Údigest_algorithms©Úencap_content_infoNÚ certificatesrTrgÚcrlsrÚ signer_infoscó>—|djdk7rtStS©Nr*r<©r�r<r5r‚s r3Ú_encap_content_info_specz#SignedData._encap_content_info_specwó$€ð � ‰?× !Ñ ! TÒ )Ü*Ð *ô Ðr2rfN) r-r.r/r:rFr3rZrar0rmr†r1r2r3rcrcmsX„à �JÐØ Ð.Ð/Ø$Ø ˜°aÀTÑ)JÐKØ Ð&°QÀDÑ(IÐJØ ˜Ð%ð €Gò ð Ð6ð�Or2rccó,—eZdZdedddœfdedddœfgZy)ÚOriginatorInfoÚcertsrTrgrhrN)r-r.r/r3rZr0r1r2r3rprpŠs(„à �.¨q¸dÑ"CÐDØ Ð&°QÀDÑ(IÐJð�Gr2rpcó"—eZdZdefdeddifgZy)ÚRecipientIdentifierrArBrhrNrCr1r2r3rsrs‘rDr2rsc ó:—eZdZddddddddd œZd d d d d dddddœ Zy)ÚKeyEncryptionAlgorithmIdÚrsaes_pkcs1v15Ú rsaes_oaepÚ aes128_wrapÚaes128_wrap_padÚ aes192_wrapÚaes192_wrap_padÚ aes256_wrapÚaes256_wrap_pad)ú1.2.840.113549.1.1.1ú1.2.840.113549.1.1.7ú2.16.840.1.101.3.4.1.5ú2.16.840.1.101.3.4.1.8ú2.16.840.1.101.3.4.1.25ú2.16.840.1.101.3.4.1.28ú2.16.840.1.101.3.4.1.45ú2.16.840.1.101.3.4.1.48r~rr€r�r‚rƒr„r…) Úrsarvrwrxryrzr{r|r}N)r-r.r/rGÚ _reverse_mapr1r2r3ruru˜sE„à 0Ø ,Ø"/Ø"3Ø#0Ø#4Ø#0Ø#4ñ €Dð&Ø0Ø,Ø/Ø3Ø0Ø4Ø0Ø4ñ �Lr2rucó.—eZdZdefdeddifgZdZdeiZy)ÚKeyEncryptionAlgorithmÚ algorithmÚ parametersriT)rŠr‹rwN) r-r.r/rurr0r8rrr1r2r3r‰r‰±s4„à Ð.Ð/Ø �s˜Z¨Ð.Ð/ð€Gð ,€Ià�oð�Jr2r‰có(—eZdZdefdefdefdefgZy)ÚKeyTransRecipientInfor*ÚridÚkey_encryption_algorithmÚ encrypted_keyN)r-r.r/r:rsr‰rr0r1r2r3r�r�½s+„à �JÐØ Ð#Ð$Ø #Ð%;Ð<Ø ˜+Ð&ð �Gr2r�có.—eZdZdefdeddifdeddifgZy)ÚOriginatorIdentifierOrKeyrArBrhrÚoriginator_keyrN)r-r.r/r>rr rXr1r2r3r’r’Æs.„à #Ð%:Ð;Ø ! ;°¸Q°Ð@Ø ˜=¨:°q¨/Ð:ð�Mr2r’có—eZdZdefdefgZy)ÚOtherKeyAttributeÚ key_attr_idÚkey_attrNrár1r2r3r•r•Îs„à Ð(Ð)Ø �SÐð�Gr2r•có.—eZdZdefdeddifdeddifgZy)ÚRecipientKeyIdentifierrBÚdateriTr&N©r-r.r/rrr•r0r1r2r3r™r™Õs0„à ! ;Ð/Ø � :¨tÐ"4Ð5Ø Ð# j°$Ð%7Ð8ð�Gr2r™có"—eZdZdefdeddifgZy)ÚKeyAgreementRecipientIdentifierrAÚr_key_idrhrN)r-r.r/r>r™rXr1r2r3r�r�Ýs!„à #Ð%:Ð;Ø Ð+¨j¸!¨_Ð=ð�Mr2r�có—eZdZdefdefgZy)ÚRecipientEncryptedKeyrŽr�N)r-r.r/r�rr0r1r2r3r r äs„à Ð/Ð0Ø ˜+Ð&ð�Gr2r có—eZdZeZy)ÚRecipientEncryptedKeysN)r-r.r/r rmr1r2r3r¢r¢ës„Ø'�Kr2r¢có<—eZdZdefdeddifdedddœfd efd efgZy ) ÚKeyAgreeRecipientInfor*Ú originatorr”rÚukmrTr¶r�Úrecipient_encrypted_keysN) r-r.r/r:r’rr‰r¢r0r1r2r3r¤r¤ïsA„à �JÐØ Ð0°:¸q°/ÐBØ � ¨!¸Ñ>Ð?Ø #Ð%;Ð<Ø #Ð%;Ð<ð �Gr2r¤có.—eZdZdefdeddifdeddifgZy)Ú KEKIdentifierÚkey_identifierršriTr&Nr›r1r2r3r©r©ùs0„à ˜;Ð'Ø � :¨tÐ"4Ð5Ø Ð# j°$Ð%7Ð8ð�Gr2r©có(—eZdZdefdefdefdefgZy)ÚKEKRecipientInfor*Úkekidr�r�N)r-r.r/r:r©r‰rr0r1r2r3r¬r¬s*„à �JÐØ �-Ð Ø #Ð%;Ð<Ø ˜+Ð&ð �Gr2r¬có0—eZdZdefdedddœfdefdefgZy) ÚPasswordRecipientInfor*Úkey_derivation_algorithmrTrgr�r�N)r-r.r/r:r r‰rr0r1r2r3r¯r¯ s1„à �JÐØ # \ÀÈtÑ3TÐUØ #Ð%;Ð<Ø ˜+Ð&ð �Gr2r¯có—eZdZdefdefgZy)ÚOtherRecipientInfoÚori_typeÚ ori_valueNrár1r2r3r²r²s„à Ð%Ð&Ø �cÐð�Gr2r²cóF—eZdZdefdeddifdeddifdeddifd edd ifgZy ) Ú RecipientInfoÚktriÚkarirhrÚkekrirBÚpwrirCÚorirDN) r-r.r/r�r¤r¬r¯r²rXr1r2r3r¶r¶sN„à Ð&Ð'Ø Ð&¨°Q¨Ð8Ø Ð" Z° OÐ4Ø Ð&¨°Q¨Ð8Ø Ð" Z° OÐ4ð �Mr2r¶có—eZdZeZy)ÚRecipientInfosN)r-r.r/r¶rmr1r2r3r½r½$rÂr2r½có*—eZdZdefdefdedddœfgZy)ÚEncryptedContentInforJÚcontent_encryption_algorithmÚencrypted_contentrTrgN)r-r.r/rZr rr0r1r2r3r¿r¿(s)„à ˜Ð%Ø 'Ð)<Ð=Ø ˜k¸ÀtÑ+LÐMð�Gr2r¿c ó>—eZdZdefdedddœfdefdefded ddœfgZy ) Ú EnvelopedDatar*Úoriginator_inforTrgÚrecipient_infosÚencrypted_content_infoÚunprotected_attrsrN) r-r.r/r:rpr½r¿rˆr0r1r2r3rÃrÃ0s@„à �JÐØ ˜N¸ÈÑ,MÐNØ ˜NÐ+Ø !Ð#7Ð8Ø ˜m¸!ÈÑ-NÐOð �Gr2rÃc óJ—eZdZdefdefdefdefdedddœfd ed ddœfd e fgZ y ) ÚSignedAndEnvelopedDatar*rÅrdrÆrgrTrgrhrriN) r-r.r/r:r½rFr¿r3rIrar0r1r2r3rÉrÉ:sR„à �JÐØ ˜NÐ+Ø Ð.Ð/Ø !Ð#7Ð8Ø ˜°aÀTÑ)JÐKØ Ð+¸!ÈÑ-NÐOØ ˜Ð%ð�Gr2rÉcó2—eZdZdefdefddefgZd„ZdeiZy)Ú DigestedDatar*rfreÚdigestcó>—|djdk7rtStSrkrlr‚s r3rmz%DigestedData._encap_content_info_specNrnr2rfN) r-r.r/r:r rr0rmr†r1r2r3rËrËFs8„à �JÐØ ˜_Ð-Ø$Ø �;Ðð €Gò ð Ð6ð�Or2rËcó*—eZdZdefdefdedddœfgZy)Ú EncryptedDatar*rÆrÇrTrgN)r-r.r/r:r¿rˆr0r1r2r3rÏrÏas)„à �JÐØ !Ð#7Ð8Ø ˜m¸!ÈÑ-NÐOð�Gr2rÏc óf—eZdZdefdedddœfdefdefded ddœfd efd e d ddœfd e fde dddœfg Z y)ÚAuthenticatedDatar*rÄrTrgrÅrjrfrrfÚ auth_attrsrBÚmacÚ unauth_attrsrCN) r-r.r/r:rpr½r r r<rˆrr0r1r2r3rÑrÑisp„à �JÐØ ˜N¸ÈÑ,MÐNØ ˜NÐ+Ø ˜-Ð(Ø ˜_¸1È$Ñ.OÐPð Ð6Ð7Ø �}°1À$Ñ&GÐHØ � ÐØ ˜°QÀDÑ(IÐJð �Gr2rÑc óR—eZdZdefdedddœfdefdefded ddœfd efd ed ddœfgZ y )ÚAuthEnvelopedDatar*rÄrTrgrÅÚauth_encrypted_content_inforÒrrÓrÔrBN) r-r.r/r:rpr½r¿rˆrr0r1r2r3rÖrÖysW„à �JÐØ ˜N¸ÈÑ,MÐNØ ˜NÐ+Ø &Ð(<Ð=Ø �}°1À$Ñ&GÐHØ � ÐØ ˜°QÀDÑ(IÐJð�Gr2rÖcó—eZdZddiZy)ÚCompressionAlgorithmIdz1.2.840.113549.1.9.16.3.8ÚzlibNrFr1r2r3rÙrÙ…s„à# Vð �Dr2rÙcó"—eZdZdefdeddifgZy)ÚCompressionAlgorithmrŠr‹riTN)r-r.r/rÙrr0r1r2r3rÜrÜ‹s!„à Ð,Ð-Ø �s˜Z¨Ð.Ð/ð�Gr2rÜcó6—eZdZdefdefdefgZdZed„«Z y)ÚCompressedDatar*Úcompression_algorithmrfNcó¨—|j€;t€ td«‚tj|ddj«|_|jS)Nz The zlib module is not availablerfr6)Ú _decompressedrÚÚ SystemErrorÚ decompressr�r‚s r3Ú decompressedzCompressedData.decompressed›sM€à × Ñ Ð %܈|Ü!Ð"DÓEÐEÜ!%§¡°Ð6JÑ1KÈIÑ1V×1]Ñ1]Ó!^ˆDÔ Ø×!Ñ!Ð!r2) r-r.r/r:rÜr<r0ráÚpropertyrär1r2r3rÞrÞ’s<„à �JÐØ Ð"6Ð7Ø Ð6Ð7ð€Gð €Mà ñ"óñ"r2rÞcó.—eZdZdefdeddifdeddifgZy)r™ÚsubjectKeyIdentifierršriTr&Nr›r1r2r3r™r™¤s0„à  Ð-Ø � :¨tÐ"4Ð5Ø Ð# j°$Ð%7Ð8ð�Gr2có4—eZdZdeddifdeddifdeddifgZy) ÚSMIMEEncryptionKeyPreferencerArhrÚrecipientKeyIdrÚsubjectAltKeyIdentifierrBN)r-r.r/r>r™r rXr1r2r3réré¬s5„à #Ð%:¸ZȸOÐLØ Ð1°JÀ°?ÐCØ " M°JÀ°?ÐCð�Mr2récó—eZdZeZy)ÚSMIMEEncryptionKeyPreferencesN)r-r.r/rérmr1r2r3rírí´s„Ø.�Kr2rícó"—eZdZdefdeddifgZy)ÚSMIMECapabilityIdentifierÚ capability_idr‹riTN)r-r.r/r rr0r1r2r3rïrï¸s!„à Ð/Ð0Ø �s˜Z¨Ð.Ð/ð�Gr2rïcó—eZdZeZy)ÚSMIMECapabilitesN)r-r.r/rïrmr1r2r3ròrò¿s„Ø+�Kr2ròcó—eZdZeZy)ÚSetOfSMIMECapabilitesN)r-r.r/ròrmr1r2r3rôrôÃrär2rô) r[r\r]r^r_r`rarbrc)r\r]r^r_r`rarbrc) rJrKrLrMrPrQrRrSrOrN)”Ú__doc__Ú __future__rrrrrÚÚ ImportErrorÚalgosrr r r r r rrÚcorerrrrrrrrrrrrrrrrXrÚkeysr Úocspr!Úx509r"r#r$r%r&r'r)r5r:rIrUrZrerlrprrrtrvrxrˆr‹r�r’r—r›r£r¦r«r°r´r¸r¼rÁrÄrÇrÉrÎrÐrÔr×rßrãrærìrîrór÷rùrrrr rrrrrr"r3r5r:r<r>r@rFrIrKrOrSrWrZr\rarcrprsrur‰r�r’r•r™r�r r¢r¤r©r¬r¯r²r¶r½r¿rÃrÉrËrÏrÑrÖrÙrÜrÞrérírïròrôrr1r2r3Úrýs³ðñ÷&SÓRðÛ÷ ÷ ó ÷÷÷÷ñõ"!ÝÝßV×Vô ˜hôô˜(ôô�ôôÐ'ôô2ˆ6ôô Ð"ô ô˜Xôô�uôô�uôô�ôôˆuôô) %ô)ô �8ô ô �Eôô�8ôô�Wôô�Vôô˜Hôô  ô ô˜Xôô˜ôô�xôôˆXôôˆXôô�Fôô�Fôô �Zô ô�Xôô!˜%ô!ô�8ôô˜ôô�ôô�eôô� ôô�xôô#˜Eô#ô�ôô�Uôôˆhôôˆxôô�Eôô�Hôô ˜ô ô�8ôô˜ôô Ð+ô ô�xôô2#˜ ô#ô  ô ô˜Xôô˜Xôô !˜ô !ôF%�Uô%ô�(ôô�uôô˜hôô˜Hôô�vôô"�uô"ô" ô"ô�ôôÐ+ôô  ô ô˜6ôô'˜Eô'ô �ô ô�%ôô�ôô:�Xôô˜&ôôÐ/ôô2 Ð1°8ô ô˜Hôô ôô˜ôô˜Xôô fôô˜Hôô(˜Zô(ô˜Hôô�Hôô�xôô˜Hôô˜ôô�Fôô �Uô ô˜8ôô�Hôô ˜Xô ô�8ôô6�Hôô ˜ô ô ˜ô ôÐ-ôô ˜8ôô"�Xô"ô$˜Xôô 6ôô/ Eô/ô ôô,�zô,ô#˜Eô#ð ØØ#Ø!7Ø!Ø#Ø+Ø%Ø$5ñ € ÔðØ#Ø!7Ø!Ø#Ø+Ø%Ø$5ñ &ÐÔ"ð%Ø&ØØ$Ø"2Ø ;Ø"2Ø"2Ø5Ø/ñ € ÕøðM òØ ƒDðús�TÔTÔ T__pycache__/core.cpython-312.pyc000064400000526230152572326550012433 0ustar00Ë uÉþiÜšã ó†—dZddlmZmZmZmZddlmZmZddlm Z ddl Z ddl Z ddl Z ddl Z ddlZddlmZddlmZdd lmZdd lmZmZmZmZmZdd lmZmZdd lmZm Z m!Z!m"Z"m#Z#m$Z$ejJd kr ddl&m'Z(e)Z*dZ+nddl,m(Z(dZ+ejZ«dddddœZ.dddddddddœZ/dddœZ0e jbd«Z2iZ3d“d„Z4Gd„d e5«Z6Gd!„d"«Z7Gd#„d$e5«Z8Gd%„d&e5«Z9Gd'„d(e6«Z:e:«Z;Gd)„d*e6«Z<Gd+„d,e6«Z=Gd-„d.e5«Z>Gd/„d0e6«Z?Gd1„d2e9e?«Z@Gd3„d4e?«ZAGd5„d6e?e7«ZBGd7„d8e5«ZCGd9„d:eCe9e8e?e7«ZDGd;„deCe9e8e?«ZFGd?„d@e9e8e?«ZGGdA„dBe9e8e?«ZHGdC„dDe9e8e?«ZIGdE„dFeI«ZJGdG„dHe?«ZKGdI„dJe?e7«ZLGdK„dLe?«ZMGdM„dNe?«ZNGdO„dPe?«ZOGdQ„dReB«ZPGdS„dTe@«ZQGdU„dVeL«ZRGdW„dXe6«ZSGdY„dZe6«ZTGd[„d\eS«ZUGd]„d^eT«ZVGd_„d`eS«ZWGda„dbe@«ZXGdc„dde@«ZYGde„dfe@«ZZGdg„dheG«Z[Gdi„dje@«Z\Gdk„dle@«Z]Gdm„dne]«Z^Gdo„dpe]«Z_Gdq„dre@«Z`Gds„dte@«ZaGdu„dve@«ZbGdw„dxe@«ZcGdy„dze@«ZdGd{„d|e@«Zed}„Zfd~„Zgd„Zhd€„Zid�„ZjideA“deB“deD“d‚eG“dƒeK“d„eL“d…eM“d†eN“d‡eO“dˆeP“d‰eW“dŠeQ“d‹eR“dŒeS“d�eU“dŽeX“d�eY“eZe[e\e^e_e`eaebecedeed�œ ¥Zkd”d‘„Zld•d’„Zmy)–a ASN.1 type classes for universal types. Exports the following items: - load() - Any() - Asn1Value() - BitString() - BMPString() - Boolean() - CharacterString() - Choice() - EmbeddedPdv() - Enumerated() - GeneralizedTime() - GeneralString() - GraphicString() - IA5String() - InstanceOf() - Integer() - IntegerBitString() - IntegerOctetString() - Null() - NumericString() - ObjectDescriptor() - ObjectIdentifier() - OctetBitString() - OctetString() - PrintableString() - Real() - RelativeOid() - Sequence() - SequenceOf() - Set() - SetOf() - TeletexString() - UniversalString() - UTCTime() - UTF8String() - VideotexString() - VisibleString() - VOID - Void() Other type classes are defined that help compose the types listed above. é)Úunicode_literalsÚdivisionÚabsolute_importÚprint_function)ÚdatetimeÚ timedelta)ÚFractionNé)Ú_teletex_codec)Úunwrap)Ú OrderedDict)Ú type_nameÚstr_clsÚbyte_clsÚ int_typesÚchr_cls)Ú_parseÚ _dump_header)Ú int_to_bytesÚint_from_bytesÚtimezoneÚextended_datetimeÚcreate_timezoneÚ utc_with_dst)é)ÚStringIOT)ÚBytesIOFÚ universalÚ applicationÚcontextÚprivate)rr érr"r)rrr r!rr r"rÚ primitiveÚ constructed)rr z ^\d+(\.\d+)*$có0—tj||¬«S)a5 Loads a BER/DER-encoded byte string and construct a universal object based on the tag value: - 1: Boolean - 2: Integer - 3: BitString - 4: OctetString - 5: Null - 6: ObjectIdentifier - 7: ObjectDescriptor - 8: InstanceOf - 9: Real - 10: Enumerated - 11: EmbeddedPdv - 12: UTF8String - 13: RelativeOid - 16: Sequence, - 17: Set - 18: NumericString - 19: PrintableString - 20: TeletexString - 21: VideotexString - 22: IA5String - 23: UTCTime - 24: GeneralizedTime - 25: GraphicString - 26: VisibleString - 27: GeneralString - 28: UniversalString - 29: CharacterString - 30: BMPString :param encoded_data: A byte string of BER or DER-encoded data :param strict: A boolean indicating if trailing data should be forbidden - if so, a ValueError will be raised when trailing data exists :raises: ValueError - when strict is True and trailing data is present ValueError - when the encoded value tag a tag other than listed above ValueError - when the ASN.1 header length is longer than the data TypeError - when encoded_data is not a byte string :return: An instance of the one of the universal classes )Ústrict)Ú Asn1ValueÚload)Ú encoded_datar&s ú@/opt/nydus/tmp/pip-target-dhtdbchl/lib/python/asn1crypto/core.pyr(r(ss€ôf �>‰>˜,¨vˆ>Ó 6Ð6ócóª—eZdZdZdZdZdZdZdZdZ dZ dZ dZ dZ edd„«Z dd„Zd„Zd„Zd „Zd „Zd „Zd „Zd „Zd„Zdd„Zd„Zd„Zdd„Zdd„Zy)r'z' The basis of all ASN.1 values NFr+c ó˜—t|t«stdt|«z«‚d}|j�|}t ||||¬«\}}|S)a” Loads a BER/DER-encoded byte string using the current class as the spec :param encoded_data: A byte string of BER or DER-encoded data :param strict: A boolean indicating if trailing data should be forbidden - if so, a ValueError will be raised when trailing data exists :return: An instance of the current class ú*encoded_data must be a byte string, not %sN©ÚspecÚ spec_paramsr&)Ú isinstancerÚ TypeErrorrÚtagÚ _parse_build)Úclsr)r&Úkwargsr0ÚvalueÚ_s r*r(zAsn1Value.loadÏsS€ô ˜,¬Ô1ÜÐHÌ9ÐUaÓKbÑbÓcÐ càˆØ �7‰7Р؈Dä  °4ÀVÐTZÔ[‰ˆˆq؈ r+c óÊ— |jtvrl|j} | j�/t| jdt«r| jf| _t | d«r|j «dt| <|�!t|t«r|€d}||f}|dk(rd}d}|�!t|t«r|€d}||f}|dk(rd}d}|�6|€d}|dk(r||f}n(|dk(r||f}nttdt|«««‚|�Ýt|«d k(rt|d t«r|f}|D]³\}}d} t|t«r |tvr|} n|tvr|} t|}| �ttd t| «««‚|�.t|t«sttd t|«««‚|j€ ||ff|_Œ�|j||ffz|_ŒµnÌ|�x|\}}|tvrttd t|«««‚|�.t|t«sttdt|«««‚t||_||_d|_nR|�4|tvrttdt|«««‚t||_|j€d|_|�||_| �C| t%gd¢«vrttdt| «««‚| dk(rd} n| dk(rd } | |_|rd|_| �| |_y|�|j%|«yy#ttf$r=} | j*d d}| j*ddt|«zzf|z| _| ‚d} ~ wwxYw)a· The optional parameter is not used, but rather included so we don't have to delete it from the parameter dictionary when passing as keyword args :param explicit: An int tag number for explicit tagging, or a 2-element tuple of class and tag. :param implicit: An int tag number for implicit tagging, or a 2-element tuple of class and tag. :param no_explicit: If explicit tagging info should be removed from this instance. Used internally to allow contructing the underlying value that has been wrapped in an explicit tag. :param tag_type: None for normal values, or one of "implicit", "explicit" for tagged values. Deprecated in favor of explicit and implicit params. :param class_: The class for the value - defaults to "universal" if tag_type is None, otherwise defaults to "context". Valid values include: - "universal" - "application" - "context" - "private" Deprecated in favor of explicit and implicit params. :param tag: The integer tag to override - usually this is used with tag_type or class_. Deprecated in favor of explicit and implicit params. :param optional: Dummy parameter that allows "optional" key in spec param dicts :param default: The default value to use if the value is currently None :param contents: A byte string of the encoded contents of the value :param method: The method for the value - no default value since this is normally set on a class. Valid values include: - "primitive" or 0 - "constructed" or 1 :raises: ValueError - when implicit, explicit, tag_type, class_ or tag are invalid values NrÚ_setupTr ÚexplicitÚimplicitzh tag_type must be one of "implicit", "explicit", not %s r"r z¬ explicit class must be one of "universal", "application", "context", "private", not %s zi explicit tag must be an integer, not %s z  implicit class must be one of "universal", "application", "context", "private", not %s za implicit tag must be an integer, not %s z¤ class_ must be one of "universal", "application", "context", "private", not %s )r#rr$r z„ method must be one of "primitive" or "constructed", not %s r#r$ú while constructing %s)Ú __class__Ú_SETUP_CLASSESr<r2rÚhasattrr;Ú ValueErrorr ÚreprÚlenÚCLASS_NUM_TO_NAME_MAPÚCLASS_NAME_TO_NUM_MAPr3rÚclass_r4r=ÚsetÚmethodÚcontentsÚargs)Úselfr<r=Ú no_explicitÚtag_typerGr4ÚoptionalÚdefaultrJrIr6Ú invalid_classÚerKs r*Ú__init__zAsn1Value.__init__ésâ€ðpT Ø�~‰~¤^Ñ3Ø—n‘n�ð—<‘<Ð+´ ¸3¿<¹<ȹ?ÌIÔ0VØ$'§L¡LÐ#3�C”Lܘ3 Ô)Ø—K‘K”MØ&*”˜sÑ#ðÐ#ܘh¬ Ô2Ø�~Ø!*˜Ø &¨Ð1�Hà˜zÒ)Ø#�HØ�CàÐ#ܘh¬ Ô2Ø�~Ø!*˜Ø &¨Ð1�Hà˜zÒ)Ø#�HØ�CðÐ#Ø�>Ø&�FؘzÒ)Ø &¨˜}‘HØ Ò+Ø &¨˜}‘Hä$¤Vðô˜X›ó &óððÐ#ä�x“= AÒ%¬*°X¸a±[Ä)Ô*LØ (˜|�HÛ#+‘K�F˜CØ$(�MÜ! &¬)Ô4Ø!Ô)>Ñ>Ø,2™Mà!Ô)>Ñ>Ø,2˜MÜ!6°vÑ!>˜Ø$Ð0Ü(¬ð ô! Ó/ó *óðð�Ü)¨#¬yÔ9Ü"+¬Fð!$ô!*¨#£ó -ó#ðð —}‘}Ð,Ø*0°#¨Ð(9˜� à(,¯ © ¸&À#¸Ð8IÑ(I˜� ñ9$,ð<Ð%Ø&‘ �˜ØÔ!6Ñ6Ü$¤Vðô˜V› ó &óðð�?Ü% c¬9Ô5Ü'¬ð ô& c›Nó )óðô 4°FÑ;�” Ø�”Ø $�• àÐ%ØÔ%:Ñ:Ü(¬ð ô! ›Ló *óðô#8¸Ñ"?�D”Kà—;‘;Ð&Ø"#�D”Kà�?Ø"�D”HàÐ!ؤÒ%GÓ!HÑHÜ$¤Vðô˜V› ó &óðð˜[Ò(Ø‘Fؘ}Ò,Ø�FØ$�” áØ $�” àÐ#Ø (�• àÐ$Ø—‘˜Õ!ð%øôœIÐ&ò Ø—6‘6˜!˜"�:ˆDØ—f‘f˜Q‘iÐ"?Ä)ÈDÃ/Ñ"QÑQÐSÐVZÑZˆAŒF؈Gûð ús‚K>LÌLÌM"Ì%8MÍM"cóN—tr|j«S|j«S©z² Since str is different in Python 2 and 3, this calls the appropriate method, __unicode__() or __bytes__() :return: A unicode string ©Ú_PY2Ú __bytes__Ú __unicode__©rLs r*Ú__str__zAsn1Value.__str__·ó#€õ Ø—>‘>Ó#Ð #à×#Ñ#Ó%Ð %r+c óâ—tr5dt|«›dt|«›dt|j ««›d�Sdt|«›dt|«›dt|j ««›d�S)ú7 :return: A unicode string Ú<Ú z bÚ>)rWrÚidrCÚdumprZs r*Ú__repr__zAsn1Value.__repr__ÅsN€ö Ü$-¨d¥O´R¸µX¼tÀDÇIÁIÃKÕ?PÐQÐ Qð ô$-¨T¥?´B°tµH¼dÀ4Ç9Á9Ã;Õ>OÐPÐ Pr+có@—|j«jd«S)z€ A fall-back method for print() in Python 2 :return: A byte string of the output of repr() úutf-8)rdÚencoderZs r*rXzAsn1Value.__bytes__Ðs€ð�}‰}‹×%Ñ% gÓ.Ð.r+có"—|j«S)zƒ A fall-back method for print() in Python 3 :return: A unicode string of the output of repr() )rdrZs r*rYzAsn1Value.__unicode__Ús€ð�}‰}‹Ðr+có®—|j«}|j|_|j|_|j|_|j|_|S)z‡ Constructs a new copy of the current object, preserving any tagging :return: An Asn1Value object )r?rGr4r=r<©rLÚnew_objs r*Ú _new_instancezAsn1Value._new_instanceäsC€ð—.‘.Ó"ˆØŸ™ˆŒØ—h‘hˆŒ ØŸ=™=ˆÔØŸ=™=ˆÔ؈r+cóf—|j«}|j|tj«|S)z‡ Implements the copy.copy() interface :return: A new shallow copy of the current Asn1Value object )rlÚ_copyÚcopyrjs r*Ú__copy__zAsn1Value.__copy__ós)€ð×$Ñ$Ó&ˆØ� ‰ �dœDŸI™IÔ&؈r+có‚—|j«}||t|«<|j|tj«|S)zÁ Implements the copy.deepcopy() interface :param memo: A dict for memoization :return: A new deep copy of the current Asn1Value object )rlrbrnroÚdeepcopy©rLÚmemorks r*Ú __deepcopy__zAsn1Value.__deepcopy__ÿs6€ð×$Ñ$Ó&ˆØ ˆŒR�‹X‰Ø� ‰ �dœDŸM™MÔ*؈r+có,—tj|«S)z} Copies the object, preserving any special tagging from it :return: An Asn1Value object ©rorrrZs r*rozAsn1Value.copyó€ô�}‰}˜TÓ"Ð"r+cóЗt|t«s||i}|j|jd«|jd«¬«}|j |t j «|S)a} Copies the object, applying a new tagging to it :param tagging: A dict containing the keys "explicit" and "implicit". Legacy API allows a unicode string of "implicit" or "explicit". :param tag: A integer tag number. Only used when tagging is a unicode string. :return: An Asn1Value object r<r=)r<r=)r2Údictr?Úgetrnrorr)rLÚtaggingr4rks r*ÚretagzAsn1Value.retagsS€ô ˜'¤4Ô(Ø �nˆGØ—.‘.¨'¯+©+°jÓ*AÈGÏKÉKÐXbÓLc�.ÓdˆØ� ‰ �dœDŸM™MÔ*؈r+cóf—|j«}|j|tj«|S)z{ Copies the object, removing any special tagging from it :return: An Asn1Value object )r?rnrorrrjs r*ÚuntagzAsn1Value.untag/s'€ð—.‘.Ó"ˆØ� ‰ �dœDŸM™MÔ*؈r+c óÖ—|j|jk7r(ttdt|«t|«««‚|j|_||j «|_y)a! Copies the contents of another Asn1Value object to itself :param object: Another instance of the same class :param copy_func: An reference of copy.copy() or copy.deepcopy() to use when copying lists, dicts and objects úQ Can not copy values from %s object to %s object N)r?r3r rrJÚ_native©rLÚotherÚ copy_funcs r*rnzAsn1Value._copy;s[€ð �>‰>˜UŸ_™_Ò ,ÜœFðô˜%Ó Ü˜$“ó óð 🙈Œ Ù  §¡Ó/ˆ� r+có’—d|z}t|d«}t||«|r|jj|dz«yt|d«r|jj|dz«yt r>t |jt«r$t|›dt|j«›�«yt|›d|j›�«y)úJ Show the binary data and parsed data in a tree structure ú Úparsedr"Úchosenz Native: bz Native: N) rAÚ _basic_debugr‰ÚdebugrŠrWr2ÚnativerÚprintrC)rLÚ nest_levelÚprefixÚ has_parseds r*rŒzAsn1Value.debugSs–€ð ˜ Ñ"ˆô˜T 8Ó,ˆ ä�V˜TÔ"Ù Ø �K‰K× Ñ ˜j¨1™nÕ -Ü �T˜8Ô $Ø �K‰K× Ñ ˜j¨1™nÕ -åœ  4§;¡;´Ô9ܪV´T¸$¿+¹+Ô5FÐGÕHäªF°D·K²KÐ@ÕAr+cóø—|j}|j�|jdddk(rd}|j�|r¥t|t«r|jrd|_t |j|j |j|j«}|j�2|jD]#\}}t |d|||jz«|z}Œ%||_d|_ |j|z|jzS)á Encodes the value using DER :param force: If the encoded contents already exist, clear them and regenerate to ensure they are in DER format instead of BER format :return: A byte string of the DER-encoded value Néÿÿÿÿó€Trr r+) rJÚ_headerr2Ú ConstructableÚ _indefiniterIrrGr4r<Ú_trailer)rLÚforcerJÚheaderrGr4s r*rczAsn1Value.dumpisØ€ð—=‘=ˆð �<‰<Ð #¨¯ © °R°SÐ(9¸WÒ(D؈Eà �<‰<Ð ¡5ܘ$¤ Ô.°4×3CÒ3CØ�” ä! $§+¡+¨t¯{©{¸D¿H¹HÀdÇmÁmÓTˆFà�}‰}Ð(Ø#'§=¤=‘K�F˜CÜ)¨&°!°S¸&À4Ç=Á=Ñ:PÓQÐTZÑZ‘Fð$1ð"ˆDŒL؈DŒMà�|‰|˜hÑ&¨¯©Ñ6Ð6r+©F) NNFNNNNNNN©N©r )Ú__name__Ú __module__Ú __qualname__Ú__doc__rIrGr4Ú_bad_tagr=r<r–rJr™r‚Ú classmethodr(rSr[rdrXrYrlrpruror}rrnrŒrc©r+r*r'r'©s³„ñð €Fð€Fð €Cð€Hð€Hð€Hð€Gð€Hð€Hð€Gàòóðð2imØDHóLò\ &ò Qò/òò ò òò #óò, ò0ó0Bô,7r+r'có—eZdZdZdZdZd„Zy)ÚValueMapzl Basic functionality that allows for mapping values from ints or OIDs to python unicode strings Ncó¾—|j}|j� |j�yi|_|jj«D]\}}||j|<Œy)ú2 Generates _reverse_map from _map N)r?Ú_mapÚ _reverse_mapÚitems)rLr6Úkeyr8s r*r;zValueMap._setup™sV€ð �n‰nˆØ �8‰8Ð ˜s×/Ñ/Ð;Ø ØˆÔØŸ(™(Ÿ.™.Ö*‰JˆC�Ø&)ˆC× Ñ ˜UÒ #ñ+r+)rŸr r¡r¢rªr«r;r¥r+r*r§r§‹s„ñð €Dð€Ló *r+r§có—eZdZdZd„Zy)ÚCastablez A mixin to handle converting an object between different classes that represent the same encoded value, but with different rules for converting to and from native Python values c ó—|j|jjk7rHttdt |«t |«|j|jj««‚|«}|j |_|j |_|j|_|j|_|j|_ |j|_ t|t«r"|j|_ |j|_|S)a+ Converts the current object into an object of a different class. The new class must use the ASN.1 encoding for the value. :param other_class: The class to instantiate the new object from :return: An instance of the type other_class z� Can not covert a value from %s object to %s object since they use different tags: %d versus %d )r4r?r3r rrGr=r<r–rJr™r2r—rIr˜)rLÚ other_classrks r*Úcastz Castable.cast­sÏ€ð �?‰?˜dŸn™n×0Ñ0Ò 0ÜœFðô˜+Ó&ܘ$“Ø—‘Ø—‘×"Ñ"ó ó ð ñ“-ˆØŸ™ˆŒØŸ=™=ˆÔØŸ=™=ˆÔØŸ,™,ˆŒØŸ=™=ˆÔØŸ=™=ˆÔÜ �dœMÔ *Ø!Ÿ[™[ˆGŒNØ"&×"2Ñ"2ˆGÔ Øˆr+N)rŸr r¡r¢r²r¥r+r*r¯r¯¦s „ñó "r+r¯có8‡—eZdZdZdZd„Zd„Zd„Zˆfd„ZˆxZ S)r—zŒ A mixin to handle string types that may be constructed from chunks contained within an indefinite length BER-encoded container Fcó@—|js|j«Sd}t|j«}d}||krQt |j||j ¬«\}}|€|j «}n||j «z }||krŒQ|€|j«S|S)zc :return: A concatenation of the native values of the contained chunks rN)r0)r˜Ú _as_chunkrDrJr5r?Ú _merge_chunks)rLÚpointerÚ contents_lenÚoutputÚ sub_values r*r¶zConstructable._merge_chunksÜsž€ð ×ÒØ—>‘>Ó#Ð #àˆÜ˜4Ÿ=™=Ó)ˆ Øˆà˜ Ò$ä!-¨d¯m©m¸WÈ4Ï>É>Ô!ZÑ ˆI�w؈~Ø"×0Ñ0Ó2‘à˜)×1Ñ1Ó3Ñ3�ð ˜ Ó$ð ˆ>Ø—>‘>Ó#Ð #àˆ r+có—|jS)a A method to return a chunk of data that can be combined for constructed method values :return: A native Python value that can be added together. Examples include byte strings, unicode strings or tuples. ©rJrZs r*rµzConstructable._as_chunkös€ð�}‰}Ðr+có—|jS)aº Returns a native value that can be round-tripped into .set(), to result in a DER encoding. This differs from .native in that .native is designed for the end use, and may account for the fact that the merged value is further parsed as ASN.1, such as in the case of ParsableOctetString() and ParsableOctetBitString(). :return: A python value that is valid to pass to .set() )r�rZs r*Ú_setable_nativezConstructable._setable_natives€ð�{‰{Ðr+c󆕗tt|� ||«|jr |j |j ««yy)a% Copies the contents of another Constructable object to itself :param object: Another instance of the same class :param copy_func: An reference of copy.copy() or copy.deepcopy() to use when copying lists, dicts and objects N)Úsuperr—rnr˜rHr¾©rLr„r…r?s €r*rnzConstructable._copys;ø€ô Œm˜TÑ(¨° Ô:ð × Ò Ø �H‰H�U×*Ñ*Ó,Õ -ð r+) rŸr r¡r¢r˜r¶rµr¾rnÚ __classcell__©r?s@r*r—r—Òs(ø„ñð€Kòò4 ò ÷.ð.r+r—cóD—eZdZdZdZd„Zd„Zd„Zd„Ze d„«Z d d„Z y ) ÚVoidz› A representation of an optional value that is not present. Has .native property and .dump() method to be compatible with other value classes. r+có4—|j|jk(S)úu :param other: The other Primitive to compare to :return: A boolean rérLr„s r*Ú__eq__z Void.__eq__+s€ð�‰ $§.¡.Ñ0Ð0r+có—y)NFr¥rZs r*Ú __nonzero__zVoid.__nonzero__6s€Ør+có—y©Nrr¥rZs r*Ú__len__z Void.__len__9s€Ør+có—td«S)Nr¥)ÚiterrZs r*Ú__iter__z Void.__iter__<s €Ü�B‹xˆr+có—y©zl The native Python datatype representation of this value :return: None Nr¥rZs r*r�z Void.native?ó€ðr+có—y)r“r+r¥©rLršs r*rcz Void.dumpJs€ðr+Nrœ) rŸr r¡r¢rJrÉrËrÎrÑÚpropertyr�rcr¥r+r*rÅrÅ#s;„ñð €Hò 1òòòðñóðô r+rÅcó^‡—eZdZdZdZd d„Zed„«Zed„«Zd d„Z ˆfd„Z d d„Z ˆxZ S) ÚAnyzü A value class that can contain any value, and allows for easy parsing of the underlying encoded value using a spec. This is normally contained in a Structure that has an ObjectIdentifier field and _oid_pair and _oid_specs defined. Nc ó„—tj|fi|¤Ž |�Xt|t«stt dt |«««‚||j df|_|j«|_ yy#ttf$r=}|jdd}|jddt |«zzf|z|_ |‚d}~wwxYw)z± Sets the value of the object before passing to Asn1Value.__init__() :param value: An Asn1Value object that will be set as the parsed value Nz` value must be an instance of Asn1Value, not %s r rr>) r'rSr2r3r rr?Ú_parsedrcrJrBrK)rLr8r7rRrKs r*rSz Any.__init__gsÇ€ô ×ј4Ñ* 6Ò*ð ØÐ Ü! %¬Ô3Ü#¤Fðô" %Ó(ó %óðð!& u§¡¸Ð=�” Ø %§ ¡ £ �• ð!øôœIÐ&ò Ø—6‘6˜!˜"�:ˆDØ—f‘f˜Q‘iÐ"?Ä)ÈDÃ/Ñ"QÑQÐSÐVZÑZˆAŒF؈Gûð ús˜AA3Á3B?Â8B:Â:B?cól—|j€|j«|jdjS)z– The native Python datatype representation of this value :return: The .native value from the parsed value object r)rÛÚparser�rZs r*r�z Any.nativeƒs+€ð �<‰<Ð Ø �J‰JŒLà�|‰|˜A‰×%Ñ%Ð%r+cóX—|j€|j«|jdS©zw Returns the parsed object from .parse() :return: The object returned by .parse() r©rÛrÝrZs r*r‰z Any.parsed‘ó%€ð �<‰<Ð Ø �J‰JŒLà�|‰|˜A‰Ðr+cób—|j�|jdd||fk7r² |xsi}t|«|j�)d|vr|j|dz|d<n|j|d<|j|jz|j z}t |||¬«\}}|||f|_d|_d|_d|_d|_||_d|_|jdS#ttf$r=}|jdd}|jdd t|«zzf|z|_ |‚d}~wwxYw) áv Parses the contents generically, or using a spec with optional params :param spec: A class derived from Asn1Value that defines what class_ and tag the value should have, and the semantics of the encoded value. The return value will be of this type. If omitted, the encoded value will be decoded using the standard universal tag based on the encoded tag number. :param spec_params: A dict of params to pass to the spec object :return: An object of the type spec, or if not present, a child of Asn1Value Nr rr<©r0r1Fr+rú while parsing %s) rÛÚ_tag_type_to_explicit_implicitr<r–rJr™r5r4r=rBr3rKr) rLr0r1Ú passed_paramsrJÚ parsed_valuer9rRrKs r*rÝz Any.parseŸsE€ð$ �<‰<Ð  4§<¡<°°!Ð#4¸¸{Ð8KÒ#Kð Ø +Ò 1¨r� Ü.¨}Ô=Ø—=‘=Ð,Ø! ]Ñ2Ø48·M±MÀMÐR\ÑD]Ñ4]˜  jÒ1à48·M±M˜  jÑ1ØŸ<™<¨$¯-©-Ñ7¸$¿-¹-ÑG�Ü".ØØØ -ô#‘� ˜að !-¨d°KÐ@�” ð �”Ø $�” Ø %�” Ø"�” Ø (�” Ø #�” ð �|‰|˜A‰Ðøô ¤ Ð*ò Ø—v‘v˜a˜b�z�ØŸ&™& ™)Ð&>ÄÈ4ÃÑ&PÑPÐRÐUYÑY�”Ø�ûð ús¢B1C"Ã"D.Ã18D)Ä)D.có\•—tt|� ||«||j«|_y)a Copies the contents of another Any object to itself :param object: Another instance of the same class :param copy_func: An reference of copy.copy() or copy.deepcopy() to use when copying lists, dicts and objects N)rÀrÙrnrÛrÁs €r*rnz Any._copyÑs&ø€ô Œc�4јu iÔ0Ù  §¡Ó/ˆ� r+cóx—|j€|j«|jdj|¬«S)r“r©rš)rÛrÝrcrÖs r*rczAny.dumpàs3€ð �<‰<Ð Ø �J‰JŒLà�|‰|˜A‰×#Ñ#¨%Ð#Ó0Ð0r+r�©NNrœ) rŸr r¡r¢rÛrSr×r�r‰rÝrnrcrÂrÃs@r*rÙrÙ\sLø„ñð€Góð8ñ &óð &ðñ óð ó0ôd 0÷1r+rÙcó܇—eZdZdZdZdZdZdZdZdZ dZ e dd„«Z d„Z dd„Zed„«Zej"d„«Zed„«Zd „Zed „«Zed „«Zd „Zd „Zˆfd„Zdd„ZˆxZS)ÚChoicezF A class to handle when a value may be one of several options Nc óx—t|t«stdt|«z«‚t ||||¬«\}}|S)a“ Loads a BER/DER-encoded byte string using the current class as the spec :param encoded_data: A byte string of BER or DER encoded data :param strict: A boolean indicating if trailing data should be forbidden - if so, a ValueError will be raised when trailing data exists :return: A instance of the current class r.r/)r2rr3rr5)r6r)r&r7r8r9s r*r(z Choice.loads?€ô ˜,¬Ô1ÜÐHÌ9ÐUaÓKbÑbÓcÐ cä  °3ÀFÐSYÔZ‰ˆˆq؈ r+có—|j}i|_i|_t|j«D][\}}t |«dkr|ifz}||j|<t |d|d«}||j|<||j|d<Œ]y)zS Generates _id_map from _alternatives to allow validating contents rr"r rN)r?Ú_id_mapÚ _name_mapÚ enumerateÚ _alternativesrDÚ_build_id_tuple)rLr6ÚindexÚinfoÚid_s r*r;z Choice._setup+sŽ€ð �n‰nˆØˆŒ ؈Œ Ü$ S×%6Ñ%6Ö7‰KˆE�4Ü�4‹y˜1Š}ؘr˜e‘|�Ø+/�×!Ñ! %Ñ(Ü! $ q¡'¨4°©7Ó3ˆCØ$ˆC�K‰K˜Ñ Ø%*ˆC�M‰M˜$˜q™'Ò "ñ 8r+c ó°—t|«tj|fi|¤Ž |jd«�t t d««‚|��=t |t«rUt|«dk7r(t t dt|«t|«««‚t|j««d\}}t |t«r@t|«dk7r(t t dt|«t|«««‚|d}|d}||jvrt t d |t|«««‚|j||_|j|j\}}}t ||«s ||fi|¤Ž}n t!||«}||_yy#tt$f$r=}|j&dd}|j&dd t|«zzf|z|_|‚d}~wwxYw) aq Checks to ensure implicit tagging is not being used since it is incompatible with Choice, then forwards on to Asn1Value.__init__() :param name: The name of the alternative to be set - used with value. Alternatively this may be a dict with a single key being the name and the value being the value, or a two-element tuple of the name and the value. :param value: The alternative value to set - used with name :raises: ValueError - when implicit param is passed (or legacy tag_type param is "implicit") r=NzÍ The Choice type can not be implicitly tagged even if in an implicit module - due to its nature any tagging must be explicit r zÝ When passing a dict as the "name" argument to %s, it must have a single key/value - however %d were present rr"zì When passing a tuple as the "name" argument to %s, it must have two elements, the name and value - however %d were present z… The name specified, "%s", is not a valid alternative for %s r>)rær'rSr{rBr r2rzrDrÚlistr¬ÚtupleròÚ_choicerôÚ _fix_taggingrÛr3rK) rLÚnamer8r7r9r0ÚparamsrRrKs r*rSzChoice.__init__;sá€ô$ ' vÔ.ä×ј4Ñ* 6Ò*ð< Ø�z‰z˜*Ó%Ð1Ü ¤ðó"óððÑܘd¤DÔ)ܘ4“y A’~Ü(¬ð ô & d›OÜ ›Ió*óðô#' t§z¡z£|Ó"4°QÑ"7‘K�D˜%ä˜d¤EÔ*ܘ4“y A’~Ü(¬ð ô & d›OÜ ›Ió*óðð! ™G�EØ ™7�Dà˜tŸ~™~Ñ-Ü$¤VððÜ! $›ó &óðð $Ÿ~™~¨dÑ3�” Ø"&×"4Ñ"4°T·\±\Ñ"B‘��4˜ä! %¨Ô.Ù  Ñ1¨&Ñ1‘Eä(¨°Ó7�EØ$�• ð[ øô^œIÐ&ò Ø—6‘6˜!˜"�:ˆDØ—f‘f˜Q‘iÐ"?Ä)ÈDÃ/Ñ"QÑQÐSÐVZÑZˆAŒF؈Gûð ús£E$F Æ GÆ8GÇGcó^—|j�|jjS|jS)zj :return: A byte string of the DER-encoded contents of the chosen alternative )rÛrJÚ _contentsrZs r*rJzChoice.contents�s(€ð �<‰<Ð #Ø—<‘<×(Ñ(Ð (à�~‰~Ðr+có—||_y)zo :param value: A byte string of the DER-encoded contents of the chosen alternative N©r©rLr8s r*rJzChoice.contents›ó €ðˆ�r+cót—|js!|j|jd|_|jS)zc :return: A unicode string of the field name of the chosen alternative r)Ú_namerôrürZs r*rþz Choice.name¤s0€ð �zŠzØ×+Ñ+¨D¯L©LÑ9¸!Ñ<ˆDŒJØ�z‰zÐr+cód—|j€J |j|j\}}}t|j||¬«\|_}|jS|jS#t t f$r=}|jdd}|jddt|«zzf|z|_|‚d}~wwxYw)z} Parses the detected alternative :return: An Asn1Value object of the chosen alternative Nrär rrå) rÛrôrür5rrBr3rKr)rLr9r0rÿrRrKs r*rÝz Choice.parse®s­€ð �<‰<Ð ð Ø"&×"4Ñ"4°T·\±\Ñ"B‘��4˜Ü".¨t¯~©~ÀDÐV\Ô"]‘�” ˜að �|‰|Јt�|‰|Ðøô ¤ Ð*ò Ø—v‘v˜a˜b�z�ØŸ&™& ™)Ð&>ÄÈ4ÃÑ&PÑPÐRÐUYÑY�”Ø�ûð úsŽ=A#Á#B/Á28B*Â*B/có"—|j«S)zT :return: An Asn1Value object of the chosen alternative )rÝrZs r*rŠz Choice.chosenÀs€ð�z‰z‹|Ðr+có.—|jjS)z™ The native Python datatype representation of this value :return: The .native value from the contained value object )rŠr�rZs r*r�z Choice.nativeÉs€ð�{‰{×!Ñ!Ð!r+c óÚ—||f}|j�S|jd|k7rttdt|«««‚t |t |««\\}}}}}}}||f}||j vr|j ||_y|j�e|j�Yt |j«dkDrttdt|«««‚||j|jfk(rd|_y|j||«}|j D�cgc]}|j|d|d«‘Œ}}ttd|t|«dj|«««‚cc}w) aÐ Ensures that the class and tag specified exist as an alternative :param class_: The integer class_ from the encoded value header :param tag: The integer tag from the encoded value header :param contents: A byte string of the contents of the value - used when the object is explicitly tagged :raises: ValueError - when value is not a valid alternative Nr”z� %s was explicitly tagged, but the value provided does not match the class and tag r z| %s was implicitly tagged, but more than one alternative exists rzs Value %s did not match the class and tag of any of the alternatives in %s: %s ú, ) r<rBr rrrDrñrürGr4rôÚ_format_class_tagÚjoin) rLrGr4rJrør9Úasn1ÚpairÚasn1ss r*ÚvalidatezChoice.validateÔsw€ð$�sˆmˆà �=‰=Ð $Ø�}‰}˜RÑ  CÒ'Ü ¤ðô˜d“Oó "óðô.4°H¼cÀ(»mÓ-LÑ *Ñ &ˆf�a˜˜a  A¨Ø˜3�-ˆCà �$—,‘,Ñ ØŸ<™<¨Ñ,ˆDŒLØ ð �;‰;Ð " t§x¡xÐ';Ü�4×%Ñ%Ó&¨Ò*Ü ¤ðô˜d“Oó "óðð�t—{‘{ D§H¡HÐ-Ò-Ø �” Øà×%Ñ% f¨cÓ2ˆØFJÇlÂlÓSÁl¸d�×'Ñ'¨¨Q©°°a±Õ9ÀlˆÐSäœð ð Ü �d‹OØ �I‰I�eÓ ó ó ð ùòTsÄE(có>—dt|j«›d|›d�S)zo :return: A unicode string of a human-friendly representation of the class and tag Ú[r`Ú])rEÚupper)rLrGr4s r*r zChoice._format_class_tags�ô 2°&Ñ9×?Ñ?ÕAÂ3ÐGÐGr+có •—tt|� ||«|j|_|j|_||j «|_y)a Copies the contents of another Choice object to itself :param object: Another instance of the same class :param copy_func: An reference of copy.copy() or copy.deepcopy() to use when copying lists, dicts and objects N)rÀrîrnrürrÛrÁs €r*rnz Choice._copys<ø€ô Œf�dÑ! %¨Ô3Ø—}‘}ˆŒ Ø—[‘[ˆŒ Ù  §¡Ó/ˆ� r+cóŽ—|j�|jdddk(rd}|jj|¬«|_|j�|r^d|_|j�K|jD]<\}}t |d||j|jz«|jz|_Œ>|j|jzS)r“Nr”r•Trër+r )r–rŠrcrr<r)rLršrGr4s r*rcz Choice.dump-s«€ð �<‰<Ð #¨¯ © °R°SÐ(9¸WÒ(D؈EàŸ™×)Ñ)°Ð)Ó6ˆŒØ �<‰<Ð ¡5؈DŒLØ�}‰}Ð(Ø#'§=¤=‘K�F˜CÜ#/°¸¸3ÀÇ Á ÈtÏ~É~Ñ@]Ó#^Ðae×amÑamÑ#m�D•Lð$1à�|‰|˜dŸn™nÑ,Ð,r+rœrì)rŸr r¡r¢rürrÛrrôrñròr¤r(r;rSr×rJÚsetterrþrÝrŠr�rr rnrcrÂrÃs@r*rîrîòsÚø„ñð €Gð €Eð€Gð€Ið€Mð€Gð€Iàòóðò*+ó Rðhñ óð ð‡_�_ñóððñóðòð$ñóððñ"óð"ò> ò@Hô0÷"-r+rîcóš—eZdZdZdZdZedd„«Zdd„Zd„Z d„Z d„Z d„Z d „Z d „Zd „Zd „Zdd „Zdd„Zed„«Zd„Zd„Zd„Zd„Zy)ÚConcata A class that contains two or more encoded child values concatentated together. THIS IS NOT PART OF THE ASN.1 SPECIFICATION! This exists to handle the x509.TrustedCertificate() class for OpenSSL certificates containing extra information. Ncó—|||¬«S)aƒ Loads a BER/DER-encoded byte string using the current class as the spec :param encoded_data: A byte string of BER or DER encoded data :param strict: A boolean indicating if trailing data should be forbidden - if so, a ValueError will be raised when trailing data exists :return: A Concat object )rJr&r¥)r6r)r&s r*r(z Concat.loadSs€ñ ˜L°Ô8Ð8r+có<—|�y t|«}g|_d}|jD];}||krt|||¬«\}}n|«}|jj |«Œ=|r||k7r||z }t d|z«‚|�P|j€dgt|j«z|_t|«D]\} } |j| | «Œyy#t t f$r=} | jdd} | jddt|«zzf| z| _| ‚d} ~ wwxYw)a :param value: A native Python datatype to initialize the object value with :param contents: A byte string of the encoded contents of the value :param strict: A boolean indicating if trailing data should be forbidden - if so, a ValueError will be raised when trailing data exists in contents :raises: ValueError - when an error occurs with one of the children TypeError - when an error occurs with one of the children Nr)r·r0ú4Extra data - %d bytes of trailing data were providedr r>) rDÚ _childrenÚ _child_specsr5ÚappendrBr3rKrróÚ __setitem__) rLr8rJr&r¸Úoffsetr0Ú child_valueÚ extra_bytesrRrKröÚdatas r*rSzConcat.__init__es7€ð" Ð ð Ü" 8›}� Ø!#�”à�Ø ×-Ô-�DØ  Ò,Ü.:¸8ÈVÐZ^Ô._Ñ+˜ ¡Vá&*£f˜ Ø—N‘N×)Ñ)¨+Õ6ð .ñ˜f¨ Ò4Ø".°Ñ"7�KÜ$Ð%[Ð^iÑ%iÓjÐjð Ð Ø�~‰~Ð%Ø"& ¬#¨d×.?Ñ.?Ó*@Ñ!@�”Ü(¨Ö/‘ ��tØ× Ñ  ¨Õ-ñ 0ð øô ¤ Ð*ò Ø—v‘v˜a˜b�z�ØŸ&™& ™)Ð&CÄiÐPTÃoÑ&UÑUÐWÐZ^Ñ^�”Ø�ûð ús„A8CÃDÃ8DÄDcóN—tr|j«S|j«SrUrVrZs r*r[zConcat.__str__’r\r+có"—|j«S)z; A byte string of the DER-encoded contents ©rcrZs r*rXzConcat.__bytes__ s€ð �y‰y‹{Ðr+có—t|«S©r^)rCrZs r*rYzConcat.__unicode__§s€ô �D‹zÐr+c ól—dt|«›dt|«›dt|j««›d�S)r^r_r`ra)rrbrCrcrZs r*rdzConcat.__repr__¯s$�ô )¨�´°4µ¼$¸t¿y¹y»{Õ:KÐLÐLr+cóf—|j«}|j|tj«|S)z| Implements the copy.copy() interface :return: A new shallow copy of the Concat object )r?rnrorjs r*rpzConcat.__copy__·s'€ð—.‘.Ó"ˆØ� ‰ �dœDŸI™IÔ&؈r+có‚—|j«}||t|«<|j|tj«|S)zÌ Implements the copy.deepcopy() interface :param memo: A dict for memoization :return: A new deep copy of the Concat object and all child objects )r?rbrnrorrrss r*ruzConcat.__deepcopy__Ãs4€ð—.‘.Ó"ˆØ ˆŒR�‹X‰Ø� ‰ �dœDŸM™MÔ*؈r+có,—tj|«S)zQ Copies the object :return: A Concat object rwrZs r*roz Concat.copyÓrxr+c ó´—|j|jk7r(ttdt|«t|«««‚||j«|_y)a Copies the contents of another Concat object to itself :param object: Another instance of the same class :param copy_func: An reference of copy.copy() or copy.deepcopy() to use when copying lists, dicts and objects r�N)r?r3r rrrƒs r*rnz Concat._copyÝsP€ð �>‰>˜UŸ_™_Ò ,ÜœFðô˜%Ó Ü˜$“ó óð ñ# 5§?¡?Ó3ˆ�r+có¼—d|z}t|›t|«›dt|«›�«t|›d�«|jD]}|j |dz«Œy)r‡rˆú Object #z Children:r"N)rŽrrbrrŒ©rLr�r�Úchilds r*rŒz Concat.debugôsN€ð ˜ Ñ"ˆÜ ¡6¬9°T­?¼B¸t¼HÐEÔFÜ ¢Ð)Ô*Ø—^”^ˆEØ �K‰K˜  Q™Õ 'ñ$r+cóV—d}|jD]}||j|¬«z }Œ|S)r“r+rë)rrc©rLršrJr4s r*rcz Concat.dumpÿs1€ðˆØ—^”^ˆEØ ˜Ÿ ™ ¨˜ Ó/Ñ /‰Hð$àˆr+có"—|j«S)z` :return: A byte string of the DER-encoded contents of the children r)rZs r*rJzConcat.contentss€ð�y‰y‹{Ðr+có,—t|j«S©z. :return: Integer )rDrrZs r*rÎzConcat.__len__s€ô �4—>‘>Ó"Ð"r+c óž—|t|j«dz kDs|dkrttd|t |«««‚|j |S)zÿ Allows accessing children by index :param key: An integer of the child index :raises: KeyError - when an index is invalid :return: The Asn1Value object of the child specified r rzN No child is definition for position %d of %s )rDr ÚKeyErrorr rr©rLr­s r*Ú __getitem__zConcat.__getitem__!sX€ð ”�T×&Ñ&Ó'¨!Ñ+Ò +¨s°QªwÜœ6ððܘ$“ó óð ð�~‰~˜cÑ"Ð"r+c óþ—|t|j«dz kDs|dkrttd|t |«««‚t |t «sttd|t |«««‚||j|<y)aG Allows settings children by index :param key: An integer of the child index :param value: An Asn1Value object to set the child to :raises: KeyError - when an index is invalid ValueError - when the value is not an instance of Asn1Value r rzK No child is defined for position %d of %s zz Value for child %s of %s is not an instance of asn1crypto.core.Asn1Value N) rDr r;r rr2r'rBr)rLr­r8s r*r"zConcat.__setitem__:sˆ€ð ”�T×&Ñ&Ó'¨!Ñ+Ò +¨s°QªwÜœ6ððܘ$“ó óð ô˜%¤Ô+ÜœVððܘ$“ó óð ð$ˆ�‰�sÒr+có,—t|j«S)zB :return: An iterator of child values )rÐrrZs r*rÑzConcat.__iter__^s€ô �D—N‘NÓ#Ð#r+rœ)NNFrž)rŸr r¡r¢r rr¤r(rSr[rXrYrdrprurornrŒrcr×rJrÎr=r"rÑr¥r+r*rrFs‡„ñð€Là€Iàò9óð9ó"+.òZ &òòòMò òò #ò4ó. (óð"ñóðò#ò#ò2"$óH$r+rcó:—eZdZdZdZdZd d„Zd„Zd d„Zd„Z d„Z y) Ú PrimitivezO Sets the class_ and method attributes for primitive, universal values rNc ó4—tj|fi|¤Ž |�||_y|�|j|«y|�|j|«yy#tt f$r=}|j dd}|j ddt|«zzf|z|_|‚d}~wwxYw)a^ Sets the value of the object before passing to Asn1Value.__init__() :param value: A native Python datatype to initialize the object value with :param default: The default value if no value is specified :param contents: A byte string of the encoded contents of the value Nr rr>)r'rSrJrHrBr3rKr)rLr8rPrJr7rRrKs r*rSzPrimitive.__init__ps£€ô ×ј4Ñ* 6Ò*ð ØÐ#Ø (�• àÐ"Ø—‘˜•àÐ$Ø—‘˜Õ!ð%øôœIÐ&ò Ø—6‘6˜!˜"�:ˆDØ—f‘f˜Q‘iÐ"?Ä)ÈDÃ/Ñ"QÑQÐSÐVZÑZˆAŒF؈Gûð ús!˜ A ¢A ¶A Á BÁ8BÂBc óÌ—t|t«s(ttdt |«t |«««‚||_||_d|_|jdk7rd|_yy)ú_ Sets the value of the object :param value: A byte string úH %s value must be a byte string, not %s Nr+) r2rr3r rr‚rJr–r™rs r*rHz Primitive.set�sg€ô˜%¤Ô*ÜœFðô˜$“ܘ%Ó ó óð ðˆŒ ØˆŒ ؈Œ Ø �=‰=˜CÒ ØˆD�Mð r+có¸—|j�|jdddk(rd}|r$|j}d|_|j|«tj |«S)r“Nr”r•T)r–r�rJrHr'rc©rLršr�s r*rczPrimitive.dump¦sS€ð �<‰<Ð #¨¯ © °R°SÐ(9¸WÒ(D؈Eá Ø—[‘[ˆFØ ˆDŒMØ �H‰H�VÔ ä�~‰~˜dÓ#Ð#r+có—||k( Sr�r¥rÈs r*Ú__ne__zPrimitive.__ne__½s€Ø˜5‘=Ð Ð r+có¶—t|t«sy|j|jk7ry|jj|jjk7ry|j|jk(r|j|jk(ryt |jj «t |jg«zt tttg«z }t |jj «t |jg«zt tttg«z }||zr|j|jk(S|js$|js|js |jr=|j«j«|j«j«k(S|j«|j«k(S)rÇFT) r2rArJr?r4rHÚ __bases__r'r§r=r<rrc)rLr„Ú self_basesÚ other_basess r*rÉzPrimitive.__eq__ÀsR€ô˜%¤Ô+Øà �=‰=˜EŸN™NÒ *Øð �>‰>× Ñ  §¡×!4Ñ!4Ò 4Øà �>‰>˜UŸ_™_Ò ,°·±À%Ç.Á.Ò1PØô˜$Ÿ.™.×2Ñ2Ó3´c¸4¿>¹>Ð:JÓ6KÑKÌsÔT]Ô_hÔjrÐSsÓOtÑtˆ ܘ5Ÿ?™?×4Ñ4Ó5¼¸U¿_¹_ÐÑ>Ð >à�y‰y‹{˜eŸj™j›lÑ*Ð*r+©NNNrœ) rŸr r¡r¢rGrIrSrHrcrIrÉr¥r+r*rArAgs,„ñð€Fà €Fóò> ó.$ò.!ó#+r+rAcóF‡—eZdZdZdZdZd„Zd„Zˆfd„Ze d„«Z ˆxZ S)ÚAbstractStringzô A base class for all strings that have a known encoding. In general, we do not worry ourselves with confirming that the decoded values match a specific set of characters, only that they are decoded into a Python unicode string Úlatin1Nc ó2—t|t«s(ttdt |«t |«««‚||_|j |j«|_d|_ |jrd|_ d|_ |jdk7rd|_ yy)zb Sets the value of the string :param value: A unicode string úK %s value must be a unicode string, not %s NFrr+) r2rr3r rÚ_unicodergÚ _encodingrJr–r˜rIr™rs r*rHzAbstractString.setósŒ€ô˜%¤Ô)ÜœFðô˜$“ܘ%Ó ó óð ðˆŒ ØŸ ™  T§^¡^Ó4ˆŒ ؈Œ Ø × Ò Ø$ˆDÔ ØˆDŒKØ �=‰=˜CÒ ØˆD�Mð r+có¨—|j€y|j€.|j«j|j«|_|jS)r^Ú)rJrTr¶ÚdecoderUrZs r*rYzAbstractString.__unicode__ sD€ð �=‰=Ð ØØ �=‰=Ð Ø ×.Ñ.Ó0×7Ñ7¸¿¹ÓGˆDŒMØ�}‰}Ðr+cóP•—tt|� ||«|j|_y)a& Copies the contents of another AbstractString object to itself :param object: Another instance of the same class :param copy_func: An reference of copy.copy() or copy.deepcopy() to use when copying lists, dicts and objects N)rÀrPrnrTrÁs €r*rnzAbstractString._copys!ø€ô Œn˜dÑ)¨%°Ô;ØŸ™ˆ� r+có<—|j€y|j«S©z€ The native Python datatype representation of this value :return: A unicode string or None N)rJrYrZs r*r�zAbstractString.native(s €ð �=‰=Ð Øà×ÑÓ!Ð!r+) rŸr r¡r¢rUrTrHrYrnr×r�rÂrÃs@r*rPrPæs9ø„ñð€Ið€Hò ò4 ô 'ðñ "óô "r+rPcó6—eZdZdZdZd„Zd„Zd„Zed„«Z y)ÚBooleanz7 Represents a boolean in both ASN.1 and Python r cóv—t|«|_|sdnd|_d|_|jdk7rd|_yy)z… Sets the value of the object :param value: True, False or another value that works with bool() óóÿNr+)Úboolr‚rJr–r™rs r*rHz Boolean.set>s9€ô˜E“{ˆŒ Ù',™°'ˆŒ ؈Œ Ø �=‰=˜CÒ ØˆD�Mð r+có"—|j«S)ú4 :return: True or False )Ú__bool__rZs r*rËzBoolean.__nonzero__Ms€ð �}‰}‹Ðr+có —|jdk7S)rcr_r¼rZs r*rdzBoolean.__bool__Ts€ð �}‰} Ñ'Ð'r+cóv—|j€y|j€|j«|_|jS)z{ The native Python datatype representation of this value :return: True, False or None N)rJr‚rdrZs r*r�zBoolean.native[s2€ð �=‰=Ð Øà �<‰<Ð ØŸ=™=›?ˆDŒLØ�|‰|Ðr+N) rŸr r¡r¢r4rHrËrdr×r�r¥r+r*r]r]7s1„ñð €Cò  òò(ðñ óñ r+r]có0—eZdZdZdZd„Zd„Zed„«Zy)ÚIntegerz8 Represents an integer in both ASN.1 and Python r"c ó"—t|t«rg|j€tt dt |«««‚||j vrtt dt |«|««‚|j |}n8t|t«s(tt dt |«t |«««‚|jr||jvr|j|n||_ t|d¬«|_ d|_ |jdk7rd|_ yy)zË Sets the value of the object :param value: An integer, or a unicode string if _map is set :raises: ValueError - when an invalid value is passed Nz\ %s value is a unicode string, but no _map provided zR %s value, %s, is not present in the _map zƒ %s value must be an integer or unicode string when a name_map is provided, not %s T©Úsignedr+)r2rrªrBr rr«rr3r‚rrJr–r™rs r*rHz Integer.setss€ô �eœWÔ %Ø�y‰yÐ Ü ¤ðô˜d“Oó "óðð˜D×-Ñ-Ñ-Ü ¤ðô˜d“OØó "óðð×%Ñ% eÑ,‰Eä˜E¤9Ô-ÜœFðô˜$“ܘ%Ó ó óð ð,0¯9ª9¸À$Ç)Á)Ñ9K�t—y‘y Ò'ÐQVˆŒ ä$ U°4Ô8ˆŒ ؈Œ Ø �=‰=˜CÒ ØˆD�Mð r+có0—t|jd¬«S)ú1 :return: An integer Trj)rrJrZs r*Ú__int__zInteger.__int__£s€ô ˜dŸm™m°DÔ9Ð9r+cóú—|j€y|j€W|j«|_|j�6|j|jvr|j|j|_|jS©zz The native Python datatype representation of this value :return: An integer or None N)rJr‚rnrªrZs r*r�zInteger.nativeªs_€ð �=‰=Ð Øà �<‰<Ð ØŸ<™<›>ˆDŒLØ�y‰yÐ$¨¯©¸¿¹Ñ)BØ#Ÿy™y¨¯©Ñ6�” Ø�|‰|Ðr+N) rŸr r¡r¢r4rHrnr×r�r¥r+r*rhrhls-„ñð €Cò. ò`:ðñóñr+rhcóB‡—eZdZdZdZd„Zd„Zˆfd„Zed„«Z ˆxZ S)Ú_IntegerBitStringzY A mixin for IntegerBitString and BitString to parse the contents as an integer. r¥cóÚ—|jrgStrt|jd«n|jd}t |jdd«}t |j«dz dz}|s||dfgSt |j«dk(rt dj|««‚|dkDrt dj|««‚t|d|zdz z|«}||z}||z}|||fgS) aÈ Parse the contents of a primitive BitString encoding as an integer value. Allows reconstructing indefinite length values. :raises: ValueError - when an invalid value is passed :return: A list with one tuple (value, bits, unused_bits) where value is an integer with the value of the BitString, bits is the bit count of value and unused_bits is a tuple of 1s and 0s. rr Nér¥ú$Empty bit string has {0} unused bitséúBit string has {0} unused bits) r˜rWÚordrJrrDrBÚformatÚ_int_to_bit_tuple)rLÚunused_bits_lenr8ÚbitsÚ unused_bitss r*rµz_IntegerBitString._as_chunkÅsø€ð × Ò àˆIå37œ#˜dŸm™m¨AÑ.Ô/¸T¿]¹]È1Ñ=MˆÜ˜tŸ}™}¨Q¨RÐ0Ó1ˆÜ�D—M‘MÓ" QÑ&¨!Ñ+ˆáؘD "Ð%Ð&Ð &ä ˆt�}‰}Ó  Ò "äÐC×JÑJÈ?Ó[Ó\Ð \à ˜QÒ äÐ=×DÑDÀ_ÓUÓVÐ Vä'¨°!°Ñ2FÈ!Ñ1KÑ(LÈoÓ^ˆ Ø �/Ñ!ˆØ �Ñˆà˜˜kÐ*Ð+Ð+r+có—|js|j«dSd}d}d}|j«D]#\}}}|dzr td«‚||z }||z|z}Œ%|||fS)aa Combines the chunks into a single value. :raises: ValueError - when an invalid value is passed :return: A tuple (value, bits, unused_bits) where value is an integer with the value of the BitString, bits is the bit count of value and unused_bits is a tuple of 1s and 0s. rr¥rvú4Only last chunk in a bit string may have unused bits)r˜rµr¶rB)rLr8Ú total_bitsr}Úchunkr|s r*Ú_chunks_to_intz _IntegerBitString._chunks_to_intìs„€ð×Òà—>‘>Ó# AÑ&Ð &àˆØˆ ؈ ð)-×(:Ñ(:Ö(<Ñ $ˆE�4˜Ø˜AŠ~ä Ð!WÓXÐXØ ˜$Ñ ˆJؘd‘] eÑ+‰Eð )=ð�j +Ð-Ð-r+cóP•—tt|� ||«|j|_y)a) Copies the contents of another _IntegerBitString object to itself :param object: Another instance of the same class :param copy_func: An reference of copy.copy() or copy.deepcopy() to use when copying lists, dicts and objects N)rÀrrrnÚ _unused_bitsrÁs €r*rnz_IntegerBitString._copy s%ø€ô Ô Ñ,¨U°IÔ>Ø!×.Ñ.ˆÕr+có2—|j|jS©zp The unused bits of the bit string encoding. :return: A tuple of 1s and 0s ©r�r„rZs r*r}z_IntegerBitString.unused_bitsó€ð � Š à× Ñ Ð r+) rŸr r¡r¢r„rµr‚rnr×r}rÂrÃs@r*rrrr½s3ø„ñð €Lò%,òN.ô> /ðñ !óô !r+rrcó@—eZdZdZdZdZd„Zd„Zd„Zd„Z e d„«Z y) Ú BitStringzK Represents a bit string from ASN.1 as a Python tuple of 1s and 0s rNcó¶—tj|«|j}|j�,t |jj ««dz|_yy)r©Nr )r§r;r?rªÚmaxÚkeysÚ_size)rLr6s r*r;zBitString._setup2sD€ô �‰˜Ôà�n‰nˆØ �8‰8РܘDŸI™IŸN™NÓ,Ó-°Ñ1ˆC�Ið r+c ó’—t|t«r¤|j€tt dt |«««‚dg|j z}||_td|j «D]*}|jj|«}|€Œ!||vsŒ&d||<Œ,djtt|««}nË|jtk(r�|j€||_n\t«|_t|«D]?\}}|sŒ |jj||«}|jj!|«ŒAdjtt|««}n(t#t dt |«t |«««‚|j�\t%|«|j kDr3tt dt |«|j t%|«««‚|j'd«}t%|«}|d z}d} |dk7r d |z } |d| zz }t)t+j,|d z ««} | r t/| «} nd } |dk(rd } nt/t)|d ««} t%| «| k7rd | t%| «z z| z} | | z|_d | z|_d|_|j6rd|_d|_|j:d k7rd |_yy)zÆ Sets the value of the object :param value: An integer or a tuple of integers 0 and 1 :raises: ValueError - when an invalid value is passed NúF %s._map has not been defined rr rWz€ %s value must be a tuple of ones and zeros or a set of unicode strings, not %s zf %s value must be at most %s bits long, specified was %s long Ú0rtr_r+r")rF)r2rHrªrBr rrŽr‚Úranger{rÚmaprr?rûróÚaddr3rDÚrstripÚintÚmathÚceilrrJr„r–r˜rIr™) rLr8r|rör­ÚbitrþÚsizeÚsize_modÚ extra_bitsÚ size_in_bytesÚextra_bits_byteÚ value_bytess r*rHz BitString.set=s›€ô �eœSÔ !Ø�y‰yÐ Ü ¤ðô˜d“Oó "óðð�3˜Ÿ™Ñ#ˆDØ ˆDŒLܘq $§*¡*Ö-�Ø—i‘i—m‘m EÓ*�Ø�;ØØ˜%’<Ø"#�D˜’Kð .ð—G‘GœC¤¨Ó.Ó/‰Eà �_‰_¤Ò %Ø�y‰yÐ Ø$�• ä"›u�” Ü"+¨EÖ"2‘J�E˜3ÚØ#Ÿy™yŸ}™}¨U°EÓ:˜ØŸ ™ ×(Ñ(¨Õ.ð#3ð—G‘GœC¤¨Ó/Ó0‰EôœFðô˜$“ܘ%Ó ó óð ð �9‰9Ð Ü�5‹z˜DŸJ™JÒ&Ü ¤ðô˜d“OØ—J‘Jܘ“Jó "óðð—L‘L Ó%ˆEÜ�5‹zˆà˜!‘8ˆØˆ Ø �qŠ=ؘX™ˆJØ �S˜:Ñ%Ñ %ˆEäœDŸI™I d¨Q¡hÓ/Ó0ˆ á Ü*¨:Ó6‰Oà%ˆOà �BŠ;؉Kä&¤s¨5°!£}Ó5ˆKÜ ˆ{Ó ˜}Ò ,Ø" m´c¸+Ó6FÑ&FÑGÈ;ÑVˆKà'¨+Ñ5ˆŒ Ø  :Ñ-ˆÔ؈Œ Ø × Ò Ø$ˆDÔ ØˆDŒKØ �=‰=˜CÒ ØˆD�Mð r+cóø—t|t«}|set|jt«st t dt |«««‚||jvrt t dt |«|««‚|j€ |j|j€4t|j«|dzk\rt|j|«Sy|r|jj||«}||jvS)aG Retrieves a boolean version of one of the bits based on a name from the _map :param key: The unicode string of one of the bit names :raises: ValueError - when _map is not set or the key name is invalid :return: A boolean if the bit is set r�úT %s._map does not contain an entry for "%s" r F) r2rrªrzrBr rr«r‚r�rDrar{)rLr­Úis_ints r*r=zBitString.__getitem__ sç€ô˜C¤Ó+ˆÙܘdŸi™i¬Ô.Ü ¤ðô˜d“Oó "óðð˜$×+Ñ+Ñ+Ü ¤ðô˜d“OØó "óðð �<‰<Ð Ø �KŠKà �9‰9Ð Ü�4—<‘<Ó  C¨!¡GÒ+ܘDŸL™L¨Ñ-Ó.Ð.Øá Ø—)‘)—-‘-  SÓ)ˆCà�d—l‘lÐ"Ð"r+cóî—t|t«}|sW|j€tt dt |«««‚||j vrtt dt |«|««‚|j€ |j|j€Zt|j«}t|«dz }||kDr|jdg||z z«|rdnd||<t|«|_ns|r|jj||«}|r*||jvrE|jj|«n)||jvr|jj|«|j!|j«y)a Sets one of the bits based on a name from the _map :param key: The unicode string of one of the bit names :param value: A boolean value :raises: ValueError - when _map is not set or the key name is invalid Nr�r¡r r)r2rrªrBr rr«r‚r�rúrDÚextendrûr{r”ÚremoverH)rLr­r8r¢Ú new_nativeÚmax_keys r*r"zBitString.__setitem__ÏsN€ô˜C¤Ó+ˆÙØ�y‰yÐ Ü ¤ðô˜d“Oó "óðð˜$×+Ñ+Ñ+Ü ¤ðô˜d“OØó "óðð �<‰<Ð Ø �KŠKà �9‰9РܘdŸl™lÓ+ˆJܘ*“o¨Ñ)ˆGØ�WŠ}Ø×!Ñ! 1 #¨¨w©Ñ"7Ô8Ù#(™a¨aˆJ�s‰OÜ  Ó,ˆD�LñØ—i‘i—m‘m C¨Ó-�áØ˜dŸl™lÑ*Ø—L‘L×$Ñ$ SÕ)à˜$Ÿ,™,Ñ&Ø—L‘L×'Ñ'¨Ô,à �‰�—‘Õr+cóø—|j€7|j€|jd«n|jt««|j€ |j «\}}|_t ||«}|jrht«|_t|«D]?\}}|sŒ |jj||«}|jj|«ŒA|jS||_|jS)zÚ The native Python datatype representation of this value :return: If a _map is set, a set of names, or if no _map is set, a tuple of integers 1 and 0. None if no value. r¥) rJrªrHr‚r‚r„rzrór{r”)rLÚ int_valueÚ bit_countr|rör™rþs r*r�zBitString.native sÈ€ð �=‰=Ð Ø�y‰yÐ Ø—‘˜• à—‘œ›”à �<‰<Ð Ø6:×6IÑ6IÓ6KÑ 3ˆI�y $Ô"3Ü$ Y° Ó:ˆDà�yŠyÜ"›u�” Ü"+¨D¦/‘J�E˜3ÚØ#Ÿy™yŸ}™}¨U°EÓ:˜ØŸ ™ ×(Ñ(¨Õ.ð#2ð �|‰|Ðð $�” Ø�|‰|Ðr+) rŸr r¡r¢r4rŽr;rHr=r"r×r�r¥r+r*rŠrŠ)s?„ñð €Cà €Eò 2òa òF-#ò^7ðrñóñr+rŠcó`‡—eZdZdZdZdZdZd„Zd„Zˆfd„Z d„Z e d „«Z e d „«Z ˆxZS) ÚOctetBitStringzB Represents a bit string in ASN.1 as a Python byte string rNr¥c ó—t|t«s(ttdt |«t |«««‚||_d|z|_d|_d|_|jrd|_ d|_ |jdk7rd|_ yy)úª Sets the value of the object :param value: A byte string :raises: ValueError - when an invalid value is passed rEr_r¥NFrr+) r2rr3r rÚ_bytesrJr„r–r˜rIr™rs r*rHzOctetBitString.set5 s‹€ô˜%¤Ô*ÜœFðô˜$“ܘ%Ó ó óð ðˆŒ à %™ˆŒ ØˆÔØˆŒ Ø × Ò Ø$ˆDÔ ØˆDŒKØ �=‰=˜CÒ ØˆD�Mð r+cót—|j€y|j€”|js,|j«d\|_|_|jS|j «}d|_|D]#}|jr t d«‚|d|_Œ%djd„|D««|_|jS)ú4 :return: A byte string r+rr¥rr c3ó&K—|] }|d–—Œ y­w)rNr¥)Ú.0r�s r*Ú z+OctetBitString.__bytes__..g sèø€Ð&D¹V°E u¨Q¥x¹Vùs‚)rJr¯r˜rµr„r¶rBr)rLÚchunksr�s r*rXzOctetBitString.__bytes__T s°€ð �=‰=Ð ØØ �;‰;Ð Ø×#Ò#Ø15·±Ó1AÀ!Ñ1DÑ.�” ˜TÔ.ð�{‰{Ðð×+Ñ+Ó-�Ø$&�Ô!Û#�EØ×(Ò(ä(Ð)_Ó`Ð`Ø(-¨a©�DÕ%ð $ð "Ÿh™hÑ&D¹VÓ&DÓD�” à�{‰{Ðr+cór•—tt|� ||«|j|_|j|_y)a& Copies the contents of another OctetBitString object to itself :param object: Another instance of the same class :param copy_func: An reference of copy.copy() or copy.deepcopy() to use when copying lists, dicts and objects N)rÀr¬rnr¯r„rÁs €r*rnzOctetBitString._copyk s/ø€ô Œn˜dÑ)¨%°Ô;Ø—l‘lˆŒ Ø!×.Ñ.ˆÕr+có—trt|jd«n|jd}|s|jdddfgSt|j«dk(rt dj |««‚|dkDrt dj |««‚d|zdz }trt|jd«n|jd}||z}|jddtr t |«n t|f«z}t||z|«}||fgS) z÷ Allows reconstructing indefinite length values :raises: ValueError - when an invalid value is passed :return: List with one tuple, consisting of a byte string and an integer (unused bits) rr Nr¥rurvrwr”) rWrxrJrDrBryÚchrÚbytesrz)rLr{ÚmaskÚ last_byteÚ zeroed_byter8r}s r*rµzOctetBitString._as_chunk{ s€õ48œ#˜dŸm™m¨AÑ.Ô/¸T¿]¹]È1Ñ=MˆÙØ—]‘] 1 2Ð&¨Ð+Ð,Ð ,ä ˆt�}‰}Ó  Ò "äÐC×JÑJÈ?Ó[Ó\Ð \à ˜QÒ äÐ=×DÑDÀ_ÓUÓVÐ Và�_Ñ$¨Ñ)ˆÝ.2”C˜Ÿ ™  bÑ)Ô*¸¿ ¹ ÀbÑ8Iˆ ð  4 %Ñ'ˆ Ø— ‘ ˜a Ð#½4¤s¨;Ô'7ÄUÈKÈ>ÓEZÑ[ˆä'¨ °DÑ(8¸/ÓJˆ à˜ Ð$Ð%Ð%r+có<—|j€y|j«S©ú} The native Python datatype representation of this value :return: A byte string or None N©rJrXrZs r*r�zOctetBitString.native� ó€ð �=‰=Ð Øà�~‰~ÓÐr+có2—|j|jSr†r‡rZs r*r}zOctetBitString.unused_bits« rˆr+)rŸr r¡r¢r4r¯r„rHrXrnrµr×r�r}rÂrÃs@r*r¬r¬( sZø„ñð €Cð€Fð€Lò ò>ô./ò &ðDñ  óð  ðñ !óô !r+r¬có*—eZdZdZdZd„Zed„«Zy)ÚIntegerBitStringz> Represents a bit string in ASN.1 as a Python integer rc ór—t|t«s(ttdt |«t |«««‚|dkrt tdt |«|««‚||_dt|d¬«z|_d|_ d|_ |jrd |_ d|_ |jd k7rd |_ yy) ú§ Sets the value of the object :param value: An integer :raises: ValueError - when an invalid value is passed úM %s value must be a positive integer, not %s rúM %s value must be a positive integer, not %d r_Trjr¥NFr+)r2rr3r rrBr‚rrJr„r–r˜rIr™rs r*rHzIntegerBitString.setÁ sÁ€ô˜%¤Ô+ÜœFðô˜$“ܘ%Ó ó óð ð �1Š9ÜœVðô˜$“Øó óð ðˆŒ à¤,¨u¸TÔ"BÑBˆŒ ØˆÔØˆŒ Ø × Ò Ø$ˆDÔ ØˆDŒKØ �=‰=˜CÒ ØˆD�Mð r+cóˆ—|j€y|j€|j«\|_}|_|jSrp)rJr‚r‚r„)rLÚ__s r*r�zIntegerBitString.nativeé s?€ð �=‰=Ð Øà �<‰<Ð Ø26×2EÑ2EÓ2GÑ /ˆDŒL˜"˜dÔ/à�|‰|Ðr+N©rŸr r¡r¢r4rHr×r�r¥r+r*rÄrĺ s(„ñð €Cò& ðPñóñr+rÄcóF‡—eZdZdZdZdZd„Zd„Zˆfd„Ze d„«Z ˆxZ S)Ú OctetStringz; Represents a byte string in both ASN.1 and Python éNc ó—t|t«s(ttdt |«t |«««‚||_||_d|_|jrd|_d|_ |jdk7rd|_ yy©rDrENFrr+© r2rr3r rr¯rJr–r˜rIr™rs r*rHzOctetString.set ó€ô˜%¤Ô*ÜœFðô˜$“ܘ%Ó ó óð ðˆŒ ØˆŒ ؈Œ Ø × Ò Ø$ˆDÔ ØˆDŒKØ �=‰=˜CÒ ØˆD�Mð r+cóv—|j€y|j€|j«|_|jS©r±r+©rJr¯r¶rZs r*rXzOctetString.__bytes__ ó5€ð �=‰=Ð ØØ �;‰;Ð Ø×,Ñ,Ó.ˆDŒKØ�{‰{Ðr+cóP•—tt|� ||«|j|_y)a# Copies the contents of another OctetString object to itself :param object: Another instance of the same class :param copy_func: An reference of copy.copy() or copy.deepcopy() to use when copying lists, dicts and objects N)rÀrÍrnr¯rÁs €r*rnzOctetString._copy+ s!ø€ô Œk˜4Ñ& u¨iÔ8Ø—l‘lˆ� r+có<—|j€y|j«Sr¾rÀrZs r*r�zOctetString.native: rÁr+) rŸr r¡r¢r4r¯rHrXrnr×r�rÂrÃs@r*rÍrÍû s9ø„ñð €Cð€Fò ò4 ô #ðñ  óô  r+rÍcó4—eZdZdZdZdZd„Zed„«Zd„Z y)ÚIntegerOctetStringz? Represents a byte string in ASN.1 as a Python integer rÎNc ót—t|t«s(ttdt |«t |«««‚|dkrt tdt |«|««‚||_t|d|j¬«|_ d|_ |jrd|_ d|_ |jdk7rd|_ yy)rÆrÇrrÈF)rkÚwidthNr+)r2rr3r rrBr‚rÚ_encoded_widthrJr–r˜rIr™rs r*rHzIntegerOctetString.setV s¼€ô˜%¤Ô+ÜœFðô˜$“ܘ%Ó ó óð ð �1Š9ÜœVðô˜$“Øó óð ðˆŒ Ü$ U°5À×@SÑ@SÔTˆŒ ؈Œ Ø × Ò Ø$ˆDÔ ØˆDŒKØ �=‰=˜CÒ ØˆD�Mð r+cóˆ—|j€y|j€t|j««|_|jSrp)rJr‚rr¶rZs r*r�zIntegerOctetString.native| s:€ð �=‰=Ð Øà �<‰<Ð Ü)¨$×*<Ñ*<Ó*>Ó?ˆDŒLØ�|‰|Ðr+có”—||_|j�5t|j«|k7r|j|j«yyy)z’ Set the explicit enoding width for the integer :param width: An integer byte width to encode the integer to N)rÝrJrDrHr�)rLrÜs r*Úset_encoded_widthz$IntegerOctetString.set_encoded_widthŒ s?€ð$ˆÔà �=‰=Ð $¬¨T¯]©]Ó);¸uÒ)DØ �H‰H�T—[‘[Õ !ð*EÐ $r+) rŸr r¡r¢r4rÝrHr×r�ràr¥r+r*rÚrÚI s4„ñð €Cð €Nò$ ðLñ óð ó "r+rÚcót‡—eZdZdZdZdZd d„Zd„Zd d„Zd„Z d„Z ˆfd„Z e d „«Z e d „«Zd d „ZˆxZS)ÚParsableOctetStringrÎNc ó²—d}|€$|�"t|t«r|j«}d}tj|fd|i|¤Ž|r||j df|_yy)a¥ Allows providing a parsed object that will be serialized to get the byte string value :param value: A native Python datatype to initialize the object value with :param parsed: If value is None and this is an Asn1Value object, this will be set as the parsed value, and the value will be obtained by calling .dump() on this object. FNTr8)r2r'rcrArSr?rÛ)rLr8r‰r7Ú set_parseds r*rSzParsableOctetString.__init__£ s`€ðˆ Ø ˆ=˜VÐ/´J¸vÄyÔ4QØ—K‘K“MˆE؈Jä×ј4Ñ7 uÐ7°Ò7á Ø" F×$4Ñ$4°dÐ;ˆD�Lð r+c ó—t|t«s(ttdt |«t |«««‚||_||_d|_|jrd|_d|_ |jdk7rd|_ yyrÐrÑrs r*rHzParsableOctetString.set» rÒr+có²—|j�|jdd||fk7r)t|j«||¬«\}}|||f|_|jdS)rãr rrär)rÛr5rX)rLr0r1rèr9s r*rÝzParsableOctetString.parseÕ s[€ð$ �<‰<Ð  4§<¡<°°!Ð#4¸¸{Ð8KÒ#KÜ*¨4¯>©>Ó+;À$ÐT_Ô`‰OˆL˜!Ø(¨$° Ð<ˆDŒLØ�|‰|˜A‰Ðr+cóv—|j€y|j€|j«|_|jSrÔrÕrZs r*rXzParsableOctetString.__bytes__ì rÖr+có"—|j«S)z“ Returns a byte string that can be passed into .set() :return: A python value that is valid to pass to .set() )rXrZs r*r¾z#ParsableOctetString._setable_nativeø s€ð�~‰~ÓÐr+có~•—tt|� ||«|j|_||j«|_y)a+ Copies the contents of another ParsableOctetString object to itself :param object: Another instance of the same class :param copy_func: An reference of copy.copy() or copy.deepcopy() to use when copying lists, dicts and objects N)rÀrârnr¯rÛrÁs €r*rnzParsableOctetString._copy s2ø€ô Ô! 4Ñ.¨u°iÔ@Ø—l‘lˆŒ Ù  §¡Ó/ˆ� r+có†—|j€y|j�|jdjS|j«S)r¿Nr)rJrÛr�rXrZs r*r�zParsableOctetString.native s<€ð �=‰=Ð Øà �<‰<Ð #Ø—<‘< ‘?×)Ñ)Ð )à—>‘>Ó#Ð #r+cóX—|j€|j«|jdSrßràrZs r*r‰zParsableOctetString.parsed# rár+cóæ—|jrd}|rM|j�|jj|¬«}n |j}d|_|j |«tj|«S)r“TNrë)r˜rÛr‰rcr�rJrHr'rGs r*rczParsableOctetString.dump1 sa€ð × Ò ØˆEá Ø�|‰|Ð'ØŸ™×)Ñ)°Ð)Ó6‘àŸ™�Ø ˆDŒMØ �H‰H�VÔ ä�~‰~˜dÓ#Ð#r+rìrœ)rŸr r¡r4rÛr¯rSrHrÝrXr¾rnr×r�r‰rcrÂrÃs@r*rârâš s_ø„à €Cà€Gð€Fó<ò0 ó4ò. ò ô0ð ñ$óð$ð ñ óð ÷$r+râcó—eZdZdZd„Zd„Zy)ÚParsableOctetBitStringrc ó—t|t«s(ttdt |«t |«««‚||_d|z|_d|_|jrd|_d|_ |jdk7rd|_ yy)r®rEr_NFrr+rÑrs r*rHzParsableOctetBitString.setP sƒ€ô˜%¤Ô*ÜœFðô˜$“ܘ%Ó ó óð ðˆŒ à %™ˆŒ ؈Œ Ø × Ò Ø$ˆDÔ ØˆDŒKØ �=‰=˜CÒ ØˆD�Mð r+có”—trt|jd«n|jd}|r td«‚|jddS)z· Allows reconstructing indefinite length values :raises: ValueError - when an invalid value is passed :return: A byte string rz1ParsableOctetBitString should have no unused bitsr N)rWrxrJrB)rLr{s r*rµz ParsableOctetBitString._as_chunkn sD€õ48œ#˜dŸm™m¨AÑ.Ô/¸T¿]¹]È1Ñ=MˆÙ ÜÐPÓQÐ Qà�}‰}˜Q˜RÐ Ð r+N)rŸr r¡r4rHrµr¥r+r*rîrîL s„à €Cò ó<!r+rîcó.—eZdZdZdZdZd„Zed„«Zy)ÚNullz< Represents a null value in ASN.1 as None in Python ér+có—d|_y)zV Sets the value of the object :param value: None r+Nr¼rs r*rHzNull.set‰ s €ðˆ� r+có—yrÓr¥rZs r*r�z Null.native“ rÔr+N) rŸr r¡r¢r4rJrHr×r�r¥r+r*ròrò€ s,„ñð €Cà€Hòðñóñr+ròcód—eZdZdZdZdZed„«Zed„«Zd„Z d„Z e d„«Z e d „«Z y) ÚObjectIdentifierú` Represents an object identifier in ASN.1 as a Python unicode dotted integer string éNcóê—|j€ttdt|«««‚t |t «st tdt|«««‚|jj||«S)a^ Converts a dotted unicode string OID into a mapped unicode string :param value: A dotted unicode string OID :raises: ValueError - when no _map dict has been defined on the class TypeError - when value is not a unicode string :return: A mapped unicode string ú> %s._map has not been defined úH value must be a unicode string, not %s )rªrBr rr2rr3r{©r6r8s r*r“zObjectIdentifier.mapª sv€ð �8‰8Ð ÜœVðô˜#“ó óð ô˜%¤Ô)ÜœFðô˜%Ó ó óð ð�x‰x�|‰|˜E 5Ó)Ð)r+có¤—|tvr|«j«dt|<|j€tt dt |«««‚t |t«stt dt |«««‚||jvr|j|Stj|«stt dt |«|««‚|S)a  Converts a mapped unicode string value into a dotted unicode string OID :param value: A mapped unicode string OR dotted unicode string OID :raises: ValueError - when no _map dict has been defined on the class or the value can't be unmapped TypeError - when value is not a unicode string :return: A dotted unicode string OID TrûrüzL %s._map does not contain an entry for "%s" ) r@r;rªrBr rr2rr3r«Ú_OID_REÚmatchrýs r*ÚunmapzObjectIdentifier.unmapÌ sÕ€ð ”nÑ $Ù ‹E�L‰LŒNØ"&ŒN˜3Ñ à �8‰8Ð ÜœVðô˜#“ó óð ô˜%¤Ô)ÜœFðô˜%Ó ó óð ð �C×$Ñ$Ñ $Ø×#Ñ# EÑ*Ð *ä�}‰}˜UÔ#ÜœVðô˜#“Øó óð ðˆ r+c óÔ—t|t«s(ttdt |«t |«««‚||_|j �||jvr|j|}d|_d}t|jd««D]¼\}}t|«}|dk(r|}Œ|dk(rS|dkDrttdt|«««‚|dkr#|d k\rttd t|«««‚|d z|z}td |z«}|d z }|dkDrtd d |zz«|z}|d z }|dkDrŒ|xj|z c_Œ¾d|_|j dk7rd|_yy)a  Sets the value of the object :param value: A unicode string. May be a dotted integer string, or if _map is provided, one of the mapped values. :raises: ValueError - when an invalid value is passed rSNr+Ú.rr r"z\ First arc must be one of 0, 1 or 2, not %s é(zˆ Second arc must be less than 40 if first arc is 0 or 1, not %s érvé€)r2rr3r rr‚rªr«rJróÚsplitr–rBrCrr–r™)rLr8ÚfirströÚpartÚ encoded_parts r*rHzObjectIdentifier.setþ s–€ô˜%¤Ô)ÜœFðô˜$“ܘ%Ó ó óð ðˆŒ à �9‰9Рؘ×)Ñ)Ñ)Ø×)Ñ)¨%Ñ0�àˆŒ ؈Ü$ U§[¡[°Ó%5Ö6‰KˆE�4Ü�t“9ˆDð˜ŠzØ�ØØ˜!’ؘ1’9Ü$¤Vðô˜U› ó &óðð ˜Q’Y 4¨2¢:Ü$¤Vðô˜T› ó &óðð ™  dÑ*�ä" 4¨$¡;Ó/ˆLؘ1‘9ˆDؘ’(Ü& t¨t°d©{Ñ';Ó<¸|ÑK� ؘq‘y�ð˜“(ð �MŠM˜\Ñ )ŽMð=7ð@ˆŒ Ø �=‰=˜CÒ ØˆD�Mð r+có—|jSr+)ÚdottedrZs r*rYzObjectIdentifier.__unicode__? s€ð �{‰{Ðr+cóŽ—|j�€-g}d}|jD�]}tr t|«}|dz}||dzz }|dzdk(sŒ+t |«dk(r¯|dk\r8|j t d««|j t |dz ««nŒ|dk\r8|j t d««|j t |dz ««nO|j t d««|j t |««n|j t |««d}�Œdj|«|_|jS) z� :return: A unicode string of the object identifier in dotted notation, thus ignoring any mapped value rrréPr"rr r)Ú_dottedrJrWrxrDr!rr)rLr¹r Úbytes r*r zObjectIdentifier.dottedG s €ð �<‰<Ñ ØˆFàˆDØŸ � �Ýܘt›9�Dؘc‘z�ؘ˜s™ Ñ"�à˜$‘; !Ó#ܘ6“{ aÒ'Ø 2š:Ø"ŸM™M¬'°!«*Ô5Ø"ŸM™M¬'°$¸±)Ó*<Õ=Ø! RšZØ"ŸM™M¬'°!«*Ô5Ø"ŸM™M¬'°$¸±)Ó*<Õ=à"ŸM™M¬'°!«*Ô5Ø"ŸM™M¬'°$«-Õ8àŸ ™ ¤g¨d£mÔ4Ø’Dð'&ð*Ÿ8™8 FÓ+ˆDŒLØ�|‰|Ðr+cóò—|j€y|j€|j|_|j�6|j|jvr|j|j|_|jS)aC The native Python datatype representation of this value :return: A unicode string or None. If _map is not defined, the unicode string is a string of dotted integers. If _map is defined and the dotted string is present in the _map, the mapped value is returned. N)rJr‚r rªrZs r*r�zObjectIdentifier.nativek s]€ð �=‰=Ð Øà �<‰<Ð ØŸ;™;ˆDŒLØ �9‰9Ð  T§\¡\°T·Y±YÑ%>ØŸ9™9 T§\¡\Ñ2ˆDŒLØ�|‰|Ðr+)rŸr r¡r¢r4rr¤r“rrHrYr×r r�r¥r+r*r÷r÷Ÿ sq„ñð €Cð€Gàñ*óð*ðBñ/óð/òb? òBðñ!óð!ðFñóñr+r÷có—eZdZdZdZy)ÚObjectDescriptorzO Represents an object descriptor from ASN.1 - no Python implementation rvN©rŸr r¡r¢r4r¥r+r*rr€ ó„ñð �Cr+rcó—eZdZdZdZy)Ú InstanceOfzF Represents an instance from ASN.1 - no Python implementation rtNrr¥r+r*rrˆ rr+rcó—eZdZdZdZy)ÚRealzH Represents a real number from ASN.1 - no Python implementation é Nrr¥r+r*rr� rr+rcó*—eZdZdZdZd„Zed„«Zy)Ú Enumeratedz\ Represents a enumerated list of integers from ASN.1 as a Python unicode string é c ó´—t|t«s8t|t«s(tt dt |«t |«««‚t|t«r=||j vrtt dt |«|««‚|j |}n-||jvrtt dt |«|««‚tj||«y)zÅ Sets the value of the object :param value: An integer or a unicode string from _map :raises: ValueError - when an invalid value is passed zY %s value must be an integer or a unicode string, not %s zL %s value "%s" is not a valid value zB %s value %s is not a valid value N) r2rrr3r rr«rBrªrhrHrs r*rHzEnumerated.set  sÓ€ô˜%¤Ô+´J¸uÄgÔ4NÜœFðô˜$“ܘ%Ó ó óð ô �eœWÔ %ؘD×-Ñ-Ñ-Ü ¤ðô˜d“OØó "óðð×%Ñ% eÑ,‰Eà ˜$Ÿ)™)Ñ #ÜœVðô˜$“Øó óð ô � ‰ �D˜%Õ r+có�—|j€y|j€"|j|j«|_|jSr[)rJr‚rªrnrZs r*r�zEnumerated.nativeË s;€ð �=‰=Ð Øà �<‰<Ð ØŸ9™9 T§\¡\£^Ñ4ˆDŒLØ�|‰|Ðr+NrËr¥r+r*rr˜ s(„ñð €Cò)!ðVñ óñ r+rcó—eZdZdZdZdZy)Ú UTF8StringzI Represents a UTF-8 string from ASN.1 as a Python unicode string é rfN©rŸr r¡r¢r4rUr¥r+r*r!r!Ü ó„ñð €CØ�Ir+r!có—eZdZdZdZy)Ú RelativeOidrøé Nrr¥r+r*r&r&å s„ñð �Cr+r&có‡—eZdZdZdZdZdZdZdZdZ gZ dZ dZ dZ dZdZdZdZdd„Zed„«Zej*d „«Zd „Zd „Zd „Zd „Zd„Zd„Zd„Zdd„Zd„Zd„Zd„Z dd„Z!d„Z"ed„«Z#ˆfd„Z$dd„Z%dd„Z&ˆxZ'S)ÚSequencezf Represents a sequence of fields from ASN.1 as a Python object with a dict-like interface érr NFc ó¨—tj|fi|¤Žd}|€1|�/d}|j€|j€d}n|j «|}|��0 |j r6|j D�cgc]}|d‘Œ }}t |j««}n|j«}t |«}|D]�}|rR|j|} | t|j«kr+|j| tur||vr|j|«ŒW||vsŒ\|j|||«|j|«Œƒt|«r@ttdt|«dj!t#t%|«««««‚yycc}w#tt&f$r=} | j(dd} | j(ddt|«zzf| z| _| ‚d} ~ wwxYw) a" Allows setting field values before passing everything else along to Asn1Value.__init__() :param value: A native Python datatype to initialize the object value with :param default: The default value if no value is specified FNTrzŒ One or more unknown fields was passed to the constructor of %s: %s r r r>)r'rSÚchildrenrJÚ_parse_childrenÚ_fieldsrHr�Ú _field_maprDÚVOIDr¥r"rBr rrÚsortedrúr3rK) rLr8rPr7Úcheck_existingr÷r�Ú unused_keysr­rörRrKs r*rSzSequence.__init__' s΀ô ×ј4Ñ* 6Ò*àˆØ ˆ=˜WÐ0Ø!ˆNØ�}‰}Ð$Ø—=‘=Ð(Ø%*‘Nà×(Ñ(Ô*؈Eà Ñ ð& ð—<’<Ø04· ² Ó=± ¨˜D ›G° �DÐ=Ü"% e§j¡j£lÓ"3‘Kà Ÿ:™:›<�DÜ"% d£)�Kã�Cñ&Ø $§¡°Ñ 4˜Ø ¤3 t§}¡}Ó#5Ò5¸$¿-¹-ÈÑ:NÔVZÑ:ZØ" kÑ1Ø +× 2Ñ 2°3Ô 7Ø$à˜e’|Ø×(Ñ(¨¨e°C©jÔ9Ø#×*Ñ*¨3Õ/ð ô�{Ô#Ü$¤Vðô" $›ØŸ ™ ¤&¬¨kÓ):Ó";Ó<ó &óðð$ð5 ùò >øô<¤ Ð*ò Ø—v‘v˜a˜b�z�ØŸ&™& ™)Ð&CÄiÐPTÃoÑ&UÑUÐWÐZ^Ñ^�”Ø�ûð ús2ÁFÁ* FÁ6BFÄ A3FÆFÆGÆ8G Ç GcóŠ—|j€ |jS|j«r|j«|jS©z` :return: A byte string of the DER-encoded contents of the sequence ©r,rÚ _is_mutatedÚ _set_contentsrZs r*rJzSequence.contentsh ó:€ð �=‰=Ð Ø—>‘>Ð !à × Ñ Ô Ø × Ñ Ô à�~‰~Ðr+có—||_y©ze :param value: A byte string of the DER-encoded contents of the sequence Nrrs r*rJzSequence.contentsw rr+có—|j}|j�F|jD]7}t|t«st|t«sŒ$|xs|j «}Œ9|S©z~ :return: A boolean - if the sequence or any children (recursively) have been mutated ©Ú_mutatedr,r2r)Ú SequenceOfr7©rLÚmutatedr4s r*r7zSequence._is_mutated€ óR€ð—-‘-ˆØ �=‰=Ð $ØŸœ�ܘe¤XÔ.´*¸UÄJÕ2OØ%Ò<¨×):Ñ):Ó)<‘Gð'ðˆr+cóx—|j|}|jtk(rt|Žx}|j|<|S©z] Builds a child object if the child has only been parsed into a tuple so far ©r,r?rûÚ_build©rLrör4s r*Ú _lazy_childzSequence._lazy_child� s:€ð — ‘ ˜eÑ$ˆØ �?‰?œeÒ #Ü+1°5¨>Ð 9ˆE�D—M‘M %Ñ(؈ r+cód—|j€|j«t|j«Sr9©r,r-rDrZs r*rÎzSequence.__len__™ ó)€ð �=‰=Ð Ø × Ñ Ô "ä�4—=‘=Ó!Ð!r+c ó—|j€|j«t|t«s<||jvrt t d|t|«««‚|j|}|t|j«k\rt t d|t|«««‚ |j|«S#ttf$r=}|jdd}|jddt|«zzf|z|_ |‚d}~wwxYw)a9 Allows accessing fields by name or index :param key: A unicode string of the field name, or an integer of the field index :raises: KeyError - when a field name or index is invalid :return: The Asn1Value object of the field specified NúL No field named "%s" defined for %s zL No field numbered %s is present in this %s r rrå) r,r-r2rr/r;r rrDrIrBr3rK)rLr­rRrKs r*r=zSequence.__getitem__¤ s€ð �=‰=Ð Ø × Ñ Ô "ä˜#œyÔ)ؘ$Ÿ/™/Ñ)Üœvððܘd“Oó  óðð—/‘/ #Ñ&ˆCà ”#�d—m‘mÓ$Ò $Üœ6ððܘ$“ó óð ð Ø×#Ñ# CÓ(Ð (øäœIÐ&ò Ø—6‘6˜!˜"�:ˆDØ—f‘f˜Q‘iÐ":¼YÀt»_Ñ"LÑLÐNÐQUÑUˆAŒF؈Gûð úsÂ!B2Â2C>Ã8C9Ã9C>c ó|—|j€|j«t|t«s<||jvrt t d|t|«««‚|j|}|j|«\}}}}}|j|||||«}d} t|t«r|jdu} n|jdu} | rtt d|t|«««‚||j|<|j�6|j|j|j|j |d<d|_y)a� Allows settings fields by name or index :param key: A unicode string of the field name, or an integer of the field index :param value: A native Python datatype to set the field value to. This method will construct the appropriate Asn1Value object from _fields. :raises: ValueError - when a field name or index is invalid NrNFzG Value for field "%s" of %s is not set rT)r,r-r2rr/r;r rÚ_determine_specÚ _make_valuerÙr‰rJrBr‚r�r.r?) rLr­r8Ú field_nameÚ field_specÚ value_specÚ field_paramsr9Ú new_valueÚ invalid_values r*r"zSequence.__setitem__Ò s=€ð �=‰=Ð Ø × Ñ Ô "ä˜#œyÔ)ؘ$Ÿ/™/Ñ)Üœvððܘd“Oó  óðð—/‘/ #Ñ&ˆCà>B×>RÑ>RÐSVÓ>WÑ;ˆ �J  ¨L¸!à×$Ñ$ Z°¸ZÈÐW\Ó]ˆ àˆ Ü �i¤Ô %Ø%×,Ñ,°Ð4‰Mà%×.Ñ.°$Ð6ˆMá ÜœVððܘ$“ó óð ð'ˆ� ‰ �cÑà �<‰<Ð #Ø15·±¸sÑ1C×1JÑ1JˆD�L‰L˜Ÿ™ cÑ*¨1Ñ-Ñ .؈� r+c óò—|j€|j«t|t«s<||jvrt t d|t|«««‚|j|}|j|\}}}|rd|vr#d|vrtt d|t|«««‚d|vr6t|j|<|j�)d|j|<d|_ y|j|d«d|_ y)a/ Allows deleting optional or default fields by name or index :param key: A unicode string of the field name, or an integer of the field index :raises: ValueError - when a field name or index is invalid, or the field is not optional or defaulted NrNrPrOz‰ Can not delete the value for the field "%s" of %s since it is not optional or defaulted T)r,r-r2rr/r;r rr.rBr0r‚r"r?)rLr­rþr9rÿs r*Ú __delitem__zSequence.__delitem__ s€ð �=‰=Ð Ø × Ñ Ô "ä˜#œyÔ)ؘ$Ÿ/™/Ñ)Üœvððܘd“Oó  óðð—/‘/ #Ñ&ˆCàŸ,™, sÑ+‰ˆˆa�Ù˜)¨6Ñ1°jÈÑ6NÜœVððܘ$“ó óð ð ˜Ñ Ü!%ˆD�M‰M˜#Ñ Ø�|‰|Ð'Ø%)�— ‘ ˜TÑ"ðˆ� ð × Ñ ˜S $Ô '؈� r+c#ó<K—|jD] }|d–—Œ y­w)zE :return: An iterator of field key names rN)r.)rLr÷s r*rÑzSequence.__iter__6sèø€ð —L”LˆDØ�q‘'‹Mñ!ùs‚cóL—|j€|j«t«}t|j«D]³\}}|j|}|€d}n[|j t k(r6|r"|j|«j|¬«}n$|d|dz|dz}n|j|¬«}|dr)d|dvr"|d d i|d¤Ž}|j«|k(rŒ£|j|«Œµ|j«|_ d|_ |jdk7rd|_ yy) a Updates the .contents attribute of the value with the encoded value of all of the child objects :param force: Ensure all contents are in DER format instead of possibly using cached BER-encoded data Nr+rërrÎrór"rPr r¥)r,r-rrór.r?rûrIrcÚwriteÚgetvaluerr–r™)rLršrJrör÷r4Ú child_dumpÚ default_values r*r8zSequence._set_contents?s"€ð �=‰=Ð Ø × Ñ Ô "ä“9ˆÜ$ T§\¡\Ö2‰KˆE�4Ø—M‘M %Ñ(ˆE؈}Ø ‘ Ø—‘¤EÒ)ÙØ!%×!1Ñ!1°%Ó!8×!=Ñ!=ÀEÐ!=Ó!J‘Jà!& q¡¨E°!©HÑ!4°u¸Q±xÑ!?‘Jà"ŸZ™Z¨e˜ZÓ4� à�AŠw˜9¨¨Q©Ñ/Ø '  Q¡Ñ 2¨$¨q©'Ñ 2� Ø ×%Ñ%Ó'¨:Ò5ØØ �N‰N˜:Õ &ð!3ð""×*Ñ*Ó,ˆŒàˆŒ Ø �=‰=˜CÒ ØˆD�Mð r+có*—|j}i|_g|_g|_t |j «D]e\}}t |«dkr|ifz}||j |<||j|d<|jjt|d|d««Œg|j�=|j|jd|j|jdf|_ t |j «D]”\}}|jduxr|d|jv}|jduxr|jd|k(}|s|r|jjd«Œi|jj|d|d|d|ddf«Œ–y©zS Generates _field_map, _field_ids and _oid_nums for use in parsing rrr"r N) r?r/Ú _field_idsÚ_precomputed_specsrór.rDr!rõÚ _oid_pairÚ _oid_numsÚ_spec_callbacks©rLr6röÚfieldÚ has_callbackÚ is_mapped_oids r*r;zSequence._setupdst€ð �n‰nˆØˆŒØˆŒØ!#ˆÔÜ% c§k¡kÖ2‰LˆE�5Ü�5‹z˜AŠ~Ø  ™ �Ø%*�— ‘ ˜EÑ"Ø',ˆC�N‰N˜5 ™8Ñ $Ø �N‰N× !Ñ !¤/°%¸±(¸EÀ!¹HÓ"EÕ Fð 3ð �=‰=Ð $Ø Ÿ^™^¨C¯M©M¸!Ñ,<Ñ=¸s¿~¹~ÈcÏmÉmÐ\]ÑN^Ñ?_Ð`ˆCŒMä% c§k¡kÖ2‰LˆE�5Ø×.Ñ.°dÐ:Ò^¸uÀQ¹xÈ3×K^ÑK^Ð?^ˆLØŸM™M°Ð5ÒS¸#¿-¹-ÈÑ:JÈeÑ:SˆMÙ™}Ø×&Ñ&×-Ñ-¨dÕ3à×&Ñ&×-Ñ-¨u°Q©x¸¸q¹À5ÈÁ8ÈUÐSTÉXÐW[Ð.\Õ]ñ 3r+cóà—|j|\}}}|}d}|j�`||jvrR|j|}||«}|rž|jtk(rt |«dk(r |\}}|€v|}d}nq|€|}|}d}nh|}ne|j �Y|j d|k(rG|j |j d«j}||jvr|j|}|}|||||fS)a Determine how a value for a field should be constructed :param index: The field number :return: A tuple containing the following elements: - unicode string of the field name - Asn1Value class of the field spec - Asn1Value class of the value spec - None or dict of params to pass to the field spec - None or Asn1Value class indicating the value spec was derived from an OID or a spec callback Nr"r r) r.rfr?rûrDrerIr�Ú _oid_specs) rLrörþrSrUrTÚ spec_overrideÚcallbackÚoids r*rPzSequence._determine_specs€ð *.¯©°eÑ)<Ñ&ˆˆj˜,؈ ؈ à × Ñ Ð +°¸×8LÑ8LÑ0LØ×+Ñ+¨DÑ1ˆHÙ$ T›NˆMÙð!×*Ñ*¬eÒ3¼¸MÓ8JÈaÒ8OØ-:Ñ*�J  Ø!Ð)Ø%/˜ Ø(,™ àÐ'Ø!.�JØ!+�JØ$(‘Mà!.‘Jà �^‰^Ð '¨D¯N©N¸1Ñ,=ÀÒ,FØ×"Ñ" 4§>¡>°!Ñ#4Ó5×<Ñ<ˆCØ�d—o‘oÑ%Ø $§¡°Ñ 4� Ø*� à�j *¨l¸MÐJÐJr+c ó—|€ d|vrtS||k7}t|t«}t|t«rÒt |t «}t |t «xrt|«dk(} t |t«xrt|«dk(} |s#| s!| sttd|t|«««‚| s| r||«}t ||«sB|«} | j|j|j|j«|| _| } nþ|} nût ||«r|} |rë| j#|«nÙ|r|rSt ||«sG|r|r9t |t «r)t%td|t|«t|«««‚||fi|¤Ž} n‚t ||«r|} nAt |t «r)t%td|t|«t|«««‚||«} |r0|s.|d d| j'«i|¤Ž} | | j(df| _| } t+| |«} | S) a& Contructs an appropriate Asn1Value object for a field :param field_name: A unicode string of the field name :param field_spec: An Asn1Value class that is the field spec :param value_spec: An Asn1Value class that is the vaue spec :param field_params: None or a dict of params for the field spec :param value: The value to construct an Asn1Value object from :return: An instance of a child class of Asn1Value NrOr"r z¯ Can not set a native python value to %s, which has the choice type of %s - value must be an instance of Asn1Value zE %s value must be %s, not %s zM %s value must be %s, not %s r8r¥)r0Ú issubclassrÙrîr2r'rûrDrzrBr rrrGr4rJrÛrÝr3rcr?rý) rLrRrSrTrUr8Úspecs_differentÚis_anyÚ is_asn1valueÚis_tupleÚis_dictÚwrapperrVs r*rQzSequence._make_value®s €ð. ˆ=˜Z¨<Ñ7܈Kà$¨ Ñ2ˆÜ˜J¬Ó,ˆä �j¤&Ô )Ü% e¬YÓ7ˆLÜ! %¬Ó/ÒC´C¸³JÀ!±OˆHÜ  ¬Ó-ÒA´#°e³*À±/ˆGÙ©¹Ü ¤ððܘjÓ)ó "óðñ™7Ù" 5Ó)�ܘe ZÔ0Ù$›,�Ø× Ñ  §¡¨u¯y©y¸%¿.¹.ÔIØ"'�”Ø#‘ à!‘ ä ˜˜zÔ *؈IÙØ—‘  Õ+á!¡V´ZÀÀzÔ5RÙ™o´:¸eÄYÔ3OܤððܘjÓ)ܘeÓ$ó !óðñ# 5Ñ9¨LÑ9‰Iô˜% Ô,Ø!‘ ä˜e¤YÔ/Ü#¤Fðð#Ü! *Ó-Ü! %Ó(ó %óðñ' uÓ-� ñ ¡vÙ$ÑL¨9¯>©>Ó+;ÐL¸|ÑL�Ø#,¨i×.AÑ.AÀ4Ð"H�”Ø#� ä  ¨LÓ9ˆ àÐr+c óÒ—|j}|j€³|jr¦tgt |j«z|_t |j«D]l\}\}}}d|vsŒ|j|r|j|\}}}} }n|j|«\}}}} }|j|||| d«|j |<Œny g|_t |j«} d} d} t |j«} d}| | k}|�r^|€t|j| | ¬«\}} | | k}| | k�r |j| xs|j| «\}}}} }| r´d| vsd| vr¬|j| |d|dfk7r’|tk7r‰d}t|t«r' |di| ¤Ž}|j|d|d|d«d }|sNd| vr |j j#t«n!|j j#|di| ¤Ž«| d z } d }�Œ |�|rt|t«r|}d}|r ||| |fz}nÝ||| fz}nÕ| dkDrÎ| d z| krÆg}| d z }|dk\rK|j|}t |«d krn-d|dvsd|dvr|j#|d«|d z}|dk\rŒKt |«d kDrd nd }dj%|«}t!t'd| d zt(j+|d«t,j+|d «|d||««‚|}|r0t/|Ž}t1|t2t4f«r|j7d ¬«|j j#|«| d z } d}|r�Œ^t |j «}|| kr~|j|\}}} d| vr"|j j#|di| ¤Ž«n9d| vr |j j#t«nt!t'd|««‚|d z }|| krŒ}yy#t $rY�ŒMwxYw#t t8f$rD}d|_|j:d d}|j:ddt=|«zzf|z|_|‚d}~wwxYw)áQ Parses the contents and generates Asn1Value objects based on the definitions from _fields. :param recurse: If child objects that are Sequence or SequenceOf objects should be recursively parsed :raises: ValueError - when an error occurs parsing child objects NrPr©r·rOr"FrÎTr rÚsrWr z¥ Data for field %s (%s class, %s method, tag %s) does not match the field definition%s of %s ©ÚrecursezV Field "%s" is missing from structure rår¥)r?rr.r0rDr,rórcrPrQrrbrÙrqrîrrBr!rr rEr{ÚMETHOD_NUM_TO_NAME_MAPrGr2r)r@r-r3rKr)rLr}r6rör9rÿrRrSrTrUÚcontents_lengthÚ child_pointerrhÚ field_lenÚpartsÚagainrmÚ choice_matchÚtesterr4Ú missed_fieldsÚ prev_fieldÚprev_field_infoÚpluralÚmissed_field_namesrþrRrKs r*r-zSequence._parse_childrensÕ€ð�n‰nˆØ �>‰>Ð !Ø�|Š|Ü!% ¬¨T¯\©\Ó):Ñ :�” Ü-6°t·|±|Ö-DÑ)�E™>˜A˜q &Ø  FÒ*Ø×1Ñ1°%Ò8ØRU×RhÑRhÐinÑRoÑO˜J¨ °JÀ ÉaàRV×RfÑRfÐglÓRmÑO˜J¨ °JÀ ÈaØ/3×/?Ñ/?À ÈJÐXbÐdpÐrvÓ/w˜Ÿ ™  eÒ,ð .Eð ðl ؈DŒMÜ! $§.¡.Ó1ˆO؈M؈EܘDŸL™LÓ)ˆI؈EØ! OÑ3ˆEÚØ�=Ü+1°$·.±.À/Ð[hÔ+iÑ(�E˜=Ø%¨Ñ7�à˜9Ó$à×.Ñ.¨uÑ5ÒT¸×9MÑ9MÈeÓ9TñK�A�z :¨|¸]ñ$¨°|Ñ)CÀyÐT`ÑG`ØŸ?™?¨5Ñ1°e¸A±hÀÀaÁÐ5IÒIÈjÔ\_ÒN_ð,1˜LÜ)¨*´fÔ=ð!)Ù-7Ñ-G¸,Ñ-G FØ$*§O¡O°E¸!±H¸eÀA¹hÈÈaÉÔ$QØ37 Lñ$0Ø#-°Ñ#=Ø$(§M¡M×$8Ñ$8¼Õ$>à$(§M¡M×$8Ñ$8¹Ñ9SÀlÑ9SÔ$TØ %¨¡  Ø(, Ù (à!Ð)©mÄ È:ÔWZÔ@[Ø%/˜ Ø(,˜ á$Ø %¨°\À:Ð(NÑ N™à %¨°\Ð(BÑ B™ð ’] u¨q¡y°IÒ'=Ø$&�MØ!&¨¡�JØ$¨š/Ø*.¯,©,°zÑ*B˜Ü˜Ó/°!Ò3Ø!Ø%¨¸Ñ);Ñ;¸yÈOÐ\]ÑL^Ñ?^Ø)×0Ñ0°ÀÑ1CÔDØ" a™˜ ð %¨›/ô%(¨ Ó$6¸Ò$:™SÀ�FØ)-¯©°=Ó)AÐ&Ü$¤Vðð ™ Ü-×1Ñ1°%¸±(Ó;Ü.×2Ñ2°5¸±8Ó<ؘa™ØØ*ó &ó ð ð"�EáÜ" E˜N�EÜ! %¬(´JÐ)?Ô@Ø×-Ñ-°dÐ-Ô;à— ‘ ×$Ñ$ UÔ+ؘ‘ �Ø�ó]ô`˜Ÿ ™ Ó&ˆEؘ)Ò#Ø15·±¸eÑ1DÑ.��j ,Ø  Ñ,Ø—M‘M×(Ñ(©Ñ)C°lÑ)CÕDØ <Ñ/Ø—M‘M×(Ñ(¬Õ.ä$¤Vððó &óð𠘑 �ð˜)Õ#øôy)3ò!)Ú$(ð!)ûôVœIÐ&ò Ø ˆDŒMØ—6‘6˜!˜"�:ˆDØ—f‘f˜Q‘iÐ":¼YÀt»_Ñ"LÑLÐNÐQUÑUˆAŒF؈Gûð  úsLà CPÆ&PÇCPÊ!CPÍ*BPÐ PÐ PÐPÐPÐQ&Ð"?Q!Ñ!Q&c ó—t|t«sttdt |«««‚|j €(t tdt|«t |«««‚|j|}|j|«}|dS)a Determines the spec to use for the field specified. Depending on how the spec is determined (_oid_pair or _spec_callbacks), it may be necessary to set preceding field values before calling this. Usually specs, if dynamic, are controlled by a preceding ObjectIdentifier field. :param field_name: A unicode string of the field name to get the spec for :return: A child class of asn1crypto.core.Asn1Value that the field must be encoded using zM field_name must be a unicode string, not %s z‡ Unable to retrieve spec for field %s in the class %s because _fields has not been set r") r2rr3r rr.rBrCr/rP)rLrRrör÷s r*r0z Sequence.spec–s�€ô ˜*¤gÔ.ÜœFðô˜*Ó%ó óð ð �<‰<Ð ÜœVðô�ZÓ Ü˜$“ó óð ð—‘  Ñ+ˆØ×#Ñ# EÓ*ˆà�A‰wˆr+cóˆ—|j€y|j€®|j€|jd¬« t «|_t |j«D][\}}|j tk(rt|Ž}||j|< |j|d}|j|j|<Œ] |jS|jS#t$rt|«}YŒJwxYw#ttf$rD}d|_|jdd}|jddt!|«zzf|z|_|‚d}~wwxYw)zè The native Python datatype representation of this value :return: An OrderedDict or None. If an OrderedDict, all child values are recursively converted to native representation also. NTr|rr rå)rJr‚r,r-r rór?rûrGr.Ú IndexErrorrr�rBr3rKr)rLrör4rþrRrKs r*r�zSequence.native½s1€ð �=‰=Ð Øà �<‰<Ð Ø�}‰}Ð$Ø×$Ñ$¨TÐ$Ô2ð Ü*›}�” Ü$-¨d¯m©mÖ$<‘L�E˜5Ø—‘¬%Ò/Ü &¨ ˜Ø/4˜Ÿ ™  eÑ,ð.Ø#Ÿ|™|¨EÑ2°1Ñ5˜ð*/¯©�D—L‘L Ò&ñ%=ð�|‰|Јt�|‰|Ðøô'ò.Ü& u›~šð.ûô¤ Ð*ò Ø#�” Ø—v‘v˜a˜b�z�ØŸ&™& ™)Ð&>ÄÈ4ÃÑ&PÑPÐRÐUYÑY�”Ø�ûð  ús<¹AC.ÂC C.ÃC+Ã(C.Ã*C+Ã+C.Ã.EÃ=?D<Ä<Ecó(•—tt|� ||«|j�qg|_|jD]Z}|jt k(r|jj |«Œ2|jj |j««Œ\yy)a  Copies the contents of another Sequence object to itself :param object: Another instance of the same class :param copy_func: An reference of copy.copy() or copy.deepcopy() to use when copying lists, dicts and objects N)rÀr)rnr,r?rûr!ro©rLr„r…r4r?s €r*rnzSequence._copyßspø€ô Œh˜Ñ# E¨9Ô5Ø �=‰=Ð $؈DŒMØŸœ�Ø—?‘?¤eÒ+Ø—M‘M×(Ñ(¨Õ/à—M‘M×(Ñ(¨¯©«Õ6ñ (ð %r+có—|j€|j«d|z}t||«|D]N}|j|j|«}|t usŒ*t |›d|›d�«|j|dz«ŒPy)r‡Nrˆz Field "Ú"r)r,r-r‹rIr/r0rŽrŒ)rLr�r�rRr4s r*rŒzSequence.debugôsv€ð �=‰=Ð Ø × Ñ Ô "à˜ Ñ"ˆÜ�V˜TÔ"ÛˆJØ×$Ñ$ T§_¡_°ZÑ%@ÓAˆEØœDÒ ÜªF²JÐ?Ô@Ø— ‘ ˜J¨™NÕ+ñ r+có¶—|j�|jdddk(rd}|r#|jgk(r|jturd}|r|j |¬«|jr`|j �Tt |j«D]<\}\}}}|j |turŒ d|vsd|vrŒ)ttd |««‚tj|«S) r“Nr”r•TFrërPrOzN Field "%s" is missing from structure ) r–r.r?r)r8r,rór0rBr r'rc)rLršrörRr9rÿs r*rcz Sequence.dumpsÞ€ð �<‰<Ð #¨¯ © °R°SÐ(9¸WÒ(D؈Eñ �T—\‘\ RÒ'¨D¯N©N¼hÑ,F؈Eá Ø × Ñ  UÐ Ô +à �<Š<˜DŸM™MÐ5Ü2;¸D¿L¹LÖ2IÑ.�Ñ.˜  A vØ—=‘= Ñ'¬tÑ3ØØ Ñ&¨*¸Ñ*>ØÜ ¤ððó "óðð 3Jô�~‰~˜dÓ#Ð#r+rìrœrž)(rŸr r¡r¢r4rGrIr,rr?r.rfr/rbrdrlrercrSr×rJrr7rIrÎr=r"rYrÑr8r;rPrQr-r0r�rnrŒrcrÂrÃs@r*r)r)î s ø„ñð €Cà €FØ €Fð€Hð€Ið€Hð€Gð€Oð€Jð€Jð €Ið€Jð€IðÐó?ðBñ óð ð‡_�_ñóðò òò "ò,ò\5òn+òZó# òJ^ò6-Kò^^ó@FòP%ðNñóðôB7ó*,÷ $$r+r)có쇗eZdZdZdZdZdZdZdZdZ dZ dd„Z e d„«Z e jd „«Z d „Zd „Zd „Zd „Zd„Zd„Zd„Zd„Zd„Zd„Zdd„Zdd„Zd„Ze d„«Zˆfd„Zdd„Zdd„ZˆxZ S)r@z� Represents a sequence (ordered) of a single type of values from ASN.1 as a Python object with a list-like interface r*rr NFc óŒ—|r||_tj|fi|¤Ž |�||_y|€|�|}|�Ct |«D]\}}|j ||«Œ|j€|j «yyy#ttf$r=}|jdd} |jddt|«zzf| z|_ |‚d}~wwxYw)a Allows setting child objects and the _child_spec via the spec parameter before passing everything else along to Asn1Value.__init__() :param value: A native Python datatype to initialize the object value with :param default: The default value if no value is specified :param contents: A byte string of the encoded contents of the value :param spec: A class derived from Asn1Value to use to parse children Nr rr>) Ú _child_specr'rSrJrór"r8rBr3rKr) rLr8rPrJr0r7rör4rRrKs r*rSzSequenceOf.__init__Csà€ñ$ Ø#ˆDÔ ä×ј4Ñ* 6Ò*ð ØÐ#Ø (�• à�= WÐ%8Ø#�EàÐ$Ü(1°%Ö(8™ ˜˜uØ×(Ñ(¨°Õ6ð)9ð—}‘}Ð,Ø×*Ñ*Õ,ð-ð %øôœIÐ&ò Ø—6‘6˜!˜"�:ˆDØ—f‘f˜Q‘iÐ"?Ä)ÈDÃ/Ñ"QÑQÐSÐVZÑZˆAŒF؈Gûð ús¡ A7«A A7Á7CÂ8B>Â>CcóŠ—|j€ |jS|j«r|j«|jSr5r6rZs r*rJzSequenceOf.contentsnr9r+có—||_yr;rrs r*rJzSequenceOf.contents}rr+có—|j}|j�F|jD]7}t|t«st|t«sŒ$|xs|j «}Œ9|Sr=r>rAs r*r7zSequenceOf._is_mutated†rCr+cóx—|j|}|jtk(rt|Ž}||j|<|SrErFrHs r*rIzSequenceOf._lazy_child•s:€ð — ‘ ˜eÑ$ˆØ �?‰?œeÒ #ܘE�NˆEØ#(ˆD�M‰M˜%Ñ Øˆ r+cót—t||j«r|}�nt|jt«r1t|t«r|}nðt t dt|«««‚t|jt«r¦t|t«s3t t dt|«|jj««‚t||j«sJ|j«}|j|j|j|j«||_|}|}n|j|¬«Si}|jjr|jj|d<|jj r/|jj|jjf|d<t#||«S)a  Constructs a _child_spec value from a native Python data type, or an appropriate Asn1Value object :param value: A native Python value, or some child of Asn1Value :return: An object of type _child_spec z« Can not set a native python value to %s where the _child_spec is Any - value must be an instance of Asn1Value zÎ Can not set a native python value to %s where the _child_spec is the choice type %s - value must be an instance of Asn1Value )r8r<r=)r2r•rqrÙr'rBr rrîrŸrrGr4rJrÛr<r=rý)rLr8rVrwrÿs r*rQzSequenceOf._make_value sy€ô �e˜T×-Ñ-Ô .ØŠIä ˜×(Ñ(¬#Ô .ܘ%¤Ô+Ø!‘ ä ¤ðô˜d“Oó "óðô˜×(Ñ(¬&Ô 1ܘe¤YÔ/Ü ¤ðô ˜d“OØ×$Ñ$×-Ñ-ó"óðô˜e T×%5Ñ%5Ô6Ø×*Ñ*Ó,�Ø× Ñ  §¡¨u¯y©y¸%¿.¹.ÔIØ"'�”Ø�؉Ið×#Ñ#¨%Ð#Ó0Ð 0àˆØ × Ñ × $Ò $Ø!%×!1Ñ!1×!:Ñ!:ˆF�:Ñ Ø × Ñ × $Ò $Ø"&×"2Ñ"2×"9Ñ"9¸4×;KÑ;K×;OÑ;OÐ!PˆF�:Ñ Ü˜I vÓ.Ð.r+cód—|j€|j«t|j«S)rmrKrZs r*rÎzSequenceOf.__len__×rLr+có\—|j€|j«|j|«S)zm Allows accessing children via index :param key: Integer index of child )r,r-rIr<s r*r=zSequenceOf.__getitem__âs+€ð �=‰=Ð Ø × Ñ Ô "à×Ñ Ó$Ð$r+có¢—|j€|j«|j|«}|t|j«k(rB|jj d«|j �|j j d«||j|<|j �&|j|j |j |<d|_y)zñ Allows overriding a child via index :param key: Integer index of child :param value: Native python datatype that will be passed to _child_spec to create new child object NT)r,r-rQrDr!r‚r�r?)rLr­r8rVs r*r"zSequenceOf.__setitem__ðs§€ð �=‰=Ð Ø × Ñ Ô "à×$Ñ$ UÓ+ˆ ð ”#�d—m‘mÓ$Ò $Ø �M‰M× Ñ  Ô &Ø�|‰|Ð'Ø— ‘ ×#Ñ# DÔ)à&ˆ� ‰ �cÑà �<‰<Ð #Ø $§ ¡ ¨cÑ 2× 9Ñ 9ˆD�L‰L˜Ñ àˆ� r+cóΗ|j€|j«|jj|«|j�|jj|«d|_y)zk Allows removing a child via index :param key: Integer index of child NT)r,r-Úpopr‚r?r<s r*rYzSequenceOf.__delitem__sO€ð �=‰=Ð Ø × Ñ Ô "à � ‰ ×ј#ÔØ �<‰<Ð #Ø �L‰L× Ñ ˜SÔ !àˆ� r+c#ó²K—|j€|j«tdt|j««D]}|j |«–—Œy­w)zA :return: An iter() of child objects Nr)r,r-r’rDrI)rLrös r*rÑzSequenceOf.__iter__!sIèø€ð �=‰=Ð Ø × Ñ Ô "ä˜1œc $§-¡-Ó0Ö1ˆEØ×"Ñ" 5Ó)Ó )ñ2ùs‚AAc óÚ—|�|turyt||j«sÓ?¹$° § £ ¸$Ñ?�” ð �|‰|Јt�|‰|Ðùò @øÜ¤ Ð*ò Ø—v‘v˜a˜b�z�ØŸ&™& ™)Ð&>ÄÈ4ÃÑ&PÑPÐRÐUYÑY�”Ø�ûð ús(¹A5½A0ÁA5Á0A5Á5CÂ8B<Â<Ccó(•—tt|� ||«|j�qg|_|jD]Z}|jt k(r|jj |«Œ2|jj |j««Œ\yy)a" Copies the contents of another SequenceOf object to itself :param object: Another instance of the same class :param copy_func: An reference of copy.copy() or copy.deepcopy() to use when copying lists, dicts and objects N)rÀr@rnr,r?rûr!ror�s €r*rnzSequenceOf._copyºspø€ô Œj˜$Ñ% e¨YÔ7Ø �=‰=Ð $؈DŒMØŸœ�Ø—?‘?¤eÒ+Ø—M‘M×(Ñ(¨Õ/à—M‘M×(Ñ(¨¯©«Õ6ñ (ð %r+có”—|j€|j«d|z}t||«|D]}|j|dz«Œy)r‡Nrˆr )r,r-r‹rŒr3s r*rŒzSequenceOf.debugÏsH€ð �=‰=Ð Ø × Ñ Ô "à˜ Ñ"ˆÜ�V˜TÔ"ÛˆEØ �K‰K˜  Q™Õ 'ñr+có”—|j�|jdddk(rd}|r|j|¬«tj|«S)r“Nr”r•Trë)r–r8r'rcrÖs r*rczSequenceOf.dumpÜsH€ð �<‰<Ð #¨¯ © °R°SÐ(9¸WÒ(D؈Eá Ø × Ñ  UÐ Ô +ä�~‰~˜dÓ#Ð#r+)NNNNrœrž)!rŸr r¡r¢r4rGrIr,rr?r•rSr×rJrr7rIrQrÎr=r"rYrÑr£r!r8r-r0r�rnrŒrcrÂrÃs@r*r@r@+sÍø„ñð €Cà €FØ €Fð€Hð€Ið€Hð€Kó)ðVñ óð ð‡_�_ñóðò ò ò5/òn "ò %òò>ò$ *òò:ó( ó("òH  ðñóðô.7ó* (÷$r+r@có6—eZdZdZdZdZdZdZd„Zd d„Z d d„Z y) ÚSetzm Represents a set of fields (unordered) from ASN.1 as a Python object with a dict-like interface r réNcó—|j}i|_i|_g|_t |j «D]Y\}}t |«dkr|ifz}||j |<||j|d<||jt|d|d«<Œ[|j�=|j|jd|j|jdf|_ t |j «D]”\}}|jduxr|d|jv}|jduxr|jd|k(}|s|r|jjd«Œi|jj|d|d|d|ddf«Œ–yra) r?r/rbrcrór.rDrõrdrerfr!rgs r*r;z Set._setupsp€ð �n‰nˆØˆŒØˆŒØ!#ˆÔÜ% c§k¡kÖ2‰LˆE�5Ü�5‹z˜AŠ~Ø  ™ �Ø%*�— ‘ ˜EÑ"Ø',ˆC�N‰N˜5 ™8Ñ $ØBGˆC�N‰Nœ?¨5°©8°U¸1±XÓ>Ò ?ð 3ð �=‰=Ð $Ø Ÿ^™^¨C¯M©M¸!Ñ,<Ñ=¸s¿~¹~ÈcÏmÉmÐ\]ÑN^Ñ?_Ð`ˆCŒMä% c§k¡kÖ2‰LˆE�5Ø×.Ñ.°dÐ:Ò^¸uÀQ¹xÈ3×K^ÑK^Ð?^ˆLØŸM™M°Ð5ÒS¸#¿-¹-ÈÑ:JÈeÑ:SˆMÙ™}Ø×&Ñ&×-Ñ-¨dÕ3à×&Ñ&×-Ñ-¨u°Q©x¸¸q¹À5ÈÁ8ÈUÐSTÉXÐW[Ð.\Õ]ñ 3r+c óš—|j}|j€³|jr¦tgt |j«z|_t |j«D]l\}\}}}d|vsŒ|j|r|j|\}}}} }n|j|«\}}}} }|j|||| d«|j |<Œny i} t |j«} d} d} | | k�rt|j| | ¬«\}} |d|df}|jj|«}|€Gttd| t j|d«t"j|d«|d««‚|j|xs|j|«\}}}} }|�|rt%|t&«r|}d}|r ||| |fz}n||| fz}|r0t)|Ž}t+|t,t.f«r|j1d¬ «|| |<| dz } | | kr�Œt |j«}t3d|«D]—}|| vrŒ|j|xs|j|«\}}}} }|�|rt%|t&«r|}d}d }| sd}n(d | vrd| vrd}nd | vr t| |<nd| vr |di| ¤Ž| |<|sŒzttd |t5|«««‚g|_t3d|«D] }|j j7| |«Œ"y#tt8f$r=}|j:dd}|j:dd t5|«zzf|z|_|‚d}~wwxYw)ryNrPrrzr"z¥ Data for field %s (%s class, %s method, tag %s) does not match any of the field definitions r Tr|FrOzU Missing required field "%s" from %s rår¥)r?rr.r0rDr,rórcrPrQrJrrbr{rBr rEr~rqrÙrGr2r)r@r-r’rr!r3rK)rLr}r6rör9rÿrRrSrTrUÚ child_maprr€Ú seen_fieldr‚rørhrmr4Ú total_fieldsrþÚmissingrRrKs r*r-zSet._parse_childrens°€ð�n‰nˆØ �>‰>Ð !Ø�|Š|Ü!% ¬¨T¯\©\Ó):Ñ :�” Ü-6°t·|±|Ö-DÑ)�E™>˜A˜q &Ø  FÒ*Ø×1Ñ1°%Ò8ØRU×RhÑRhÐinÑRoÑO˜J¨ °JÀ ÉaàRV×RfÑRfÐglÓRmÑO˜J¨ °JÀ ÈaØ/3×/?Ñ/?À ÈJÐXbÐdpÐrvÓ/w˜Ÿ ™  eÒ,ð .Eð ðS ؈IÜ! $§-¡-Ó0ˆO؈M؈JØ /Ó1Ü'-¨d¯m©m¸_ÐVcÔ'dÑ$��}à˜Q‘x  q¡Ð*�àŸ™×+Ñ+¨CÓ0�Ø�=Ü$¤Vðð#Ü-×1Ñ1°%¸±(Ó;Ü.×2Ñ2°5¸±8Ó<ؘa™ó &ó ð ð×*Ñ*¨5Ñ1ÒP°T×5IÑ5IÈ%Ó5PñG��:˜z¨<¸ðÐ%©-¼JÀzÔSVÔÑ>�EáÜ" E˜N�EÜ! %¬(´JÐ)?Ô@Ø×-Ñ-°dÐ-Ô;à#(� ˜%Ñ Ø˜a‘� ðI  /Ô1ôL˜tŸ|™|Ó,ˆLä˜q ,Ö/�ؘIÑ%Øð×*Ñ*¨5Ñ1ÒP°T×5IÑ5IÈ%Ó5PñJ��j *¨l¸MðÐ%©-¼JÀzÔSVÔˆDŒMܘq ,Ö/�Ø— ‘ ×$Ñ$ Y¨uÑ%5Õ6ñ0øôœIÐ&ò Ø—6‘6˜!˜"�:ˆDØ—f‘f˜Q‘iÐ":¼YÀt»_Ñ"LÑLÐNÐQUÑUˆAŒF؈Gûð ús'à D=K>È BK>Ê'AK>Ë>M Ì 8MÍM cóô—|j€|j«g}t|j«D]e\}}|j|¬«}|j|\}}}d|vr|di|¤Žj«|k(rŒI|j |j |f«Œg|jd„¬«dj|D� cgc]} | d‘Œ c} «|_ d|_ |jdk7rd|_ yycc} w) ac Encodes all child objects into the contents for this object. This method is overridden because a Set needs to be encoded by removing defaulted fields and then sorting the fields by tag. :param force: Ensure all contents are in DER format instead of possibly using cached BER-encoded data NrërPcó —|dSrÍr¥)Úcts r*Úz#Set._set_contents..¤s€°°1²r+)r­r+r r¥) r,r-rórcr.r!r4Úsortrrr–r™) rLršÚchild_tag_encodingsrör4Úchild_encodingrþr0rUr·s r*r8zSet._set_contentsŠsø€ð �=‰=Ð Ø × Ñ Ô "à ÐÜ% d§m¡mÖ4‰LˆE�5Ø"ŸZ™Z¨e˜ZÓ4ˆNð(,§|¡|°EÑ':Ñ $ˆD�$˜ ؘLÑ(ÙÑ'˜,Ñ'×,Ñ,Ó.°.Ò@Øà × &Ñ &¨¯ © °>Ð'BÕ Cð5ð × Ñ Ñ%5Ð Ô6àŸ™Ñ3FÓ"GÑ3F¨R 2 a£5Ð3FÑ"GÓHˆŒØˆŒ Ø �=‰=˜CÒ ØˆD�Mð ùò#HsÂ> C5rœ) rŸr r¡r¢rIrGr4rbr;r-r8r¥r+r*r­r­òs1„ñð €FØ €FØ €Cð€Jò^ó6mô^ r+r­có—eZdZdZdZdd„Zy)ÚSetOfz~ Represents a set (unordered) of a single type of values from ASN.1 as a Python object with a list-like interface r®có —|j€|j«g}|D]#}|j|j|¬««Œ%dj t |««|_d|_|jdk7rd|_yy)aD Encodes all child objects into the contents for this object. This method is overridden because a SetOf needs to be encoded by sorting the child encodings. :param force: Ensure all contents are in DER format instead of possibly using cached BER-encoded data Nrër+) r,r-r!rcrr1rr–r™)rLršÚchild_encodingsr4s r*r8zSetOf._set_contents´sx€ð �=‰=Ð Ø × Ñ Ô "àˆÛˆEØ × "Ñ " 5§:¡:°E :Ó#:Õ ;ð🙤&¨Ó"9Ó:ˆŒØˆŒ Ø �=‰=˜CÒ ØˆD�Mð r+Nrœ)rŸr r¡r¢r4r8r¥r+r*r½r½¬s„ñð €Cô r+r½có—eZdZdZdZy)Ú EmbeddedPdvz A sequence structure é Nrr¥r+r*rÁrÁÍó„ñð �Cr+rÁcó—eZdZdZdZdZy)Ú NumericStringzK Represents a numeric string from ASN.1 as a Python unicode string érQNr#r¥r+r*rÅrÅÕó„ñð €CØ�Ir+rÅcó—eZdZdZdZdZy)ÚPrintableStringzM Represents a printable string from ASN.1 as a Python unicode string érQNr#r¥r+r*rÉrÉÞrÇr+rÉcó—eZdZdZdZdZy)Ú TeletexStringzK Represents a teletex string from ASN.1 as a Python unicode string éÚteletexNr#r¥r+r*rÌrÌçs„ñð €CØ�Ir+rÌcó—eZdZdZdZy)ÚVideotexStringzI Represents a videotex string from ASN.1 as a Python byte string éNrr¥r+r*rÐrÐðrÃr+rÐcó—eZdZdZdZdZy)Ú IA5StringzH Represents an IA5 string from ASN.1 as a Python unicode string éÚasciiNr#r¥r+r*rÓrÓør$r+rÓcó0—eZdZdZed„«Zed„«Zy)Ú AbstractTimezK Represents a time from ASN.1 as a Python datetime.datetime object c óä—t|«}|jj|«}|stt d|t |«««‚|j «}d}|drtj}nF|drA|ddk(rdnd}t|tt|d«t|d xsd «¬ «z«}|d rZtt|d «d t|d «z«dz}|d€|dz}n |d€|dz}t|jd««}nd }t|d«t|d«t|d«t|d«t|dxsd «t|dxsd «||dœS)z´ The parsed datetime string. :raises: ValueError - when an invalid value is passed :return: A dict with the parsed values z: Error parsing %s to a %s NÚzuluÚdsignÚ+r r”ÚdhourÚdminuter)ÚhoursÚminutesÚfractionri@BÚminuteiÚsecondé<ÚyearÚmonthÚdayÚhour)rärårærçrárâÚtzinforà)rÚ_TIMESTRING_RErrBr rÚ groupdictrÚutcrrr–r rDÚlimit_denominator)rLÚstringÚmÚgroupsÚtzÚsignÚfractÚ fract_usecs r*Ú _parsed_timezAbstractTime._parsed_times¥€ô˜“ˆà × Ñ × %Ñ % fÓ -ˆÙÜœVððܘ$“ó óð ð—‘“ˆà ˆØ �&Š>Ü—‘‰BØ �GŠ_ؘw™¨3Ò.‘1°BˆDÜ  ¬ ܘ& ™/Ó*ܘF 9Ñ-Ò2°Ó3ô)ñ"óˆBð �*Ò äÜ�F˜:Ñ&Ó'Ø”c˜& Ñ,Ó-Ñ-óðñˆEð �hÑÐ'ؘ‘ ‘ؘÑ!Ð)ؘ‘ �ä˜U×4Ñ4°QÓ7Ó8‰JðˆJô˜˜v™Ó'ܘ ™Ó)Ü�v˜e‘}Ó%ܘ˜v™Ó'ܘ& Ñ*Ò/¨aÓ0ܘ& Ñ*Ò/¨aÓ0ØØ"ñ  ð r+cóÚ—|j€y|j€G|j}|jdd«}|j |«}|r|t |¬«z }||_|jS)aF The native Python datatype representation of this value :return: A datetime.datetime object, asn1crypto.util.extended_datetime object or None. The datetime object is usually timezone aware. If it's naive, then it's in the sender's local time; see X.680 sect. 42.3 Nràr)Ú microseconds)rJr‚rôrŸÚ _get_datetimer)rLr‰ràr8s r*r�zAbstractTime.nativeFsi€ð �=‰=Ð Øà �<‰<Ð Ø×&Ñ&ˆFà—z‘z *¨aÓ0ˆHà×&Ñ& vÓ.ˆEáØœ°Ô9Ñ9�à ˆDŒLà�|‰|Ðr+N)rŸr r¡r¢r×rôr�r¥r+r*r×r×s0„ñðñ= óð= ð~ñóñr+r×cóZ—eZdZdZdZej dej«Zd„Z d„Z y)ÚUTCTimez^ Represents a UTC time from ASN.1 as a timezone aware Python datetime.datetime object éa  ^ # YYMMDD (?P\d{2}) (?P\d{2}) (?P\d{2}) # hhmm or hhmmss (?P\d{2}) (?P\d{2}) (?P\d{2})? # Matches nothing, needed because GeneralizedTime uses this. (?P) # Z or [-+]hhmm (?: (?PZ) | (?: (?P[-+]) (?P\d{2}) (?P\d{2}) ) ) $ có^—t|t«r€|js td«‚|j t «}d|j cxkrdkstd«‚td«‚|jd«}tr|jd«}tj||«d|_ y)zË Sets the value of the object :param value: A unicode string or a datetime.datetime object :raises: ValueError - when an invalid value is passed úMust be timezone awareižizMYear of the UTCTime is not in range [1950, 2049], use GeneralizedTime insteadz %y%m%d%H%M%SZrÕN) r2rrèrBÚ astimezonerräÚstrftimerWrXrPrHr‚rs r*rHz UTCTime.set‡s™€ô �eœXÔ &Ø—<’<Ü Ð!9Ó:Ð:ð×$Ñ$¤\Ó2ˆEà˜5Ÿ:™:Ô-¨Ò-Ü Ð!pÓqÐqð.Ü Ð!pÓqÐqà—N‘N ?Ó3ˆEÝØŸ ™  WÓ-�ä×ј4 Ô'ðˆ� r+có^—|ddkr|dxxdz cc<n |dxxdz cc<tdi|¤ŽS)z€ Create a datetime object from the parsed time. :return: An aware datetime.datetime object räé2iÐilr¥)r©rLr‰s r*r÷zUTCTime._get_datetime¥s:€ð �&‰>˜BÒ Ø �6‹N˜dÑ "ŒNà �6‹N˜dÑ "‹NäÑ!˜&Ñ!Ð!r+N© rŸr r¡r¢r4ÚreÚcompileÚXrérHr÷r¥r+r*rùrùcs8„ñð €Cð �R—Z‘Zð!ð4 �‰ó5€Nò8ó<"r+rùcóZ—eZdZdZdZej dej«Zd„Z d„Z y)ÚGeneralizedTimezŽ Represents a generalized time from ASN.1 as a Python datetime.datetime object or asn1crypto.util.extended_datetime object in UTC éaO ^ # YYYYMMDD (?P\d{4}) (?P\d{2}) (?P\d{2}) # hh or hhmm or hhmmss (?P\d{2}) (?: (?P\d{2}) (?P\d{2})? )? # Optional fraction; [.,]dddd (one or more decimals) # If Seconds are given, it's fractions of Seconds. # Else if Minutes are given, it's fractions of Minutes. # Else it's fractions of Hours. (?: [,.] (?P\d+) )? # Optional timezone. If left out, the time is in local time. # Z or [-+]hh or [-+]hhmm (?: (?PZ) | (?: (?P[-+]) (?P\d{2}) (?P\d{2})? ) )? $ có¨—t|ttf«rŸ|js t d«‚|j t «}|jr7dt|j«jd«jd«z}nd}|jd«|zdz}tr|jd«}tj||«d |_y ) a Sets the value of the object :param value: A unicode string, a datetime.datetime object or an asn1crypto.util.extended_datetime object :raises: ValueError - when an invalid value is passed rürrùr‘rWz %Y%m%d%H%M%SÚZrÕN)r2rrrèrBrýrÚ microsecondÚstrÚzfillr•rþrWrXrPrHr‚)rLr8ràs r*rHzGeneralizedTime.setçs´€ô �eœhÔ(9Ð:Ô ;Ø—<’<Ü Ð!9Ó:Ð:ð×$Ñ$¤\Ó2ˆEà× Ò Ø¤ U×%6Ñ%6Ó!7×!=Ñ!=¸aÓ!@×!GÑ!GÈÓ!LÑL‘à�à—N‘N >Ó2°XÑ=ÀÑCˆEÝØŸ ™  WÓ-�ä×ј4 Ô'ðˆ� r+có>—|ddk(r tdi|¤ŽStdi|¤ŽS)zÎ Create a datetime object from the parsed time. :return: A datetime.datetime object or asn1crypto.util.extended_datetime object. It may or may not be aware. rärr¥)rrrs r*r÷zGeneralizedTime._get_datetimes,€ð �&‰>˜QÒ ä$Ñ. vÑ.Ð .äÑ%˜fÑ%Ð %r+Nrr¥r+r*rr¹s<„ñð €Cð �R—Z‘Zð#!ðF �‰óG#€NòJóB &r+rcó—eZdZdZdZdZy)Ú GraphicStringzK Represents a graphic string from ASN.1 as a Python unicode string érQNr#r¥r+r*rró„ñð €Cà�Ir+rcó—eZdZdZdZdZy)Ú VisibleStringzK Represents a visible string from ASN.1 as a Python unicode string érQNr#r¥r+r*rr"rÇr+rcó—eZdZdZdZdZy)Ú GeneralStringzK Represents a general string from ASN.1 as a Python unicode string érQNr#r¥r+r*rr+rr+rcó—eZdZdZdZdZy)ÚUniversalStringzM Represents a universal string from ASN.1 as a Python unicode string éz utf-32-beNr#r¥r+r*rr5ó„ñð €CØ�Ir+rcó—eZdZdZdZdZy)ÚCharacterStringzM Represents a character string from ASN.1 as a Python unicode string érQNr#r¥r+r*rr>rr+rcó—eZdZdZdZdZy)Ú BMPStringzG Represents a BMP string from ASN.1 as a Python unicode string éz utf-16-beNr#r¥r+r*r!r!Hrr+r!c óP—t|›t|«›dt|«›�«|jr@t|›dt j |jxsd«j d«›�«|jduxr|jduxr|jdu}|r>tj|j«}tj|j«}|j�^|jD],\}}t|›dtj|«›d|›d�«Œ.|rst|›d ›d ›d |j›�«nR|jr$|rDt|›d›d ›d|j›d �«n"|r t|›d›d ›d|j›�«|jr@t|›d t j |jxsd«j d«›�«t|›d t j |j xsd«j d«›�«y)a7 Prints out basic information about an Asn1Value object. Extracted for reuse among different classes that customize the debug information. :param prefix: A unicode string of spaces to prefix output line with :param self: The object to print the debugging information about r2z Header: 0xr+rfNz z tag z (explicitly tagged)z r`z (implicitly tagged)z Trailer: 0xz Data: 0x)rŽrrbr–ÚbinasciiÚhexlifyrXrIrGr4r~r{rEr<r=r™rJ)r�rLÚ has_headerÚ method_nameÚ class_namerGr4s r*r‹r‹Qsš€ô ™v¤y°¥¼¸4¼Ð AÔBØ ‡|‚|Ü ¢F¬H×,<Ñ,<¸T¿\¹\Ò=PÈSÓ,Q×,XÑ,XÐY`Ô,aÐbÔcà—‘ DÐ(Ò]¨T¯[©[ÀÐ-DÒ]ÈÏÉÐY]ÐI]€JÙÜ,×0Ñ0°·±Ó=ˆ Ü*×.Ñ.¨t¯{©{Ó;ˆ à ‡}�}Ð ØŸ=œ=‰KˆF�CÜ òÜ)×-Ñ-¨fÕ5Úð õ ð)ñ Ü ª² ºZÈÏÊÐRÕ Sà �ŠÙ Ü ºfÂkÒS]Ð_c×_gÓ_gÐhÕ iá Ü ¢fªkº:ÀtÇxÂxÐPÔQà ‡}‚}Ü ¢V¬X×-=Ñ-=¸d¿m¹mÒ>RÈsÓ-S×-ZÑ-ZÐ[bÔ-cÐdÔeä šf¤h×&6Ñ&6°t·}±}Ò7KÈÓ&L×&SÑ&SÐT[Ô&\Ð ]Õ^r+có´—d|vrT|ddk(r|jdd«|df|d<n"|ddk(r|jdd«|df|d<|d=|d=d|vr|d=yyy)z¸ Converts old-style "tag_type" and "tag" params to "explicit" and "implicit" :param params: A dict of parameters to convert from tag_type/tag to explicit/implicit rNr<Úclassr"r4r=N)r{)rÿs r*ræræ€sŠ€ð�VÑØ �*Ñ  Ò +Ø"(§*¡*¨W°aÓ"8¸&À¹-Ð!HˆF�:Ò Ø �JÑ  :Ò -Ø"(§*¡*¨W°aÓ"8¸&À¹-Ð!HˆF�:Ñ Ø �:Ð Ø �5ˆMØ �fÑ Ø�w‘ð ðr+cóf—t|«d}d|vr|jdur^d}n[t|dt«r |d\}}n|d}d}|jdurd}n'|jt |k7s|j |k7rd}|jd«|jk7rd}|r|j|«S|S)zü Checks if a value is properly tagged based on the spec, and re/untags as necessary :param value: An Asn1Value object :param params: A dict of spec params :return: An Asn1Value that is properly tagged Fr=Tr r<) rær=r2rûrGrFr4r{r<r})r8rÿr}rGr4s r*rýrý“sº€ô# 6Ô*à €EØ˜ÑØ �>‰> Ñ &؉Eä �f˜ZÑ(¬%Ô 0Ø  Ñ,‰KˆF‘Cà˜Ñ$ˆC؈FØ �>‰>˜UÑ "؉EØ �\‰\Ô2°6Ñ:Ò :¸e¿i¹iÈ3Ò>N؈Eà ‡z�z�*Ó §¡Ò/Øˆá Ø�{‰{˜6Ó"Ð"Ø €Lr+cór—|€y|j}|j}t|«d|vr$t|dt«r |d\}}n/d}|d}n'd|vr#t|dt«r |d\}}nd}|d}|�t|t «s t |}|jd|«}|jd|«}||fS)aP Builds a 2-element tuple used to identify fields by grabbing the class_ and tag from an Asn1Value class and the params dict being passed to it :param params: A dict of params to pass to spec :param spec: An Asn1Value class :return: A 2-element integer tuple in the form (class_, tag) rìr<r"r=rGr4)rGr4rær2rûrrFr{)rÿr0Úrequired_classÚ required_tags r*rõrõ»sÔ€ð  €|Øà—[‘[€NØ—8‘8€Lä" 6Ô*à�VÑÜ �f˜ZÑ(¬%Ô 0Ø+1°*Ñ+=Ñ (ˆN™LàˆNØ! *Ñ-‰LØ �vÑ Ü �f˜ZÑ(¬%Ô 0Ø+1°*Ñ+=Ñ (ˆN™LàˆNØ! *Ñ-ˆLØÐ!¬*°^ÄYÔ*OÜ.¨~Ñ>ˆà—Z‘Z ¨.Ó9€NØ—:‘:˜e \Ó2€Là ˜LÐ )Ð)r+c óØ—|s|sytttt|dj|««««}t |«|k7r$t djt |«|««‚|S)zà Format value as a tuple of 1s and 0s. :param value: A non-negative integer to format :param bits: Number of bits in the output :return: A tuple of 1s and 0s with bits members. r¥z0{0}bzResult too large: {0} > {1})rûr“r–ryrDrB)r8r|Úresults r*rzrzès[€ñ ™Øä ”3”sœF 5¨'¯.©.¸Ó*>Ó?Ó@Ó A€FÜ ˆ6ƒ{�dÒÜÐ6×=Ñ=¼cÀ&»kÈ4ÓPÓQÐQà €Mr+rÎrórùrvrtrrrÂr"r'r*r®rÆrÊ) rÍrÑrÔrúrrrrrrr"c ó —|� t|«|€tSd} |��a|xrd|v} | �sx|js|�rid|v�rd|r |di|¤Ž} n|«} | j} t| «} |}|}|}|}|}|xsd}| D]ÿ\}}||k7rGt t dt | «tj|«tj||«««‚|dk7rGt t dt | «tjd«tj||«««‚||k7r t t d t | «||««‚t|t|««\}}|\}}}}}}t| t«rŒõ||z }||z}�Œt|dd id œŽ} || _|| _| | _d } �n|r |dd |i|¤Ž} n ||¬ «} |t"ur�nÿt| t«r<| j%|||« || j&z| _d}| j)«�n³|| j.k7rQt t dt | «tj| j.«tj||«««‚|| j0k7rŽ|dk(xr| j0dk(xr|dk(}|rt| t2«sQt t dt | «tj| j0«tj||«««‚|| _d | _|| j6k7�r¦t| j8t:«r|| j8v}n|| j8k(}|�skt t dt | «| j6|««‚|rªd|vr¦t=dd |i|¤Ž}|j} |}|}|xsd}t| «D]0\}}t|t|««\}}|\}}}}}}||z }||z}Œ2t|dd id œŽ} || jz| _| xj |xsdz c_| | _d } n•|t>vr=t t dtj|«tj|«|««‚t>|}|||¬«} |dk(xr| j0dk(xr|dk(}|rt| t2«rd | _|| _| s|| _|xsd| _d| _ |r | j)|«| S| S#tt*f$r=}|j,dd}|j,ddt | «zzf|z|_|‚d}~wwxYw#tt*f$r=}|j,dd}|j,ddt | «zzf|z|_|‚d}~wwxYw)a Builds an Asn1Value object generically, or using a spec with optional params :param class_: An integer representing the ASN.1 class :param method: An integer representing the ASN.1 method :param tag: An integer representing the ASN.1 tag :param header: A byte string of the ASN.1 header (class, method, tag, length) :param contents: A byte string of the ASN.1 value :param trailer: A byte string of any ASN.1 trailer (only used by indefinite length encodings) :param spec: A class derived from Asn1Value that defines what class_ and tag the value should have, and the semantics of the encoded value. The return value will be of this type. If omitted, the encoded value will be decoded using the standard universal tag based on the encoded tag number. :param spec_params: A dict of params to pass to the spec object :param nested_spec: For certain Asn1Value classes (such as OctetString and BitString), the contents can be further parsed and interpreted as another Asn1Value. This parameter controls the spec for that sub-parsing. :return: An object of the type spec, or if not specified, a child of Asn1Value NFrMr<r+zš Error parsing %s - explicitly-tagged class should have been %s, but %s was found r z› Error parsing %s - explicitly-tagged method should have been %s, but %s was found z˜ Error parsing %s - explicitly-tagged tag should have been %s, but %s was found TrärJr¼rråzˆ Error parsing %s - class should have been %s, but %s was found szy Error parsing %s - method should have been %s, but %s was found zv Error parsing %s - tag should have been %s, but %s was found zO Unknown element - %s class, %s method, tag %s )rJrGr¥)!rær0r<ÚreversedrBr rrEr{r~rrDr2rîrGr–r™rÙrrJrÝr3rKrGrIr—r˜r4r£rûr'Ú_UNIVERSAL_SPECSr‚)rGrIr4r›rJÚtrailerr0r1Ú nested_specÚ header_setrMr8Úoriginal_explicitÚ explicit_infoÚ parsed_classÚ parsed_methodÚ parsed_tagÚto_parseÚexplicit_headerÚexplicit_trailerÚexpected_classÚ expected_tagr÷r9Ú parsed_headerÚparsed_trailerrRrKÚ ber_indefÚ is_bad_tagÚoriginal_values r*rGrG sð€ðRÐÜ& {Ô3à €~܈ à€Jð Ñð"ÒB m°{Ð&Bˆ Ú § ¢ ²+À*ÐP[ÒB[ÙÙÑ+˜{Ñ+‘á›�Ø %§¡Ð Ü$Ð%6Ó7ˆMØ!ˆLØ"ˆM؈J؈HØ$ˆOØ&š~¨#Ð Û0=Ñ,�  Ø >Ò1Ü$¤Vðô" %Ó(Ü-×1Ñ1°.ÓAÜ-×1Ñ1°,À ÓMó&óðð! AÒ%Ü$¤Vðô" %Ó(Ü.×2Ñ2°1Ó5Ü.×2Ñ2°=À-ÓPó&óðð Ò-Ü$¤Vðô" %Ó(Ø$Ø"ó&óðô! ¬3¨x«=Ó9‘��aØcgÑ`� ˜m¨Z¸ÈÐR`ä! %¬Õ0Ø# }Ñ4�OØ'5Ð8HÑ'HÒ$ðI1>ôL˜D t¸-ÈÐ9NÒOˆEØ+ˆEŒMØ-ˆEŒNØ.ˆEŒNØŠJáÙÑ> hÐ>°+Ñ>‘á hÔ/�à”s‰{Ùä˜E¤6Ô*Ø—‘˜v s¨HÔ5ðà%+¨e¯n©nÑ%<�E”NØ �FØ—K‘K–Mð˜UŸ\™\Ò)Ü$¤Vðô" %Ó(Ü-×1Ñ1°%·,±,Ó?Ü-×1Ñ1°&¸&ÓAó&óðð˜UŸ\™\Ò)ð!'¨!¡ Ò \°· ± ÀÑ0AÒ \ÀgÐQ\ÑF\�IÙ$¬J°u¼mÔ,LÜ(¬ð ô& eÓ,Ü2×6Ñ6°u·|±|ÓDÜ2×6Ñ6°v¸vÓFó *óðð(.˜œ Ø,0˜Ô)ؘ%Ÿ)™)Ó#Ü! %§.¡.´%Ô8Ø%(¨E¯N©NÐ%:™ à%(¨E¯N©NÑ%:˜ Ú%Ü(¬ð ô& eÓ,Ø!ŸI™IØó *óðñ ˜ {Ñ2Ü"ÑD¨HÐD¸ ÑDˆØ*×3Ñ3ÐàˆØ ˆØ"š> cÐÜ,4Ð5FÖ,GÑ (ˆN˜LܘX¤s¨8£}Ó5‰GˆD�!Ø?CÑ <ˆAˆq�!�] H¨nØ ˜}Ñ ,ˆOØ-Ð0@Ñ@Ñ ð -Hô ˜ 4°mÀTÐ5JÒKˆØ §¡Ñ.ˆŒ Ø �Š˜'š. SÑ(�Ø*ˆŒØ‰ ð Ô&Ñ &ÜœVðô&×)Ñ)¨&Ó1Ü&×*Ñ*¨6Ó2Øó óð ô  Ñ$ˆá˜h¨vÔ6ˆØ˜a‘KÒP E§L¡L°AÑ$5ÒP¸'À[Ñ:Pˆ Ù œ E¬=Ô9Ø $ˆEÔ ØˆŒ á ØˆŒ Ø š CˆŒð€E„Máð Ø �K‰K˜ Ô $ð €Lˆ5€LøôQ#¤IÐ.òØŸ6™6 ! "˜:�DØŸf™f Q™iÐ*BÄYÈuÓEUÑ*UÑUÐWÐZ^Ñ^�A”FØ�GûðûôFœIÐ&ò Ø—6‘6˜!˜"�:ˆDØ—f‘f˜Q‘iÐ":¼YÀuÓ=MÑ"MÑMÐOÐRVÑVˆAŒF؈Gûð ús0Ç"&S0ÓT?Ó0T<Ó?8T7Ô7T<Ô?V Õ8VÖV có”—t|«}t|||«\}}|r|||zk7r||z|z }td|z«‚t|||dœŽ|fS)aß Parses a byte string generically, or using a spec with optional params :param encoded_data: A byte string that contains BER-encoded data :param pointer: The index in the byte string to parse from :param spec: A class derived from Asn1Value that defines what class_ and tag the value should have, and the semantics of the encoded value. The return value will be of this type. If omitted, the encoded value will be decoded using the standard universal tag based on the encoded tag number. :param spec_params: A dict of params to pass to the spec object :param strict: A boolean indicating if trailing data should be forbidden - if so, a ValueError will be raised when trailing data exists :return: A 2-element tuple: - 0: An object of the type spec, or if not specified, a child of Asn1Value - 1: An integer indicating how many bytes were consumed rrä)rDrrBrG) r)r·r0r1r&Ú encoded_lenr÷Ú new_pointerr%s r*r5r5 se€ô<�lÓ#€Kܘ|¨[¸'ÓBÑ€Dˆ+Ù �+ ¨;Ñ!6Ò6Ø  Ñ+¨kÑ9ˆ ÜÐOÐR]Ñ]Ó^Ð^Ü �D˜t°Ò =¸{Ð KÐKr+rœrN)rNNF)nr¢Ú __future__rrrrrrÚ fractionsr r$ror—rÚsysrWr Ú_errorsr Ú _ordereddictr Ú_typesrrrrrÚparserrrÚutilrrrrrrÚ version_infoÚ cStringIOrrÚxranger’rWÚioÚregisterrErFr~rrÿr@r(Úobjectr'r§r¯r—rÅr0rÙrîrrArPr]rhrrrŠr¬rÄrÍrÚrârîròr÷rrrrr!r&r)r@r­r½rÁrÅrÉrÌrÐrÓr×rùrrrrrrr!r‹rærýrõrzr3rGr5r¥r+r*ÚrWs®ðñ,÷\SÓRç(ÝÛÛ Û Û Û åÝÝ%ßDÕDß(ßj×jà×Ñ�tÒÝ-à €EØ �Dõà €Dð€×ÑÔðØØØñ ÐðØØØØØØØñ ÐðØñÐð ˆ"�*‰*Ð%Ó &€ð€ó37ôl_7�ô_7÷D*ñ*ô6)ˆvô)ôXN.�FôN.ôb3ˆ9ô3ñl ƒv€ôS1ˆ)ôS1ôlQ-ˆYôQ-ôh ^$ˆVô^$ôB |+� ô|+ô~N"�] IôN"ôb2ˆiô2ôjNˆi˜ôNôbi!˜ôi!ôX|Ð! =°(¸IÀxô|ô~O!�] H¨iôO!ôd>Ð(¨-¸À9ô>ôBK �- ¨9ôK ô\N"˜¨°)ôN"ôbo$˜-¨°9ôo$ôd1!Ð0ô1!ôhˆ9ôô>^�y (ô^ôB �yô ô �ô ô ˆ9ô ôA�ôAôH�ôô Ð"ô ôz $ˆyôz $ôzD$�ôD$ôNw ˆ(ôw ôt ˆJô ôB �(ô ô�Nôô�nôô�Nôô �[ô ô�ôô_�>ô_ôDS"ˆlôS"ôl\&�lô\&ô~�Nôô�Nôô�Nôô�nôô�nôô�ôò,_ò^ ò&%òP**òZð0Ø€wðà€wðð€yðð€{ð ð €tð ð Ðð ðÐðð€zðð€tððˆ ððˆ ððˆ ððˆ ððˆððˆðð ˆ ð!ð"ˆð#ð$ ØØØØØØØØØØò9Ðó@fôR#Lr+__pycache__/crl.cpython-312.pyc000064400000044507152572326550012265 0ustar00Ë uÉþiè>ãó¦—dZddlmZmZmZmZddlZddlmZddl m Z m Z m Z m Z mZmZmZmZmZddlmZmZmZmZmZmZmZmZGd„d e «ZGd „d e«ZGd „d e«ZGd„de«ZGd„de«Z Gd„de «Z!Gd„de«Z"Gd„de«Z#Gd„de«Z$Gd„de«Z%Gd„de«Z&Gd„de«Z'Gd „d!e«Z(y)"z¹ ASN.1 type classes for certificate revocation lists (CRL). Exports the following items: - CertificateList() Other type classes are defined that help compose the types listed above. é)Úunicode_literalsÚdivisionÚabsolute_importÚprint_functionNé)ÚSignedDigestAlgorithm) ÚBooleanÚ EnumeratedÚGeneralizedTimeÚIntegerÚObjectIdentifierÚOctetBitStringÚParsableOctetStringÚSequenceÚ SequenceOf)ÚAuthorityInfoAccessSyntaxÚAuthorityKeyIdentifierÚCRLDistributionPointsÚDistributionPointNameÚ GeneralNamesÚNameÚ ReasonFlagsÚTimecó—eZdZddddœZy)ÚVersionÚv1Úv2Úv3)rréN©Ú__name__Ú __module__Ú __qualname__Ú_map©óú?/opt/nydus/tmp/pip-target-dhtdbchl/lib/python/asn1crypto/crl.pyrr+s„à Ø Ø ñ �Dr&rc ód—eZdZdedddœfdedddœfd ed ddœfd ed dd œfdedddœfdedddœfgZy)ÚIssuingDistributionPointÚdistribution_pointrT©ÚexplicitÚoptionalÚonly_contains_user_certsrF)ÚimplicitÚdefaultÚonly_contains_ca_certsrÚonly_some_reasonsé)r/r-Ú indirect_crléÚonly_contains_attribute_certséN)r!r"r#rr rÚ_fieldsr%r&r'r)r)3se„à Ð4À1ÐRVÑ6WÐXØ # W¸1ÈÑ.OÐPØ ! 7¸ÀuÑ,MÐNØ ˜k¸ÀtÑ+LÐMØ ˜¨q¸UÑ"CÐDØ (¨'ÀÈeÑ3TÐUð �Gr&r)có —eZdZddddddddœZy ) ÚTBSCertListExtensionIdÚissuer_alt_nameÚ crl_numberÚdelta_crl_indicatorÚissuing_distribution_pointÚauthority_key_identifierÚ freshest_crlÚauthority_information_access)z 2.5.29.18z 2.5.29.20z 2.5.29.27z 2.5.29.28z 2.5.29.35z 2.5.29.46z1.3.6.1.5.5.7.1.1Nr r%r&r'r:r:>s„à&Ø!Ø*Ø1Ø/Ø#Ø;ñ �Dr&r:có@—eZdZdefdeddifdefgZdZee e e e e e dœZy) ÚTBSCertListExtensionÚextn_idÚcriticalr0FÚ extn_value©rDrF)r;r<r=r>r?r@rAN)r!r"r#r:r rr8Ú _oid_pairrr r)rrrÚ _oid_specsr%r&r'rCrCJsM„à Ð*Ð+Ø �W˜y¨%Ð0Ð1Ø Ð*Ð+ð€Gð *€Ià'ØØ&Ø&>Ø$:Ø-Ø(Añ�Jr&rCcó—eZdZeZy)ÚTBSCertListExtensionsN)r!r"r#rCÚ _child_specr%r&r'rKrK]s„Ø&�Kr&rKc ó6—eZdZddddddddd d d œ Zed „«Zy )Ú CRLReasonÚ unspecifiedÚkey_compromiseÚ ca_compromiseÚaffiliation_changedÚ supersededÚcessation_of_operationÚcertificate_holdÚremove_from_crlÚprivilege_withdrawnÚ aa_compromise) rrrr3r5r7ééé é c ó6—ddddddddd d d œ |jS) a :return: A unicode string with revocation description that is suitable to show to end-users. Starts with a lower case letter and phrased in such a way that it makes sense after the phrase "because of" or "due to". zan unspecified reasonza compromised keyzthe CA being compromisedzan affiliation changezcertificate supersessionza cessation of operationza certificate holdzremoval from the CRLzprivilege withdrawlzthe AA being compromised) rOrPrQrRrSrTrUrVrWrX©Únative©Úselfs r'Úhuman_friendlyzCRLReason.human_friendlyos:€ð3Ø1Ø7Ø#:Ø4Ø&@Ø 4Ø5Ø#8Ø7ñ  ð �+‰+ñ ð r&N)r!r"r#r$Úpropertyrbr%r&r'rNrNas;„à Ø Ø Ø Ø Ø #Ø Ø Ø Ø ñ €Dðñóñr&rNcó—eZdZdddddœZy)ÚCRLEntryExtensionIdÚ crl_reasonÚhold_instruction_codeÚinvalidity_dateÚcertificate_issuer)z 2.5.29.21z 2.5.29.23z 2.5.29.24z 2.5.29.29Nr r%r&r'rere‡s„à!Ø,Ø&Ø)ñ  �Dr&recó:—eZdZdefdeddifdefgZdZee e e dœZ y) ÚCRLEntryExtensionrDrEr0FrFrG)rfrgrhriN) r!r"r#rer rr8rHrNr r rrIr%r&r'rkrk�sD„à Ð'Ð(Ø �W˜y¨%Ð0Ð1Ø Ð*Ð+ð€Gð *€IàØ!1Ø*Ø*ñ �Jr&rkcó—eZdZeZy)ÚCRLEntryExtensionsN)r!r"r#rkrLr%r&r'rmrm s„Ø#�Kr&rmcó–—eZdZdefdefdeddifgZdZdZdZ dZ dZ dZ d„Z ed „«Zed „«Zed „«Zed „«Zed „«Zy)ÚRevokedCertificateÚuser_certificateÚrevocation_dateÚcrl_entry_extensionsr-TFNcó—t«|_|dD]g}|dj}d|z}t||«rt |||dj «|djsŒM|jj |«Œid|_y)úv Sets common named extensions to private attributes and creates a list of critical extensions rrrDú _%s_valuerFrETN©ÚsetÚ_critical_extensionsr_ÚhasattrÚsetattrÚparsedÚaddÚ_processed_extensions©raÚ extensionÚnameÚattribute_names r'Ú_set_extensionsz"RevokedCertificate._set_extensions²s…€ô %(£EˆÔ!àÐ4Ô5ˆIؘYÑ'×.Ñ.ˆDØ(¨4Ñ/ˆNÜ�t˜^Ô,ܘ˜n¨i¸ Ñ.E×.LÑ.LÔMؘÑ$×+Ó+Ø×)Ñ)×-Ñ-¨dÕ3ð 6ð&*ˆÕ"r&cóR—|js|j«|jS©z² Returns a set of the names (or OID if not a known extension) of the extensions marked as critical :return: A set of unicode strings ©r}r‚rxr`s r'Úcritical_extensionsz&RevokedCertificate.critical_extensionsÄó%€ð×)Ò)Ø × Ñ Ô "Ø×(Ñ(Ð(r&cóV—|jdur|j«|jS)zŽ This extension indicates the reason that a certificate was revoked. :return: None or a CRLReason object F)r}r‚Ú_crl_reason_valuer`s r'Úcrl_reason_valuez#RevokedCertificate.crl_reason_valueÒs*€ð × %Ñ %¨Ñ .Ø × Ñ Ô "Ø×%Ñ%Ð%r&cóV—|jdur|j«|jS)a= This extension indicates the suspected date/time the private key was compromised or the certificate became invalid. This would usually be before the revocation date, which is when the CA processed the revocation. :return: None or a GeneralizedTime object F)r}r‚Ú_invalidity_date_valuer`s r'Úinvalidity_date_valuez(RevokedCertificate.invalidity_date_valueßs*€ð × %Ñ %¨Ñ .Ø × Ñ Ô "Ø×*Ñ*Ð*r&cóV—|jdur|j«|jS)a This extension indicates the issuer of the certificate in question, and is used in indirect CRLs. CRL entries without this extension are for certificates issued from the last seen issuer. :return: None or an x509.GeneralNames object F)r}r‚Ú_certificate_issuer_valuer`s r'Úcertificate_issuer_valuez+RevokedCertificate.certificate_issuer_valueïs*€ð × %Ñ %¨Ñ .Ø × Ñ Ô "Ø×-Ñ-Ð-r&cóØ—|jdurQd|_|jr>|jD]/}|jdk(sŒ|j|_|jS|jS)zi :return: None, or an asn1crypto.x509.Name object for the issuer of the cert FNÚdirectory_name)Ú _issuer_namer�r€Úchosen)raÚ general_names r'Ú issuer_namezRevokedCertificate.issuer_nameþsn€ð × Ñ  Ñ %Ø $ˆDÔ Ø×,Ò,Ø$(×$AÔ$A�LØ#×(Ñ(Ð,<Ó<Ø,8×,?Ñ,?˜Ô)ØØ× Ñ Ð ð %Bð× Ñ Ð r&)r!r"r#r rrmr8r}rxr‰rŒr�r“r‚rcr†rŠr�r�r–r%r&r'roro¤s·„à ˜WÐ%Ø ˜DÐ!Ø Ð!3°jÀ$Ð5GÐHð€Gð "ÐØÐØÐØ!ÐØ $ÐØ€Lò*ð$ñ )óð )ðñ &óð &ðñ +óð +ðñ .óð .ðñ !óñ !r&rocó—eZdZeZy)ÚRevokedCertificatesN)r!r"r#rorLr%r&r'r˜r˜s„Ø$�Kr&r˜c óT—eZdZdeddifdefdefdefdeddifdeddifd ed dd œfgZ y ) Ú TbsCertListÚversionr-TÚ signatureÚissuerÚ this_updateÚ next_updateÚrevoked_certificatesÚcrl_extensionsrr+N) r!r"r#rrrrr˜rKr8r%r&r'ršršs`„à �G˜j¨$Ð/Ð0Ø Ð+Ð,Ø �4ÐØ ˜ÐØ ˜˜z¨4Ð0Ð1Ø Ð!4°zÀ4Ð6HÐIØ Ð0¸qÈdÑ2SÐTð�Gr&ršcóL—eZdZdefdefdefgZdZdZdZ dZ dZ dZ dZ dZdZdZdZdZdZd„Zed„«Zed„«Zed „«Zed „«Zed „«Zed „«Zed „«Zed„«Zed„«Zed„«Zed„«Z ed„«Z!ed„«Z"ed„«Z#ed„«Z$y)ÚCertificateListÚ tbs_cert_listÚsignature_algorithmrœFNcó—t«|_|ddD]g}|dj}d|z}t||«rt |||dj «|djsŒM|jj |«Œid|_y) rtr¤r¡rDrurFrETNrvr~s r'r‚zCertificateList._set_extensions4s‹€ô %(£EˆÔ!à˜oÑ.Ð/?Ô@ˆIؘYÑ'×.Ñ.ˆDØ(¨4Ñ/ˆNÜ�t˜^Ô,ܘ˜n¨i¸ Ñ.E×.LÑ.LÔMؘÑ$×+Ó+Ø×)Ñ)×-Ñ-¨dÕ3ð Að&*ˆÕ"r&cóR—|js|j«|jSr„r…r`s r'r†z#CertificateList.critical_extensionsFr‡r&cóV—|jdur|j«|jS)z· This extension allows associating one or more alternative names with the issuer of the CRL. :return: None or an x509.GeneralNames object F)r}r‚Ú_issuer_alt_name_valuer`s r'Úissuer_alt_name_valuez%CertificateList.issuer_alt_name_valueTs*€ð × %Ñ %¨Ñ .Ø × Ñ Ô "Ø×*Ñ*Ð*r&cóV—|jdur|j«|jS)zÌ This extension adds a monotonically increasing number to the CRL and is used to distinguish different versions of the CRL. :return: None or an Integer object F)r}r‚Ú_crl_number_valuer`s r'Úcrl_number_valuez CertificateList.crl_number_valuebs*€ð × %Ñ %¨Ñ .Ø × Ñ Ô "Ø×%Ñ%Ð%r&cóV—|jdur|j«|jS)zÅ This extension indicates a CRL is a delta CRL, and contains the CRL number of the base CRL that it is a delta from. :return: None or an Integer object F)r}r‚Ú_delta_crl_indicator_valuer`s r'Údelta_crl_indicator_valuez)CertificateList.delta_crl_indicator_valueps*€ð × %Ñ %¨Ñ .Ø × Ñ Ô "Ø×.Ñ.Ð.r&cóV—|jdur|j«|jS)zÌ This extension includes information about what types of revocations and certificates are part of the CRL. :return: None or an IssuingDistributionPoint object F)r}r‚Ú!_issuing_distribution_point_valuer`s r'Ú issuing_distribution_point_valuez0CertificateList.issuing_distribution_point_value~s*€ð × %Ñ %¨Ñ .Ø × Ñ Ô "Ø×5Ñ5Ð5r&cóV—|jdur|j«|jS)zÇ This extension helps in identifying the public key with which to validate the authenticity of the CRL. :return: None or an AuthorityKeyIdentifier object F)r}r‚Ú_authority_key_identifier_valuer`s r'Úauthority_key_identifier_valuez.CertificateList.authority_key_identifier_valueŒs*€ð × %Ñ %¨Ñ .Ø × Ñ Ô "Ø×3Ñ3Ð3r&cóV—|jdur|j«|jS)z´ This extension is used in complete CRLs to indicate where a delta CRL may be located. :return: None or a CRLDistributionPoints object F)r}r‚Ú_freshest_crl_valuer`s r'Úfreshest_crl_valuez"CertificateList.freshest_crl_valuešs*€ð × %Ñ %¨Ñ .Ø × Ñ Ô "Ø×'Ñ'Ð'r&cóV—|jdur|j«|jS)zÉ This extension is used to provide a URL with which to download the certificate used to sign this CRL. :return: None or an AuthorityInfoAccessSyntax object F)r}r‚Ú#_authority_information_access_valuer`s r'Ú"authority_information_access_valuez2CertificateList.authority_information_access_value¨s*€ð × %Ñ %¨Ñ .Ø × Ñ Ô "Ø×7Ñ7Ð7r&có—|ddS)z_ :return: An asn1crypto.x509.Name object for the issuer of the CRL r¤r�r%r`s r'r�zCertificateList.issuer¶s€ð�OÑ$ XÑ.Ð.r&cóN—|jsy|jdjS)zŠ :return: None or a byte string of the key_identifier from the authority key identifier extension NÚkey_identifier)r¶r_r`s r'r?z(CertificateList.authority_key_identifier¿s(€ð×2Ò2Øà×2Ñ2Ð3CÑD×KÑKÐKr&cóF—|j€Šg|_|jrw|jD]h}|djdk(sŒ|d}|jdk7rŒ+|j}|j «dddk(sŒN|jj |«Œj|jS)zì :return: A list of unicode strings that are URLs that should contain either an individual DER-encoded X.509 certificate, or a DER-encoded CMS message containing multiple certificates Ú access_methodÚ ca_issuersÚaccess_locationÚuniform_resource_identifierrézhttp://)Ú_issuer_cert_urlsr¼r_r€ÚlowerÚappend)raÚentryÚlocationÚurls r'Úissuer_cert_urlsz CertificateList.issuer_cert_urlsÌs €ð × !Ñ !Ð )Ø%'ˆDÔ "Ø×6Ò6Ø!×DÔD�Eؘ_Ñ-×4Ñ4¸ ÓDØ#(Ð):Ñ#;˜Ø#Ÿ=™=Ð,IÒIØ$Ø&Ÿo™o˜ØŸ9™9›; q¨Ð+¨yÓ8Ø ×2Ñ2×9Ñ9¸#Õ>ðEð×%Ñ%Ð%r&có—|j€ug|_|j�b|jD]S}|d}|jdk(rŒ|jD]-}|jdk(sŒ|jj |«Œ/ŒU|jS)z— Returns delta CRL URLs - only applies to complete CRLs :return: A list of zero or more DistributionPoint objects r*Úname_relative_to_crl_issuerrÄ)Ú_delta_crl_distribution_pointsr¹r€r”rÈ)rar*Údistribution_point_namer•s r'Údelta_crl_distribution_pointsz-CertificateList.delta_crl_distribution_pointsâs—€ð × .Ñ .Ð 6Ø24ˆDÔ /à×&Ñ&Ð2Ø*.×*AÔ*AÐ&Ø.@ÐAUÑ.VÐ+à.×3Ñ3Ð7TÒTØ à(?×(FÔ(F˜ Ø'×,Ñ,Ð0MÓMØ ×?Ñ?×FÑFÐGYÕZñ)Gð +Bð×2Ñ2Ð2r&có —|djS)zE :return: A byte string of the signature rœr^r`s r'rœzCertificateList.signatureûs€ð�KÑ ×'Ñ'Ð'r&cóž—|j€6tj|j««j «|_|jS)zf :return: The SHA1 hash of the DER-encoded bytes of this certificate list )Ú_sha1ÚhashlibÚsha1ÚdumpÚdigestr`s r'rÖzCertificateList.sha1s7€ð �:‰:Ð Ü Ÿ™ d§i¡i£kÓ2×9Ñ9Ó;ˆDŒJØ�z‰zÐr&cóž—|j€6tj|j««j «|_|jS)zi :return: The SHA-256 hash of the DER-encoded bytes of this certificate list )Ú_sha256rÕÚsha256r×rØr`s r'rÛzCertificateList.sha256s7€ð �<‰<Ð Ü"Ÿ>™>¨$¯)©)«+Ó6×=Ñ=Ó?ˆDŒLØ�|‰|Ðr&)%r!r"r#ršrrr8r}rxr©r¬r¯r²rµr¸r»rÆrÏrÔrÚr‚rcr†rªr­r°r³r¶r¹r¼r�r?rÌrÑrœrÖrÛr%r&r'r£r£s£„à ˜+Ð&Ø Ð 5Ð6Ø �nÐ%ð€Gð "ÐØÐØ!ÐØÐØ!%ÐØ(,Ð%Ø&*Ð#ØÐØ*.Ð'ØÐØ%)Ð"Ø €EØ€Gò*ð$ñ )óð )ðñ +óð +ðñ &óð &ðñ /óð /ðñ 6óð 6ðñ 4óð 4ðñ (óð (ðñ 8óð 8ðñ/óð/ðñ Lóð Lðñ&óð&ð*ñ3óð3ð0ñ(óð(ðñóððñóñr&r£))Ú__doc__Ú __future__rrrrrÕÚalgosrÚcorer r r r r rrrrÚx509rrrrrrrrrr)r:rCrKrNrerkrmror˜ršr£r%r&r'ÚrásÛðñ÷SÓRãå(÷ ÷ õ ÷ ÷ ó ôˆgôô˜xôô Ð-ô ô˜8ôô&'˜Jô'ô#� ô#ôLÐ*ôô ˜ô ô $˜ô$ôh!˜ôh!ôV%˜*ô%ô �(ô ôy�hõyr&__pycache__/csr.cpython-312.pyc000064400000010713152572326550012264 0ustar00Ë uÉþiÖ ãó¬—dZddlmZmZmZmZddlmZddlm Z m Z m Z m Z m Z mZmZmZmZddlmZddlmZmZmZGd„d e «ZGd „d e «ZGd „d e«ZGd„de«ZGd„de«ZGd„de«ZGd„de«ZGd„de«ZGd„de«Z Gd„de«Z!Gd„de«Z"Gd„de«Z#Gd „d!e«Z$Gd"„d#e«Z%y$)%z¾ ASN.1 type classes for certificate signing requests (CSR). Exports the following items: - CertificationRequest() Other type classes are defined that help compose the types listed above. é)Úunicode_literalsÚdivisionÚabsolute_importÚprint_functioné)ÚSignedDigestAlgorithm) ÚAnyÚ BitStringÚ BMPStringÚIntegerÚObjectIdentifierÚOctetBitStringÚSequenceÚSetOfÚ UTF8String)Ú PublicKeyInfo)ÚDirectoryStringÚ ExtensionsÚNamecó—eZdZddiZy)ÚVersionrÚv1N©Ú__name__Ú __module__Ú __qualname__Ú_map©óú?/opt/nydus/tmp/pip-target-dhtdbchl/lib/python/asn1crypto/csr.pyrr"s„à ˆ4ð �Drrcó—eZdZdddddddœZy) ÚCSRAttributeTypeÚchallenge_passwordÚextended_certificate_attributesÚextension_requestÚ!microsoft_enrollment_csp_providerÚmicrosoft_os_versionÚmicrosoft_request_client_info)z1.2.840.113549.1.9.7z1.2.840.113549.1.9.9z1.2.840.113549.1.9.14z1.3.6.1.4.1.311.13.2.2z1.3.6.1.4.1.311.13.2.3z1.3.6.1.4.1.311.21.20Nrrrr r"r"(s„à 4Ø AØ!4à"Eà"8à!@ñ �Drr"có—eZdZeZy)ÚSetOfDirectoryStringN)rrrrÚ _child_specrrr r*r*6s„Ø!�Krr*có"—eZdZdefdedeifgZy)Ú AttributeÚtypeÚvaluesÚspecN)rrrr rr Ú_fieldsrrr r-r-:s „à Ð!Ð"Ø �5˜6 3˜-Ð(ð�Grr-có—eZdZeZy)ÚSetOfAttributesN)rrrr-r+rrr r3r3As„Ø�Krr3có—eZdZeZy)ÚSetOfExtensionsN)rrrrr+rrr r5r5Es„Ø�Krr5có"—eZdZdefdefdefgZy)ÚMicrosoftEnrollmentCSProviderÚkeyspecÚcspnameÚ signatureN)rrrr r r r1rrr r7r7Is!„à �GÐØ �IÐØ �iÐ ð�Grr7có—eZdZeZy)Ú"SetOfMicrosoftEnrollmentCSProviderN)rrrr7r+rrr r<r<Qs„Ø/�Krr<có(—eZdZdefdefdefdefgZy)ÚMicrosoftRequestClientInfoÚclientidÚ machinenameÚusernameÚ processnameN)rrrr rr1rrr r>r>Us)„à �WÐØ ˜ Ð#Ø �ZÐ Ø ˜ Ð#ð �Grr>có—eZdZeZy)ÚSetOfMicrosoftRequestClientInfoN)rrrr>r+rrr rDrD^s„Ø,�KrrDcó2—eZdZdefdefgZdZeee e ee dœZ y)Ú CRIAttributer.r/)r.r/)r#r$r%r&r'r(N) rrrr"r r1Ú _oid_pairr*r3r5r<rDÚ _oid_specsrrr rFrFbs9„à Ð!Ð"Ø �3ˆð€Gð #€Ià2Ø+:Ø,Ø-OØ 4Ø)Hñ �JrrFcó—eZdZeZy)Ú CRIAttributesN)rrrrFr+rrr rJrJss„Ø�KrrJcó0—eZdZdefdefdefdedddœfgZy) ÚCertificationRequestInfoÚversionÚsubjectÚsubject_pk_infoÚ attributesrT)ÚimplicitÚoptionalN)rrrrrrrJr1rrr rLrLws0„à �GÐØ �DÐØ ˜MÐ*Ø �}°1À$Ñ&GÐHð �GrrLcó"—eZdZdefdefdefgZy)ÚCertificationRequestÚcertification_request_infoÚsignature_algorithmr:N)rrrrLrrr1rrr rTrT€s#„à %Ð'?Ð@Ø Ð 5Ð6Ø �nÐ%ð�GrrTN)&Ú__doc__Ú __future__rrrrÚalgosrÚcorer r r r r rrrrÚkeysrÚx509rrrrr"r*r-r3r5r7r<r>rDrFrJrLrTrrr Úr]sÙðñ÷SÓRå(÷ ÷ õ õ ß3Ñ3ôˆgôô Ð'ô ô"˜5ô"ô�ôô�eôô�eôô Hôô0¨ô0ô ôô- eô-ô�8ôô"�Eôô˜xôô˜8õr__pycache__/keys.cpython-312.pyc000064400000120271152572326550012451 0ustar00Ë uÉþiç“ãóœ—dZddlmZmZmZmZddlZddlZddlm Z m Z ddl m Z m Z ddlmZmZmZmZmZddlmZmZmZmZmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#dd l$m%Z%m&Z&Gd „d e!«Z'Gd „d e"«Z(Gd„de«Z)Gd„de!«Z*Gd„de!«Z+Gd„de!«Z,Gd„d«Z-Gd„dee-«Z.Gd„dee-«Z/Gd„de«Z0Gd„de«Z1Gd „d!e«Z2Gd"„d#e!«Z3Gd$„d%e!«Z4Gd&„d'e!«Z5Gd(„d)e!«Z6Gd*„d+e!«Z7Gd,„d-e«Z8Gd.„d/e«Z9Gd0„d1e«Z:Gd2„d3e!«Z;Gd4„d5e!«Z<Gd6„d7e!«Z=Gd8„d9e#«Z>Gd:„d;e«Z?Gd<„d=ee!«Z@Gd>„d?e!«ZAGd@„dAe!«ZBGdB„dCe!«ZCGdD„dEe!«ZDGdF„dGe«ZEGdH„dIee!«ZFGdJ„dKe!«ZGy)La' ASN.1 type classes for public and private keys. Exports the following items: - DSAPrivateKey() - ECPrivateKey() - EncryptedPrivateKeyInfo() - PrivateKeyInfo() - PublicKeyInfo() - RSAPrivateKey() - RSAPublicKey() Other type classes are defined that help compose the types listed above. é)Úunicode_literalsÚdivisionÚabsolute_importÚprint_functionNé)ÚunwrapÚ APIException)Ú type_nameÚbyte_cls)Ú_ForceNullParametersÚDigestAlgorithmÚEncryptionAlgorithmÚRSAESOAEPParamsÚRSASSAPSSParams)ÚAnyÚ Asn1ValueÚ BitStringÚChoiceÚIntegerÚIntegerOctetStringÚNullÚObjectIdentifierÚOctetBitStringÚ OctetStringÚParsableOctetStringÚParsableOctetBitStringÚSequenceÚ SequenceOfÚSetOf)Úint_from_bytesÚ int_to_bytescó&—eZdZdZdefdefdefgZy)ÚOtherPrimeInfoú= Source: https://tools.ietf.org/html/rfc3447#page-46 ÚprimeÚexponentÚ coefficientN©Ú__name__Ú __module__Ú __qualname__Ú__doc__rÚ_fields©óú@/opt/nydus/tmp/pip-target-dhtdbchl/lib/python/asn1crypto/keys.pyr#r#-s(„ñð �'ÐØ �WÐØ ˜Ð ð�Gr/r#có—eZdZdZeZy)ÚOtherPrimeInfosr$N)r)r*r+r,r#Ú _child_specr.r/r0r2r29s„ñð!�Kr/r2có—eZdZdZdddœZy)ÚRSAPrivateKeyVersionzX Original Name: Version Source: https://tools.ietf.org/html/rfc3447#page-45 z two-primeÚmulti)rrN©r)r*r+r,Ú_mapr.r/r0r5r5As„ñð Ø ñ �Dr/r5c óV—eZdZdZdefdefdefdefdefdefdefd efd efd ed d ifg Zy)Ú RSAPrivateKeyz= Source: https://tools.ietf.org/html/rfc3447#page-45 ÚversionÚmodulusÚpublic_exponentÚprivate_exponentÚprime1Úprime2Ú exponent1Ú exponent2r'Úother_prime_infosÚoptionalTN)r)r*r+r,r5rr2r-r.r/r0r:r:Msh„ñð Ð(Ð)Ø �GÐØ ˜GÐ$Ø ˜WÐ%Ø �7ÐØ �7ÐØ �gÐØ �gÐØ ˜Ð Ø ˜o° ¸DÐ/AÐBð �Gr/r:có —eZdZdZdefdefgZy)Ú RSAPublicKeyz= Source: https://tools.ietf.org/html/rfc3447#page-44 r<r=Nr(r.r/r0rFrF`s „ñð �GÐØ ˜GÐ$ð�Gr/rFcó8—eZdZdZdefdefdefdefdefdefgZy) Ú DSAPrivateKeya& The ASN.1 structure that OpenSSL uses to store a DSA private key that is not part of a PKCS#8 structure. Reversed engineered from english-language description on linked OpenSSL documentation page. Original Name: None Source: https://www.openssl.org/docs/apps/dsa.html r;ÚpÚqÚgÚ public_keyÚ private_keyNr(r.r/r0rHrHks=„ñð �GÐØ ˆgˆØ ˆgˆØ ˆgˆØ �wÐØ ˜Ð ð �Gr/rHcó&—eZdZdZed„«Zd„Zy)Ú_ECPointa  In both PublicKeyInfo and PrivateKeyInfo, the EC public key is a byte string that is encoded as a bit string. This class adds convenience methods for converting to and from the byte string to a pair of integers that are the X and Y coordinates. cóB—ttjtj|d«dz ««}ttjtj|d«dz ««}t ||«}d}|t ||¬«z }|t ||¬«z }||«S)a Creates an ECPoint object from the X and Y integer coordinates of the point :param x: The X coordinate, as an integer :param y: The Y coordinate, as an integer :return: An ECPoint object éç @ó)Úwidth)ÚintÚmathÚceilÚlogÚmaxr!)ÚclsÚxÚyÚx_bytesÚy_bytesÚ num_bytesÚ byte_strings r0Ú from_coordsz_ECPoint.from_coords‡s†€ô ”d—i‘i¤§¡¨¨A£°Ñ 4Ó5Ó6ˆÜ”d—i‘i¤§¡¨¨A£°Ñ 4Ó5Ó6ˆä˜ Ó)ˆ àˆ Ø”| A¨YÔ7Ñ7ˆ Ø”| A¨YÔ7Ñ7ˆ á�;ÓÐr/có—|j}|dd}|dk(r3|dd}t|«dz}t|d|«}t||d«}||fS|tddg«vrt t d««‚t t d ««‚) z± Returns the X and Y coordinates for this EC point, as native Python integers :return: A 2-element tuple containing integers (X, Y) rrrSNrQóózQ Invalid EC public key - first byte is incorrect z| Compressed representations of EC public keys are not supported due to patent US6252960 )ÚnativeÚlenr ÚsetÚ ValueErrorr)ÚselfÚdataÚ first_byteÚ remainingÚ field_lenr[r\s r0Ú to_coordsz_ECPoint.to_coords¢s¬€ð�{‰{ˆØ˜!˜A�Yˆ ð ˜Ò ؘQ˜R˜ˆIܘI›¨!Ñ+ˆIܘy¨¨9Ð5Ó6ˆAܘy¨¨Ð4Ó5ˆAØ�q�6ˆMà œS '¨7Ð!3Ó4Ñ 4ÜœVðóóð ô œð ó ó ð r/N)r)r*r+r,Ú classmethodrarnr.r/r0rOrOs „ñðñ óð ó4  r/rOcó —eZdZy)ÚECPointN©r)r*r+r.r/r0rqrqÅó„àr/rqcó —eZdZy)ÚECPointBitStringNrrr.r/r0ruruÊrsr/rucó—eZdZdZddddœZy)ÚSpecifiedECDomainVersionú: Source: http://www.secg.org/sec1-v2.pdf page 104 ÚecdpVer1ÚecdpVer2ÚecdpVer3)rrQéNr7r.r/r0rwrwÏs„ñð Ø Ø ñ �Dr/rwcó—eZdZdZdddœZy)Ú FieldTypezR Original Name: None Source: http://www.secg.org/sec1-v2.pdf page 101 Ú prime_fieldÚcharacteristic_two_field)z1.2.840.10045.1.1z1.2.840.10045.1.2Nr7r.r/r0r~r~Ús„ñð +Ø7ñ �Dr/r~có—eZdZdZddddœZy)ÚCharacteristicTwoBasiszR Original Name: None Source: http://www.secg.org/sec1-v2.pdf page 102 Úgn_basisÚtp_basisÚpp_basis)z1.2.840.10045.1.2.1.1z1.2.840.10045.1.2.1.2z1.2.840.10045.1.2.1.3Nr7r.r/r0r‚r‚æs„ñð ",Ø!+Ø!+ñ �Dr/r‚có&—eZdZdZdefdefdefgZy)Ú Pentanomialú: Source: http://www.secg.org/sec1-v2.pdf page 102 Úk1Úk2Úk3Nr(r.r/r0r‡r‡ós%„ñð ˆwˆØ ˆwˆØ ˆwˆð�Gr/r‡có6—eZdZdZdefdefdefgZdZe ee dœZ y)ÚCharacteristicTwoz` Original Name: Characteristic-two Source: http://www.secg.org/sec1-v2.pdf page 101 ÚmÚbasisÚ parameters)r�r�)rƒr„r…N) r)r*r+r,rr‚rr-Ú _oid_pairrr‡Ú _oid_specsr.r/r0r�r�ÿs?„ñð ˆgˆØ Ð(Ð)Ø �sÐð€Gð (€IàØØñ�Jr/r�có.—eZdZdZdefdefgZdZee dœZ y)ÚFieldIDz: Source: http://www.secg.org/sec1-v2.pdf page 100 Ú field_typer�)r•r�)rr€N) r)r*r+r,r~rr-r‘rr�r’r.r/r0r”r”s4„ñð �yÐ!Ø �sÐð€Gð -€IàØ$5ñ�Jr/r”có,—eZdZdZdefdefdeddifgZy)ÚCurverxÚaÚbÚseedrDTN)r)r*r+r,rrr-r.r/r0r—r—$s/„ñð ˆkÐØ ˆkÐØ � *¨dÐ!3Ð4ð�Gr/r—c óJ—eZdZdZdefdefdefdefdefdedd ifd e dd ifgZ y ) ÚSpecifiedECDomainz: Source: http://www.secg.org/sec1-v2.pdf page 103 r;Úfield_idÚcurveÚbaseÚorderÚcofactorrDTÚhashN) r)r*r+r,rwr”r—rqrr r-r.r/r0rœrœ0sW„ñð Ð,Ð-Ø �WÐØ �%ÐØ �ÐØ �'ÐØ �W˜z¨4Ð0Ð1Ø � :¨tÐ"4Ð5ð�Gr/rœcóŒ—eZdZdZidd“dd“dd“dd “d d “d d “dd“dd“dd“dd“dd“dd“dd“dd“dd“d d!“d"d#“id$d%“d&d'“d(d)“d*d+“d,d-“d.d/“d0d1“d2d3“d4d5“d6d7“d8d9“d:d;“dd?“d@dA“dBdC“dDdE“¥idFdG“dHdI“dJdK“dLdM“dNdO“dPdQ“dRdS“dTdU“dVdW“dXdY“dZd[“d\d]“d^d_“d`da“dbdc“ddde“dfdg“¥idhdi“djdk“dldm“dndo“dpdq“drds“dtdu“dvdw“dxdy“dzd{“d|d}“d~d“d€d�“d‚dƒ“d„d…“d†d‡“dˆd‰“¥dŠd‹dŒd�dŽœ¥Zidd�“dd�“dd�“dd�“d d�“d d�“dd�“dd�“dd�“dd‘“dd’“dd’“dd’“dd’“dd’“d d““d"d”“id$d•“d&d•“d(d–“d*d�“d,d�“d.d’“d0d’“d2d’“d4d�“d6d—“d8d�“d:d�“dd˜“d@d˜“dBd™“dDd™“¥idFd�“dHd�“dJd—“dLd�“dNdš“dPdš“dRd›“dTd›“dVd‘“dXd‘“dZdœ“d\d’“d^d�“d`d�“dbd�“ddd�“dfdœ“¥idhdž“djdŸ“dld “dnd¡“dpd¢“drd£“dtd£“dvd¤“dxd¤“dzd�“d|d�“d~dž“d€dž“d‚d—“d„d—“d†d¥“dˆd¥“¥dŸdŸd¦d¦dŽœ¥Zed§„«Zy¨)©Ú NamedCurvez§ Various named curves Original Name: None Source: https://tools.ietf.org/html/rfc3279#page-23, https://tools.ietf.org/html/rfc5480#page-5 z1.2.840.10045.3.0.1Ú c2pnb163v1z1.2.840.10045.3.0.2Ú c2pnb163v2z1.2.840.10045.3.0.3Ú c2pnb163v3z1.2.840.10045.3.0.4Ú c2pnb176w1z1.2.840.10045.3.0.5Ú c2tnb191v1z1.2.840.10045.3.0.6Ú c2tnb191v2z1.2.840.10045.3.0.7Ú c2tnb191v3z1.2.840.10045.3.0.8Ú c2onb191v4z1.2.840.10045.3.0.9Ú c2onb191v5z1.2.840.10045.3.0.10Ú c2pnb208w1z1.2.840.10045.3.0.11Ú c2tnb239v1z1.2.840.10045.3.0.12Ú c2tnb239v2z1.2.840.10045.3.0.13Ú c2tnb239v3z1.2.840.10045.3.0.14Ú c2onb239v4z1.2.840.10045.3.0.15Ú c2onb239v5z1.2.840.10045.3.0.16Ú c2pnb272w1z1.2.840.10045.3.0.17Ú c2pnb304w1z1.2.840.10045.3.0.18Ú c2tnb359v1z1.2.840.10045.3.0.19Ú c2pnb368w1z1.2.840.10045.3.0.20Ú c2tnb431r1z1.2.840.10045.3.1.2Ú prime192v2z1.2.840.10045.3.1.3Ú prime192v3z1.2.840.10045.3.1.4Ú prime239v1z1.2.840.10045.3.1.5Ú prime239v2z1.2.840.10045.3.1.6Ú prime239v3z1.2.840.10045.3.1.1Ú secp192r1z1.2.840.10045.3.1.7Ú secp256r1z 1.3.132.0.1Ú sect163k1z 1.3.132.0.2Ú sect163r1z 1.3.132.0.3Ú sect239k1z 1.3.132.0.4Ú sect113r1z 1.3.132.0.5Ú sect113r2z 1.3.132.0.6Ú secp112r1z 1.3.132.0.7Ú secp112r2z 1.3.132.0.8Ú secp160r1z 1.3.132.0.9Ú secp160k1z 1.3.132.0.10Ú secp256k1z 1.3.132.0.15Ú sect163r2z 1.3.132.0.16Ú sect283k1z 1.3.132.0.17Ú sect283r1z 1.3.132.0.22Ú sect131r1z 1.3.132.0.23Ú sect131r2z 1.3.132.0.24Ú sect193r1z 1.3.132.0.25Ú sect193r2z 1.3.132.0.26Ú sect233k1z 1.3.132.0.27Ú sect233r1z 1.3.132.0.28Ú secp128r1z 1.3.132.0.29Ú secp128r2z 1.3.132.0.30Ú secp160r2z 1.3.132.0.31Ú secp192k1z 1.3.132.0.32Ú secp224k1z 1.3.132.0.33Ú secp224r1z 1.3.132.0.34Ú secp384r1z 1.3.132.0.35Ú secp521r1z 1.3.132.0.36Ú sect409k1z 1.3.132.0.37Ú sect409r1z 1.3.132.0.38Ú sect571k1z 1.3.132.0.39Ú sect571r1z1.3.36.3.3.2.8.1.1.1Úbrainpoolp160r1z1.3.36.3.3.2.8.1.1.2Úbrainpoolp160t1z1.3.36.3.3.2.8.1.1.3Úbrainpoolp192r1z1.3.36.3.3.2.8.1.1.4Úbrainpoolp192t1z1.3.36.3.3.2.8.1.1.5Úbrainpoolp224r1z1.3.36.3.3.2.8.1.1.6Úbrainpoolp224t1z1.3.36.3.3.2.8.1.1.7Úbrainpoolp256r1z1.3.36.3.3.2.8.1.1.8Úbrainpoolp256t1z1.3.36.3.3.2.8.1.1.9Úbrainpoolp320r1z1.3.36.3.3.2.8.1.1.10Úbrainpoolp320t1Úbrainpoolp384r1Úbrainpoolp384t1Úbrainpoolp512r1Úbrainpoolp512t1)z1.3.36.3.3.2.8.1.1.11z1.3.36.3.3.2.8.1.1.12z1.3.36.3.3.2.8.1.1.13z1.3.36.3.3.2.8.1.1.14ééééé!é%é-é5é ééé$ééééé0éBé3é4éHéé(é@cóv—||j|<|j�||j|<||j|<y)a€ Registers a new named elliptic curve that is not included in the default list of named curves :param name: A unicode string of the curve name :param oid: A unicode string of the dotted format OID :param key_size: An integer of the number of bytes the private key should be encoded to N)r8Ú _reverse_mapÚ _key_sizes)rZÚnameÚoidÚkey_sizes r0ÚregisterzNamedCurve.registerës;€ð"ˆ�‰�‰ Ø × Ñ Ð 'Ø%(ˆC× Ñ ˜TÑ "Ø&ˆ�‰�sÒr/N)r)r*r+r,r8rror r.r/r0r¤r¤@sí„ñðM à˜|ðM ð ˜|ðM ð ˜|ð M ð ˜|ð M ð ˜|ð M ð ˜|ðM ð ˜|ðM ð ˜|ðM ð ˜|ðM ð   ðM ð   ðM ð   ðM ð   ðM ð   ðM ð   ð!M ð"   ð#M ð$   ñ%M ð&   ð'M ð(   ð)M ð*   ð+M ð, ˜|ð-M ð. ˜|ð/M ð0 ˜|ð1M ð2 ˜|ð3M ð4 ˜|ð5M ð: ˜{ð;M ð< ˜{ð=M ð> �{ð?M ð@ �{ðAM ðB �{ðCM ðD �{ðEM ðF �{ðGM ðH �{ðIM ðJ �{òKM ðL �{ðMM ðN �{ðOM ðP ˜ ðQM ðR ˜ ðSM ðT ˜ ðUM ðV ˜ ðWM ðX ˜ ðYM ðZ ˜ ð[M ð\ ˜ ð]M ð^ ˜ ð_M ð` ˜ ðaM ðb ˜ ðcM ðd ˜ ðeM ðf ˜ ðgM ðh ˜ ðiM ðj ˜ ðkM ðl ˜ òmM ðn ˜ ðoM ðp ˜ ðqM ðr ˜ ðsM ðt ˜ ðuM ðv ˜ ðwM ðx ˜ ðyM ðz ˜ ð{M ð~ Ð 1ðM ð@ Ð 1ðAM ðB Ð 1ðCM ðD Ð 1ðEM ðF Ð 1ðGM ðH Ð 1ðIM ðJ Ð 1ðKM ðL Ð 1ðMM ðN Ð 1ðOM ðP Ð!2ñQM ðR"3Ø!2Ø!2Ø!2òYM €Dð^Qð ˜rðQð ˜rð Qð ˜rð Qð ˜rð Qð ˜rðQð ˜rðQð ˜rðQð ˜rðQð ˜rðQð  ðQð  ðQð  ðQð  ðQð  ð!Qð"  ð#Qð$  ð%Qð&  ñ'Qð(  ð)Qð*  ð+Qð,  ð-Qð. ˜rð/Qð0 ˜rð1Qð2 ˜rð3Qð4 ˜rð5Qð6 ˜rð7Qð> ˜rð?Qð@ ˜rðAQðB �rðCQðD �rðEQðF �rðGQðH �rðIQðJ �rðKQðL �rðMQðN �ròOQðP �rðQQðR �rðSQðT ˜ðUQðV ˜ðWQðX ˜ðYQðZ ˜ð[Qð\ ˜ð]Qð^ ˜ð_Qð` ˜ðaQðb ˜ðcQðd ˜ðeQðf ˜ðgQðh ˜ðiQðj ˜ðkQðl ˜ðmQðn ˜ðoQðp ˜òqQðr ˜ðsQðt ˜ðuQðv ˜ðwQðx ˜ðyQðz ˜ð{Qð| ˜ð}Qð~ ˜ðQðF  ðGQðH  ðIQðJ  ðKQðL  ðMQðN  ðOQðP  ðQQðR  ðSQðT  ðUQðV  ðWQðX  ñYQðZ"$Ø!#Ø!#Ø!#òaQ€Jðfñ'óñ'r/r¤có6—eZdZdZdefdefdefgZed„«Z y)ÚECDomainParametersrˆÚ specifiedÚnamedÚ implicit_cacó¢—|jdk(rttd««‚|jdk(rE|jdj}t j t j|d«dz «S|jj}|tjvrttdt|«««‚tj|S)Nrz� Unable to calculate key_size from ECDomainParameters that are implicitly defined by the CA key rr g@rRz¬ The asn1crypto.keys.NamedCurve %s does not have a registered key length, please call asn1crypto.keys.NamedCurve.register() ) rrhrÚchosenrerVrWrXÚdottedr¤rÚrepr)rir r s r0r zECDomainParameters.key_size sº€à �9‰9˜ Ò %ÜœVðóóð ð �9‰9˜ Ò #Ø—K‘K Ñ(×/Ñ/ˆEÜ—9‘9œTŸX™X e¨SÓ1°CÑ7Ó8Ð 8à�k‰k× Ñ ˆØ ”j×+Ñ+Ñ +ÜœVðô�S“ ó óð ô×$Ñ$ SÑ)Ð)r/N) r)r*r+r,rœr¤rÚ _alternativesÚpropertyr r.r/r0r r s=„ñð Ð'Ð(Ø �*ÐØ ˜Ðð€Mð ñ*óñ*r/r có—eZdZdZddiZy)ÚECPrivateKeyVersionzR Original Name: None Source: http://www.secg.org/sec1-v2.pdf page 108 rÚ ecPrivkeyVer1Nr7r.r/r0rr's„ñð ˆ?ð �Dr/rcó^‡—eZdZdZdefdefdedddœfded ddœfgZd Z ˆfd „Z d „Z d „Z ˆxZ S)Ú ECPrivateKeyz: Source: http://www.secg.org/sec1-v2.pdf page 108 r;rMr�rT)ÚexplicitrDrLrNcóÊ•—tt|� ||«}|dk(r€|j€V|dj}t |t «rSt|«dkDrE|jt|dj««|S|j�|j«|S|dk(rCt |dt«r0|djdk7r|j|dj«|S)NrMrr�r) ÚsuperrÚ __setitem__Ú _key_sizeÚcontentsÚ isinstancer rfÚ set_key_sizeÚ_update_key_sizer rr )riÚkeyÚvalueÚresÚ pkey_contentsÚ __class__s €r0rzECPrivateKey.__setitem__BsÝø€Ü”L $Ñ3°C¸Ó?ˆà �-Ò Ø�~‰~Ð%à $ ]Ñ 3× <Ñ <� ܘm¬XÔ6¼3¸}Ó;MÐPQÒ;QØ×%Ñ%¤c¨$¨}Ñ*=×*FÑ*FÓ&GÔHðˆ ð—‘Ð+Ø×%Ñ%Ô'ð ˆ ð �LÒ ¤Z°°\Ñ0BÔDVÔ%WØ�\Ñ"×'Ñ'¨=Ò8Ø × Ñ ˜d <Ñ0×9Ñ9Ô :àˆ r/có2—||_|j«y)z· Sets the key_size to ensure the private key is encoded to the proper length :param key_size: An integer byte length to encode the private_key to N)r r$)rir s r0r#zECPrivateKey.set_key_sizeUs€ð"ˆŒØ ×ÑÕr/có‚—|j�3t|dt«r|dj|j«yyy)zG Ensure the private_key explicit encoding width is set NrM)r r"rÚset_encoded_width©ris r0r$zECPrivateKey._update_key_size`s=€ð �>‰>Ð %¬*°T¸-Ñ5HÔJ\Ô*]Ø �Ñ × 1Ñ 1°$·.±.Õ Að+^Ð %r/)r)r*r+r,rrr rur-r rr#r$Ú __classcell__©r)s@r0rr2sZø„ñð Ð'Ð(Ø Ð*Ð+Ø Ð)¸ÀtÑ+LÐMØ Ð'°aÀTÑ)JÐKð €Gð€Iôò&  öBr/rcó&—eZdZdZdefdefdefgZy)Ú DSAParamsz‰ Parameters for a DSA public or private key Original Name: Dss-Parms Source: https://tools.ietf.org/html/rfc3279#page-9 rIrJrKNr(r.r/r0r1r1is%„ñð ˆgˆØ ˆgˆØ ˆgˆð�Gr/r1có&—eZdZdZdefdedeifgZy)Ú Attributezq Source: https://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-X.501-198811-S!!PDF-E&type=items page 8 ÚtypeÚvaluesÚspecN)r)r*r+r,rrrr-r.r/r0r3r3xs'„ñð Ð!Ð"Ø �5˜6 3˜-Ð(ð�Gr/r3có—eZdZdZeZy)Ú Attributesú< Source: https://tools.ietf.org/html/rfc5208#page-3 N)r)r*r+r,r3r3r.r/r0r8r8ƒs„ñð�Kr/r8c ó&—eZdZdZdddddddd d œZy ) ÚPrivateKeyAlgorithmIdz» These OIDs for various public keys are reused when storing private keys inside of a PKCS#8 structure Original Name: None Source: https://tools.ietf.org/html/rfc3279 ÚrsaÚ rsassa_pssÚdsaÚecÚx25519Úx448Úed25519Úed448)ú1.2.840.113549.1.1.1ú1.2.840.113549.1.1.10ú1.2.840.10040.4.1ú1.2.840.10045.2.1ú 1.3.101.110ú 1.3.101.111ú 1.3.101.112ú 1.3.101.113Nr7r.r/r0r;r;‹s(„ñð!&à!-à"à!àØØ Øñ �Dr/r;có6—eZdZdZdefdeddifgZdZee e dœZ y) ÚPrivateKeyAlgorithmzm Original Name: PrivateKeyAlgorithmIdentifier Source: https://tools.ietf.org/html/rfc5208#page-3 Ú algorithmr�rDT©rNr�)r>r?r=N) r)r*r+r,r;rr-r‘r1r rr’r.r/r0rMrM¥s?„ñð Ð+Ð,Ø �s˜Z¨Ð.Ð/ð€Gð ,€IàØ Ø%ñ�Jr/rMcóú‡—eZdZdZdefdefdefdedddœfgZd „Z de iZ d Z d Z d Z d Zed „«Zˆfd „Zd „Zed„«Zed„«Zed„«Zed„«Zed„«Zed„«Zed„«Zed„«ZˆxZS)ÚPrivateKeyInfor9r;Úprivate_key_algorithmrMÚ attributesrT)ÚimplicitrDc ó‚—|ddj}ttttttttdœ|S)NrRrN)r<r=r>r?r@rArBrC)rer:rrr©rirNs r0Ú_private_key_specz PrivateKeyInfo._private_key_specÄsF€ØÐ0Ñ1°+Ñ>×EÑEˆ ä Ü'ÜÜô"ÜÜ"Ü ñ  ð ñ ð r/Ncó—t|t«s.t|t«stt dt |«««‚|dk(s|dk(r0t|t «st j|«}t«}n¹|dk(rRt|t«stj|«}t«}|d|d<|d|d<|d|d<|d}|d }nb|d k(r?t|t«stj|«}n|j«}|d }|d =ntt d t|«««‚t«}t!|«|d <||d <|«}||_t%d«|d<||d<||d <|dk(r|_|S)a' Wraps a private key in a PrivateKeyInfo structure :param private_key: A byte string or Asn1Value object of the private key :param algorithm: A unicode string of "rsa", "dsa" or "ec" :return: A PrivateKeyInfo object zX private_key must be a byte string or Asn1Value, not %s r<r=r>rIrJrKrLrMr?r�zU algorithm must be one of "rsa", "dsa", "ec", not %s rNrr;rR)r"r rÚ TypeErrorrr r:ÚloadrrHr1rÚcopyrhrrMr;Ú _algorithmrÚ _public_key)rZrMrNÚparamsrLÚprivate_key_algoÚ containers r0ÚwrapzPrivateKeyInfo.wrapÜs¨€ô˜+¤xÔ0¼ÀKÔQZÔ9[ÜœFðô˜+Ó&ó óð ð ˜Ò  ¨lÒ!:ܘk¬=Ô9Ü+×0Ñ0°Ó=� Ü“V‰FØ ˜%Ò Ü˜k¬=Ô9Ü+×0Ñ0°Ó=� Ü“[ˆFØ% cÑ*ˆF�3‰KØ% cÑ*ˆF�3‰KØ% cÑ*ˆF�3‰KØ$ \Ñ2ˆJØ% mÑ4‰KØ ˜$Ò Ü˜k¬<Ô8Ü*×/Ñ/° Ó<‘ à)×.Ñ.Ó0� Ø  Ñ.ˆFؘLÑ)äœVðô�Y“ó óð ô/Ó0ÐÜ(=¸iÓ(HИÑ%Ø)/ИÑ&á“Eˆ Ø(ˆ ÔÜ& q›zˆ �)ÑØ-=ˆ Ð)Ñ*Ø#.ˆ �-Ñ ð ˜Ò Ø$.ˆIÔ !àÐr/cór•—tt|� ||«}|d}|dk(s|dk(r’|djdk(r€t |dt «rm|dj dk7r[t |dt«rHt |djt«r+|djj|dj«|S)NrRrMrNr?r�r) rrQrrer"r rrÚparsedrr#r )rir%r&r'rNr)s €r0rzPrivateKeyInfo.__setitem__"s·ø€Ü”N DÑ5°c¸5ÓAˆàÐ0Ñ1ˆ ð Ð*Ò *¨c°]Ò.Bؘ+Ñ&×-Ñ-°Ò5ܘ9 \Ñ2Ô4FÔGؘ,Ñ'×,Ñ,° Ò=ܘ4  Ñ.Ô0CÔDܘ4  Ñ.×5Ñ5´|ÔDØ �Ñ × &Ñ &× 3Ñ 3°I¸lÑ4K×4TÑ4TÔ Uàˆ r/có—td«‚)z Unwraps the private key into an RSAPrivateKey, DSAPrivateKey or ECPrivateKey object :return: An RSAPrivateKey, DSAPrivateKey or ECPrivateKey object zxasn1crypto.keys.PrivateKeyInfo().unwrap() has been removed, please use oscrypto.asymmetric.PrivateKey().unwrap() instead©r r-s r0rzPrivateKeyInfo.unwrap3s€ôð KóLð Lr/cóú—|jdk7r-ttd|jj«««‚|dd}|j}|j dk(rd}n |j }|j |fS)á# Returns information about the curve used for an EC key :raises: ValueError - when the key is not an EC key :return: A two-element tuple, with the first element being a unicode string of "implicit_ca", "specified" or "named". If the first element is "implicit_ca", the second is None. If "specified", the second is an OrderedDict that is the native version of SpecifiedECDomain. If "named", the second is a unicode string of the curve name. r?úK Only EC keys have a curve, this key is %s rRr�rN©rNrhrÚupperrrre©rir^rr&s r0ržzPrivateKeyInfo.curve@s€ð �>‰>˜TÒ !ÜœVðð—‘×$Ñ$Ó&ó óð ðÐ-Ñ.¨|Ñ<ˆØ—‘ˆà �;‰;˜-Ò '؉Eà—M‘MˆEà— ‘ ˜UÐ#Ð#r/cóä—|jdk7r-ttd|jj«««‚t j |dddj d«dz }|dkrd Sd S) zò Returns the name of the family of hash algorithms used to generate a DSA key :raises: ValueError - when the key is not a DSA key :return: A unicode string of "sha1" or "sha2" r>út Only DSA keys are generated using a hash algorithm, this key is %s rRr�rJrQérÚsha1Úsha2)rNrhrrjrVrXre)riÚbyte_lens r0Ú hash_algozPrivateKeyInfo.hash_algobs{€ð �>‰>˜UÒ "ÜœVðð—‘×$Ñ$Ó&ó óð ô—8‘8˜DÐ!8Ñ9¸,ÑGÈÑL×SÑSÐUVÓWÐZ[Ñ[ˆà! RšˆvÐ3¨VÐ3r/có`—|j€|ddj|_|jS)ú] :return: A unicode string of "rsa", "rsassa_pss", "dsa" or "ec" rRrN©r\rer-s r0rNzPrivateKeyInfo.algorithm|s0€ð �?‰?Ð "Ø"Ð#:Ñ;¸KÑH×OÑOˆDŒOØ�‰Ðr/có—|j€î|jdk(s|jdk(r|djdj}nP|jdk(r|dddj}n+|jd k(r|djdj}t t j t jd «««|_|jd z}|d k7r|xjd |z z c_|jS) zU :return: The bit size of the private key, as an integer r<r=rMr<r>rRr�rIr?rQrnr)Ú _bit_sizerNrcrerUrVrWrX©rir%r<s r0Úbit_sizezPrivateKeyInfo.bit_size‡s߀ð �>‰>Ð !Ø�~‰~ Ò&¨$¯.©.¸LÒ*Hؘ]Ñ+×2Ñ2°9Ñ=×DÑD‘Ø—‘ 5Ò(ØÐ4Ñ5°lÑCÀCÑH×OÑO‘Ø—‘ 4Ò'ؘ]Ñ+×2Ñ2°=ÑA×HÑH�Ü ¤§¡¬4¯8©8°E¸1Ó+=Ó!>Ó?ˆDŒNØ—n‘n qÑ(ˆGؘ!Š|Ø—’ ! g¡+Ñ-•Ø�~‰~Ðr/cóX—ttj|jdz ««S)zV :return: The byte size of the private key, as an integer rn©rUrVrWryr-s r0Ú byte_sizezPrivateKeyInfo.byte_size›ó!€ô”4—9‘9˜TŸ]™]¨QÑ.Ó/Ó0Ð0r/có—td«‚)z¤ :return: If an RSA key, an RSAPublicKey object. If a DSA key, an Integer object. If an EC key, an ECPointBitString object. z…asn1crypto.keys.PrivateKeyInfo().public_key has been removed, please use oscrypto.asymmetric.PrivateKey().public_key.unwrap() insteadrer-s r0rLzPrivateKeyInfo.public_key¤s€ôð VóWð Wr/có—td«‚)z\ :return: A PublicKeyInfo object derived from this private key. z†asn1crypto.keys.PrivateKeyInfo().public_key_info has been removed, please use oscrypto.asymmetric.PrivateKey().public_key.asn1 insteadrer-s r0Úpublic_key_infozPrivateKeyInfo.public_key_info°s€ôð RóSð Sr/có—td«‚)aY Creates a fingerprint that can be compared with a public key to see if the two form a pair. This fingerprint is not compatible with fingerprints generated by any other software. :return: A byte string that is a sha256 hash of selected components (based on the key type) z~asn1crypto.keys.PrivateKeyInfo().fingerprint has been removed, please use oscrypto.asymmetric.PrivateKey().fingerprint insteadrer-s r0Ú fingerprintzPrivateKeyInfo.fingerprint»s€ôð NóOð Or/)r)r*r+r,rrMrr8r-rWÚ_spec_callbacksr\rwr]Ú _fingerprintrorarrrržrrrNryr|rLr€r‚r.r/s@r0rQrQ¸s+ø„ñð �GÐØ Ð"5Ð6Ø Ð+Ð,Ø �z°¸tÑ#DÐEð €Gò ð Ð(ð€Oð€JØ€IØ€KØ€LàñAóðAôJò" Lðñ$óð$ðBñ4óð4ð2ñóððñóðð&ñ1óð1ðñ Wóð WðñSóðSðñOóôOr/rQcó —eZdZdZdefdefgZy)ÚEncryptedPrivateKeyInfoz< Source: https://tools.ietf.org/html/rfc5208#page-4 Úencryption_algorithmÚencrypted_dataN)r)r*r+r,rrr-r.r/r0r†r†Îs!„ñð Ð!4Ð5Ø ˜;Ð'ð�Gr/r†có —eZdZdZdefdefgZy)ÚValidationParmsú= Source: https://tools.ietf.org/html/rfc3279#page-10 ršÚ pgen_counterN)r)r*r+r,rrr-r.r/r0rŠrŠÛs „ñð �ÐØ ˜Ð!ð�Gr/rŠcó>—eZdZdZdefdefdefdeddifdeddifgZy ) ÚDomainParametersr‹rIrKrJÚjrDTÚvalidation_paramsN)r)r*r+r,rrŠr-r.r/r0rŽrŽæsC„ñð ˆgˆØ ˆgˆØ ˆgˆØ ˆg˜  DÐ)Ð*Ø ˜o° ¸DÐ/AÐBð �Gr/rŽc ó*—eZdZdZdddddddd d d d œ Zy )ÚPublicKeyAlgorithmIdzM Original Name: None Source: https://tools.ietf.org/html/rfc3279 r<Ú rsaes_oaepr=r>r?Údhr@rArBrC) rDz1.2.840.113549.1.1.7rErFrGz1.2.840.10046.2.1rHrIrJrKNr7r.r/r0r’r’ôs.„ñð!&à ,à!-à"à!à!àØØ Øñ# �Dr/r’có:—eZdZdZdefdeddifgZdZee e e e dœZ y) ÚPublicKeyAlgorithmzd Original Name: AlgorithmIdentifier Source: https://tools.ietf.org/html/rfc5280#page-18 rNr�rDTrO)r>r?r”r“r=N)r)r*r+r,r’rr-r‘r1r rŽrrr’r.r/r0r–r–sE„ñð Ð*Ð+Ø �s˜Z¨Ð.Ð/ð€Gð ,€IàØ ØØ%Ø%ñ �Jr/r–cóØ—eZdZdZdefdefgZd„ZdeiZdZ dZ dZ dZ dZ ed„«Zd„Zed„«Zed „«Zed „«Zed „«Zed „«Zed „«Zed„«Zed„«Zy)Ú PublicKeyInfoze Original Name: SubjectPublicKeyInfo Source: https://tools.ietf.org/html/rfc5280#page-17 rNrLc óª—|ddj}tttttdfttdftdftdftdfdœ |S)NrN) r<r“r=r>r?r”r@rArBrC)rerFrrurrVs r0Ú_public_key_speczPublicKeyInfo._public_key_spec/sf€Ø˜Ñ% kÑ2×9Ñ9ˆ äÜ&Ü&Üô$ TÐ*Üô& tÐ,Ü# TÐ*Ü&¨Ð-Ü$ dÐ+ñ ð ñð r/Ncó¬—t|t«s.t|t«stt dt |«««‚|dk7r#|dk7rt t dt|«««‚t«}t|«|d<t«|d<|«}||d<t|t«r|j«j«}t|«|d<|S)a Wraps a public key in a PublicKeyInfo structure :param public_key: A byte string or Asn1Value object of the public key :param algorithm: A unicode string of "rsa" :return: A PublicKeyInfo object zW public_key must be a byte string or Asn1Value, not %s r<r=z> algorithm must "rsa", not %s rNr�rL)r"r rrYrr rhrr–r’rÚuntagÚdumpr)rZrLrNÚalgor`s r0razPublicKeyInfo.wrapLsÙ€ô˜*¤hÔ/¼ À:ÌyÔ8YÜœFðô˜*Ó%ó óð ð ˜Ò  )¨|Ò";ÜœVðô�Y“ó óð ô"Ó#ˆÜ0°Ó;ˆˆ[ÑÜ!›Vˆˆ\Ñá“Eˆ Ø!%ˆ �+ÑÜ �j¤)Ô ,Ø#×)Ñ)Ó+×0Ñ0Ó2ˆJÜ"8¸Ó"Dˆ �,ÑàÐr/có—td«‚)zÖ Unwraps an RSA public key into an RSAPublicKey object. Does not support DSA or EC public keys since they do not have an unwrapped form. :return: An RSAPublicKey object zvasn1crypto.keys.PublicKeyInfo().unwrap() has been removed, please use oscrypto.asymmetric.PublicKey().unwrap() insteadrer-s r0rzPublicKeyInfo.unwrapws€ôð JóKð Kr/cóú—|jdk7r-ttd|jj«««‚|dd}|j}|j dk(rd}n |j }|j |fS)rgr?rhrNr�rNrirks r0ržzPublicKeyInfo.curve„s~€ð �>‰>˜TÒ !ÜœVðð—‘×$Ñ$Ó&ó óð ð�kÑ" <Ñ0ˆØ—‘ˆà �;‰;˜-Ò '؉Eà—M‘MˆEà— ‘ ˜UÐ#Ð#r/có—|jdk7r-ttd|jj«««‚|dd}|j€yt j |djd«dz }|d krd Sd S) a# Returns the name of the family of hash algorithms used to generate a DSA key :raises: ValueError - when the key is not a DSA key :return: A unicode string of "sha1" or "sha2" or None if no parameters are present r>rmrNr�NrJrQrnrrorp)rNrhrrjrerVrX)rir�rqs r0rrzPublicKeyInfo.hash_algo¦s‹€ð �>‰>˜UÒ "ÜœVðð—‘×$Ñ$Ó&ó óð ð˜+Ñ& |Ñ4ˆ Ø × Ñ Ð $Øä—8‘8˜J s™O×2Ñ2°AÓ6¸Ñ:ˆà! RšˆvÐ3¨VÐ3r/có`—|j€|ddj|_|jS)rtrNrur-s r0rNzPublicKeyInfo.algorithmÅs/€ð �?‰?Ð "Ø" ;Ñ/° Ñ<×CÑCˆDŒOØ�‰Ðr/cóL—|j�€ |jdk(r;tt|dj«dz dz dz«|_|jS|jdk(s|jdk(r|dj dj}n$|jd k(r|d d d j}tt jt jd«««|_|jdz}|d k7r|xjd|z z c_|jS)zT :return: The bit size of the public key, as an integer r?rLrrQrnr<r=r<r>rNr�rIr) rwrNrUrfrercrVrWrXrxs r0ryzPublicKeyInfo.bit_sizeÐsý€ð �>‰>Ñ !Ø�~‰~ Ò%Ü!$¤s¨4° Ñ+=×+DÑ+DÓ'EÈÑ'IÈQÑ&NÐRSÑ%SÓ!T�”ð�~‰~Ðð—>‘> UÒ*¨d¯n©nÀ Ò.LØ  Ñ.×5Ñ5°iÑ@×GÑG‘EØ—^‘^ uÒ,Ø  Ñ-¨lÑ;¸CÑ@×GÑG�EÜ!$¤T§Y¡Y¬t¯x©x¸¸qÓ/AÓ%BÓ!C�”ØŸ.™.¨1Ñ,�ؘa’<Ø—N’N a¨'¡kÑ1•Nà�~‰~Ðr/cóX—ttj|jdz ««S)zU :return: The byte size of the public key, as an integer rnr{r-s r0r|zPublicKeyInfo.byte_sizeær}r/cóš—|j€4tjt|d««j «|_|jS)ze :return: The SHA1 hash of the DER-encoded bytes of this public key info rL)Ú_sha1Úhashlibror Údigestr-s r0rozPublicKeyInfo.sha1ïs;€ð �:‰:Ð Ü Ÿ™¤h¨t°LÑ/AÓ&BÓC×JÑJÓLˆDŒJØ�z‰zÐr/cóš—|j€4tjt|d««j «|_|jS)zh :return: The SHA-256 hash of the DER-encoded bytes of this public key info rL)Ú_sha256r§Úsha256r r¨r-s r0r«zPublicKeyInfo.sha256ús;€ð �<‰<Ð Ü"Ÿ>™>¬(°4¸ Ñ3EÓ*FÓG×NÑNÓPˆDŒLØ�|‰|Ðr/có—td«‚)aZ Creates a fingerprint that can be compared with a private key to see if the two form a pair. This fingerprint is not compatible with fingerprints generated by any other software. :return: A byte string that is a sha256 hash of selected components (based on the key type) z|asn1crypto.keys.PublicKeyInfo().fingerprint has been removed, please use oscrypto.asymmetric.PublicKey().fingerprint insteadrer-s r0r‚zPublicKeyInfo.fingerprints€ôð MóNð Nr/)r)r*r+r,r–rr-ršrƒr\rwr„r¦rªrorarrržrrrNryr|ror«r‚r.r/r0r˜r˜$s „ñð Ð(Ð)Ø Ð-Ð.ð€Gò ð( Ð&ð€Oð€JØ€IØ€LØ €EØ€Gàñ(óð(òT Kðñ$óð$ðBñ4óð4ð<ñóððñóðð*ñ1óð1ðñóððñóððñNóñNr/r˜)Hr,Ú __future__rrrrr§rVÚ_errorsrr Ú_typesr r Úalgosr r rrrÚcorerrrrrrrrrrrrrrrÚutilr r!r#r2r5r:rFrHrOrqrurwr~r‚r‡r�r”r—rœr¤r rrr1r3r8r;rMrQr†rŠrŽr’r–r˜r.r/r0Úr³sïðñ ÷SÓRãÛ ç)ß'ßoÕo÷÷÷÷ñ÷"/ô �Xô ô!�jô!ô ˜7ô ô�Hôô&�8ôô�Hô÷(C ñC ôL ˆk˜8ô ô  �~ xô ô ˜wôô Ð ô ô Ð-ô ô �(ô ô˜ôô(ˆhôô" ˆHô ô ˜ô ô 'Ð!ô'ôD"*˜ô"*ôJ˜'ôô4B�8ô4Bôn �ô ô�ôô�ôôÐ,ôô4Ð.°ôô&SO�XôSOôl˜hôô�hôô �xô ôÐ+ôô6Ð-¨xôô*qN�HõqNr/__pycache__/ocsp.cpython-312.pyc000064400000055526152572326550012454 0ustar00Ë uÉþiPJãóð—dZddlmZmZmZmZddlmZddlm Z m Z ddl m Z m Z mZmZmZmZmZmZmZmZmZmZmZddlmZmZddlmZdd lmZm Z m!Z!m"Z"Gd „d e«Z#Gd „d e«Z$Gd„de«Z%Gd„de«Z&Gd„de«Z'Gd„de«Z(Gd„de«Z)Gd„de«Z*Gd„de«Z+Gd„de«Z,Gd„de«Z-Gd „d!e«Z.Gd"„d#e«Z/Gd$„d%e«Z0Gd&„d'e«Z1Gd(„d)e«Z2Gd*„d+e«Z3Gd,„d-e«Z4Gd.„d/e«Z5Gd0„d1e«Z6Gd2„d3e «Z7Gd4„d5e«Z8Gd6„d7e«Z9Gd8„d9e«Z:Gd:„d;e «Z;Gd<„d=e«Z<Gd>„d?e«Z=Gd@„dAe«Z>GdB„dCe«Z?GdD„dEe«Z@GdF„dGe«ZAGdH„dIe«ZBGdJ„dKe«ZCGdL„dMe«ZDGdN„dOe«ZEGdP„dQe«ZFGdR„dSe«ZGGdT„dUe«ZHyV)WzÒ ASN.1 type classes for the online certificate status protocol (OCSP). Exports the following items: - OCSPRequest() - OCSPResponse() Other type classes are defined that help compose the types listed above. é)Úunicode_literalsÚdivisionÚabsolute_importÚprint_functioné)Úunwrap)ÚDigestAlgorithmÚSignedDigestAlgorithm) ÚBooleanÚChoiceÚ EnumeratedÚGeneralizedTimeÚ IA5StringÚIntegerÚNullÚObjectIdentifierÚOctetBitStringÚ OctetStringÚParsableOctetStringÚSequenceÚ SequenceOf)ÚAuthorityInfoAccessSyntaxÚ CRLReason)ÚPublicKeyAlgorithm)Ú CertificateÚ GeneralNameÚ GeneralNamesÚNamecó—eZdZddiZy)ÚVersionrÚv1N©Ú__name__Ú __module__Ú __qualname__Ú_map©óú@/opt/nydus/tmp/pip-target-dhtdbchl/lib/python/asn1crypto/ocsp.pyr r (s„à ˆ4ð �Dr(r có(—eZdZdefdefdefdefgZy)ÚCertIdÚhash_algorithmÚissuer_name_hashÚissuer_key_hashÚ serial_numberN)r#r$r%r rrÚ_fieldsr'r(r)r+r+.s)„à ˜?Ð+Ø ˜[Ð)Ø ˜KÐ(Ø ˜'Ð"ð �Gr(r+có—eZdZdefdefgZy)ÚServiceLocatorÚissuerÚlocatorN)r#r$r%rrr0r'r(r)r2r27s„à �4ÐØ Ð-Ð.ð�Gr(r2có—eZdZddiZy)ÚRequestExtensionIdz1.3.6.1.5.5.7.48.1.7Úservice_locatorNr"r'r(r)r6r6>s„àÐ 1ð �Dr(r6có4—eZdZdefdeddifdefgZdZdeiZ y) ÚRequestExtensionÚextn_idÚcriticalÚdefaultFÚ extn_value©r:r=r7N) r#r$r%r6r rr0Ú _oid_pairr2Ú _oid_specsr'r(r)r9r9Ds=„à Ð&Ð'Ø �W˜y¨%Ð0Ð1Ø Ð*Ð+ð€Gð *€Ià˜>ð�Jr(r9có—eZdZeZy)ÚRequestExtensionsN)r#r$r%r9Ú _child_specr'r(r)rBrBQs„Ø"�Kr(rBcóV—eZdZdefdedddœfgZdZdZdZd„Z e d „«Z e d „«Z y) ÚRequestÚreq_certÚsingle_request_extensionsrT©ÚexplicitÚoptionalFNcó—t«|_|dD]g}|dj}d|z}t||«rt |||dj «|djsŒM|jj |«Œid|_y)úv Sets common named extensions to private attributes and creates a list of critical extensions rGr:ú _%s_valuer=r;TN©ÚsetÚ_critical_extensionsÚnativeÚhasattrÚsetattrÚparsedÚaddÚ_processed_extensions©ÚselfÚ extensionÚnameÚattribute_names r)Ú_set_extensionszRequest._set_extensions_s…€ô %(£EˆÔ!àÐ9Ô:ˆIؘYÑ'×.Ñ.ˆDØ(¨4Ñ/ˆNÜ�t˜^Ô,ܘ˜n¨i¸ Ñ.E×.LÑ.LÔMؘÑ$×+Ó+Ø×)Ñ)×-Ñ-¨dÕ3ð ;ð&*ˆÕ"r(cóR—|js|j«|jS©z² Returns a set of the names (or OID if not a known extension) of the extensions marked as critical :return: A set of unicode strings ©rVr\rP©rXs r)Úcritical_extensionszRequest.critical_extensionsqó%€ð×)Ò)Ø × Ñ Ô "Ø×(Ñ(Ð(r(cóV—|jdur|j«|jS)z¿ This extension is used when communicating with an OCSP responder that acts as a proxy for OCSP requests :return: None or a ServiceLocator object F)rVr\Ú_service_locator_valuer`s r)Úservice_locator_valuezRequest.service_locator_valueó*€ð × %Ñ %¨Ñ .Ø × Ñ Ô "Ø×*Ñ*Ð*r() r#r$r%r+rBr0rVrPrdr\Úpropertyrarer'r(r)rErEUsc„à �VÐØ $Ð&7ÀaÐUYÑ9ZÐ[ð€Gð "ÐØÐØ!Ðò*ð$ñ )óð )ðñ +óñ +r(rEcó—eZdZeZy)ÚRequestsN)r#r$r%rErCr'r(r)ririŽs„Ø�Kr(ricó—eZdZddiZy)Ú ResponseTypez1.3.6.1.5.5.7.48.1.1Úbasic_ocsp_responseNr"r'r(r)rkrk’s„àÐ 5ð �Dr(rkcó—eZdZeZy)ÚAcceptableResponsesN)r#r$r%rkrCr'r(r)rnrn˜s„Ø�Kr(rncó"—eZdZdefdeddifgZy)ÚPreferredSignatureAlgorithmÚsig_identifierÚcert_identifierrJTN)r#r$r%r rr0r'r(r)rprpœs"„à Ð0Ð1Ø Ð.°¸TÐ0BÐCð�Gr(rpcó—eZdZeZy)ÚPreferredSignatureAlgorithmsN)r#r$r%rprCr'r(r)rtrt£s„Ø-�Kr(rtcó—eZdZddddœZy)ÚTBSRequestExtensionIdÚnonceÚacceptable_responsesÚpreferred_signature_algorithms)ú1.3.6.1.5.5.7.48.1.2z1.3.6.1.5.5.7.48.1.4z1.3.6.1.5.5.7.48.1.8Nr"r'r(r)rvrv§s„à 'Ø 6Ø @ñ �Dr(rvcó8—eZdZdefdeddifdefgZdZee e dœZ y) ÚTBSRequestExtensionr:r;r<Fr=r>)rwrxryN) r#r$r%rvr rr0r?rrnrtr@r'r(r)r|r|¯sA„à Ð)Ð*Ø �W˜y¨%Ð0Ð1Ø Ð*Ð+ð€Gð *€IàØ 3Ø*Fñ�Jr(r|có—eZdZeZy)ÚTBSRequestExtensionsN)r#r$r%r|rCr'r(r)r~r~¾s„Ø%�Kr(r~có@—eZdZdedddœfdedddœfd efd ed ddœfgZy ) Ú TBSRequestÚversionrr!©rIr<Úrequestor_namerTrHÚ request_listÚrequest_extensionséN)r#r$r%r rrir~r0r'r(r)r€r€Âs@„à �G¨!¸Ñ=Ð>Ø ˜;°QÀDÑ(IÐJØ ˜Ð"Ø Ð3À!ÐQUÑ5VÐWð �Gr(r€có—eZdZeZy)Ú CertificatesN)r#r$r%rrCr'r(r)rˆrˆËs„Ø�Kr(rˆcó*—eZdZdefdefdedddœfgZy)Ú SignatureÚsignature_algorithmÚ signatureÚcertsrTrHN)r#r$r%r rrˆr0r'r(r)rŠrŠÏs)„à Ð 5Ð6Ø �nÐ%Ø �,¨Q¸DÑ AÐBð�Gr(rŠcó~—eZdZdefdedddœfgZdZdZdZdZ dZ d„Z e d „«Z e d „«Ze d „«Ze d „«Zy) Ú OCSPRequestÚ tbs_requestÚoptional_signaturerTrHFNcó—t«|_|ddD]g}|dj}d|z}t||«rt |||dj «|djsŒM|jj |«Œid|_y) rLr�r…r:rMr=r;TNrNrWs r)r\zOCSPRequest._set_extensionsãs‹€ô %(£EˆÔ!à˜mÑ,Ð-AÔBˆIؘYÑ'×.Ñ.ˆDØ(¨4Ñ/ˆNÜ�t˜^Ô,ܘ˜n¨i¸ Ñ.E×.LÑ.LÔMؘÑ$×+Ó+Ø×)Ñ)×-Ñ-¨dÕ3ð Cð&*ˆÕ"r(cóR—|js|j«|jSr^r_r`s r)razOCSPRequest.critical_extensionsõrbr(cóV—|jdur|j«|jS)zÊ This extension is used to prevent replay attacks by including a unique, random value with each request/response pair :return: None or an OctetString object F©rVr\Ú _nonce_valuer`s r)Ú nonce_valuezOCSPRequest.nonce_valueó*€ð × %Ñ %¨Ñ .Ø × Ñ Ô "Ø× Ñ Ð r(cóV—|jdur|j«|jS)a( This extension is used to allow the client and server to communicate with alternative response formats other than just basic_ocsp_response, although no other formats are defined in the standard. :return: None or an AcceptableResponses object F)rVr\Ú_acceptable_responses_valuer`s r)Úacceptable_responses_valuez&OCSPRequest.acceptable_responses_values*€ð × %Ñ %¨Ñ .Ø × Ñ Ô "Ø×/Ñ/Ð/r(cóV—|jdur|j«|jS)aj This extension is used by the client to define what signature algorithms are preferred, including both the hash algorithm and the public key algorithm, with a level of detail down to even the public key algorithm parameters, such as curve name. :return: None or a PreferredSignatureAlgorithms object F)rVr\Ú%_preferred_signature_algorithms_valuer`s r)Ú$preferred_signature_algorithms_valuez0OCSPRequest.preferred_signature_algorithms_value s*€ð × %Ñ %¨Ñ .Ø × Ñ Ô "Ø×9Ñ9Ð9r()r#r$r%r€rŠr0rVrPr–ršr�r\rgrar—r›ržr'r(r)r�r�×s”„à ˜ Ð#Ø ˜y°qÀdÑ*KÐLð€Gð "ÐØÐØ€LØ"&ÐØ,0Ð)ò*ð$ñ )óð )ðñ !óð !ðñ 0óð 0ðñ :óñ :r(r�có—eZdZdddddddœZy) ÚOCSPResponseStatusÚ successfulÚmalformed_requestÚinternal_errorÚ try_laterÚ sign_requiredÚ unauthorized)rrr†éééNr"r'r(r)r r 1s„à Ø Ø Ø Ø Ø ñ  �Dr(r có(—eZdZdeddifdeddifgZy)Ú ResponderIdÚby_namerIrÚby_keyr†N)r#r$r%rrÚ _alternativesr'r(r)r«r«<s%„à �D˜: q˜/Ð*Ø �; ¨Q Ð0ð�Mr(r«có"—eZdZd„Zed„«Zy)Ú StatusGoodcó|—|�3|dk7r.t|t«sttdt |«««‚d|_y)z` Sets the value of the object :param value: None or 'good' NÚgoodzK value must be one of None, "good", not %s r(©Ú isinstancerÚ ValueErrorrÚreprÚcontents©rXÚvalues r)rOzStatusGood.setEsD€ð Ð  ¨&¢¼ÀEÌ4Ô9PÜœVðô�U“ ó óð ðˆ� r(có—y)Nr²r'r`s r)rQzStatusGood.nativeWs€àr(N©r#r$r%rOrgrQr'r(r)r°r°Ds„òð$ñóñr(r°có"—eZdZd„Zed„«Zy)Ú StatusUnknowncó|—|�3|dk7r.t|t«sttdt |«««‚d|_y)zc Sets the value of the object :param value: None or 'unknown' NÚunknownzN value must be one of None, "unknown", not %s r(r³r¸s r)rOzStatusUnknown.set^sE€ð Ð  ¨)Ò!3¼JÀuÌdÔÐ?Ø �_°1À$Ñ&GÐHð�Gr(rÊcó—eZdZdddddddœZy) ÚSingleResponseExtensionIdÚcrlÚarchive_cutoffÚ crl_reasonÚinvalidity_dateÚcertificate_issuerÚ!signed_certificate_timestamp_list)z1.3.6.1.5.5.7.48.1.3z1.3.6.1.5.5.7.48.1.6z 2.5.29.21z 2.5.29.24z 2.5.29.29z1.3.6.1.4.1.11129.2.4.5Nr"r'r(r)rÏrÏŒs„à %Ø 0ð"Ø&Ø)à#Fñ �Dr(rÏcó>—eZdZdefdeddifdefgZdZee e e e e dœZ y) ÚSingleResponseExtensionr:r;r<Fr=r>)rÐrÑrÒrÓrÔrÕN)r#r$r%rÏr rr0r?rÊrrrrr@r'r(r)r×rךsJ„à Ð-Ð.Ø �W˜y¨%Ð0Ð1Ø Ð*Ð+ð€Gð *€IàØ)ØØ*Ø*Ø-8ñ �Jr(r×có—eZdZeZy)ÚSingleResponseExtensionsN)r#r$r%r×rCr'r(r)rÙrÙ¬s„Ø)�Kr(rÙc óÀ—eZdZdefdefdefdedddœfded ddœfgZd Zd Z d Z d Z d Z d Z d Zd „Zed „«Zed„«Zed„«Zed„«Zed„«Zed„«Zy )ÚSingleResponseÚcert_idÚ cert_statusÚ this_updateÚ next_updaterTrHÚsingle_extensionsrFNcó—t«|_|dD]g}|dj}d|z}t||«rt |||dj «|djsŒM|jj |«Œid|_y)rLràr:rMr=r;TNrNrWs r)r\zSingleResponse._set_extensionsÁs…€ô %(£EˆÔ!àÐ1Ô2ˆIؘYÑ'×.Ñ.ˆDØ(¨4Ñ/ˆNÜ�t˜^Ô,ܘ˜n¨i¸ Ñ.E×.LÑ.LÔMؘÑ$×+Ó+Ø×)Ñ)×-Ñ-¨dÕ3ð 3ð&*ˆÕ"r(cóR—|js|j«|jSr^r_r`s r)raz"SingleResponse.critical_extensionsÓrbr(cóV—|jdur|j«|jS)z¬ This extension is used to locate the CRL that a certificate's revocation is contained within. :return: None or a CrlId object F)rVr\Ú _crl_valuer`s r)Ú crl_valuezSingleResponse.crl_valueás(€ð × %Ñ %¨Ñ .Ø × Ñ Ô "Ø�‰Ðr(cóV—|jdur|j«|jS)zÜ This extension is used to indicate the date at which an archived (historical) certificate status entry will no longer be available. :return: None or a GeneralizedTime object F)rVr\Ú_archive_cutoff_valuer`s r)Úarchive_cutoff_valuez#SingleResponse.archive_cutoff_valueïs*€ð × %Ñ %¨Ñ .Ø × Ñ Ô "Ø×)Ñ)Ð)r(cóV—|jdur|j«|jS)zŽ This extension indicates the reason that a certificate was revoked. :return: None or a CRLReason object F)rVr\Ú_crl_reason_valuer`s r)Úcrl_reason_valuezSingleResponse.crl_reason_valueýs*€ð × %Ñ %¨Ñ .Ø × Ñ Ô "Ø×%Ñ%Ð%r(cóV—|jdur|j«|jS)a= This extension indicates the suspected date/time the private key was compromised or the certificate became invalid. This would usually be before the revocation date, which is when the CA processed the revocation. :return: None or a GeneralizedTime object F)rVr\Ú_invalidity_date_valuer`s r)Úinvalidity_date_valuez$SingleResponse.invalidity_date_value s*€ð × %Ñ %¨Ñ .Ø × Ñ Ô "Ø×*Ñ*Ð*r(cóV—|jdur|j«|jS)z— This extension indicates the issuer of the certificate in question. :return: None or an x509.GeneralNames object F)rVr\Ú_certificate_issuer_valuer`s r)Úcertificate_issuer_valuez'SingleResponse.certificate_issuer_values*€ð × %Ñ %¨Ñ .Ø × Ñ Ô "Ø×-Ñ-Ð-r()r#r$r%r+rÆrrÙr0rVrPrärçrêrírðr\rgrarårèrërîrñr'r(r)rÛrÛ°sé„à �FÐØ ˜ Ð#Ø ˜Ð(Ø ˜°aÀTÑ)JÐKØ Ð6ÀQÐTXÑ8YÐZð €Gð"ÐØÐØ€JØ ÐØÐØ!ÐØ $Ðò*ð$ñ )óð )ðñ óð ðñ *óð *ðñ &óð &ðñ +óð +ðñ .óñ .r(rÛcó—eZdZeZy)Ú ResponsesN)r#r$r%rÛrCr'r(r)róró(s„Ø �Kr(rócó—eZdZdddœZy)ÚResponseDataExtensionIdrwÚextended_revoke)rzz1.3.6.1.5.5.7.48.1.9Nr"r'r(r)rõrõ,s„à 'Ø 1ñ �Dr(rõcó6—eZdZdefdeddifdefgZdZee dœZ y) ÚResponseDataExtensionr:r;r<Fr=r>)rwröN) r#r$r%rõr rr0r?rrr@r'r(r)rørø3s>„à Ð+Ð,Ø �W˜y¨%Ð0Ð1Ø Ð*Ð+ð€Gð *€IàØñ�Jr(røcó—eZdZeZy)ÚResponseDataExtensionsN)r#r$r%rørCr'r(r)rúrúAs„Ø'�Kr(rúc ó>—eZdZdedddœfdefdefdefded d d œfgZy ) Ú ResponseDatar�rr!r‚Ú responder_idÚ produced_atÚ responsesÚresponse_extensionsrTrHN) r#r$r%r r«rrórúr0r'r(r)rürüEsA„à �G¨!¸Ñ=Ð>Ø ˜Ð%Ø ˜Ð(Ø �iÐ Ø Ð 6ÀQÐTXÑ8YÐZð �Gr(rücó0—eZdZdefdefdefdedddœfgZy) ÚBasicOCSPResponseÚtbs_response_datar‹rŒr�rTrHN)r#r$r%rür rrˆr0r'r(r)rrOs1„à ˜lÐ+Ø Ð 5Ð6Ø �nÐ%Ø �,¨Q¸DÑ AÐBð �Gr(rcó(—eZdZdefdefgZdZdeiZy)Ú ResponseBytesÚ response_typeÚresponse)rrrlN) r#r$r%rkrr0r?rr@r'r(r)rrXs.„à ˜,Ð'Ø Ð(Ð)ð€Gð .€IàÐ0ð�Jr(rcóŠ—eZdZdefdedddœfgZdZdZdZdZ d„Z e d „«Z e d „«Z e d „«Ze d „«Ze d „«Zy)Ú OCSPResponseÚresponse_statusÚresponse_bytesrTrHFNcó4—t«|_|ddjddD]g}|dj}d|z}t ||«rt |||dj«|djsŒM|jj |«Œid |_y ) rLr rrrr:rMr=r;TN)rOrPrTrQrRrSrUrVrWs r)r\zOCSPResponse._set_extensionsos�€ô %(£EˆÔ!àÐ.Ñ/° Ñ;×BÑBÐCVÑWÐXmÔnˆIؘYÑ'×.Ñ.ˆDØ(¨4Ñ/ˆNÜ�t˜^Ô,ܘ˜n¨i¸ Ñ.E×.LÑ.LÔMؘÑ$×+Ó+Ø×)Ñ)×-Ñ-¨dÕ3ð oð&*ˆÕ"r(cóR—|js|j«|jSr^r_r`s r)raz OCSPResponse.critical_extensions�rbr(cóV—|jdur|j«|jS)z§ This extension is used to prevent replay attacks on the request/response exchange :return: None or an OctetString object Fr•r`s r)r—zOCSPResponse.nonce_value�r˜r(cóV—|jdur|j«|jS)zÊ This extension is used to signal that the responder will return a "revoked" status for non-issued certificates. :return: None or a Null object (if present) F)rVr\Ú_extended_revoke_valuer`s r)Úextended_revoke_valuez"OCSPResponse.extended_revoke_value�rfr(có&—|ddjS)z’ A shortcut into the BasicOCSPResponse sequence :return: None or an asn1crypto.ocsp.BasicOCSPResponse object r r©rTr`s r)rlz OCSPResponse.basic_ocsp_response«s€ðÐ$Ñ% jÑ1×8Ñ8Ð8r(có,—|ddjdS)z� A shortcut into the parsed, ResponseData sequence :return: None or an asn1crypto.ocsp.ResponseData object r rrrr`s r)Ú response_datazOCSPResponse.response_data¶s!€ðÐ$Ñ% jÑ1×8Ñ8Ð9LÑMÐMr()r#r$r%r rr0rVrPr–rr\rgrar—rrlrr'r(r)r r ds¥„à Ð.Ð/Ø ˜=°qÀdÑ*KÐLð€Gð "ÐØÐØ€LØ!Ðò*ð$ñ )óð )ðñ !óð !ðñ +óð +ðñ9óð9ðñNóñNr(r N)IÚ__doc__Ú __future__rrrrÚ_errorsrÚalgosr r Úcorer r r rrrrrrrrrrrÐrrÚkeysrÚx509rrrrr r+r2r6r9rBrErirkrnrprtrvr|r~r€rˆrŠr�r r«r°r½rÂrÆrÊrÏr×rÙrÛrórõrørúrürrr r'r(r)Úrsðñ÷SÓRåß9÷÷÷õ÷6Ý$ß>Ó>ô ˆgôô ˆXôô�XôôÐ)ôô �xô ô#˜ ô#ô6+ˆhô6+ôrˆzôôÐ#ôô ˜*ôô (ôô. :ô.ôÐ,ôô ˜(ô ô&˜:ô&ô�ôô�:ôô�ôôW:�(ôW:ôt˜ôô�&ôô�ôô2�Dôô0�(ôô�ôôˆHôô Ð 0ô ô˜hôô$*˜zô*ôu.�Xôu.ôp!� ô!ôÐ.ôô ˜Hô ô(˜Zô(ô�8ôô˜ôô �Hô ô[N�8õ[Nr(__pycache__/parser.cpython-312.pyc000064400000022300152572326550012764 0ustar00Ë uÉþiÓ#ãó”—dZddlmZmZmZmZddlZddlmZm Z m Z ddl m Z m Z ejdkZdZd Zd „Zdd „Zd „Zdd „Zd„Zy)zÈ Functions for parsing and dumping using the ASN.1 DER encoding. Exports the following items: - emit() - parse() - peek() Other type classes are defined that help compose the types listed above. é)Úunicode_literalsÚdivisionÚabsolute_importÚprint_functionNé)Úbyte_clsÚchr_clsÚ type_name)Úint_from_bytesÚ int_to_bytes)ézOÑOÓPÐPà �‚z�V˜a’ZÜÐEÈÑNÓOÐOä �fœcÔ "ÜÐ;¼iÈÓ>OÑOÓPÐPà �‚z�V˜a’ZÜÐ8¸6ÑAÓBÐBä �cœ3Ô ÜÐ8¼9ÀS»>ÑIÓJÐJà ˆQ‚wÜÐ@À3ÑFÓGÐGä �h¤Ô )ÜÐ@Ä9ÈXÓCVÑVÓWÐWä ˜ ¨¨XÓ 6¸Ñ AÐAócó¸—t|t«stdt|«z«‚t |«}t ||«\}}|r||k7rt d||z z«‚|S)al Parses a byte string of ASN.1 BER/DER-encoded data. This is typically not useful. Instead, use one of the standard classes from asn1crypto.core, or construct a new class with specific fields, and call the .load() class method. :param contents: A byte string of BER/DER-encoded data :param strict: A boolean indicating if trailing data should be forbidden - if so, a ValueError will be raised when trailing data exists :raises: ValueError - when the contents do not contain an ASN.1 header or are truncated in some way TypeError - when contents is not a byte string :return: A 6-element tuple: - 0: integer class (0 to 3) - 1: integer method - 2: integer tag - 3: byte string header - 4: byte string content - 5: byte string trailer rz4Extra data - %d bytes of trailing data were provided)rrrr ÚlenÚ_parser)rÚstrictÚ contents_lenÚinfoÚconsumeds rÚparser$Ksd€ô: �h¤Ô )ÜÐ@Ä9ÈXÓCVÑVÓWÐWä�x“=€LܘH lÓ3�N€Dˆ(Ù �(˜lÒ*ÜÐOÐS_ÐbjÑSjÑkÓlÐlØ €Krcó„—t|t«stdt|«z«‚t |t |««\}}|S)aW Parses a byte string of ASN.1 BER/DER-encoded data to find the length This is typically used to look into an encoded value to see how long the next chunk of ASN.1-encoded data is. Primarily it is useful when a value is a concatenation of multiple values. :param contents: A byte string of BER/DER-encoded data :raises: ValueError - when the contents do not contain an ASN.1 header or are truncated in some way TypeError - when contents is not a byte string :return: An integer with the number of bytes occupied by the ASN.1 value r)rrrr rr)rr"r#s rÚpeekr&rs=€ô& �h¤Ô )ÜÐ@Ä9ÈXÓCVÑVÓWÐWä˜H¤c¨(£mÓ4�N€Dˆ(Ø €Orc ó—|tkDr td«‚|}||dzkrttd||z fz«‚trt ||«n||}|dz }|dz}|dz dz}|dk(r|d} ||dzkrttd||z fz«‚trt ||«n||} |dz }| dk(r|dk(r td«‚|dz}|| d zz }| d z dk(rnŒi|dkr td«‚||dzkrttd||z fz«‚trt ||«n||} |dz }d } | d z dk(r || d zz} n–| d z} | r;||| zkrtt| ||z fz«‚|| z }|t ||| z |d ¬ «z} nT|s td«‚|} || dzks || | dzdk7r+t ||| d|dz¬«\}} || dzkrŒ|| | dzdk7rŒ+| dz } d} | |kDrtt| |z ||z fz«‚|r|| fS|dz |||||||| t| «z | f| fS)aø Parses a byte string into component parts :param encoded_data: A byte string that contains BER-encoded data :param data_len: The integer length of the encoded data :param pointer: The index in the byte string to parse from :param lengths_only: A boolean to cause the call to return a 2-element tuple of the integer number of bytes in the header and the integer number of bytes in the contents. Internal use only. :param depth: The recursion depth when evaluating indefinite-length encoding. :return: A 2-element tuple: - 0: A tuple of (class_, method, tag, header, content, trailer) - 1: An integer indicating how many bytes were consumed z*Indefinite-length recursion limit exceededréérTé€zNon-minimal tag encodingéérF)Úsignedz-Indefinite-length element must be constructedés)Ú lengths_onlyÚdepthé)Ú _MAX_DEPTHrÚ_INSUFFICIENT_DATA_MESSAGEÚ_PY2Úordr rr)Ú encoded_dataÚdata_lenÚpointerr/r0ÚstartÚ first_octetrÚ constructedÚnumÚ length_octetÚtrailerÚ contents_endÚ length_octetsÚ_s rrrŒsù€ð6 ŒzÒÜÐEÓFÐFà €Eà�'˜A‘+ÒÜÔ3°q¸(ÀWÑ:LÐ6MÑMÓNÐNÝ04”#�l 7Ñ+Ô,¸,ÀwÑ:O€Kà ˆq�L€Gà ˜Ñ €CØ !Ñ# qÑ(€Kà ˆb‚yØˆØØ˜' A™+Ò%Ü Ô!;¸qÀ(ÈWÑBTÐ>UÑ!UÓVÐVÝ04”#�l 7Ñ+Ô,¸,ÀwÑ:OˆCØ �q‰LˆGØ�dŠ{˜s ašxÜ Ð!;Ó<Ð<Ø �3‰JˆCØ �3˜‘9Ñ ˆCØ�a‰x˜1Š}Øðð �Š8ÜÐ7Ó8Ð 8à�'˜A‘+ÒÜÔ3°q¸(ÀWÑ:LÐ6MÑMÓNÐNÝ15”3�| GÑ,Ô-¸<ÈÑ;P€LØ ˆq�L€GØ€Gà�qјAÒØ ,°Ñ"4Ñ5‰ ð% sÑ*ˆ ٠ؘ' MÑ1Ò1Ü Ô!;¸}ÈhÐY`ÑN`Ð>aÑ!aÓbÐbØ �}Ñ $ˆGØ"¤^°LÀÈ=ÑAXÐY`Ð4aÐjoÔ%pÑp‰LñÜ Ð!PÓQÐQØ"ˆLؘ\¨AÑ-Ò-°¸lÈ<ÐXYÉ>Ð1ZÐ^iÒ1iÜ"(¨°xÀÐ\`ÐhmÐnoÑhoÔ"p‘��<ð˜\¨AÑ-Ó-°¸lÈ<ÐXYÉ>Ð1ZÐ^iÓ1ià ˜AÑ ˆLØ!ˆGà�hÒÜÔ3°|ÀgÑ7MÈxÐZaÑOaÐ6bÑbÓcÐcáØ˜Ð&Ð&ð ˜1Ñ Ø Ø Ø ˜˜wÐ 'Ø ˜ ¬c°'«lÑ!:Ð ;Ø ð  ð ð ð rcóf—d}d}||dzz}||dzz}|dk\rˆFÙØ�ؘ‘(ˆCð �A‹gô ˜ "™Ó%¨Ñ.‰à”'˜& 3™,Ó'Ñ'ˆä �‹]€FØ �‚}Ø”'˜&“/Ñ!ˆð €Mô $ FÓ+ˆ Ø”'˜$¤ \Ó!2Ñ2Ó3Ñ3ˆØ�,Ñˆà €Mr)F)rFr)Ú__doc__Ú __future__rrrrÚsysÚ_typesrr r Úutilr r Ú version_infor4r3r2rr$r&rr©rrÚrOsXðñ ÷SÓRã ç0Ñ0ß.à ×ј4Ñ€Ø[ÐØ € ò.Bób$òNó4góT.r__pycache__/pdf.cpython-312.pyc000064400000006602152572326550012250 0ustar00Ë uÉþiÊãóF—dZddlmZmZmZmZddlmZmZddl m Z m Z m Z m Z mZmZmZmZddlmZddlmZddlmZmZmZmZGd „d e«ZGd „d e«ZGd „de«ZGd„de«ZGd„de«ZGd„de«Z Gd„de«Z!Gd„de«Z"dejFd<dejFd<dejFd<eejHd<eejHd<e ejHd<dejFd <d!ejFd"<e"ejHd!<y#)$z� ASN.1 type classes for PDF signature structures. Adds extra oid mapping and value parsing to asn1crypto.x509.Extension() and asn1crypto.xms.CMSAttribute(). é)Úunicode_literalsÚdivisionÚabsolute_importÚprint_functioné)ÚCMSAttributeTypeÚ CMSAttribute)ÚBooleanÚIntegerÚNullÚObjectIdentifierÚ OctetStringÚSequenceÚ SequenceOfÚSetOf)ÚCertificateList)Ú OCSPResponse)Ú ExtensionÚ ExtensionIdÚ GeneralNameÚ KeyPurposeIdcó—eZdZdefgZy)ÚAdobeArchiveRevInfoÚversionN)Ú__name__Ú __module__Ú __qualname__r Ú_fields©óú?/opt/nydus/tmp/pip-target-dhtdbchl/lib/python/asn1crypto/pdf.pyrrs„à �GÐð�Gr rcó*—eZdZdefdefdedddœfgZy)ÚAdobeTimestamprÚlocationÚ requires_authTF)ÚoptionalÚdefaultN)rrrr rr rrr r!r#r#%s(„à �GÐØ �[Ð!Ø ˜'°ÀÑ#GÐHð�Gr r#có—eZdZdefdefgZy)Ú OtherRevInfoÚtypeÚvalueN)rrrr rrrr r!r)r)-s„à Ð!Ð"Ø �+Ðð�Gr r)có—eZdZeZy)ÚSequenceOfCertificateListN)rrrrÚ _child_specrr r!r-r-4s„Ø!�Kr r-có—eZdZeZy)ÚSequenceOfOCSPResponseN)rrrrr.rr r!r0r08ó„Ø�Kr r0có—eZdZeZy)ÚSequenceOfOtherRevInfoN)rrrr)r.rr r!r3r3<r1r r3có:—eZdZdedddœfdedddœfdedddœfgZy ) ÚRevocationInfoArchivalÚcrlrT)Úexplicitr&ÚocsprÚother_rev_infoéN)rrrr-r0r3rrr r!r5r5@s9„à Ð)¸ÀtÑ+LÐMØ Ð'°aÀTÑ)JÐKØ Ð1ÀÈtÑ3TÐUð�Gr r5có—eZdZeZy)ÚSetOfRevocationInfoArchivalN)rrrr5r.rr r!r<r<Hs„Ø(�Kr r<Úadobe_archive_rev_infoz1.2.840.113583.1.1.9.2Úadobe_timestampz1.2.840.113583.1.1.9.1Úadobe_ppklite_credentialz1.2.840.113583.1.1.10Ú pdf_signingz1.2.840.113583.1.1.5Úadobe_revocation_info_archivalz1.2.840.113583.1.1.8N)%Ú__doc__Ú __future__rrrrÚcmsrr Úcorer r r r rrrrr6rr8rÚx509rrrrrr#r)r-r0r3r5r<Ú_mapÚ _oid_specsrr r!ÚrIs4ðñ÷ SÓRç/÷ ÷ ó õ!Ý÷óô˜(ôô �Xôô�8ôô"  ô"ô˜Zôô˜Zôô˜Xôô) %ô)ð.F€ ×ÑÐ)Ñ*Ø->€ ×ÑÐ)Ñ*Ø,F€ ×ÑÐ(Ñ)Ø1D€ ×ÑÐ-Ñ.Ø*8€ ×ÑÐ&Ñ'Ø37€ ×ÑÐ/Ñ0Ø,9€ ×ÑÐ(Ñ)Ø0PÐ×ÑÐ,Ñ-Øt jd|«}|sŒ'|jd«jd«}d }d }ŒL|d k(rQ|jd «d k(rd }n:|jd«} | jdd«\} } | j«|| <Œ¢|d k(sŒ¨|dddvr'tj|«} ||| f–—d}i}d}d}d }ŒÖ||z }ŒÜ|r|sttd««‚y­w)ax Convert a PEM-encoded byte string into one or more DER-encoded byte strings :param pem_bytes: A byte string of the PEM-encoded data :raises: ValueError - when the pem_bytes do not appear to be PEM-encoded bytes :return: A generator of 3-element tuples in the format: (object_type, headers, der_bytes). The object_type is a unicode string of what is between "-----BEGIN " and "-----". Examples include: "CERTIFICATE", "PUBLIC KEY", "PRIVATE KEY". The headers is a dict containing any lines in the form "Name: Value" that are right after the begin line. zA pem_bytes must be a byte string, not %s ÚtrashrNFs1^(?:---- |-----)BEGIN ([A-Z0-9 ]+)(?: ----|-----)rrTr%ó:rÚbodyÚ:ré)s-----s---- z| pem_bytes does not appear to contain PEM-encoded data - no BEGIN/END combination found )rr rrrÚ splitlinesÚreÚmatchÚgroupÚdecoderÚsplitÚstripr Ú b64decodeÚ ValueError) Ú pem_bytesÚstater%Ú base64_dataÚ object_typeÚ found_startÚ found_endÚlineÚtype_name_matchÚ decoded_lineÚnameÚvaluer$s rÚ_unarmorrFps‘èø€ô$ �i¤Ô *Üœð ô �yÓ !ó  ó ð ð €EØ€GØ€KØ€Kà€KØ€Ià×$Ñ$ UÖ+ˆØ �3Š;Ø à �GÒ ô!Ÿh™hÐ'[Ð]aÓbˆOÙ"ØØ)×/Ñ/°Ó2×9Ñ9¸'ÓBˆKàˆK؈EØ à �IÒ Ø�y‰y˜‹ "Ò$Ø‘à#Ÿ{™{¨7Ó3� Ø*×0Ñ0°°aÓ8‘ ��eØ %§ ¡ £ �˜‘ Øà �F‹?Ø�A�aˆyÐ0Ñ0Ü"×,Ñ,¨[Ó9� à" G¨YÐ7Ò7à�Ø�Ø!� Ø"� Ø � Øà ˜4Ñ ‰KðM,ñP ™iÜœð ó ó ð ð(ùs ‚C3EÃ6AEcó6—t|«}|s t|«S|S)a˜ Convert a PEM-encoded byte string into a DER-encoded byte string :param pem_bytes: A byte string of the PEM-encoded data :param multiple: If True, function will return a generator :raises: ValueError - when the pem_bytes do not appear to be PEM-encoded bytes :return: A 3-element tuple (object_name, headers, der_bytes). The object_name is a unicode string of what is between "-----BEGIN " and "-----". Examples include: "CERTIFICATE", "PUBLIC KEY", "PRIVATE KEY". The headers is a dict containing any lines in the form "Name: Value" that are right after the begin line. )rFÚnext)r;ÚmultipleÚ generators rÚunarmorrKÄs!€ô*˜Ó#€Iá Ü�I‹Ðà Ðr)N)F)Ú__doc__Ú __future__rrrrr r3ÚsysÚ_errorsrÚ_typesr rr r Ú version_infoÚ cStringIOr rÚiorr+rFrK©rrÚrUsQðñ÷SÓRã Û Û åß>Ñ>à×Ñ�dÒÞ-åòZó.;ò|Q ôhr__pycache__/pkcs12.cpython-312.pyc000064400000014436152572326550012606 0ustar00Ë uÉþiÖãó"—dZddlmZmZmZmZddlmZddlm Z m Z ddl m Z m Z mZmZmZmZmZmZmZddlmZmZddlmZmZGd „d e«ZGd „d e«ZGd „de«ZGd„de«ZGd„de«ZGd„de«Z Gd„de«Z!Gd„de«Z"Gd„de«Z#Gd„de«Z$Gd„de«Z%Gd„d e«Z&Gd!„d"e«Z'Gd#„d$e«Z(Gd%„d&e«Z)Gd'„d(e«Z*Gd)„d*e«Z+Gd+„d,e«Z,e,e+_-y-).zÍ ASN.1 type classes for PKCS#12 files. Exports the following items: - CertBag() - CrlBag() - Pfx() - SafeBag() - SecretBag() Other type classes are defined that help compose the types listed above. é)Úunicode_literalsÚdivisionÚabsolute_importÚprint_functioné)Ú DigestInfo)Ú ContentInfoÚ SignedData) ÚAnyÚ BMPStringÚIntegerÚObjectIdentifierÚ OctetStringÚParsableOctetStringÚSequenceÚ SequenceOfÚSetOf)ÚPrivateKeyInfoÚEncryptedPrivateKeyInfo)Ú CertificateÚ KeyPurposeIdcó(—eZdZdefdefdeddifgZy)ÚMacDataÚmacÚmac_saltÚ iterationsÚdefaultrN)Ú__name__Ú __module__Ú __qualname__rrr Ú_fields©óúB/opt/nydus/tmp/pip-target-dhtdbchl/lib/python/asn1crypto/pkcs12.pyrr$s'„à � ÐØ �[Ð!Ø �w ¨A Ð/ð�Gr#rcó—eZdZddiZy)ÚVersionéÚv3N©rrr Ú_mapr"r#r$r&r&,s„à ˆ4ð �Dr#r&có—eZdZdddddœZy)Ú AttributeTypeÚ friendly_nameÚ local_key_idÚmicrosoft_local_machine_keysetÚtrusted_key_usage)z1.2.840.113549.1.9.20z1.2.840.113549.1.9.21z1.3.6.1.4.1.311.17.1z2.16.840.1.113894.746875.1.1Nr)r"r#r$r,r,2s„ð"1Ø!/à @ð)<ñ �Dr#r,có—eZdZeZy)ÚSetOfAnyN)rrr r Ú _child_specr"r#r$r2r2?s„Ø�Kr#r2có—eZdZeZy)ÚSetOfBMPStringN)rrr r r3r"r#r$r5r5Có„Ø�Kr#r5có—eZdZeZy)ÚSetOfOctetStringN)rrr rr3r"r#r$r8r8Gó„Ø�Kr#r8có—eZdZeZy)ÚSetOfKeyPurposeIdN)rrr rr3r"r#r$r;r;Ks„Ø�Kr#r;có4—eZdZdefdgZeeeedœZd„Z de iZ y)Ú AttributeÚtype)ÚvaluesN)r-r.Úmicrosoft_csp_namer0có\—|jj|djt«S)Nr>)Ú _oid_specsÚgetÚnativer2)Úselfs r$Ú _values_speczAttribute._values_spec\s#€Ø�‰×"Ñ" 4¨¡<×#6Ñ#6¼ÓAÐAr#r?N) rrr r,r!r5r8r;rBrFÚ_spec_callbacksr"r#r$r=r=Os=„à �ÐØð€Gð (Ø(Ø,Ø.ñ €JòBð �,ð�Or#r=có—eZdZeZy)Ú AttributesN)rrr r=r3r"r#r$rIrIdr6r#rIcó<—eZdZdefdefdeddifgZdZed„«Z y)ÚPfxÚversionÚ auth_safeÚmac_dataÚoptionalTNcóº—|j€D|dd}t|t«r|dd}tj |j «|_|jS)NrMÚcontentÚ content_info)Ú_authenticated_safeÚ isinstancer ÚAuthenticatedSafeÚloadrD)rErQs r$Úauthenticated_safezPfx.authenticated_safeqsY€à × #Ñ #Ð +ؘ;Ñ'¨ Ñ2ˆGܘ'¤:Ô.Ø! .Ñ1°)Ñ<�Ü'8×'=Ñ'=¸g¿n¹nÓ'MˆDÔ $Ø×'Ñ'Ð'r#) rrr r&r rr!rSÚpropertyrWr"r#r$rKrKhsB„à �GÐØ �kÐ"Ø �W˜z¨4Ð0Ð1ð€Gð Ðà ñ(óñ(r#rKcó—eZdZeZy)rUN)rrr r r3r"r#r$rUrU{r9r#rUcó—eZdZdddddddœZy) ÚBagIdÚkey_bagÚpkcs8_shrouded_key_bagÚcert_bagÚcrl_bagÚ secret_bagÚ safe_contents)z1.2.840.113549.1.12.10.1.1z1.2.840.113549.1.12.10.1.2z1.2.840.113549.1.12.10.1.3z1.2.840.113549.1.12.10.1.4z1.2.840.113549.1.12.10.1.5z1.2.840.113549.1.12.10.1.6Nr)r"r#r$r[r[s„à&/Ø&>Ø&0Ø&/Ø&2Ø&5ñ  �Dr#r[có—eZdZdddœZy)ÚCertIdÚx509Úsdsi)z1.2.840.113549.1.9.22.1z1.2.840.113549.1.9.22.2Nr)r"r#r$rcrcŠs„à#)Ø#)ñ �Dr#rccó.—eZdZdefdeddifgZdZdeiZy)ÚCertBagÚcert_idÚ cert_valueÚexplicitr)rhrirdN) rrr rcrr!Ú _oid_pairrrBr"r#r$rgrg‘s3„à �FÐØ Ð*¨Z¸¨OÐ<ð€Gð *€Ià� ð�Jr#rgcó"—eZdZdefdeddifgZy)ÚCrlBagÚcrl_idÚ crl_valuerjrN©rrr rrr!r"r#r$rmrm�s „à Ð#Ð$Ø �k J° ?Ð3ð�Gr#rmcó"—eZdZdefdeddifgZy)Ú SecretBagÚsecret_type_idÚ secret_valuerjrNrpr"r#r$rrrr¤s „à Ð+Ð,Ø ˜ z°1 oÐ6ð�Gr#rrcó —eZdZy)Ú SafeContentsN)rrr r"r#r$rvrv«s„Ør#rvcóD—eZdZdefdeddifdeddifgZdZee e e e e d œZy ) ÚSafeBagÚbag_idÚ bag_valuerjrÚbag_attributesrOT)ryrz)r\r]r^r_r`raN)rrr r[r rIr!rkrrrgrmrrrvrBr"r#r$rxrx¯sN„à �5ÐØ �c˜J¨˜?Ð+Ø ˜:¨ °DÐ'9Ð:ð€Gð (€Ià!Ø"9ØØØØ%ñ �Jr#rxN).Ú__doc__Ú __future__rrrrÚalgosrÚcmsr r Úcorer r r rrrrrrÚkeysrrrdrrrr&r,r2r5r8r;r=rIrKrUr[rcrgrmrrrvrxr3r"r#r$Úr‚sðñ ÷SÓRåß(÷ ÷ õ ÷:ß+ô ˆhôôˆgôô Ð$ô ôˆuôô�Uôô�uôô˜ôô�ôô*�ôô(ˆ(ô(ô&˜ ôôÐ ôôÐ ôô ˆhô ôˆXôô�ôô �:ô ôˆhôð$#€ Õr#__pycache__/tsp.cpython-312.pyc000064400000025574152572326550012316 0ustar00Ë uÉþi‘ãó¢—dZddlmZmZmZmZddlmZddlm Z m Z m Z m Z m Z ddlmZmZmZmZmZmZmZmZmZmZmZmZmZddlmZddlmZm Z m!Z!m"Z"Gd „d e«Z#Gd „d e«Z$Gd „de«Z%Gd„de«Z&Gd„de«Z'Gd„de«Z(Gd„de«Z)Gd„de«Z*Gd„de«Z+Gd„de«Z,Gd„de«Z-Gd„d e«Z.Gd!„d"e«Z/Gd#„d$e«Z0Gd%„d&e«Z1Gd'„d(e«Z2Gd)„d*e«Z3Gd+„d,e«Z4Gd-„d.e«Z5Gd/„d0e«Z6Gd1„d2e«Z7Gd3„d4e«Z8Gd5„d6e«Z9Gd7„d8e«Z:Gd9„d:e«Z;Gd;„de«Z=Gd?„d@e«Z>GdA„dBe«Z?GdC„dDe«Z@GdE„dFe«ZAGdG„dHe«ZBGdI„dJe«ZCGdK„dLe«ZDe(e jŠdM<e;e jŠdN<e;e jŠdN<dMe jŒdO<dNe jŒdP<dQe jŒdR<e@e jŠdQ<dSe jŒdT<eDe jŠdS<yU)Va  ASN.1 type classes for the time stamp protocol (TSP). Exports the following items: - TimeStampReq() - TimeStampResp() Also adds TimeStampedData() support to asn1crypto.cms.ContentInfo(), TimeStampedData() and TSTInfo() support to asn1crypto.cms.EncapsulatedContentInfo() and some oids and value parsers to asn1crypto.cms.CMSAttribute(). Other type classes are defined that help compose the types listed above. é)Úunicode_literalsÚdivisionÚabsolute_importÚprint_functioné)ÚDigestAlgorithm)Ú CMSAttributeÚCMSAttributeTypeÚ ContentInfoÚ ContentTypeÚEncapsulatedContentInfo) ÚAnyÚ BitStringÚBooleanÚChoiceÚGeneralizedTimeÚ IA5StringÚIntegerÚObjectIdentifierÚ OctetStringÚSequenceÚ SequenceOfÚSetOfÚ UTF8String)ÚCertificateList)Ú AttributesÚCertificatePoliciesÚ GeneralNameÚ GeneralNamescó—eZdZdddddddœZy) ÚVersionÚv0Úv1Úv2Úv3Úv4Úv5©rrééééN©Ú__name__Ú __module__Ú __qualname__Ú_map©óú?/opt/nydus/tmp/pip-target-dhtdbchl/lib/python/asn1crypto/tsp.pyr!r!8s„à Ø Ø Ø Ø Ø ñ  �Dr3r!có—eZdZdefdefgZy)ÚMessageImprintÚhash_algorithmÚhashed_messageN)r.r/r0rrÚ_fieldsr2r3r4r6r6Cs„à ˜?Ð+Ø ˜;Ð'ð�Gr3r6có8—eZdZdeddifdedddœfdedddœfgZy ) ÚAccuracyÚsecondsÚoptionalTÚmillisr©Úimplicitr=ÚmicrosrN)r.r/r0rr9r2r3r4r;r;Js6„à �G˜j¨$Ð/Ð0Ø �7¨¸Ñ=Ð>Ø �7¨¸Ñ=Ð>ð�Gr3r;có(—eZdZdefdeddifdefgZy)Ú ExtensionÚextn_idÚcriticalÚdefaultFÚ extn_valueN)r.r/r0rrrr9r2r3r4rCrCRs)„à Ð$Ð%Ø �W˜y¨%Ð0Ð1Ø �{Ð#ð�Gr3rCcó—eZdZeZy)Ú ExtensionsN)r.r/r0rCÚ _child_specr2r3r4rIrIZó„Ø�Kr3rIcón—eZdZdefdefdefdefdefdeddifd e d d ifd eddifd e dddœfde dddœfg Z y)ÚTSTInfoÚversionÚpolicyÚmessage_imprintÚ serial_numberÚgen_timeÚaccuracyr=TÚorderingrFFÚnonceÚtsar)Úexplicitr=Ú extensionsrr?N) r.r/r0r!rr6rrr;rrrIr9r2r3r4rMrM^s}„à �GÐØ Ð#Ð$Ø ˜NÐ+Ø ˜'Ð"Ø �_Ð%Ø �X  ¨DÐ1Ð2Ø �W˜y¨%Ð0Ð1Ø �'˜J¨Ð-Ð.Ø � ¨!¸Ñ>Ð?Ø �z°¸tÑ#DÐEð �Gr3rMc óN—eZdZdefdefdeddifdeddifdedd ifd ed dd œfgZ y )Ú TimeStampReqrNrPÚ req_policyr=TrUÚcert_reqrFFrXrr?N) r.r/r0r!r6rrrrIr9r2r3r4rZrZmsV„à �GÐØ ˜NÐ+Ø Ð'¨*°dÐ);Ð<Ø �'˜J¨Ð-Ð.Ø �W˜y¨%Ð0Ð1Ø �z°¸tÑ#DÐEð �Gr3rZcó—eZdZdddddddœZy) Ú PKIStatusÚgrantedÚgranted_with_modsÚ rejectionÚwaitingÚrevocation_warningÚrevocation_notificationr(Nr-r2r3r4r^r^xs„à Ø Ø Ø Ø Ø $ñ  �Dr3r^có—eZdZeZy)Ú PKIFreeTextN)r.r/r0rrJr2r3r4rfrfƒs„Ø�Kr3rfc ó"—eZdZddddddddd œZy ) ÚPKIFailureInfoÚbad_algÚ bad_requestÚbad_data_formatÚtime_not_availableÚunaccepted_policyÚunaccepted_extensionsÚadd_info_not_availableÚsystem_failure)rr)r,éééééNr-r2r3r4rhrh‡s!„à Ø Ø Ø Ø Ø #Ø $Ø ñ �Dr3rhcó.—eZdZdefdeddifdeddifgZy)Ú PKIStatusInfoÚstatusÚ status_stringr=TÚ fail_infoN)r.r/r0r^rfrhr9r2r3r4rwrw”s/„à �9ÐØ ˜+¨ °DÐ'9Ð:Ø �n z°4Ð&8Ð9ð�Gr3rwcó—eZdZdefdefgZy)Ú TimeStampResprxÚtime_stamp_tokenN)r.r/r0rwr r9r2r3r4r|r|œs„à �=Ð!Ø ˜[Ð)ð�Gr3r|có:—eZdZdefdeddifdeddifdeddifgZy)ÚMetaDataÚhash_protectedÚ file_namer=TÚ media_typeÚother_meta_dataN)r.r/r0rrrrr9r2r3r4rr£s>„à ˜7Ð#Ø �j :¨tÐ"4Ð5Ø �y :¨tÐ"4Ð5Ø ˜J¨°TÐ(:Ð;ð �Gr3rcó"—eZdZdefdeddifgZy)ÚTimeStampAndCRLÚ time_stampÚcrlr=TN)r.r/r0r rr9r2r3r4r…r…¬s!„à Ð.Ð/Ø � *¨dÐ!3Ð4ð�Gr3r…có—eZdZeZy)ÚTimeStampTokenEvidenceN)r.r/r0r…rJr2r3r4r‰r‰³ó„Ø!�Kr3r‰có—eZdZeZy)ÚDigestAlgorithmsN)r.r/r0rrJr2r3r4rŒrŒ·rŠr3rŒcó—eZdZdefdefgZy)ÚEncryptionInfoÚencryption_info_typeÚencryption_info_valueN©r.r/r0rrr9r2r3r4rŽrŽ»s„à Ð!1Ð2Ø  #Ð&ð�Gr3rŽcó—eZdZeZy)ÚPartialHashtreeN)r.r/r0rrJr2r3r4r“r“Âó„Ø�Kr3r“có—eZdZeZy)ÚPartialHashtreesN)r.r/r0r“rJr2r3r4r–r–ÆrŠr3r–có@—eZdZdedddœfdedddœfdedddœfd efgZy ) ÚArchiveTimeStampÚdigest_algorithmrTr?Ú attributesrÚreduced_hashtreer)r†N)r.r/r0rrr–r r9r2r3r4r˜r˜Ês?„à ˜_¸1È$Ñ.OÐPØ �z°¸tÑ#DÐEØ Ð-¸AÈ4Ñ/PÐQØ �{Ð#ð �Gr3r˜có—eZdZeZy)ÚArchiveTimeStampSequenceN)r.r/r0r˜rJr2r3r4r�r�Ós„Ø"�Kr3r�có>—eZdZdefdefdedddœfdedddœfd efgZy ) ÚEvidenceRecordrNÚdigest_algorithmsÚ crypto_infosrTr?Úencryption_inforÚarchive_time_stamp_sequenceN) r.r/r0r!rŒrrŽr�r9r2r3r4rŸrŸ×sA„à �GÐØ Ð.Ð/Ø ˜°!ÀÑ%FÐGØ ˜N¸ÈÑ,MÐNØ &Ð(@ÐAð �Gr3rŸcó—eZdZdefdefgZy)Ú OtherEvidenceÚoe_typeÚoe_valueNr‘r2r3r4r¥r¥ás„à Ð$Ð%Ø �SÐð�Gr3r¥có4—eZdZdeddifdeddifdeddifgZy) ÚEvidenceÚ tst_evidencer@rÚ ers_evidencerÚother_evidencer)N)r.r/r0r‰rŸr¥Ú _alternativesr2r3r4r©r©ès4„à Ð/°*¸a°ÐAØ ˜¨*°a¨Ð9Ø ˜=¨:°q¨/Ð:ð�Mr3r©có@—eZdZdefdeddifdeddifdeddifdefgZy) ÚTimeStampedDatarNÚdata_urir=TÚ meta_dataÚcontentÚtemporal_evidenceN) r.r/r0r!rrrr©r9r2r3r4r¯r¯ðsF„à �GÐØ �Y ¨TÐ 2Ð3Ø �h ¨TÐ 2Ð3Ø �K *¨dÐ!3Ð4Ø ˜hÐ'ð �Gr3r¯có—eZdZdefdefgZy)Ú IssuerSerialÚissuerrQN)r.r/r0rrr9r2r3r4rµrµús„à �<Ð Ø ˜'Ð"ð�Gr3rµcó"—eZdZdefdeddifgZy)Ú ESSCertIDÚ cert_hashÚ issuer_serialr=TN)r.r/r0rrµr9r2r3r4r¸r¸s „à �kÐ"Ø ˜,¨°TÐ(:Ð;ð�Gr3r¸có—eZdZeZy)Ú ESSCertIDsN)r.r/r0r¸rJr2r3r4r¼r¼rKr3r¼có"—eZdZdefdeddifgZy)ÚSigningCertificateÚcertsÚpoliciesr=TN)r.r/r0r¼rr9r2r3r4r¾r¾ s!„à �*ÐØ Ð(¨:°tÐ*<Ð=ð�Gr3r¾có—eZdZeZy)ÚSetOfSigningCertificatesN)r.r/r0r¾rJr2r3r4rÂrÂs„Ø$�Kr3rÂcó2—eZdZdedddiifdefdeddifgZy ) Ú ESSCertIDv2r7rFÚ algorithmÚsha256r¹rºr=TN)r.r/r0rrrµr9r2r3r4rÄrÄs4„à ˜?¨Y¸ÀhÐ8OÐ,PÐQØ �kÐ"Ø ˜,¨°TÐ(:Ð;ð�Gr3rÄcó—eZdZeZy)Ú ESSCertIDv2sN)r.r/r0rÄrJr2r3r4rÈrÈr”r3rÈcó"—eZdZdefdeddifgZy)ÚSigningCertificateV2r¿rÀr=TN)r.r/r0rÈrr9r2r3r4rÊrÊ#s!„à �,ÐØ Ð(¨:°tÐ*<Ð=ð�Gr3rÊcó—eZdZeZy)ÚSetOfSigningCertificatesV2N)r.r/r0rÊrJr2r3r4rÌrÌ*s„Ø&�Kr3rÌÚtst_infoÚtimestamped_dataz1.2.840.113549.1.9.16.1.4z1.2.840.113549.1.9.16.1.31Úsigning_certificatez1.2.840.113549.1.9.16.2.12Úsigning_certificate_v2z1.2.840.113549.1.9.16.2.47N)GÚ__doc__Ú __future__rrrrÚalgosrÚcmsr r r r r Úcorerrrrrrrrrrrrrr‡rÚx509rrrrr!r6r;rCrIrMrZr^rfrhrwr|rr…r‰rŒrŽr“r–r˜r�rŸr¥r©r¯rµr¸r¼r¾rÂrÄrÈrÊrÌÚ _oid_specsr1r2r3r4ÚrØsyðñ ÷SÓRå"÷õ÷÷÷õõ!÷óôˆgôô�Xôôˆxôô�ôô�ôô ˆhô ô�8ôô�ôô�*ôô �Yô ô�Hôô�Hôôˆxôô�hôô"˜Zô"ô"�zô"ô�Xôô�jôô"�zô"ô�xôô#˜zô#ô�Xôô�Hôôˆvôô�hôô�8ôô�ôô�ôô˜ôô%˜uô%ô�(ôô�:ôô˜8ôô' ô'ð29Ð×"Ñ" :Ñ.Ø9HÐ×"Ñ"Ð#5Ñ6Ø-<€ ×ÑÐ)Ñ*Ø0:€ ×ÑÐ,Ñ-Ø1C€ ×ÑÐ-Ñ.Ø6KÐ×ÑÐ2Ñ3Ø1I€ ×ÑÐ-Ñ.Ø6NÐ×ÑÐ2Ñ3Ø4N€ ×ÑÐ0Ò1r3__pycache__/util.cpython-312.pyc000064400000065737152572326550012472 0ustar00Ë uÉþiqUãó¤—dZddlmZmZmZmZddlZddlZddlmZm Z m Z m Z ddl m Z ddlmZmZddlmZdd lmZej*d k(r dd lmZmZndd lmZmZej4d kr'dd „Zdd„ZGd„de «Zee d««e_nddlmZdd„Zdd„Zd„ZGd„de «Z e «Z!iZ"d„Z#Gd„de$«Z%Gd„de$«Z&y)a5 Miscellaneous data helpers, including functions for converting integers to and from bytes and UTC timezone. Exports the following items: - OrderedDict() - int_from_bytes() - int_to_bytes() - timezone.utc - utc_with_dst - create_timezone() - inet_ntop() - inet_pton() - uri_to_iri() - iri_to_uri() é)Úunicode_literalsÚdivisionÚabsolute_importÚprint_functionN)ÚdatetimeÚdateÚ timedeltaÚtzinfoé)Úunwrap)Ú iri_to_uriÚ uri_to_iri)Ú OrderedDict)Ú type_nameÚwin32)Ú inet_ntopÚ inet_pton)éc óì—|dk(r|dk(ryd}|rN|dkrId}ttjtdt |«z«dz «dz«}|d|zzd|zz}d|z}t|«dzrd |z}|j d «}|r|st |dd«d zrd |z}|�6t|«|kDr td «‚|rd}nd }||t|«z z|z}|S|rt |dd«d zdk(rd|z}|S)ᜠConverts an integer to a byte string :param value: The integer to convert :param signed: If the byte string should be encoded using two's complement :param width: If None, the minimal possible size (but at least 1), otherwise an integer of the byte width for the return value :return: A byte string róFTz%xg@ér Ú0Úhexé€ózint too big to convertóÿ)ÚintÚmathÚceilÚlenÚabsÚdecodeÚordÚ OverflowError)ÚvalueÚsignedÚwidthÚis_negÚbitsÚhex_strÚoutputÚpad_chars ú@/opt/nydus/tmp/pip-target-dhtdbchl/lib/python/asn1crypto/util.pyÚ int_to_bytesr/'s-€ð$ �AŠ:˜% 1š*ØðˆÙ �e˜a’i؈FÜ”t—y‘y¤ T¬C°«JÑ%6Ó!7¸#Ñ!=Ó>ÀÑBÓCˆDؘa 4™iÑ(¨Q°$©YÑ7ˆEà˜‘,ˆÜ ˆw‹<˜!Ò Ø˜G‘mˆGà—‘ Ó&ˆá ™&¤S¨°°!¨Ó%5¸Ò%<ؘvÑ%ˆFà Ð Ü�6‹{˜UÒ"Ü#Ð$<Ó=Ð=ÙØ"‘à"�Ø %¬#¨f«+Ñ"5Ñ6¸&Ñ@ˆFðˆ ñœ˜F 1 Q˜KÓ(¨4Ñ/°1Ò4ؘvÑ%ˆFàˆ rcóž—|dk(ryt|jd«d«}|s|St|dd«dzrt|«dz}|d|zz S|S)á Converts a byte string to an integer :param value: The byte string to convert :param signed: If the byte string should be interpreted using two's complement :return: An integer rrrér rr)ÚlongÚencoder$r!)r&r'ÚnumÚbit_lens r.Úint_from_bytesr7Ys`€ð �CŠ<Øä�5—<‘< Ó&¨Ó+ˆá؈Jô ˆu�Q�qˆz‹?˜TÒ !ܘ%“j 1‘nˆGؘ!˜w™,Ñ'Ð 'àˆ rcó6—eZdZdZd d„Zd„Zd„Zd„Zd„Zd„Z y) Útimezonez… Implements datetime.timezone for py2. Only full minute offsets are supported. DST is not supported. Ncó—td¬«|cxkrtd¬«kstd«‚td«‚|jdzs |jr td«‚||_|�||_y|sd|_ydt |«z|_y) zÀ :param offset: A timedelta with this timezone's offset from UTC :param name: Name of the timezone; if None, generate one. ièÿÿÿ)Úhourséz!Offset must be in [-23:59, 23:59]é<zOffset must be full minutesNÚUTC)r Ú ValueErrorÚsecondsÚ microsecondsÚ_offsetÚ_nameÚ_format_offset)ÚselfÚoffsetÚnames r.Ú__init__ztimezone.__init__}sˆ€ô 3Ô'¨&ÔF´9À2Ô3FÒFÜ Ð!DÓEÐEðGÜ Ð!DÓEÐEà�~‰~ Ò" f×&9Ò&9Ü Ð!>Ó?Ð?à!ˆDŒLàÐØ!�• ÙØ"�• à"¤^°FÓ%;Ñ;�• rcóZ—t|«tk7ry|j|jk(S)z« Compare two timezones :param other: The other timezone to compare to :return: A boolean F)Útyper9rB©rEÚothers r.Ú__eq__ztimezone.__eq__•s&€ô�E‹{œhÒ&ØØ—<‘< 5§=¡=Ñ0Ð 0rcó2—|j|jfS)z  Called by tzinfo.__reduce__ to support pickle and copy. :return: offset and name, to be used for __init__ )rBrC©rEs r.Ú__getinitargs__ztimezone.__getinitargs__¤s€ð—<‘< §¡Ð+Ð +rcó—|jS)zŒ :param dt: A datetime object; ignored. :return: Name of this timezone )rC©rEÚdts r.Útznameztimezone.tzname®s€ð—:‘:Ð rcó—|jS)z¢ :param dt: A datetime object; ignored. :return: A timedelta object with the offset from UTC )rBrRs r.Ú utcoffsetztimezone.utcoffset¹s€ð—<‘<Ð rcó—td«S)z… :param dt: A datetime object; ignored. :return: Zero timedelta r©r rRs r.Údstz timezone.dstÄs€ô˜Q“<Ð r©N) Ú__name__Ú __module__Ú __qualname__Ú__doc__rHrMrPrTrVrY©rr.r9r9vs%„ñ ó  <ò0 1ò ,ò ò ó rr9)r9có —|€n|r@|dkrt|dz«j«}n|j«}|dzdk(r|dz }n|j«}tj|dz «xsd}|j |d|¬«S)rrr rÚbig)Ú byteorderr')r"Ú bit_lengthrr Úto_bytes)r&r'r(Ú bits_requireds r.r/r/Ös‰€ð$ ˆ=ÙØ˜1’9Ü$'¨°© £N×$=Ñ$=Ó$?‘Mà$)×$4Ñ$4Ó$6�MØ  1Ñ$¨Ò)Ø! QÑ&‘Mà %× 0Ñ 0Ó 2� Ü—I‘I˜m¨aÑ/Ó0Ò5°AˆEØ�~‰~˜e¨u¸Vˆ~ÓDÐDrcó2—tj|d|¬«S)r1ra)r')rÚ from_bytes)r&r's r.r7r7õs€ô�~‰~˜e U°6ˆ~Ó:Ð:rcó”—|€y|jdzdz|jdzz}|dkrdnd}|dtt|«d«zzS)zC Format a timedelta into "[+-]HH:MM" format or "" for None Úr<r=rÚ-Ú+z %02d:%02d)Údaysr@Údivmodr")ÚoffÚminsÚsigns r.rDrDsT€ð  €{ØØ �8‰8�b‰=˜2Ñ  § ¡ ¨rÑ 1Ñ 1€Dؘ’(‰3 €DØ �+¤¤s¨4£y°"Ó 5Ñ5Ñ 5Ð5rcó"—eZdZdZd„Zd„Zd„Zy)Ú _UtcWithDstzK Utc class where dst does not return None; required for astimezone có—y)Nr>r_rRs r.rTz_UtcWithDst.tznames€Ørcó—td«S©NrrXrRs r.rVz_UtcWithDst.utcoffsetó €Ü˜‹|Ðrcó—td«SrurXrRs r.rYz_UtcWithDst.dstrvrN)r[r\r]r^rTrVrYr_rr.rrrrs„ñòòórrrcób— t|}|S#t$rt|«x}t|<Y|SwxYw)a Returns a new datetime.timezone object with the given offset. Uses cached objects if possible. :param offset: A datetime.timedelta object; It needs to be in full minutes and between -23:59 and +23:59. :return: A datetime.timezone object )Ú_timezone_cacheÚKeyErrorr9)rFÚtzs r.Úcreate_timezoner|&sB€ð8Ü ˜VÑ $ˆð €Iøô ò8Ü'/°Ó'7Ð7ˆŒ_˜VÒ $Ø €Ið8ús ‚ �.­.có�—eZdZdZd„Zed„«Zed„«Zed„«Zd„Z d„Z dd „Z d „Z d „Z d „Zd „Zd„Zd„Zd„Zd„Zd„Zy)Ú extended_dateáB A datetime.datetime-like object that represents the year 0. This is just to handle 0000-01-01 found in some certificates. Python's datetime does not support year 0. The proleptic gregorian calendar repeats itself every 400 years. Therefore, the simplest way to format is to substitute year 2000. cóH—|dk7r td«‚td||«|_y)z¬ :param year: The integer 0 :param month: An integer from 1 to 12 :param day: An integer from 1 to 31 rúyear must be 0éÐN)r?rÚ_y2k)rEÚyearÚmonthÚdays r.rHzextended_date.__init__Cs'€ð �1Š9ÜÐ-Ó.Ð .䘘u cÓ*ˆ� rcó—y©z4 :return: The integer 0 rr_rOs r.r„zextended_date.yearTó€ðrcó.—|jjS©z> :return: An integer from 1 to 12 ©rƒr…rOs r.r…zextended_date.month]ó€ð�y‰y�‰Ðrcó.—|jjS©z> :return: An integer from 1 to 31 ©rƒr†rOs r.r†zextended_date.dayfó€ð�y‰y�}‰}ÐrcóÒ—|jj|«}|jjd¬«j|«}djd„t ||«D««S)zô Formats the date using strftime() :param format: A strftime() format string :return: A str, the formatted date as a unicode string in Python 3 and a byte string in Python 2 é ©r„ric3ó8K—|]\}}||fdk(rdn|–—Œy­w©)Ú2Ú4rNr_©Ú.0Úc2Úc4s r.Ú z)extended_date.strftime..ó%èø€ÐYÉ=ÁÀÀR˜r 2˜h¨*Ò4‘s¸"Ó<É=ùó‚©rƒÚstrftimeÚreplaceÚjoinÚzip©rEÚformatÚy2kÚy4ks r.r¡zextended_date.strftimeosV€ð�i‰i× Ñ  Ó(ˆØ�i‰i×Ñ TÐÓ*×3Ñ3°FÓ;ˆØ�w‰wÑYÌ3ÈsÐTWÌ=ÓYÓYÐYrcó$—|jd«S)zµ Formats the date as %Y-%m-%d :return: The date formatted to %Y-%m-%d as a unicode string in Python 3 and a byte string in Python 2 z 0000-%m-%d©r¡rOs r.Ú isoformatzextended_date.isoformat�s€ð�}‰}˜\Ó*Ð*rNcóŽ—|€ |j}|€ |j}|€ |j}|dkDrt}nt}||||«S)zÚ Returns a new datetime.date or asn1crypto.util.extended_date object with the specified components replaced :return: A datetime.date or asn1crypto.util.extended_date object r)r„r…r†rr~)rEr„r…r†Úclss r.r¢zextended_date.replaceŒsU€ð ˆ<Ø—9‘9ˆDØ ˆ=Ø—J‘JˆEØ ˆ;Ø—(‘(ˆCà �!Š8܉CäˆCáØ Ø Ø ó ð rcó$—|jd«S)z_ :return: A str representing this extended_date, e.g. "0000-01-01" z%Y-%m-%drªrOs r.Ú__str__zextended_date.__str__§s€ð �}‰}˜ZÓ(Ð(rcóX—t||j«sy|j|«dk(S)ú¤ Compare two extended_date objects :param other: The other extended_date to compare to :return: A boolean Fr)Ú isinstanceÚ __class__Ú__cmp__rKs r.rMzextended_date.__eq__¯s)€ô˜% §¡Ô0ØØ�|‰|˜EÓ" aÑ'Ð'rcó&—|j|« S)r±©rMrKs r.Ú__ne__zextended_date.__ne__¿ó€ð—;‘;˜uÓ%Ð%Ð%rcó>—ttdt|«««‚)Nz¦ An asn1crypto.util.extended_date object can only be compared to an asn1crypto.util.extended_date or datetime.date object, not %s ©Ú TypeErrorr rrKs r.Ú_comparison_errorzextended_date._comparison_errorÌs%€Üœð ô �eÓ ó  ó ð rcóÜ—t|t«ryt||j«s|j|«|j|jkry|j|jkDryy)zæ Compare two extended_date or datetime.date objects :param other: The other extended_date object to compare to :return: An integer smaller than, equal to, or larger than 0 éÿÿÿÿr r)r²rr³r¼rƒrKs r.r´zextended_date.__cmp__ÕsV€ô �eœTÔ "Øä˜% §¡Ô0Ø × "Ñ " 5Ô )à �9‰9�u—z‘zÒ !ØØ �9‰9�u—z‘zÒ !ØØrcó*—|j|«dkSru©r´rKs r.Ú__lt__zextended_date.__lt__íó€Ø�|‰|˜EÓ" QÑ&Ð&rcó*—|j|«dkSrurÀrKs r.Ú__le__zextended_date.__le__ðó€Ø�|‰|˜EÓ" aÑ'Ð'rcó*—|j|«dkDSrurÀrKs r.Ú__gt__zextended_date.__gt__órÂrcó*—|j|«dk\SrurÀrKs r.Ú__ge__zextended_date.__ge__örÅr)NNN)r[r\r]r^rHÚpropertyr„r…r†r¡r«r¢r¯rMr·r¼r´rÁrÄrÇrÉr_rr.r~r~9s…„ñò+ð"ñóððñóððñóðòZò$ +ó ò6)ò(ò &ò òò0'ò(ò'ó(rr~có0—eZdZdZdZdezZd„Zed„«Zed„«Z ed„«Z ed„«Z ed „«Z ed „«Z ed „«Zed „«Zd „Zd„Zd„Zd„Zd#d„Zd$d„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Z d„Z!d „Z"d!„Z#e$d"„«Z%y)%Úextended_datetimeri±:écóL—|dk7r td«‚tdg|¢­i|¤Ž|_y)zá :param year: The integer 0 :param args: Other positional arguments; see datetime.datetime. :param kwargs: Other keyword arguments; see datetime.datetime. rr�r‚N)r?rrƒ©rEr„ÚargsÚkwargss r.rHzextended_datetime.__init__s-€ð �1Š9ÜÐ-Ó.Ð .ä˜TÐ3 DÒ3¨FÑ3ˆ� rcó—yrˆr_rOs r.r„zextended_datetime.yearr‰rcó.—|jjSr‹rŒrOs r.r…zextended_datetime.month"r�rcó.—|jjSr�r�rOs r.r†zextended_datetime.day+r‘rcó.—|jjS)z> :return: An integer from 1 to 24 )rƒÚhourrOs r.rÖzextended_datetime.hour4s€ð�y‰y�~‰~Ðrcó.—|jjS©z> :return: An integer from 1 to 60 )rƒÚminuterOs r.rÙzextended_datetime.minute=ó€ð�y‰y×ÑÐrcó.—|jjSrØ)rƒÚsecondrOs r.rÜzextended_datetime.secondFrÚrcó.—|jjS)zB :return: An integer from 0 to 999999 )rƒÚ microsecondrOs r.rÞzextended_datetime.microsecondOs€ð�y‰y×$Ñ$Ð$rcó.—|jjS)zh :return: If object is timezone aware, a datetime.tzinfo object, else None. )rƒr rOs r.r zextended_datetime.tzinfoXrÚrcó6—|jj«S)zk :return: If object is timezone aware, a datetime.timedelta object, else None. )rƒrVrOs r.rVzextended_datetime.utcoffsetas€ð �y‰y×"Ñ"Ó$Ð$rcó6—|jj«S)z= :return: A datetime.time object )rƒÚtimerOs r.râzextended_datetime.timeis€ð �y‰y�~‰~ÓÐrcóD—td|j|j«S)zS :return: An asn1crypto.util.extended_date of the date r)r~r…r†rOs r.rzextended_datetime.dateqs€ô ˜Q § ¡ ¨D¯H©HÓ5Ð5rcóÒ—|jj|«}|jjd¬«j|«}djd„t ||«D««S)zº Performs strftime(), always returning a str :param format: A strftime() format string :return: A str of the formatted datetime r“r”ric3ó8K—|]\}}||fdk(rdn|–—Œy­wr–r_r™s r.r�z-extended_datetime.strftime..ˆržrŸr r¥s r.r¡zextended_datetime.strftimeysV€ð�i‰i× Ñ  Ó(ˆØ�i‰i×Ñ TÐÓ*×3Ñ3°FÓ;ˆØ�w‰wÑYÌ3ÈsÐTWÌ=ÓYÓYÐYrcóð—d|j|j||j|j|jfz}|j r|d|j zz }|t |j««zS)aj Formats the date as "%Y-%m-%d %H:%M:%S" with the sep param between the date and time portions :param set: A single character of the separator to place between the date and time :return: The formatted datetime as a unicode string in Python 3 and a byte string in Python 2 z0000-%02d-%02d%c%02d:%02d:%02dz.%06d)r…r†rÖrÙrÜrÞrDrV)rEÚsepÚss r.r«zextended_datetime.isoformatŠsj€ð -°· ± ¸D¿H¹HÀcÈ4Ï9É9ÐVZ×VaÑVaÐcg×cnÑcnÐ/oÑ oˆØ × Ò Ø �˜4×+Ñ+Ñ+Ñ +ˆAØ”> $§.¡.Ó"2Ó3Ñ3Ð3rNcó¬—|r |jj|g|¢­i|¤ŽStj|jjdg|¢­i|¤Ž«S)aò Returns a new datetime.datetime or asn1crypto.util.extended_datetime object with the specified components replaced :param year: The new year to substitute. None to keep it. :param args: Other positional arguments; see datetime.datetime.replace. :param kwargs: Other keyword arguments; see datetime.datetime.replace. :return: A datetime.datetime or asn1crypto.util.extended_datetime object r‚)rƒr¢rÌÚfrom_y2krÏs r.r¢zextended_datetime.replace�sU€ñ$ Ø$�4—9‘9×$Ñ$ TÐ;¨DÒ;°FÑ;Ð ;ä ×)Ñ)Ð*;¨$¯)©)×*;Ñ*;¸DÐ*RÀ4Ò*RÈ6Ñ*RÓSÐSrcó^—tj|jj|««S)zÑ Convert this extended_datetime to another timezone. :param tz: A datetime.tzinfo object. :return: A new extended_datetime or datetime.datetime object )rÌrêrƒÚ astimezone)rEr{s r.rìzextended_datetime.astimezone´s$€ô!×)Ñ)¨$¯)©)×*>Ñ*>¸rÓ*BÓCÐCrcóV—|jj«|jdzz S)z½ Return POSIX timestamp. Only supported in python >= 3.3 :return: A float representing the seconds since 1970-01-01 UTC. This will be a negative value. i€Q)rƒÚ timestampÚDAYS_IN_2000_YEARSrOs r.rîzextended_datetime.timestampÁs'€ð�y‰y×"Ñ"Ó$ t×'>Ñ'>ÀÑ'FÑFÐFrcó&—|jd¬«S)zy :return: A str representing this extended_datetime, e.g. "0000-01-01 00:00:00.000001-10:00" Ú )rç)r«rOs r.r¯zextended_datetime.__str__Ës€ð �~‰~ #ˆ~Ó&Ð&rcó —t||jtf«sy|jdu|jduk7ry|j |«dk(S)ú¬ Compare two extended_datetime objects :param other: The other extended_datetime to compare to :return: A boolean FNr)r²r³rr r´rKs r.rMzextended_datetime.__eq__ÓsM€ô˜% $§.¡.´(Ð!;Ô<Øð �K‰K˜4Ð  U§\¡\°TÐ%9Ò :Øà�|‰|˜EÓ" aÑ'Ð'rcó&—|j|« S)rór¶rKs r.r·zextended_datetime.__ne__èr¸rcó>—ttdt|«««‚)z¥ Raises a TypeError about the other object not being suitable for comparison :param other: The object being compared to z¾ An asn1crypto.util.extended_datetime object can only be compared to an asn1crypto.util.extended_datetime or datetime.datetime object, not %s rºrKs r.r¼z#extended_datetime._comparison_errorõs'€ôœð ô �eÓ ó  ó ð rcóæ—t||jtf«s|j|«|jdu|jduk7r t d«‚||z }t d«}||kry||kDryy)a Compare two extended_datetime or datetime.datetime objects :param other: The other extended_datetime or datetime.datetime object to compare to :return: An integer smaller than, equal to, or larger than 0 Nz5can't compare offset-naive and offset-aware datetimesrr¾r )r²r³rr¼r r»r )rErLÚdiffÚzeros r.r´zextended_datetime.__cmp__st€ô˜% $§.¡.´(Ð!;Ô<Ø × "Ñ " 5Ô )à �K‰K˜4Ð  U§\¡\°TÐ%9Ò :ÜÐSÓTÐ Tà�e‰|ˆÜ˜‹|ˆØ �$Š;ØØ �$Š;ØØrcó*—|j|«dkSrurÀrKs r.rÁzextended_datetime.__lt__ rÂrcó*—|j|«dkSrurÀrKs r.rÄzextended_datetime.__le__#rÅrcó*—|j|«dkDSrurÀrKs r.rÇzextended_datetime.__gt__&rÂrcó*—|j|«dk\SrurÀrKs r.rÉzextended_datetime.__ge__)rÅrcóF—tj|j|z«S)z¼ Adds a timedelta :param other: A datetime.timedelta object to add. :return: A new extended_datetime or datetime.datetime object. )rÌrêrƒrKs r.Ú__add__zextended_datetime.__add__,s€ô!×)Ñ)¨$¯)©)°eÑ*;Ó<ÐrsÍðñ÷ SÓRã Û ß6Ó6åß(Ý%Ýà‡<�<�7Òß+Ð+ç+ð×Ñ�tÒó0ódô:W �6ôW ñr™I a›LÓ)€H…Lõ "óEó>;ò" 6ô �&ô ñ‹}€ à€òô&~(�Fô~(ôBt ˜õt r__pycache__/version.cpython-312.pyc000064400000000557152572326550013167 0ustar00Ë uÉþi˜ãó$—ddlmZmZmZmZdZdZy)é)Úunicode_literalsÚdivisionÚabsolute_importÚprint_functionz1.5.1)éérN)Ú __future__rrrrÚ __version__Ú__version_info__©óúC/opt/nydus/tmp/pip-target-dhtdbchl/lib/python/asn1crypto/version.pyÚrsðçRÓRð€ ØÑr __pycache__/x509.cpython-312.pyc000064400000320115152572326550012202 0ustar00Ë uÉþiRnãó —dZddlmZmZmZmZddlmZddlm Z ddl Z ddl Z ddl Z ddl Z ddlZddlZddlmZddlmZmZdd lmZdd lmZmZmZdd lmZmZmZmZdd l m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;mZ>ddl?m@Z@mAZAmBZBmCZCGd„de*«ZDGd„de*«ZEGd„de*«ZFGd„de0«ZGGd„de3«ZHGd„de4«ZIGd„de"«ZJGd„de3«ZKGd„d e7«ZLed!„«ZMGd"„d#e%«ZNGd$„d%e.«ZOGd&„d'e3«ZPGd(„d)e6«ZQGd*„d+e4«ZRGd,„d-e%«ZSGd.„d/e3«ZTGd0„d1e%«ZUGd2„d3e%«ZVGd4„d5e%«ZWGd6„d7e5«ZXGd8„d9e5«ZYGd:„d;e4«ZZGd<„d=e4«Z[Gd>„d?e3«Z\Gd@„dAe3«Z]GdB„dCe4«Z^GdD„dEe3«Z_GdF„dGe4«Z`GdH„dIe%«ZaGdJ„dKe%«ZbGdL„dMe5«ZcGdN„dOe4«ZdGdP„dQe5«ZeGdR„dSe3«ZfGdT„dUe6«ZgGdV„dWe3«ZhGdX„dYe%«ZiGdZ„d[e+«ZjGd\„d]e+«ZkGd^„d_e3«ZlGd`„dae4«ZmGdb„dce3«ZnGdd„dee3«ZoGdf„dge%«ZpGdh„die4«ZqGdj„dke%«ZrGdl„dme3«ZsGdn„doe3«ZtGdp„dqe3«ZuGdr„dse%«ZvGdt„due"«ZwGdv„dwe3«ZxGdx„dye4«ZyGdz„d{e3«ZzGd|„d}e3«Z{Gd~„de4«Z|Gd€„d�e%«Z}Gd‚„dƒe4«Z~Gd„„d…e3«ZGd†„d‡e3«Z€Gdˆ„d‰e.«Z�GdŠ„d‹e3«Z‚GdŒ„d�e4«ZƒGdŽ„d�e.«Z„Gd�„d‘e3«Z…Gd’„d“e4«Z†Gd”„d•e3«Z‡Gd–„d—e4«ZˆGd˜„d™e3«Z‰Gdš„d›e.«ZŠGdœ„d�e4«Z‹Gdž„dŸe.«ZŒGd „d¡e3«Z�Gd¢„d£e4«ZŽGd¤„d¥e4«Z�Gd¦„d§e4«Z�Gd¨„d©e3«Z‘Gdª„d«e"«Z’Gd¬„d­e+«Z“Gd®„d¯e3«Z”Gd°„d±e6«Z•Gd²„d³e3«Z–Gd´„dµe3«Z—Gd¶„d·e6«Z˜Gd¸„d¹e'«Z™Gdº„d»e'«ZšGd¼„d½e'«Z›Gd¾„d¿e'«ZœGdÀ„dÁe'«Z�Gd„dÃe'«ZžGdÄ„dÅe3«ZŸGdÆ„dÇe3«Z GdÈ„dÉe'«Z¡GdÊ„dËe3«Z¢GdÌ„dÍe3«Z£Gd΄dÏe6«Z¤GdЄdÑe.«Z¥GdÒ„dÓe6«Z¦GdÔ„dÕe6«Z§GdÖ„d×e6«Z¨GdØ„dÙe3«Z©GdÚ„dÛe6«ZªGdÜ„dÝe3«Z«GdÞ„dße4«Z¬Gdà„dáe.«Z­Gdâ„dãe3«Z®Gdä„dåe4«Z¯Gdæ„dçe3«Z°Gdè„dée3«Z±Gdê„dëe4«Z²Gdì„díe4«Z³Gdî„dïe3«Z´Gdð„dñe&«Zµy)òzò ASN.1 type classes for X.509 certificates. Exports the following items: - Attributes() - Certificate() - Extensions() - GeneralName() - GeneralNames() - Name() Other type classes are defined that help compose the types listed above. é)Úunicode_literalsÚdivisionÚabsolute_importÚprint_function)Úcontextmanager)ÚidnaNé)Úunwrap)Ú iri_to_uriÚ uri_to_iri)Ú OrderedDict)Ú type_nameÚstr_clsÚ bytes_to_list)ÚAlgorithmIdentifierÚAnyAlgorithmIdentifierÚDigestAlgorithmÚSignedDigestAlgorithm)ÚAnyÚ BitStringÚ BMPStringÚBooleanÚChoiceÚConcatÚ EnumeratedÚGeneralizedTimeÚ GeneralStringÚ IA5StringÚIntegerÚNullÚ NumericStringÚObjectIdentifierÚOctetBitStringÚ OctetStringÚParsableOctetStringÚPrintableStringÚSequenceÚ SequenceOfÚSetÚSetOfÚ TeletexStringÚUniversalStringÚUTCTimeÚ UTF8StringÚ VisibleStringÚVOID)Ú PublicKeyInfo)Ú int_to_bytesÚint_from_bytesÚ inet_ntopÚ inet_ptoncó&—eZdZdZdZd„Zd„Zd„Zy)ÚDNSNamer©é écó—||k( S©N©©ÚselfÚothers ú@/opt/nydus/tmp/pip-target-dhtdbchl/lib/python/asn1crypto/x509.pyÚ__ne__zDNSName.__ne__Ló€Ø˜5‘=Ð Ð ócóž—t|t«sy|j«j«|j«j«k(S)zº Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.2 :param other: Another DNSName object :return: A boolean F)Ú isinstancer7Ú __unicode__Úlowerr>s rAÚ__eq__zDNSName.__eq__Os@€ô˜%¤Ô)Øà×ÑÓ!×'Ñ'Ó)¨U×->Ñ->Ó-@×-FÑ-FÓ-HÑHÐHrDc óh—t|t«s(ttdt |«t |«««‚|j d«r"d|ddj |j«z}n|j |j«}||_||_ d|_ |jdk7rd|_ yy)zd Sets the value of the DNS name :param value: A unicode string úK %s value must be a unicode string, not %s Ú.ó.r NrD) rFrÚ TypeErrorr rÚ startswithÚencodeÚ _encodingÚ_unicodeÚcontentsÚ_headerÚ_trailer)r?ÚvalueÚ encoded_values rAÚsetz DNSName.set_s¦€ô˜%¤Ô)ÜœFðô˜$“ܘ%Ó ó óð ð × Ñ ˜CÔ Ø  5¨¨ 9×#3Ñ#3°D·N±NÓ#CÑC‰Mà!ŸL™L¨¯©Ó8ˆMàˆŒ Ø%ˆŒ ؈Œ Ø �=‰=˜CÒ ØˆD�Mð rDN)Ú__name__Ú __module__Ú __qualname__rQÚ_bad_tagrBrIrXr=rDrAr7r7Gs„à€IØ€Hò!òIó  rDr7có$—eZdZd„Zd„Zd„Zd„Zy)ÚURIc óÞ—t|t«s(ttdt |«t |«««‚||_t |«|_d|_|jdk7rd|_ yy)úb Sets the value of the string :param value: A unicode string rKNrD) rFrrNr rrRr rSrTrU©r?rVs rArXzURI.set~sl€ô˜%¤Ô)ÜœFðô˜$“ܘ%Ó ó óð ðˆŒ Ü" 5Ó)ˆŒ ؈Œ Ø �=‰=˜CÒ ØˆD�Mð rDcó—||k( Sr<r=r>s rArBz URI.__ne__•rCrDcó~—t|t«syt|jd«t|jd«k(S)z¶ Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.4 :param other: Another URI object :return: A boolean FT)rFr^r Únativer>s rArIz URI.__eq__˜s2€ô˜%¤Ô%Øä˜$Ÿ+™+ tÓ,´ ¸5¿<¹<ÈÓ0NÑNÐNrDcóˆ—|j€y|j€t|j««|_|jS©ú7 :return: A unicode string Ú)rSrRr Ú _merge_chunks©r?s rArGzURI.__unicode__¨s:€ð �=‰=Ð ØØ �=‰=Ð Ü& t×'9Ñ'9Ó';Ó<ˆDŒMØ�}‰}ÐrDN)rYrZr[rXrBrIrGr=rDrAr^r^|s„ò ò.!òOó rDr^cód—eZdZdZdZdZed„«Zejd„«Zd„Z d„Z d„Z d „Z y) Ú EmailAddressNFr8có—|jS)z` :return: A byte string of the DER-encoded contents of the sequence )Ú _contentsrjs rArSzEmailAddress.contents¿s€ð�~‰~ÐrDcó —d|_||_y)ze :param value: A byte string of the DER-encoded contents of the sequence FN)Ú _normalizedrnras rArSzEmailAddress.contentsÈs€ð!ˆÔ؈�rDc óœ—t|t«s(ttdt |«t |«««‚|j d«dk7r<|j dd«\}}|jd«dz|jd«z}n|jd«}d|_||_ ||_ d |_ |jd k7rd |_ y y ) r`rKÚ@éÿÿÿÿr Úasciió@rTNrD) rFrrNr rÚfindÚrsplitrPrprRrSrTrU)r?rVÚmailboxÚhostnamerWs rArXzEmailAddress.setÒsÀô˜%¤Ô)ÜœFðô˜$“ܘ%Ó ó óð ð �:‰:�c‹?˜bÒ Ø %§ ¡ ¨S°!Ó 4Ñ ˆG�XØ#ŸN™N¨7Ó3°dÑ:¸X¿_¹_ÈVÓ=TÑT‰Mà!ŸL™L¨Ó1ˆMàˆÔ؈Œ Ø%ˆŒ ؈Œ Ø �=‰=˜CÒ ØˆD�Mð rDcó>—|j€†|j«}|jd«dk(r"|jd«|_|jS|j dd«\}}|jd«dz|jd«z|_|jS)rgrursÚcp1252r rrr)rRrirvÚdecoderw)r?rSrxrys rArGzEmailAddress.__unicode__ðsŽ€ð �=‰=Ð Ø×)Ñ)Ó+ˆHØ�}‰}˜TÓ" bÒ(Ø (§¡°Ó 9�” ð�}‰}Ðð%-§O¡O°D¸!Ó$<Ñ!�˜Ø '§¡¨xÓ 8¸3Ñ >ÀÇÁÐQWÓAXÑ X�” Ø�}‰}ÐrDcó—||k( Sr<r=r>s rArBzEmailAddress.__ne__rCrDcó8—t|t«sy|js|j|j«|js|j|j«|j j d«dk(s|j j d«dk(r|j |j k(S|j jdd«\}}|j jdd«\}}||k7ry|j«|j«k7ryy)z¿ Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.5 :param other: Another EmailAddress object :return: A boolean Frursr T) rFrlrprXrdrnrvrwrH)r?r@Ú other_mailboxÚother_hostnamerxrys rArIzEmailAddress.__eq__sâ€ô˜%¤Ô.Øà×ÒØ �H‰H�T—[‘[Ô !Ø× Ò Ø �I‰I�e—l‘lÔ #à �>‰>× Ñ ˜tÓ $¨Ò *¨e¯o©o×.BÑ.BÀ4Ó.HÈBÒ.NØ—>‘> U§_¡_Ñ4Ð 4à(-¯©×(>Ñ(>¸tÀQÓ(GÑ%ˆ �~Ø ŸN™N×1Ñ1°$¸Ó:ш�à �mÒ #Øà �>‰>Ó ˜~×3Ñ3Ó5Ò 5ØàrD) rYrZr[rnrpr\ÚpropertyrSÚsetterrXrGrBrIr=rDrArlrlµsS„à€Ið€Kð€Hà ñóðð‡_�_ñóðò ò<ò"!órDrlcó6—eZdZdd„Zd„Zed„«Zd„Zd„Zy)Ú IPAddressNcó*—ttd««‚)z? This method is not applicable to IP addresses z= IP address values can not be parsed )Ú ValueErrorr )r?ÚspecÚ spec_paramss rAÚparsezIPAddress.parse's€ô œð ó ó ð rDc ó\—t|t«s(ttdt |«t |«««‚|}|j d«dk7}d}|rH|j dd«}|d}t|d«}|dkrttdt |«««‚|j d«dk7r6tj}|dkDrttd t |«««‚d}n5tj}|d kDrttd t |«««‚d }d }|rEd |z} | d|t| «z zz } tt| d««}d|dzt|«z z|z}||_t||«|z|_|j |_d|_|j&d k7rd |_yy)zÌ Sets the value of the object :param value: A unicode string containing an IPv4 address, IPv4 address with CIDR, an IPv6 address or IPv6 address with CIDR rKÚ/rsrr zT %s value contains a CIDR range less than 0 Ú:é€z“ %s value contains a CIDR range bigger than 128, the maximum value for an IPv6 address é z’ %s value contains a CIDR range bigger than 32, the maximum value for an IPv4 address rDÚ1Ú0éóéN)rFrrNr rrvÚsplitÚintr†ÚsocketÚAF_INET6ÚAF_INETÚlenr2Ú_nativer5rSÚ_bytesrTrU) r?rVÚoriginal_valueÚhas_cidrÚcidrÚpartsÚfamilyÚ cidr_sizeÚ cidr_bytesÚ cidr_masks rArXz IPAddress.set2sÆ€ô˜%¤Ô)ÜœFðô˜$“ܘ%Ó ó óð ðˆà—:‘:˜c“? bÑ(ˆØˆÙ Ø—K‘K  QÓ'ˆEؘ!‘HˆEÜ�u˜Q‘x“=ˆDØ�aŠxÜ ¤ðô˜d“Oó "óðð �:‰:�c‹?˜bÒ Ü—_‘_ˆFØ�cŠzÜ ¤ðô˜d“Oó "óðð‰Iä—^‘^ˆFØ�bŠyÜ ¤ðô˜d“Oó "óððˆIàˆ Ù Ø˜d™ ˆIØ ˜  ¬C° «NÑ :Ñ;Ñ ;ˆIÜ%¤c¨)°QÓ&7Ó8ˆJØ! i°1¡n¼¸J»Ñ%GÑHÈJÑVˆJà%ˆŒ Ü! &¨%Ó0°:Ñ=ˆŒ Ø—m‘mˆŒ ؈Œ Ø �=‰=˜CÒ ØˆD�Mð rDcó—|j€y|j€ã|j«}t|«}d}d}|t ddg«vr1t t j|dd«}|dkDrNt|dd«}n?|t ddg«vr0t t j|dd«}|dkDrt|dd«}|�Ó?‘HØœS ! Q ›[Ñ(Ü!¤&§.¡.°+¸aÀÐ2BÓC�ؘa’<Ü-¨k¸!¸"¨oÓ>�HØÐ#Ø#ŸN™N¨8Ó4� ܘ9×+Ñ+¨CÓ0Ó1�Ø ™ ¤g¨d£mÑ3�Ø ˆDŒLØ�|‰|ÐrDcó—||k( Sr<r=r>s rArBzIPAddress.__ne__™rCrDcóf—t|t«sy|j«|j«k(S)zl :param other: Another IPAddress object :return: A boolean F)rFr„r§r>s rArIzIPAddress.__eq__œs*€ô˜%¤Ô+Øà�~‰~Ó 5§?¡?Ó#4Ñ4Ð4rD)NN) rYrZr[r‰rXr�rdrBrIr=rDrAr„r„&s,„ó  òE ðNñóðò>!ó 5rDr„có"—eZdZdefdedeifgZy)Ú AttributeÚtypeÚvaluesr‡N)rYrZr[r"r*rÚ_fieldsr=rDrAr±r±«s „à Ð!Ð"Ø �5˜6 3˜-Ð(ð�GrDr±có—eZdZeZy)Ú AttributesN)rYrZr[r±Ú _child_specr=rDrAr¶r¶²ó„Ø�KrDr¶c ó$—eZdZddddddddd d œ Zy ) ÚKeyUsageÚdigital_signatureÚnon_repudiationÚkey_enciphermentÚdata_enciphermentÚ key_agreementÚ key_cert_signÚcrl_signÚ encipher_onlyÚ decipher_only© rr r‘ér¦ééér“N©rYrZr[Ú_mapr=rDrArºrº¶s$„à Ø Ø Ø Ø Ø Ø Ø Ø ñ �DrDrºcó,—eZdZdedddœfdedddœfgZy)ÚPrivateKeyUsagePeriodÚ not_beforerT©ÚimplicitÚoptionalÚ not_afterr N)rYrZr[rr´r=rDrArÌrÌÄs'„à �°QÀDÑ(IÐJØ �o°AÀ4Ñ'HÐIð�GrDrÌcó—eZdZdZdZd„Zy)ÚNotReallyTeletexStringa6 OpenSSL (and probably some other libraries) puts ISO-8859-1 into TeletexString instead of ITU T.61. We use Windows-1252 when decoding since it is a superset of ISO-8859-1, and less likely to cause encoding issues, but we stay strict with encoding to prevent us from creating bad data. r{có¨—|j€y|j€.|j«j|j«|_|jSrf)rSrRrir|Ú_decoding_encodingrjs rArGz"NotReallyTeletexString.__unicode__ÖsF€ð �=‰=Ð ØØ �=‰=Ð Ø ×.Ñ.Ó0×7Ñ7¸×8OÑ8OÓPˆDŒMØ�}‰}ÐrDN)rYrZr[Ú__doc__rÕrGr=rDrArÓrÓËs„ñð"Ðó rDrÓc#óbK— dt_d–—dt_y#dt_wxYw­w)NÚteletexr{)rÓrÕr=rDrAÚstrict_teletexrÙãs)èø€ð=Ø4=ÔÔ1Û à4<ÔÕ1ø°HÔÕ1üs‚/„“ /Ÿ ,¬/có4—eZdZdefdefdefdefdefdefgZ y)ÚDirectoryStringÚteletex_stringÚprintable_stringÚuniversal_stringÚ utf8_stringÚ bmp_stringÚ ia5_stringN) rYrZr[rÓr&r,r.rrÚ _alternativesr=rDrArÛrÛìs:„à Ð1Ð2Ø ˜_Ð-Ø ˜_Ð-Ø ˜ Ð#Ø �yÐ!à �yÐ!ð�MrDrÛcó—eZdZidd“dd“dd“dd“d d “d d “d d“dd“dd“dd“dd“dd“dd“dd“dd“dd “d!d"“id#d$“d%d&“d'd(“d)d*“d+d,“d-d.“d/d0“d1d2“d3d4“d5d6“d7d8“d9d:“d;d<“d=d>“d?d@“dAdB“dCdD“¥ZgdE¢ZedF„«ZedG„«ZyH)IÚNameTypez2.5.4.3Ú common_namez2.5.4.4Úsurnamez2.5.4.5Ú serial_numberz2.5.4.6Ú country_namez2.5.4.7Ú locality_namez2.5.4.8Ústate_or_province_namez2.5.4.9Ústreet_addressz2.5.4.10Úorganization_namez2.5.4.11Úorganizational_unit_namez2.5.4.12Útitlez2.5.4.15Úbusiness_categoryz2.5.4.17Ú postal_codez2.5.4.20Útelephone_numberz2.5.4.41Únamez2.5.4.42Ú given_namez2.5.4.43Úinitialsz2.5.4.44Úgeneration_qualifierz2.5.4.45Úunique_identifierz2.5.4.46Ú dn_qualifierz2.5.4.65Ú pseudonymz2.5.4.97Úorganization_identifierz 2.23.133.2.1Útpm_manufacturerz 2.23.133.2.2Ú tpm_modelz 2.23.133.2.3Ú tpm_versionz 2.23.133.2.4Úplatform_manufacturerz 2.23.133.2.5Úplatform_modelz 2.23.133.2.6Úplatform_versionz1.2.840.113549.1.9.1Ú email_addressz1.3.6.1.4.1.311.60.2.1.1Úincorporation_localityz1.3.6.1.4.1.311.60.2.1.2Úincorporation_state_or_provincez1.3.6.1.4.1.311.60.2.1.3Úincorporation_countryz0.9.2342.19200300.100.1.1Úuser_idz0.9.2342.19200300.100.1.25Údomain_componentz0.2.262.1.10.7.20Úname_distinguisher)!rrrrïrçrèrðrêrérërìrírîrårrôrõræróròrør÷rñrrrrùrúrûrürýrþrÿcó°—|j|«}||jvr|jj|«}||fSt|j«}||fS)zÍ Returns an ordering value for a particular attribute key. Unrecognized attributes and OIDs will be sorted lexically at the end. :return: An orderable value. )ÚmapÚpreferred_orderÚindexr™)ÚclsÚ attr_nameÚordinals rAÚpreferred_ordinalzNameType.preferred_ordinalKs`€ð—G‘G˜IÓ&ˆ Ø ˜×+Ñ+Ñ +Ø×)Ñ)×/Ñ/° Ó:ˆGð˜Ð#Ð#ô˜#×-Ñ-Ó.ˆGà˜Ð#Ð#rDcó—idd“dd“dd“dd“d d “d d “d d“dd“dd“dd“dd“dd“dd“dd“dd“dd “d!d"“id#d$“d%d&“d'd(“d)d*“d+d,“d-d.“d/d0“d1d2“d3d4“d5d6“d7d8“d9d:“d;d<“d=d>“d?d@“dAdB“dCdD“¥j|j|j«S)EzZ :return: A human-friendly unicode string to display to users råz Common NameræÚSurnamerçz Serial NumberrèÚCountryréÚLocalityrêzState/ProvincerëzStreet AddressrìÚ OrganizationrízOrganizational UnitrîÚTitlerïzBusiness Categoryrðz Postal CoderñzTelephone NumberròÚNameróz Given NamerôÚInitialsrõzGeneration QualifierrözUnique Identifierr÷z DN QualifierrøÚ Pseudonymrz Email AddressrzIncorporation LocalityrzIncorporation State/ProvincerzIncorporation CountryrzDomain ComponentrzName DistinguisherrùzOrganization IdentifierrúzTPM Manufacturerrûz TPM Modelrüz TPM VersionrýzPlatform ManufacturerrþzPlatform ModelrÿzPlatform VersionrzUser ID)Úgetrdrjs rAÚhuman_friendlyzNameType.human_friendly_sÏ€ð# Ø ˜=ð# à �yð# ð ˜_ð# ð ˜Ið # ð ˜Zð # ð %Ð&6ð # ð Ð.ð# ð  ð# ð 'Ð(=ð# ð �Wð# ð Ð!4ð# ð ˜=ð# ð Ð 2ð# ð �Fð# ð ˜,ð# ð ˜ ð!# ð" #Ð$:ñ## ð$ Ð!4ð%# ð& ˜Nð'# ð( ˜ð)# ð* ˜_ð+# ð, %Ð&>ð-# ð. .Ð/Mð/# ð0 $Ð%<ð1# ð2 Ð 2ð3# ð4 !Ð"6ð5# ð6 &Ð'@ð7# ð8 Ð 2ð9# ð: ˜ð;# ð< ˜=ð=# ð> $Ð%<ð?# ð@ Ð.ðA# ðB Ð 2ðC# ðD �yñE# ÷F ‰#ˆd�k‰k˜4Ÿ;™;Ó 'ðG# (rDN) rYrZr[rÊr Ú classmethodrr�rr=rDrAräräøsì„ð) Ø�=ð) à�9ð) ð �?ð) ð �>ð ) ð �?ð ) ð Ð+ð ) ð Ð#ð) ð Ð'ð) ð Ð.ð) ð �Gð) ð Ð'ð) ð �Mð) ð Ð&ð) ð �Fð) ð �Lð) ð �Jð!) ð" Ð*ñ#) ð$ Ð'ð%) ð& �Nð') ð( �Kð)) ð* Ð-ð+) ð. Ð*ð/) ð0 ˜ ð1) ð2 ˜ ð3) ð4 Ð/ð5) ð6 Ð(ð7) ð8 Ð*ð9) ð<  ð=) ð@ #Ð$<ðA) ðB #Ð$EðC) ðD #Ð$;ðE) ðH $ YðI) ðL %Ð&8ðM) ðP Ð1ñQ) €Dò\"€OðHñ$óð$ð&ñ)(óñ)(rDräcó—eZdZdefdefgZdZide“de“de“de“de“d e“d e“d e“d e“d e“de“de“de“de“de“de“de“ide “de“de“de “de“de“de“de “de“de“de “d e “d!e “d"e “d#e “d$e “d%e“¥Z d&Zed'„«Zd(„Zd)„Zd*„Zy&)+ÚNameTypeAndValuer²rV©r²rVrårærçrèrérêrërìrírîrïrðrñròrórôrõrör÷rørrrrrrrùrúrûrürýrþrÿrNcóx—|j€#|j|dj«|_|jS)zµ Returns the value after being processed by the internationalized string preparation as specified by RFC 5280 :return: A unicode string rV)Ú_preppedÚ_ldap_string_preprdrjs rAÚ prepped_valuezNameTypeAndValue.prepped_value¼s4€ð �=‰=Ð Ø ×2Ñ2°4¸±=×3GÑ3GÓHˆDŒMØ�}‰}ÐrDcó—||k( Sr<r=r>s rArBzNameTypeAndValue.__ne__ÊrCrDcó–—t|t«sy|dj|djk7ry|j|jk(S)zà Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.1 :param other: Another NameTypeAndValue object :return: A boolean Fr²)rFrrdr!r>s rArIzNameTypeAndValue.__eq__ÍsH€ô˜%Ô!1Ô2Øà �‰=× Ñ  4¨¡<×#6Ñ#6Ò 6Øà×"Ñ" d×&8Ñ&8Ñ8Ð8rDcó"—tjdd|«}tjdd|«}tjdk(rtjdd|«}ntjdd|«}tjdd|«}|j d d«}tjd d|«}dj t tj|««}tjd |«}|D]è}tj|«rttd ««‚tj|«rttd ««‚tj|«rttd««‚tj |«rttd««‚tj"|«rttd««‚|dk(sŒÖttd««‚d}d}|D]2}tj$|«rd}Œtj&|«sŒ1d}Œ4|rJtj$|d«}tj$|d«}|s|r|sttd««‚dtjdd|«j)«zdz}|S)a" Implements the internationalized string preparation algorithm from RFC 4518. https://tools.ietf.org/html/rfc4518#section-2 :param string: A unicode string to prepare :return: A prepared unicode string, ready for comparison u[­᠆Í�á ‹-á �ï¸�-＀]+rhu [ Â…]Ú iÿÿuí ´[íµ³-íµº]|í­€[í° -í±¿]|ó €�u[ð�…³-ð�…ºó € -ó �¿ó €�]u?[---„†-ŸÛ�Ü�᠎‌-â€�‪-‮â� -â�£â�ª-â�¯ï»¿ï¿¹-ï¿»]+u​u[   - 
-
 â�Ÿã€€]ÚNFKCzc X.509 Name objects may not contain unassigned code points zŒ X.509 Name objects may not contain change display or zzzzdeprecated characters zc X.509 Name objects may not contain private use characters zf X.509 Name objects may not contain non-character code points zb X.509 Name objects may not contain surrogate code points u�zf X.509 Name objects may not contain the replacement character FTrrsz{ X.509 Name object contains a malformed bidirectional sequence z +z )ÚreÚsubÚsysÚ maxunicodeÚreplaceÚjoinrÚ stringprepÚ map_table_b2Ú unicodedataÚ normalizeÚ in_table_a1r†r Ú in_table_c8Ú in_table_c3Ú in_table_c4Ú in_table_c5Ú in_table_d1Ú in_table_d2Ústrip)r?ÚstringÚcharÚhas_r_and_al_catÚ has_l_catÚfirst_is_r_and_alÚlast_is_r_and_als rAr z"NameTypeAndValue._ldap_string_prepàs‹€ô—‘ÐOÐQSÐU[Ó\ˆÜ—‘Ð@À#ÀvÓNˆÜ �>‰>˜VÒ #ô—V‘VÐTÐVXÐZ`Óa‰Fä—V‘VÐTÐVXÐZ`ÓaˆFÜ—‘ð Kà Ø ó  ˆð —‘ ¨"Ó-ˆÜ—‘ÐTÐVYÐ[aÓbˆà—‘œœZ×4Ñ4°fÓ=Ó>ˆô×&Ñ& v¨vÓ6ˆóˆDÜ×%Ñ% dÔ+Ü ¤ðó"óðô ×%Ñ% dÔ+Ü ¤ðó"óðô×%Ñ% dÔ+Ü ¤ðó"óðô ×%Ñ% dÔ+Ü ¤ðó"óðô ×%Ñ% dÔ+Ü ¤ðó"óðð �xÓÜ ¤ðó"óððMð\!ÐØˆ ÛˆDÜ×%Ñ% dÔ+Ø#'Ñ Ü×'Ñ'¨Õ-Ø ‘ ð ñ Ü *× 6Ñ 6°v¸a±yÓ AÐ Ü)×5Ñ5°f¸R±jÓAÐ áÑ 1Ñ9IÜ ¤ðó"óðð”r—v‘v˜d D¨&Ó1×7Ñ7Ó9Ñ9¸CÑ?ˆàˆ rD)rYrZr[rärr´Ú _oid_pairrÛr&r#rlr7r.Ú _oid_specsrr�r!rBrIr r=rDrArrŒsî„à �ÐØ �#ˆð€Gð "€Ið%Ø�ð%à�?ð%ð ˜ð%ð ˜ð %ð ˜ð %ð ! /ð %ð ˜/ð%ð ˜_ð%ð # Oð%ð �ð%ð ˜_ð%ð �ð%ð ˜Oð%ð �ð%ð �oð%ð �Oð!%ð"  ñ#%ð$ ˜^ð%%ð& ˜ð'%ð( �_ð)%ð, ˜ð-%ð0 ! /ð1%ð2 *¨?ð3%ð4  ð5%ð6 ˜Gð7%ð8 ˜oð9%ð: " ?ð;%ð< ˜Jð=%ð> �Zð?%ð@ �zðA%ðB  ðC%ðD ˜*ðE%ðF ˜JðG%ðH �?ñI%€JðN€Hà ñ óð ò!ò9ó&jrDrcó8—eZdZeZed„«Zd„Zd„Zd„Z d„Z y)ÚRelativeDistinguishedNamecó¸—g}|j|«}t|j««D]}|j|›d||›�«Œdj |«S)úb :return: A unicode string that can be used as a dict key or in a set ú: Ú)Ú _get_valuesÚsortedÚkeysÚappendr,)r?Úoutputr³Úkeys rAÚhashablez"RelativeDistinguishedName.hashablePsT€ðˆØ×!Ñ! $Ó'ˆÜ˜&Ÿ+™+›-Ö(ˆCØ �M‰M¢c¨6°#ª;Ð7Õ 8ð)ð �{‰{˜6Ó"Ð"rDcó—||k( Sr<r=r>s rArBz RelativeDistinguishedName.__ne__`rCrDcó—t|t«syt|«t|«k7ry|j|«}|j|«}||k7ry|j |«}|j |«}|D]}||||k7sŒyy)zÌ Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.1 :param other: Another RelativeDistinguishedName object :return: A boolean FT)rFrBr™Ú _get_typesrG)r?r@Ú self_typesÚ other_typesÚ self_valuesÚ other_valuesÚ type_name_s rArIz RelativeDistinguishedName.__eq__cs�€ô˜%Ô!:Ô;Øä ˆt‹9œ˜E› Ò "Øà—_‘_ TÓ*ˆ Ø—o‘o eÓ,ˆ à ˜Ò $Øà×&Ñ& tÓ,ˆ Ø×'Ñ'¨Ó.ˆ ã$ˆJؘ:Ñ&¨,°zÑ*BÓBÙð%ðrDcóX—t|D�cgc]}|dj‘Œc}«Scc}w)zò Returns a set of types contained in an RDN :param rdn: A RelativeDistinguishedName object :return: A set object with unicode strings of NameTypeAndValue type field values r²)rXrd)r?ÚrdnÚntvs rArPz$RelativeDistinguishedName._get_typesƒs+€ô±#Ó6±#¨3�C˜‘K×&Ó&°#Ñ6Ó7Ð7ùÒ6sŠ'có†—i}|D�cgc]-}|j|dj|jfg«‘Œ/c}|Scc}w)a$ Returns a dict of prepped values contained in an RDN :param rdn: A RelativeDistinguishedName object :return: A dict object with unicode strings of NameTypeAndValue value field values that have been prepped for comparison r²)Úupdaterdr!)r?rWrKrXs rArGz%RelativeDistinguishedName._get_values‘sG€ðˆÙMPÓQÉSÀcˆ�‰˜˜V™×+Ñ+¨S×->Ñ->Ð?Ð@Õ AÈSÒQ؈ ùò Rs‡2>N) rYrZr[rr·r�rMrBrIrPrGr=rDrArBrBMs.„Ø"€Kà ñ #óð #ò!òò@ 8órDrBcó,—eZdZeZed„«Zd„Zd„Zy)Ú RDNSequencecó2—djd„|D««S)rDÚc3ó4K—|]}|j–—Œy­wr<)rM)Ú.0rWs rAÚ z'RDNSequence.hashable..¯sèø€Ð8±4¨C˜3Ÿ<�<±4ùs‚)r,rjs rArMzRDNSequence.hashable¥s€ð�{‰{Ñ8±4Ó8Ó8Ð8rDcó—||k( Sr<r=r>s rArBzRDNSequence.__ne__±rCrDcó�—t|t«syt|«t|«k7ryt|«D]\}}|||k7sŒyy)z¾ Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.1 :param other: Another RDNSequence object :return: A boolean FT)rFr\r™Ú enumerate)r?r@r Úself_rdns rArIzRDNSequence.__eq__´sJ€ô˜%¤Ô-Øä ˆt‹9œ˜E› Ò "Øä(¨ž‰OˆE�8Ø�U‰|˜xÓ'Ùð /ðrDN) rYrZr[rBr·r�rMrBrIr=rDrAr\r\¢s#„Ø+€Kà ñ 9óð 9ò!órDr\cóœ—eZdZdefgZdZdZdZed d„«Z e d„«Z d„Z d„Z d„Ze d„«Ze d „«Zd „Ze d „«Ze d „«Zy)rrhNc óú—g}|s d}t}nd}t}tt|j «d„¬««}|j «D]œ\}}t j |«}|dk(r t|«}nJ|dk(r t|«}n9|tgd¢«vrtdt|«¬«}nt|||«¬«}|jtt||d œ«g««Œž|d t|«¬«S) aY Creates a Name object from a dict of unicode string keys and values. The keys should be from NameType._map, or a dotted-integer OID unicode string. :param name_dict: A dict of name information, e.g. {"common_name": "Will Bond", "country_name": "US", "organization_name": "Codex Non Sufficit LC"} :param use_printable: A bool - if PrintableString should be used for encoding instead of UTF8String. This is for backwards compatibility with old software. :return: An x509.Name object rßrÝcó2—tj|d«S)Nr)rär)Úitems rAÚzName.build..ôs€¤×!;Ñ!;¸DÀ¹GÔ!DrD)rLrr)r÷rèrç)ròrVrrh)r.r&r rHÚitemsrärrlr7rXrÛrJrBrr\) r Ú name_dictÚ use_printableÚrdnsÚ encoding_nameÚencoding_classÚattribute_nameÚattribute_valuerVs rAÚbuildz Name.buildÕs €ð&ˆÙØ)ˆMÜ'‰Nà.ˆMÜ,ˆNô Ü Ø—‘Ó!ÙDô ó ˆ ð09¯©Ö/@Ñ +ˆN˜OÜ%Ÿ\™\¨.Ó9ˆNØ Ò0Ü$ _Ó5‘ØÐ#5Ò5Ü Ó0‘ؤ3Ò'XÓ#YÑYÜ'Ø+Ü)¨/Ó:ô‘ô (Ø&Ù(¨Ó9ô�ð �K‰KÔ1Ü Ø*Ø"ñ"óð3óõ ð#0Añ0˜¤+¨dÓ"3Ô4Ð4rDcó.—|jjS)rD)ÚchosenrMrjs rArMz Name.hashables€ð�{‰{×#Ñ#Ð#rDcó,—t|j«Sr<)r™rurjs rAÚ__len__z Name.__len__s€Ü�4—;‘;ÓÐrDcó—||k( Sr<r=r>s rArBz Name.__ne__rCrDcóV—t|t«sy|j|jk(S)z· Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.1 :param other: Another Name object :return: A boolean F)rFrrur>s rArIz Name.__eq__!s$€ô˜%¤Ô&ØØ�{‰{˜eŸl™lÑ*Ð*rDcój—|j€œt«|_|jjD]t}|D]m}|d}||jvrF|j|}t |t «s|gx}|j|<|j |d«Œ\|d|j|<ŒoŒv|jS)Nr²rV)ršr rurdrFÚlistrJ)r?rWÚtype_valÚ field_nameÚexistings rArdz Name.native0s¦€à �<‰<Ð Ü&›=ˆDŒLØ—{‘{×)Ô)�Û #�HØ!)¨&Ñ!1�JØ! T§\¡\Ñ1Ø#'§<¡<° Ñ#;˜Ü)¨(´DÔ9ØCKÀ*ÐL˜H t§|¡|°JÑ'?Ø Ÿ™¨°Ñ(9Õ:à3;¸GÑ3D˜Ÿ ™  ZÒ0ñ!$ð*ð�|‰|ÐrDcó:—|j�€t«}d}|jD]G}|D]@}|dj}|}||vr!||g||<||j |d«Œ9|d||<ŒBŒIg}|j «}|dk(rt t|««}|D].}||} |j| «} |j |›d| ›�«Œ0d} |D]} | jd«dk7sŒd } n| sd nd } | j|ddd…«|_|jS) zg :return: A human-friendly unicode string containing the parts of the name Nr²rVrrEFÚ,rsTú, z; ) Ú_human_friendlyr rurrJrIÚreversedr{Ú_recursive_humanizervr,)r?ÚdataÚ last_fieldrWr|r}Úto_joinrIrLrVÚ native_valueÚ has_commaÚelementÚ separators rArzName.human_friendly@s@€ð × Ñ Ñ 'Ü“=ˆD؈JØ—{”{�Û #�HØ!)¨&Ñ!1×!@Ñ!@�JØ!+�JØ! TÑ)Ø,0°Ñ,<Ð+=˜˜ZÑ(ؘZÑ(×/Ñ/°¸Ñ0AÕBà+3°GÑ+<˜˜ZÒ(ñ!$ð#ðˆGØ—9‘9“;ˆDؘYÒ&ܤ T£ Ó+�Û�ؘS™ �Ø#×7Ñ7¸Ó>� Ø—‘ª3± Ð=Õ>ðð ˆIÛ"�Ø—<‘< Ó$¨Ó*Ø $�IÙð#ñ %.™°4ˆIØ#,§>¡>°'¹$¸B¸$±-Ó#@ˆDÔ à×#Ñ#Ð#rDc ó²—t|t«r7djt|D�cgc]}|j |«‘Œc}««S|j Scc}w)zÑ Recursively serializes data compiled from the RDNSequence :param value: An Asn1Value object, or a list of Asn1Value objects :return: A unicode string r�)rFr{r,rƒr„rd)r?rVÚ sub_values rAr„zName._recursive_humanizegsS€ô �eœTÔ "Ø—9‘9ÜÉuÓUÉuÀ)˜$×2Ñ2°9Õ=ÈuÑUÓVóð ð�|‰|ÐùòVs¥A cóž—|j€6tj|j««j «|_|jS)zZ :return: The SHA1 hash of the DER-encoded bytes of this name ©Ú_sha1ÚhashlibÚsha1ÚdumpÚdigestrjs rAr’z Name.sha1xó7€ð �:‰:Ð Ü Ÿ™ d§i¡i£kÓ2×9Ñ9Ó;ˆDŒJØ�z‰zÐrDcóž—|j€6tj|j««j «|_|jS)z] :return: The SHA-256 hash of the DER-encoded bytes of this name ©Ú_sha256r‘Úsha256r“r”rjs rAr™z Name.sha256ƒs7€ð �<‰<Ð Ü"Ÿ>™>¨$¯)©)«+Ó6×=Ñ=Ó?ˆDŒLØ�|‰|ÐrD)F)rYrZr[r\râr‚r�r˜rrsr�rMrwrBrIrdrr„r’r™r=rDrArrÌs®„à ˆ[Ðð€Mð€OØ €EØ€Gàò:5óð:5ðxñ$óð$ò ò!ò +ðñ óð ðñ$$óð$$òLð"ñóððñóñrDrcó"—eZdZdefdeddifgZy)Ú AnotherNameÚtype_idrVÚexplicitrN)rYrZr[r"rr´r=rDrAr›r›�s „à Ð$Ð%Ø �#˜  A�Ð'ð�GrDr›có$—eZdZdZdZdefdefgZy)Ú CountryNamer Ú x121_dcc_codeÚiso_3166_alpha2_codeN©rYrZr[Úclass_Útagr!r&râr=rDrArŸrŸ–s%„Ø €FØ €Cð ˜-Ð(Ø  Ð1ð�MrDrŸcó$—eZdZdZdZdefdefgZy)ÚAdministrationDomainNamer r‘ÚnumericÚ printableNr¢r=rDrAr¦r¦ s%„Ø €FØ €Cð �MÐ"Ø �oÐ&ð�MrDr¦có—eZdZdefdefgZy)ÚPrivateDomainNamer§r¨N©rYrZr[r!r&râr=rDrArªrªªs„à �MÐ"Ø �oÐ&ð�MrDrªcóF—eZdZdeddifdedddœfded ddœfd ed ddœfgZy ) Ú PersonalNamerærÏrrór TrÎrôr‘rõrÅN©rYrZr[r&r´r=rDrAr­r­±sD„à �O j°! _Ð5Ø �°QÀDÑ(IÐJØ �_°1À$Ñ&GÐHØ  ¸qÈdÑ2SÐTð �GrDr­cóF—eZdZdeddifdedddœfded ddœfd ed ddœfgZy ) ÚTeletexPersonalNamerærÏrrór TrÎrôr‘rõrÅN©rYrZr[r+r´r=rDrAr°r°ºsD„à �M J° ?Ð3Ø �}°1À$Ñ&GÐHØ �]°ÀÑ$EÐFØ  ¸QÈDÑ0QÐRð �GrDr°có—eZdZeZy)ÚOrganizationalUnitNamesN©rYrZr[r&r·r=rDrAr³r³Ãó„Ø!�KrDr³có—eZdZeZy)ÚTeletexOrganizationalUnitNamesN)rYrZr[r+r·r=rDrAr·r·Çó„Ø�KrDr·c óŠ—eZdZdeddifdeddifdedddœfded ddœfd ed dd œfd edddœfdedddœfdedddœfde dddœfg Z y)ÚBuiltInStandardAttributesrèrÐTÚadministration_domain_nameÚnetwork_addressrrÎÚterminal_identifierr Úprivate_domain_namer‘©r�rÐrìrÅÚnumeric_user_identifierr¦Ú personal_namerÆÚorganizational_unit_namesrÇN) rYrZr[rŸr¦r!r&rªr­r³r´r=rDrArºrºËs”„à ˜ z°4Ð&8Ð9Ø %Ð'?À*ÈdÐASÐTØ ˜M¸ÀtÑ+LÐMØ  ¸aÈTÑ1RÐSØ Ð 1ÀÈtÑ3TÐUØ ˜o¸AÈ4Ñ/PÐQØ " MÀÈtÑ3TÐUØ ˜,°QÀDÑ(IÐJØ $Ð&=ÈAÐ[_Ñ?`Ðað �GrDrºcó—eZdZdefdefgZy)ÚBuiltInDomainDefinedAttributer²rVNr®r=rDrArÄrÄÙs„à �Ð!Ø �/Ð"ð�GrDrÄcó—eZdZeZy)ÚBuiltInDomainDefinedAttributesN)rYrZr[rÄr·r=rDrArÆrÆàó„Ø/�KrDrÆcó—eZdZdefdefgZy)ÚTeletexDomainDefinedAttributer²rVNr±r=rDrArÉrÉäs„à �ÐØ �-Ð ð�GrDrÉcó—eZdZeZy)ÚTeletexDomainDefinedAttributesN)rYrZr[rÉr·r=rDrArËrËërÇrDrËcó—eZdZdefdefgZy)ÚPhysicalDeliveryCountryNamer r¡Nr«r=rDrArÍrÍïs„à ˜-Ð(Ø  Ð1ð�MrDrÍcó—eZdZdefdefgZy)Ú PostalCodeÚ numeric_codeÚprintable_codeNr«r=rDrArÏrÏös„à ˜Ð'Ø ˜?Ð+ð�MrDrÏcó(—eZdZdeddifdeddifgZy)Ú PDSParameterrÝrÐTrÜN)rYrZr[r&r+r´r=rDrArÓrÓýs'„à ˜_¨z¸4Ð.@ÐAØ ˜=¨:°tÐ*<Ð=ð�GrDrÓcó—eZdZeZy)ÚPrintableAddressNr´r=rDrArÕrÕrµrDrÕcó(—eZdZdeddifdeddifgZy)ÚUnformattedPostalAddressÚprintable_addressrÐTrÜN)rYrZr[rÕr+r´r=rDrAr×r×s(„à Ð.°¸TÐ0BÐCØ ˜=¨:°tÐ*<Ð=ð�GrDr×có*—eZdZdeddifdedddœfgZy) Ú E1634AddressÚnumberrÏrÚ sub_addressr TrÎN)rYrZr[r!r´r=rDrArÚrÚs&„à �= :¨q /Ð2Ø ˜ °AÀ4Ñ'HÐIð�GrDrÚcó—eZdZeZy)Ú NAddressesN)rYrZr[r$r·r=rDrArÞrÞó„Ø�KrDrÞcóF—eZdZdedddœfdedddœfdedddœfd ed d ifgZy ) ÚPresentationAddressÚ p_selectorrTr¿Ú s_selectorr Ú t_selectorr‘Ú n_addressesr�rÅN)rYrZr[r$rÞr´r=rDrArárásD„à �{°ÀÑ$EÐFØ �{°ÀÑ$EÐFØ �{°ÀÑ$EÐFØ ˜  Z° OÐ4ð �GrDrácó"—eZdZdefdeddifgZy)ÚExtendedNetworkAddressÚe163_4_addressÚ psap_addressrÏrN)rYrZr[rÚrárâr=rDrArçrç#s „à ˜<Ð(Ø Ð,¨z¸1¨oÐ>ð�MrDrçcó—eZdZdddddddœZy) Ú TerminalTypeÚtelexrØÚ g3_facsimileÚ g4_facsimileÚ ia5_terminalÚvideotex)rÅr¦rÆrÇrÈr“NrÉr=rDrArërë*s„à Ø Ø Ø Ø Ø ñ  �DrDrëcóˆ—eZdZidd“dd“dd“dd“d d “d d “d d“dd“dd“dd“dd“dd“dd“dd“dd“dd “d!d"“d#d$d%d&d'd(d)œ¥Zy*)+ÚExtensionAttributeTyper rår‘Úteletex_common_namerÅÚteletex_organization_namer¦Úteletex_personal_namerÆÚteletex_organization_unit_namesrÇÚ!teletex_domain_defined_attributesrÈÚpds_namer“Úphysical_delivery_country_nameé rðé Úphysical_delivery_office_nameé Úphysical_delivery_office_numberr9Úextension_of_address_componentsé Úphysical_delivery_personal_nameéÚ#physical_delivery_organization_nameéÚ.extension_physical_delivery_address_componentsr¥Úunformatted_postal_addressérëÚpost_office_box_addressÚposte_restante_addressÚunique_postal_nameÚlocal_postal_attributesÚextended_network_addressÚ terminal_type)ér:ééééNrÉr=rDrAròrò5sø„ð Ø ˆ=ð à Ð ð ð Ð &ð ð Ð "ð  ð Ð ,ð  ð Ð .ð  ð ˆ:ð ð Ð +ð ð ˆ=ð ð Ð +ð ð Ð -ð ð Ð -ð ð Ð -ð ð Ð 1ð ð Ð <ð ð Ð (ð! ð" Ð ð# ð$ &Ø $Ø Ø %Ø &Ø ò/ �DrDròcó¨—eZdZdeddifdeddifgZdZide“d e“d e“d e “d e “d e “de“de “de “de“de“de“de“de“de“de“de“eeeeeedœ¥Zy)ÚExtensionAttributeÚextension_attribute_typerÏrÚextension_attribute_valuer�r )rrrårórôrõrör÷rørùrðrürþrÿrrrrrë)rr r r r r N)rYrZr[ròrr´r?r&r+r°r·rËrÍrÏrÓr×rçrër@r=rDrArrQs„à #Ð%;¸jÈ!¸_ÐMØ $ c¨J¸¨?Ð;ð€Gð J€IðØ�ðà˜}ðð $ ]ðð Ð!4ð ð *Ð+Ið ð ,Ð-Kð ð �Oðð )Ð*Eðð �zðð (¨ðð *¨<ðð *¨<ðð *¨<ðð .¨|ðð 9¸,ðð %Ð&>ð!ð" ˜,ð#ð$$0Ø".Ø*Ø#/Ø$:Ø%ò/�JrDrcó—eZdZeZy)ÚExtensionAttributesN)rYrZr[rr·r=rDrArrsó„Ø$�KrDrcó.—eZdZdefdeddifdeddifgZy)Ú ORAddressÚbuilt_in_standard_attributesÚ"built_in_domain_defined_attributesrÐTÚextension_attributesN)rYrZr[rºrÆrr´r=rDrArrws4„à 'Ð)BÐCØ -Ð/MÐPZÐ\`ÐOaÐbØ Ð!4°zÀ4Ð6HÐIð�GrDrcó*—eZdZdedddœfdeddifgZy) Ú EDIPartyNameÚ name_assignerrTrÎÚ party_namerÏr N)rYrZr[rÛr´r=rDrAr r s&„à ˜/¸ÀtÑ+LÐMØ �¨°Q¨Ð8ð�GrDr c óˆ—eZdZdeddifdeddifdeddifdedd ifd ed d ifd eddifde ddifde ddifde ddifg Z d„Z d„Zy)Ú GeneralNameÚ other_namerÏrÚ rfc822_namer Údns_namer‘Ú x400_addressrÅÚdirectory_namer�r¦Úedi_party_namerÆÚuniform_resource_identifierrÇÚ ip_addressrÈÚ registered_idr“có—||k( Sr<r=r>s rArBzGeneralName.__ne__“rCrDcó—|jdvrttd|j««‚|jdvrttd|j««‚|j|jk7ry|j|jk(S)z¼ Does not support other_name, x400_address or edi_party_name :param other: The other GeneralName to compare to :return: A boolean )r%r(r*zr Comparison is not supported for GeneralName objects of choice %s za Comparison is not supported for GeneralName objects of choice %sF)ròr†r rur>s rArIzGeneralName.__eq__–sŒ€ð �9‰9ÐHÑ HÜœVðð— ‘ ó óð ð �:‰:ÐIÑ IÜœVðð— ‘ ó óð ð �9‰9˜Ÿ ™ Ò "Øà�{‰{˜eŸl™lÑ*Ð*rDN)rYrZr[r›rlr7rrr r^r„r"rârBrIr=rDrAr$r$†s’„à �{ Z° OÐ4Ø ˜  z°1 oÐ6Ø �W˜z¨1˜oÐ.Ø ˜ Z° OÐ4Ø ˜4 *¨a Ð1Ø ˜<¨*°a¨Ð9Ø &¨¨j¸!¨_Ð=Ø �y :¨q /Ð2Ø Ð*¨Z¸¨OÐ<ð €Mò!ó+rDr$có—eZdZeZy)Ú GeneralNamesN)rYrZr[r$r·r=rDrAr1r1¸rßrDr1có—eZdZdefdefgZy)ÚTimeÚutc_timeÚ general_timeN)rYrZr[r-rrâr=rDrAr3r3¼s„à �WÐØ ˜Ð)ð�MrDr3có—eZdZdefdefgZy)ÚValidityrÍrÑN)rYrZr[r3r´r=rDrAr7r7Ãs„à �tÐØ �dÐð�GrDr7có(—eZdZdeddifdeddifgZy)ÚBasicConstraintsÚcaÚdefaultFÚpath_len_constraintrÐTN)rYrZr[rrr´r=rDrAr9r9Ês'„à ˆw˜ EÐ*Ð+Ø  ¨*°dÐ);Ð<ð�GrDr9có:—eZdZdedddœfdedddœfdedddœfgZy ) ÚAuthorityKeyIdentifierÚkey_identifierrTrÎÚauthority_cert_issuerr Úauthority_cert_serial_numberr‘N)rYrZr[r$r1rr´r=rDrAr>r>Ñs6„à ˜;°QÀDÑ(IÐJØ  ,¸QÈDÑ0QÐRØ '¨¸qÈdÑ2SÐTð�GrDr>có(—eZdZdeddifdeddifgZy)ÚDistributionPointNameÚ full_namerÏrÚname_relative_to_crl_issuerr N)rYrZr[r1rBrâr=rDrArCrCÙs'„à �l Z° OÐ4Ø &Ð(AÀJÐPQÀ?ÐSð�MrDrCc ó$—eZdZddddddddd d œ Zy ) Ú ReasonFlagsÚunusedÚkey_compromiseÚ ca_compromiseÚaffiliation_changedÚ supersededÚcessation_of_operationÚcertificate_holdÚprivilege_withdrawnÚ aa_compromiserÄNrÉr=rDrArGrGàs$„à Ø Ø Ø Ø Ø #Ø Ø Ø ñ �DrDrGcó2—eZdZdefdedddœfdedddœfgZy ) ÚGeneralSubtreeÚbaseÚminimumr©rÏr;Úmaximumr TrÎN)rYrZr[r$rr´r=rDrArRrRîs/„à �ÐØ �G¨!¸Ñ:Ð;Ø �G¨!¸Ñ>Ð?ð�GrDrRcó—eZdZeZy)ÚGeneralSubtreesN)rYrZr[rRr·r=rDrArXrXös„Ø �KrDrXcó,—eZdZdedddœfdedddœfgZy)ÚNameConstraintsÚpermitted_subtreesrTrÎÚexcluded_subtreesr N)rYrZr[rXr´r=rDrArZrZús'„à ˜¸QÈDÑ0QÐRØ ˜o¸AÈ4Ñ/PÐQð�GrDrZcóN—eZdZdedddœfdedddœfded ddœfgZd Zed „«Z y ) ÚDistributionPointÚdistribution_pointrTr¿Úreasonsr rÎÚ crl_issuerr‘FcóT—|jdur�d|_|d}|jdk7rttd««‚|jD]Q}|jdk(sŒ|j }|j «jd«sŒ?||_|jS|jS)z_ :return: None or a unicode string of the distribution point's URL FNr_rDz‡ CRL distribution points that are relative to the issuer are not supported r+©zhttp://zhttps://zldap://zldaps://)Ú_urlròr†r rurdrHrO)r?ròÚ general_nameÚurls rArfzDistributionPoint.url s¦€ð �9‰9˜Ñ ؈DŒIØÐ,Ñ-ˆDØ�y‰y˜KÒ'Ü ¤ðó"óðð!%§ ¤ � Ø×$Ñ$Ð(EÓEØ&×-Ñ-�CØ—y‘y“{×-Ñ-Ð.\Õ]Ø$'˜œ Øà�y‰yÐð!,ð�y‰yÐrDN) rYrZr[rCrGr1r´rdr�rfr=rDrAr^r^sQ„à Ð4À1ÐRVÑ6WÐXØ �K¨a¸TÑ!BÐCØ �|°!ÀÑ%FÐGð€Gð €Dà ñóñrDr^có—eZdZeZy)ÚCRLDistributionPointsN)rYrZr[r^r·r=rDrArhrh&ó„Ø#�KrDrhcó(—eZdZdefdefdefdefgZy)Ú DisplayTextráÚvisible_stringràrßN)rYrZr[rr/rr.râr=rDrArkrk*s)„à �yÐ!Ø ˜=Ð)Ø �yÐ!Ø ˜ Ð#ð �MrDrkcó—eZdZeZy)Ú NoticeNumbersN©rYrZr[rr·r=rDrArnrn3ó„Ø�KrDrncó—eZdZdefdefgZy)ÚNoticeReferenceÚ organizationÚnotice_numbersN)rYrZr[rkrnr´r=rDrArrrr7s„à ˜Ð%Ø ˜=Ð)ð�GrDrrcó(—eZdZdeddifdeddifgZy)Ú UserNoticeÚ notice_refrÐTÚ explicit_textN)rYrZr[rrrkr´r=rDrArvrv>s'„à �¨°TÐ(:Ð;Ø ˜+¨ °DÐ'9Ð:ð�GrDrvcó—eZdZdddœZy)ÚPolicyQualifierIdÚ certification_practice_statementÚ user_notice)z1.3.6.1.5.5.7.2.1z1.3.6.1.5.5.7.2.2NrÉr=rDrArzrzEs„à?Ø*ñ �DrDrzcó*—eZdZdefdefgZdZeedœZ y)ÚPolicyQualifierInfoÚpolicy_qualifier_idÚ qualifier)rr€)r{r|N) rYrZr[rzrr´r?rrvr@r=rDrAr~r~Ls.„à Ð 1Ð2Ø �cÐð€Gð 5€Ià,5Ø!ñ�JrDr~có—eZdZeZy)ÚPolicyQualifierInfosN)rYrZr[r~r·r=rDrAr‚r‚Yó„Ø%�KrDr‚có—eZdZddiZy)ÚPolicyIdentifierz 2.5.29.32.0Ú any_policyNrÉr=rDrAr…r…]s„à�|ð �DrDr…có"—eZdZdefdeddifgZy)ÚPolicyInformationÚpolicy_identifierÚpolicy_qualifiersrÐTN)rYrZr[r…r‚r´r=rDrArˆrˆcs"„à Ð.Ð/Ø Ð2°ZÀÐ4FÐGð�GrDrˆcó—eZdZeZy)ÚCertificatePoliciesN)rYrZr[rˆr·r=rDrArŒrŒjrirDrŒcó—eZdZdefdefgZy)Ú PolicyMappingÚissuer_domain_policyÚsubject_domain_policyN)rYrZr[r…r´r=rDrArŽrŽns„à Ð!1Ð2Ø Ð"2Ð3ð�GrDrŽcó—eZdZeZy)ÚPolicyMappingsN)rYrZr[rŽr·r=rDrAr’r’ur¸rDr’có,—eZdZdedddœfdedddœfgZy)ÚPolicyConstraintsÚrequire_explicit_policyrTrÎÚinhibit_policy_mappingr N©rYrZr[rr´r=rDrAr”r”ys'„à " G¸!ÈÑ-NÐOØ ! 7¸ÈÑ,MÐNð�GrDr”có—eZdZidd“dd“dd“dd“d d “d d “d d“dd“dd“dd“dd“dd“dd“dd“dd“dd “d!d"“id#d$“d%d&“d'd(“d)d*“d+d,“d-d.“d/d0“d1d2“d3d4“d5d6“d7d8“d9d:“d;d<“d=d>“d?d@“dAdB“dCdD“¥idEdF“dGdH“dIdJ“dKdL“dMdN“dOdP“dQdR“dSdT“dUdV“dWdX“dYdZ“d[d\“d]d^“d_d`“dadb“dcdd“dedf“¥idgdh“didj“dkdl“dmdn“dodp“dqdr“dsdt“dudv“dwdx“dydz“d{d|“d}d~“dd€“d�d‚“dƒd„“d…d†“d‡dˆ“¥id‰dŠ“d‹dŒ“d�dŽ“d�d�“d‘d’“d“d”“d•d–“d—d˜“d™dš“d›dœ“d�dž“dŸd “d¡d¢“d£d¤“d¥d¦“d§d¨“d©dª“¥Zy«)¬Ú KeyPurposeIdz 2.5.29.37.0Úany_extended_key_usagez1.3.6.1.5.5.7.3.1Ú server_authz1.3.6.1.5.5.7.3.2Ú client_authz1.3.6.1.5.5.7.3.3Ú code_signingz1.3.6.1.5.5.7.3.4Úemail_protectionz1.3.6.1.5.5.7.3.5Úipsec_end_systemz1.3.6.1.5.5.7.3.6Ú ipsec_tunnelz1.3.6.1.5.5.7.3.7Ú ipsec_userz1.3.6.1.5.5.7.3.8Ú time_stampingz1.3.6.1.5.5.7.3.9Ú ocsp_signingz1.3.6.1.5.5.7.3.10Údvcsz1.3.6.1.5.5.7.3.13Ú eap_over_pppz1.3.6.1.5.5.7.3.14Ú eap_over_lanz1.3.6.1.5.5.7.3.15Ú scvp_serverz1.3.6.1.5.5.7.3.16Ú scvp_clientz1.3.6.1.5.5.7.3.17Ú ipsec_ikez1.3.6.1.5.5.7.3.18Ú capwap_acz1.3.6.1.5.5.7.3.19Ú capwap_wtpz1.3.6.1.5.5.7.3.20Ú sip_domainz1.3.6.1.5.5.7.3.21Úsecure_shell_clientz1.3.6.1.5.5.7.3.22Úsecure_shell_serverz1.3.6.1.5.5.7.3.23Ú send_routerz1.3.6.1.5.5.7.3.24Úsend_proxied_routerz1.3.6.1.5.5.7.3.25Ú send_ownerz1.3.6.1.5.5.7.3.26Úsend_proxied_ownerz1.3.6.1.5.5.7.3.27Úcmc_caz1.3.6.1.5.5.7.3.28Úcmc_raz1.3.6.1.5.5.7.3.29Ú cmc_archivez1.3.6.1.5.5.7.3.30Úbgpspec_routerz1.3.6.1.5.5.8.2.2Úike_intermediatez1.3.6.1.4.1.311.10.3.1Úmicrosoft_trust_list_signingz1.3.6.1.4.1.311.10.3.2Úmicrosoft_time_stamp_signingz1.3.6.1.4.1.311.10.3.3Úmicrosoft_server_gatedz1.3.6.1.4.1.311.10.3.3.1Úmicrosoft_serializedz1.3.6.1.4.1.311.10.3.4Ú microsoft_efsz1.3.6.1.4.1.311.10.3.4.1Úmicrosoft_efs_recoveryz1.3.6.1.4.1.311.10.3.5Úmicrosoft_whqlz1.3.6.1.4.1.311.10.3.6Ú microsoft_nt5z1.3.6.1.4.1.311.10.3.7Úmicrosoft_oem_whqlz1.3.6.1.4.1.311.10.3.8Úmicrosoft_embedded_ntz1.3.6.1.4.1.311.10.3.9Úmicrosoft_root_list_signerz1.3.6.1.4.1.311.10.3.10Ú!microsoft_qualified_subordinationz1.3.6.1.4.1.311.10.3.11Úmicrosoft_key_recoveryz1.3.6.1.4.1.311.10.3.12Úmicrosoft_document_signingz1.3.6.1.4.1.311.10.3.13Úmicrosoft_lifetime_signingz1.3.6.1.4.1.311.10.3.14Ú microsoft_mobile_device_softwarez1.3.6.1.4.1.311.20.2.2Úmicrosoft_smart_card_logonz1.2.840.113635.100.1.2Úapple_x509_basicz1.2.840.113635.100.1.3Ú apple_sslz1.2.840.113635.100.1.4Úapple_local_cert_genz1.2.840.113635.100.1.5Ú apple_csr_genz1.2.840.113635.100.1.6Úapple_revocation_crlz1.2.840.113635.100.1.7Úapple_revocation_ocspz1.2.840.113635.100.1.8Ú apple_smimez1.2.840.113635.100.1.9Ú apple_eapz1.2.840.113635.100.1.10Úapple_software_update_signingz1.2.840.113635.100.1.11Ú apple_ipsecz1.2.840.113635.100.1.12Ú apple_ichatz1.2.840.113635.100.1.13Úapple_resource_signingz1.2.840.113635.100.1.14Úapple_pkinit_clientz1.2.840.113635.100.1.15Úapple_pkinit_serverz1.2.840.113635.100.1.16Úapple_code_signingz1.2.840.113635.100.1.17Úapple_package_signingz1.2.840.113635.100.1.18Úapple_id_validationz1.2.840.113635.100.1.20Úapple_time_stampingz1.2.840.113635.100.1.21Úapple_revocationz1.2.840.113635.100.1.22Úapple_passbook_signingz1.2.840.113635.100.1.23Úapple_mobile_storez1.2.840.113635.100.1.24Úapple_escrow_servicez1.2.840.113635.100.1.25Úapple_profile_signerz1.2.840.113635.100.1.26Úapple_qa_profile_signerz1.2.840.113635.100.1.27Úapple_test_mobile_storez1.2.840.113635.100.1.28Úapple_otapki_signerz1.2.840.113635.100.1.29Úapple_test_otapki_signerz1.2.840.113625.100.1.30Ú)apple_id_validation_record_signing_policyz1.2.840.113625.100.1.31Úapple_smp_encryptionz1.2.840.113625.100.1.32Úapple_test_smp_encryptionz1.2.840.113635.100.1.33Úapple_server_authenticationz1.2.840.113635.100.1.34Úapple_pcs_escrow_servicez2.16.840.1.101.3.6.8Úpiv_card_authenticationz2.16.840.1.101.3.6.7Úpiv_content_signingz1.3.6.1.5.2.3.4Úpkinit_kpclientauthz1.3.6.1.5.2.3.5Ú pkinit_kpkdcz1.2.840.113583.1.1.5Úadobe_authentic_documents_trustz2.16.840.1.101.3.8.7Úfpki_pivi_content_signingNrÉr=rDrAr™r™€s„ðl àÐ/ðl ð ˜]ðl ð ˜]ð l ð ˜^ð l ð Ð/ð l ð Ð/ðl ð ˜^ðl ð ˜\ðl ð ˜_ðl ð ˜^ðl ð ˜fðl ð ˜nðl ð ˜nð!l ð$ ˜mð%l ð& ˜mð'l ð* ˜kð+l ð. ˜kñ/l ð0 ˜lð1l ð4 ˜lð5l ð8 Ð3ð9l ð: Ð3ð;l ð> ˜mð?l ð@ Ð3ðAl ðB ˜lðCl ðD Ð2ðEl ðH ˜hðIl ðJ ˜hðKl ðL ˜mðMl ðP Ð.ðQl ðT Ð/ðUl ðZ !Ð"@ð[l ð\ !Ð"@ð]l ð^ !Ð":ð_l ð` #Ð$:òal ðb ! /ðcl ðd #Ð$<ðel ðf !Ð"2ðgl ðh ! /ðil ðj !Ð"6ðkl ðl !Ð"9ðml ðn !Ð">ðol ðp "Ð#Fðql ðr "Ð#;ðsl ðt "Ð#?ðul ðv "Ð#?ðwl ðx "Ð#Eðyl ð| !Ð">ð}l ðD !Ð"4ðEl ðF ! +ðGl ðH !Ð"8ðIl ðJ ! /òKl ðL !Ð"8ðMl ðN !Ð"9ðOl ðP ! -ðQl ðR ! +ðSl ðT "Ð#BðUl ðV " =ðWl ðX " =ðYl ðZ "Ð#;ð[l ð\ "Ð#8ð]l ð^ "Ð#8ð_l ð` "Ð#7ðal ðb "Ð#:ðcl ðd "Ð#8ðel ðf "Ð#8ðgl ðh "Ð#5ðil ðj "Ð#;ðkl ðl "Ð#7òml ðn "Ð#9ðol ðp "Ð#9ðql ðr "Ð#<ðsl ðt "Ð#<ðul ðv "Ð#8ðwl ðx "Ð#=ðyl ðz "Ð#Nð{l ð| "Ð#9ð}l ð~ "Ð#>ðl ð@ "Ð#@ðAl ðB "Ð#=ðCl ðF Ð 9ðGl ðH Ð 5ðIl ðL Ð0ðMl ðN ˜>ðOl ðR Ð AðSl ðV Ð ;ñWl �DrDr™có—eZdZeZy)ÚExtKeyUsageSyntaxN©rYrZr[r™r·r=rDrArðrððó„Ø�KrDrðcó—eZdZdddddœZy)Ú AccessMethodÚocspÚ ca_issuersr¢Ú ca_repository)z1.3.6.1.5.5.7.48.1z1.3.6.1.5.5.7.48.2z1.3.6.1.5.5.7.48.3z1.3.6.1.5.5.7.48.5NrÉr=rDrArôrôôs„à$Ø*Ø-Ø-ñ  �DrDrôcó—eZdZdefdefgZy)ÚAccessDescriptionÚ access_methodÚaccess_locationN)rYrZr[rôr$r´r=rDrArùrùýs„à ˜,Ð'Ø ˜KÐ(ð�GrDrùcó—eZdZeZy)ÚAuthorityInfoAccessSyntaxN©rYrZr[rùr·r=rDrArýrýrirDrýcó—eZdZeZy)ÚSubjectInfoAccessSyntaxNrþr=rDrArrrirDrcó—eZdZeZy)ÚFeaturesNror=rDrArr rprDrcó—eZdZdefdefgZy)ÚEntrustVersionInfoÚ entrust_versÚentrust_info_flagsN)rYrZr[rrr´r=rDrArrs„à ˜Ð'Ø ˜yÐ)ð�GrDrc ó"—eZdZddddddddd œZy ) ÚNetscapeCertificateTypeÚ ssl_clientÚ ssl_serverÚemailÚobject_signingÚreservedÚssl_caÚemail_caÚobject_signing_ca)rr r‘rÅr¦rÆrÇrÈNrÉr=rDrArrs!„à Ø Ø Ø Ø Ø Ø Ø ñ �DrDrcó—eZdZddddœZy)ÚVersionÚv1Úv2Úv3©rr r‘NrÉr=rDrArr%s„à Ø Ø ñ �DrDrcó"—eZdZdefdefdefgZy)ÚTPMSpecificationr ÚlevelÚrevisionN)rYrZr[r.rr´r=rDrArr-s!„à �:ÐØ �'ÐØ �WÐð�GrDrcó—eZdZeZy)ÚSetOfTPMSpecificationN)rYrZr[rr·r=rDrArr5s„Ø"�KrDrcó"—eZdZdefdefdefgZy)ÚTCGSpecificationVersionÚ major_versionÚ minor_versionrNr—r=rDrArr9s!„à ˜'Ð"Ø ˜'Ð"Ø �WÐð�GrDrcó—eZdZdefdefgZy)ÚTCGPlatformSpecificationÚversionÚplatform_classN)rYrZr[rr$r´r=rDrAr"r"As„à Ð+Ð,Ø ˜;Ð'ð�GrDr"có—eZdZeZy)ÚSetOfTCGPlatformSpecificationN)rYrZr[r"r·r=rDrAr&r&Hs„Ø*�KrDr&có—eZdZdddddœZy)ÚEKGenerationTypeÚinternalÚinjectedÚinternal_revocableÚinjected_revocable)rr r‘rÅNrÉr=rDrAr(r(Ls„à Ø Ø Ø ñ  �DrDr(có—eZdZddddœZy)ÚEKGenerationLocationrúrýÚek_cert_signerrNrÉr=rDrAr.r.Uó„à Ø "Ø ñ �DrDr.có—eZdZddddœZy)ÚEKCertificateGenerationLocationrúrýr/rNrÉr=rDrAr2r2]r0rDr2có —eZdZddddddddœZy ) ÚEvaluationAssuranceLevelÚlevel1Úlevel2Úlevel3Úlevel4Úlevel5Úlevel6Úlevel7)r r‘rÅr¦rÆrÇrÈNrÉr=rDrAr4r4es„à Ø Ø Ø Ø Ø Ø ñ �DrDr4có—eZdZddddœZy)ÚEvaluationStatusÚdesigned_to_meetÚevaluation_in_progressÚevaluation_completedrNrÉr=rDrAr=r=qs„à Ø #Ø !ñ �DrDr=có—eZdZddddœZy)ÚStrengthOfFunctionÚbasicÚmediumÚhighrNrÉr=rDrArBrBys„à Ø Ø ñ �DrDrBcó.—eZdZdefdeddifdeddifgZy)Ú URIReferencer+Úhash_algorithmrÐTÚ hash_valueN)rYrZr[rrrr´r=rDrArGrG�s/„à &¨ Ð2Ø ˜?¨Z¸Ð,>Ð?Ø �y :¨tÐ"4Ð5ð�GrDrGc ót—eZdZdefdefdefdeddifdedd d œfd ed d d œfd e dd d œfdedd d œfde dd d œfg Z y)ÚCommonCriteriaMeasuresr#Úassurance_levelÚevaluation_statusÚplusr;FÚstrengh_of_functionrTrÎÚ profile_oidr Ú profile_urlr‘Ú target_oidrÅÚ target_urir¦N) rYrZr[rr4r=rrBr"rGr´r=rDrArKrK‰s�„à �IÐØ Ð4Ð5Ø Ð.Ð/Ø �˜9 eÐ,Ð-Ø Ð 2ÀÐPTÑ4UÐVØ Ð(°qÀdÑ*KÐLØ ˜ °1À$Ñ&GÐHØ Ð'°aÀTÑ)JÐKØ �|°!ÀÑ%FÐGð �GrDrKcó—eZdZdddddœZy)Ú SecurityLevelr5r6r7r8)r r‘rÅr¦NrÉr=rDrArUrU—s„à Ø Ø Ø ñ  �DrDrUcó(—eZdZdefdefdeddifgZy)Ú FIPSLevelr#rrNr;FN)rYrZr[rrUrr´r=rDrArWrW s(„à �IÐØ �-Ð Ø �˜9 eÐ,Ð-ð�GrDrWc óˆ—eZdZdeddifdeddifdeddd œfd ed dd œfd ed dd œfdeddd œfde ddd œfdedddœfde ddifg Z y)ÚTPMSecurityAssertionsr#r;rÚfield_upgradableFÚek_generation_typerTrÎÚek_generation_locationr Ú"ek_certificate_generation_locationr‘Úcc_inforÅÚ fips_levelr¦Úiso_9000_certifiedrÆrUÚ iso_9000_urirÐN) rYrZr[rrr(r.r2rKrWrr´r=rDrArYrY¨s—„à �G˜i¨Ð.Ð/Ø ˜W y°%Ð&8Ð9Ø Ð/¸aÈTÑ1RÐSØ !Ð#7ÀaÐUYÑ9ZÐ[Ø -Ð/NÐ]^ÐlpÑPqÐrØ Ð*¸ÈÑ,MÐNØ �y¨q¸dÑ"CÐDØ ˜w°QÀ5Ñ(IÐJØ ˜ Z°Ð$6Ð7ð �GrDrYcó—eZdZeZy)ÚSetOfTPMSecurityAssertionsN)rYrZr[rYr·r=rDrArcrc¶s„Ø'�KrDrcc ó&—eZdZddddddddd d d œ Zy ) ÚSubjectDirectoryAttributeIdÚsupported_algorithmsÚtpm_specificationÚtcg_platform_specificationÚtpm_security_assertionsÚpda_date_of_birthÚpda_place_of_birthÚ pda_genderÚpda_country_of_citizenshipÚpda_country_of_residenceÚentrust_user_role) z2.5.4.52z 2.23.133.2.16z 2.23.133.2.17z 2.23.133.2.18z1.3.6.1.5.5.7.9.1z1.3.6.1.5.5.7.9.2z1.3.6.1.5.5.7.9.3z1.3.6.1.5.5.7.9.4z1.3.6.1.5.5.7.9.5z1.2.840.113533.7.68.29NrÉr=rDrArereºs)„ð+à,Ø5Ø2à0Ø1Ø)Ø9Ø7à"5ñ �DrDrecó—eZdZeZy)ÚSetOfGeneralizedTimeN)rYrZr[rr·r=rDrArqrqÍrµrDrqcó—eZdZeZy)ÚSetOfDirectoryStringN)rYrZr[rÛr·r=rDrArsrsÑrµrDrscó—eZdZeZy)ÚSetOfPrintableStringNr´r=rDrAruruÕrµrDrucó2—eZdZdefdedddœfdedddœfgZy) ÚSupportedAlgorithmÚalgorithm_identifierÚintended_usagerTr¿Úintended_certificate_policiesr N)rYrZr[rrºrŒr´r=rDrArwrwÙs2„à Ð!7Ð8Ø ˜8°!ÀÑ%FÐGØ (Ð*=ÈAÐ[_Ñ?`Ðað�GrDrwcó—eZdZeZy)ÚSetOfSupportedAlgorithmN)rYrZr[rwr·r=rDrAr|r|árrDr|c óF—eZdZdefdefgZdZeee e e e e e e dœ Zd„ZdeiZy)ÚSubjectDirectoryAttributer²r³)r²r³) rfrgrhrirjrkrlrmrncóf—|dj}||jvr|j|StS)Nr²)rdr@r*)r?Útype_s rAÚ _values_specz&SubjectDirectoryAttribute._values_specøs1€Ø�V‘ ×#Ñ#ˆØ �D—O‘OÑ #Ø—?‘? 5Ñ)Ð )܈ rDN)rYrZr[rerr´r?r|rr&rcrqrsrur@r�Ú_spec_callbacksr=rDrAr~r~åsU„à Ð,Ð-Ø �3ˆð€Gð #€Ià 7Ø2Ø&CØ#=Ø1Ø2Ø*Ø&:Ø$8ñ €Jòð �,ð�OrDr~có—eZdZeZy)ÚSubjectDirectoryAttributesN)rYrZr[r~r·r=rDrAr„r„s„Ø+�KrDr„c óŠ—eZdZidd“dd“dd“dd“d d “d d “d d“dd“dd“dd“dd“dd“dd“dd“dd“dd “d!d"“d#d$d%d&d'd(d)d*œ¥Zy+),Ú ExtensionIdz2.5.29.9Úsubject_directory_attributesz 2.5.29.14r?z 2.5.29.15Ú key_usagez 2.5.29.16Úprivate_key_usage_periodz 2.5.29.17Úsubject_alt_namez 2.5.29.18Úissuer_alt_namez 2.5.29.19Úbasic_constraintsz 2.5.29.30Úname_constraintsz 2.5.29.31Úcrl_distribution_pointsz 2.5.29.32Úcertificate_policiesz 2.5.29.33Úpolicy_mappingsz 2.5.29.35Úauthority_key_identifierz 2.5.29.36Úpolicy_constraintsz 2.5.29.37Úextended_key_usagez 2.5.29.46Ú freshest_crlz 2.5.29.54Úinhibit_any_policyz1.3.6.1.5.5.7.1.1Úauthority_information_accessÚsubject_information_accessÚ tls_featureÚ ocsp_no_checkÚentrust_version_extensionÚnetscape_certificate_typeÚ!signed_certificate_timestamp_listÚmicrosoft_enroll_certtype)z1.3.6.1.5.5.7.1.11z1.3.6.1.5.5.7.1.24z1.3.6.1.5.5.7.48.1.5z1.2.840.113533.7.65.0z2.16.840.1.113730.1.1z1.3.6.1.4.1.11129.2.4.2z1.3.6.1.4.1.311.20.2NrÉr=rDrAr†r†sü„ð ØÐ2ð àÐ%ð ð �[ð ð Ð/ð  ð Ð'ð  ð Ð&ð  ð Ð(ð ð Ð'ð ð Ð.ð ð Ð+ð ð Ð&ð ð Ð/ð ð Ð)ð ð Ð)ð ð �^ð ð Ð)ð! ð" Ð;ð# ð$;à+Ø /Ø!<Ø!<à#Fà ;ò7 �DrDr†c óª—eZdZdefdeddifdefgZdZide“de “d e “d e “d e “d e “d e “de“de“de“de“de“de“de“de“de“de“eeeeee edœ¥Zy)Ú ExtensionÚextn_idÚcriticalr;FÚ extn_value)r r¢r‡r?rˆr‰rŠr‹rŒr�rŽr�r�r‘r’r“r”r•r–)r—r˜r™ršr›rœr�N)rYrZr[r†rr%r´r?r„r$rºrÌr1r9rZrhrŒr’r>r”rðrrýrrr rrrr@r=rDrArŸrŸ's'„à �KÐ Ø �W˜y¨%Ð0Ð1Ø Ð*Ð+ð€Gð *€IðØ&Ð(Bðà˜+ðð �Xðð #Ð$9ð ð ˜Lð ð ˜<ð ð Ð-ðð ˜Oðð "Ð#8ðð Ð 3ðð ˜>ðð #Ð$:ðð Ð/ðð Ð/ðð Ð-ðð ˜gð!ð" 'Ð(Að#ð$'>ØØØ%7Ø%<Ø-8ð&/ò5�JrDrŸcó—eZdZeZy)Ú ExtensionsN)rYrZr[rŸr·r=rDrAr¤r¤Mr¸rDr¤cól—eZdZdedddœfdefdefdefdefd efd efd e d d dœfde dd dœfde dd dœfg Z y)ÚTbsCertificater#rr)r�r;rçÚ signatureÚissuerÚvalidityÚsubjectÚsubject_public_key_infoÚissuer_unique_idr TrÎÚsubject_unique_idr‘Ú extensionsrÅr¿N) rYrZr[rrrrr7r1r#r¤r´r=rDrAr¦r¦Qsv„à �G¨!¸Ñ=Ð>Ø ˜'Ð"Ø Ð+Ð,Ø �4ÐØ �XÐØ �DÐØ " MÐ2Ø ˜^¸!ÈÑ-NÐOØ ˜n¸1È$Ñ.OÐPØ �z°¸tÑ#DÐEð �GrDr¦có°—eZdZdefdefdefgZdZdZdZ dZ dZ dZ dZ dZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ dZ!dZ"dZ#dZ$dZ%dZ&d„Z'e(d„«Z)e(d„«Z*e(d „«Z+e(d „«Z,e(d „«Z-e(d „«Z.e(d „«Z/e(d„«Z0e(d„«Z1e(d„«Z2e(d„«Z3e(d„«Z4e(d„«Z5e(d„«Z6e(d„«Z7e(d„«Z8e(d„«Z9e(d„«Z:e(d„«Z;e(d„«Ze(d„«Z?e(d„«Z@e(d„«ZAe(d „«ZBe(d!„«ZCe(d"„«ZDe(d#„«ZEe(d$„«ZFe(d%„«ZGe(d&„«ZHe(d'„«ZIe(d(„«ZJe(d)„«ZKe(d*„«ZLd+„ZMe(d,„«ZNe(d-„«ZOe(d.„«ZPe(d/„«ZQe(d0„«ZRe(d1„«ZSe(d2„«ZTe(d3„«ZUe(d4„«ZVe(d5„«ZWe(d6„«ZXd7„ZYd8„ZZd9„Z[y):Ú CertificateÚtbs_certificateÚsignature_algorithmÚsignature_valueFNcó—t«|_|ddD]g}|dj}d|z}t||«rt |||dj «|djsŒM|jj |«Œid|_y) zv Sets common named extensions to private attributes and creates a list of critical extensions r±r®r z _%s_valuer¢r¡TN)rXÚ_critical_extensionsrdÚhasattrÚsetattrÚparsedÚaddÚ_processed_extensions)r?Ú extensionròrqs rAÚ_set_extensionszCertificate._set_extensionsˆsŠ€ô %(£EˆÔ!àÐ/Ñ0°Ô>ˆIؘYÑ'×.Ñ.ˆDØ(¨4Ñ/ˆNÜ�t˜^Ô,ܘ˜n¨i¸ Ñ.E×.LÑ.LÔMؘÑ$×+Ó+Ø×)Ñ)×-Ñ-¨dÕ3ð ?ð&*ˆÕ"rDcóR—|js|j«|jS)z² Returns a set of the names (or OID if not a known extension) of the extensions marked as critical :return: A set of unicode strings )rºr¼rµrjs rAÚcritical_extensionszCertificate.critical_extensionsšs%€ð×)Ò)Ø × Ñ Ô "Ø×(Ñ(Ð(rDcóR—|js|j«|jS)z¼ This extension is used to constrain the period over which the subject private key may be used :return: None or a PrivateKeyUsagePeriod object )rºr¼Ú_private_key_usage_period_valuerjs rAÚprivate_key_usage_period_valuez*Certificate.private_key_usage_period_value¨ó%€ð×)Ò)Ø × Ñ Ô "Ø×3Ñ3Ð3rDcóR—|js|j«|jS)z½ This extension is used to contain additional identification attributes about the subject. :return: None or a SubjectDirectoryAttributes object )rºr¼Ú#_subject_directory_attributes_valuerjs rAÚ"subject_directory_attributes_valuez.Certificate.subject_directory_attributes_value¶ó%€ð×)Ò)Ø × Ñ Ô "Ø×7Ñ7Ð7rDcóR—|js|j«|jS)zü This extension is used to help in creating certificate validation paths. It contains an identifier that should generally, but is not guaranteed to, be unique. :return: None or an OctetString object )rºr¼Ú_key_identifier_valuerjs rAÚkey_identifier_valuez Certificate.key_identifier_valueÄs%€ð×)Ò)Ø × Ñ Ô "Ø×)Ñ)Ð)rDcóR—|js|j«|jS)z« This extension is used to define the purpose of the public key contained within the certificate. :return: None or a KeyUsage )rºr¼Ú_key_usage_valuerjs rAÚkey_usage_valuezCertificate.key_usage_valueÓs%€ð×)Ò)Ø × Ñ Ô "Ø×$Ñ$Ð$rDcóR—|js|j«|jS)aT This extension allows for additional names to be associate with the subject of the certificate. While it may contain a whole host of possible names, it is usually used to allow certificates to be used with multiple different domain names. :return: None or a GeneralNames object )rºr¼Ú_subject_alt_name_valuerjs rAÚsubject_alt_name_valuez"Certificate.subject_alt_name_valueás%€ð×)Ò)Ø × Ñ Ô "Ø×+Ñ+Ð+rDcóR—|js|j«|jS)z¿ This extension allows associating one or more alternative names with the issuer of the certificate. :return: None or an x509.GeneralNames object )rºr¼Ú_issuer_alt_name_valuerjs rAÚissuer_alt_name_valuez!Certificate.issuer_alt_name_valueñs%€ð×)Ò)Ø × Ñ Ô "Ø×*Ñ*Ð*rDcóR—|js|j«|jS)a' This extension is used to determine if the subject of the certificate is a CA, and if so, what the maximum number of intermediate CA certs after this are, before an end-entity certificate is found. :return: None or a BasicConstraints object )rºr¼Ú_basic_constraints_valuerjs rAÚbasic_constraints_valuez#Certificate.basic_constraints_valueÿs%€ð×)Ò)Ø × Ñ Ô "Ø×,Ñ,Ð,rDcóR—|js|j«|jS)zà This extension is used in CA certificates, and is used to limit the possible names of certificates issued. :return: None or a NameConstraints object )rºr¼Ú_name_constraints_valuerjs rAÚname_constraints_valuez"Certificate.name_constraints_value s%€ð×)Ò)Ø × Ñ Ô "Ø×+Ñ+Ð+rDcóR—|js|j«|jS)zµ This extension is used to help in locating the CRL for this certificate. :return: None or a CRLDistributionPoints object extension )rºr¼Ú_crl_distribution_points_valuerjs rAÚcrl_distribution_points_valuez)Certificate.crl_distribution_points_value s%€ð×)Ò)Ø × Ñ Ô "Ø×2Ñ2Ð2rDcóR—|js|j«|jS)a; This extension defines policies in CA certificates under which certificates may be issued. In end-entity certificates, the inclusion of a policy indicates the issuance of the certificate follows the policy. :return: None or a CertificatePolicies object )rºr¼Ú_certificate_policies_valuerjs rAÚcertificate_policies_valuez&Certificate.certificate_policies_value* s%€ð×)Ò)Ø × Ñ Ô "Ø×/Ñ/Ð/rDcóR—|js|j«|jS)zû This extension allows mapping policy OIDs to other OIDs. This is used to allow different policies to be treated as equivalent in the process of validation. :return: None or a PolicyMappings object )rºr¼Ú_policy_mappings_valuerjs rAÚpolicy_mappings_valuez!Certificate.policy_mappings_value: s%€ð×)Ò)Ø × Ñ Ô "Ø×*Ñ*Ð*rDcóR—|js|j«|jS)zÏ This extension helps in identifying the public key with which to validate the authenticity of the certificate. :return: None or an AuthorityKeyIdentifier object )rºr¼Ú_authority_key_identifier_valuerjs rAÚauthority_key_identifier_valuez*Certificate.authority_key_identifier_valueI rÂrDcóR—|js|j«|jS)z¹ This extension is used to control if policy mapping is allowed and when policies are required. :return: None or a PolicyConstraints object )rºr¼Ú_policy_constraints_valuerjs rAÚpolicy_constraints_valuez$Certificate.policy_constraints_valueW ó%€ð×)Ò)Ø × Ñ Ô "Ø×-Ñ-Ð-rDcóR—|js|j«|jS)z– This extension is used to help locate any available delta CRLs :return: None or an CRLDistributionPoints object )rºr¼Ú_freshest_crl_valuerjs rAÚfreshest_crl_valuezCertificate.freshest_crl_valuee s%€ð×)Ò)Ø × Ñ Ô "Ø×'Ñ'Ð'rDcóR—|js|j«|jS)z¥ This extension is used to prevent mapping of the any policy to specific requirements :return: None or a Integer object )rºr¼Ú_inhibit_any_policy_valuerjs rAÚinhibit_any_policy_valuez$Certificate.inhibit_any_policy_valuer rèrDcóR—|js|j«|jS)zÖ This extension is used to define additional purposes for the public key beyond what is contained in the basic constraints. :return: None or an ExtKeyUsageSyntax object )rºr¼Ú_extended_key_usage_valuerjs rAÚextended_key_usage_valuez$Certificate.extended_key_usage_value€ rèrDcóR—|js|j«|jS)zâ This extension is used to locate the CA certificate used to sign this certificate, or the OCSP responder for this certificate. :return: None or an AuthorityInfoAccessSyntax object )rºr¼Ú#_authority_information_access_valuerjs rAÚ"authority_information_access_valuez.Certificate.authority_information_access_valueŽ rÆrDcóR—|js|j«|jS)z´ This extension is used to access information about the subject of this certificate. :return: None or a SubjectInfoAccessSyntax object )rºr¼Ú!_subject_information_access_valuerjs rAÚ subject_information_access_valuez,Certificate.subject_information_access_valueœ s%€ð×)Ò)Ø × Ñ Ô "Ø×5Ñ5Ð5rDcóR—|js|j«|jS)zÍ This extension is used to list the TLS features a server must respond with if a client initiates a request supporting them. :return: None or a Features object )rºr¼Ú_tls_feature_valuerjs rAÚtls_feature_valuezCertificate.tls_feature_valueª s%€ð×)Ò)Ø × Ñ Ô "Ø×&Ñ&Ð&rDcóR—|js|j«|jS)a- This extension is used on certificates of OCSP responders, indicating that revocation information for the certificate should never need to be verified, thus preventing possible loops in path validation. :return: None or a Null object (if present) )rºr¼Ú_ocsp_no_check_valuerjs rAÚocsp_no_check_valuezCertificate.ocsp_no_check_value¸ s%€ð×)Ò)Ø × Ñ Ô "Ø×(Ñ(Ð(rDcó —|djS)zE :return: A byte string of the signature r³©rdrjs rAr§zCertificate.signatureÇ s€ðÐ%Ñ&×-Ñ-Ð-rDcó —|djS)zj :return: A unicode string of "rsassa_pkcs1v15", "rsassa_pss", "dsa", "ecdsa" r²)Úsignature_algorjs rArzCertificate.signature_algoÐ s€ðÐ)Ñ*×9Ñ9Ð9rDcó —|djS)zŸ :return: A unicode string of "md2", "md5", "sha1", "sha224", "sha256", "sha384", "sha512", "sha512_224", "sha512_256" r²)Ú hash_algorjs rArzCertificate.hash_algoÙ s€ðÐ)Ñ*×4Ñ4Ð4rDcó—|ddS)zT :return: The PublicKeyInfo object for this certificate r±r«r=rjs rAÚ public_keyzCertificate.public_keyã s€ðÐ%Ñ&Ð'@ÑAÐArDcó—|ddS)zZ :return: The Name object for the subject of this certificate r±rªr=rjs rArªzCertificate.subjectì s€ðÐ%Ñ& yÑ1Ð1rDcó—|ddS)zY :return: The Name object for the issuer of this certificate r±r¨r=rjs rAr¨zCertificate.issuerõ s€ðÐ%Ñ& xÑ0Ð0rDcó&—|ddjS)zT :return: An integer of the certificate's serial number r±rçrÿrjs rArçzCertificate.serial_numberþ s€ðÐ%Ñ& Ñ7×>Ñ>Ð>rDcóH—|jsy|jjS)zŽ :return: None or a byte string of the certificate's key identifier from the key identifier extension N)rÉrdrjs rAr?zCertificate.key_identifier s"€ð×(Ò(Øà×(Ñ(×/Ñ/Ð/rDcó¸—|j€C|jjdzt|j«j d«z|_|jS)zÐ :return: A byte string of the SHA-256 hash of the issuer concatenated with the ascii character ":", concatenated with the serial number as an ascii string ó:rt)Ú_issuer_serialr¨r™rrçrPrjs rAÚ issuer_serialzCertificate.issuer_serial sO€ð × Ñ Ð &Ø"&§+¡+×"4Ñ"4°tÑ";¼gÀd×FXÑFXÓ>Y×>`Ñ>`ÐahÓ>iÑ"iˆDÔ Ø×"Ñ"Ð"rDcó,—|dddjS)zd :return: A datetime of latest time when the certificate is still valid r±r©rÑrÿrjs rAÚnot_valid_afterzCertificate.not_valid_after! s €ð Ð%Ñ& zÑ2°;Ñ?×FÑFÐFrDcó,—|dddjS)zd :return: A datetime of the earliest time when the certificate is valid r±r©rÍrÿrjs rAÚnot_valid_beforezCertificate.not_valid_before) s €ð Ð%Ñ& zÑ2°<Ñ@×GÑGÐGrDcóN—|jsy|jdjS)zŠ :return: None or a byte string of the key_identifier from the authority key identifier extension Nr?)rärdrjs rAr‘z$Certificate.authority_key_identifier1 s(€ð×2Ò2Øà×2Ñ2Ð3CÑD×KÑKÐKrDcó~—|jdur¤|j}|r�|djr€|jddj}|j «}|jdj}|j dzt |«jd«z|_|jSd|_|jS)a; :return: None or a byte string of the SHA-256 hash of the isser from the authority key identifier extension concatenated with the ascii character ":", concatenated with the serial number from the authority key identifier extension as an ascii string Fr@rrAr rtN)Ú_authority_issuer_serialrärdruÚuntagr™rrP)r?Úakivr¨Úauthority_serials rAÚauthority_issuer_serialz#Certificate.authority_issuer_serial> sº€ð × (Ñ (¨EÑ 1Ø×6Ñ6ˆDÙ˜Ð4Ñ5×<Ò<Ø×<Ñ<Ð=TÑUÐVWÑX×_Ñ_�àŸ™›�Ø#'×#FÑ#FÐGeÑ#f×#mÑ#mÐ Ø06· ± ÀÑ0DÄwÐO_ÓG`×GgÑGgÐhoÓGpÑ0p�Ô-ð×,Ñ,Ð,ð15�Ô-Ø×,Ñ,Ð,rDcór—|j€ |j|j«|_|jS)z˜ Returns complete CRL URLs - does not include delta CRLs :return: A list of zero or more DistributionPoint objects )Ú_crl_distribution_pointsÚ!_get_http_crl_distribution_pointsrÛrjs rArŽz#Certificate.crl_distribution_pointsT s6€ð × (Ñ (Ð 0Ø,0×,RÑ,RÐSW×SuÑSuÓ,vˆDÔ )Ø×,Ñ,Ð,rDcór—|j€ |j|j«|_|jS)z˜ Returns delta CRL URLs - does not include complete CRLs :return: A list of zero or more DistributionPoint objects )Ú_delta_crl_distribution_pointsrrërjs rAÚdelta_crl_distribution_pointsz)Certificate.delta_crl_distribution_pointsa s6€ð × .Ñ .Ð 6Ø26×2XÑ2XÐY]×YpÑYpÓ2qˆDÔ /Ø×2Ñ2Ð2rDcóÀ—g}|€gS|D]R}|d}|turŒ|jdk(rŒ!|jD]#}|jdk(sŒ|j|«Œ%ŒT|S)a? Fetches the DistributionPoint object for non-relative, HTTP CRLs referenced by the certificate :param crl_distribution_points: A CRLDistributionPoints object to grab the DistributionPoints from :return: A list of zero or more DistributionPoint objects r_rEr+)r0ròrurJ)r?rŽrKr_Údistribution_point_nameres rArz-Certificate._get_http_crl_distribution_pointsn s{€ðˆà "Ð *؈Iã"9Ð Ø&8Ð9MÑ&NÐ #Ø&¬$Ñ.Øà&×+Ñ+Ð/LÒLØà 7× >Ô >� Ø×$Ñ$Ð(EÓEØ—M‘MÐ"4Õ5ñ!?ð#:ðˆ rDcó—|jsgSg}|jD]g}|djdk(sŒ|d}|jdk7rŒ+|j}|j«j d«sŒW|j |«Œi|S)zx :return: A list of zero or more unicode strings of the OCSP URLs for this cert rúrõrûr+rc)rôrdròrHrOrJ)r?rKÚentryÚlocationrfs rAÚ ocsp_urlszCertificate.ocsp_urls� s†€ð×6Ò6؈IàˆØ×<Ô<ˆEØ�_Ñ%×,Ñ,°Ó6Ø Ð!2Ñ3�Ø—=‘=Ð$AÒAØØ—o‘o�Ø—9‘9“;×)Ñ)Ð*XÕYØ—M‘M #Õ&ð=ðˆ rDcó<—|j�€g|_|jrk|jD]P}|jdk(sŒ|j|jvsŒ,|jj |j«ŒR|jSt j d«}|jjD]X}|D]Q}|djdk(sŒ|dj}|j|«sŒ7|jj |«ŒSŒZ|jS)z» :return: A list of unicode strings of valid domain names for the certificate. Wildcard certificates will have a domain in the form: *.example.com r'zE^(\*\.)?(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-]*[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$r²rårV) Ú_valid_domainsrÏròrdrJr'ÚcompilerªruÚmatch)r?reÚpatternrWÚname_type_valuerVs rAÚ valid_domainszCertificate.valid_domains£ sþ€ð × Ñ Ñ &Ø"$ˆDÔ ð ×*Ò*Ø$(×$?Ô$?�LØ#×(Ñ(¨JÓ6¸<×;NÑ;NÐVZ×ViÑViÒ;iØ×+Ñ+×2Ñ2°<×3FÑ3FÕGð%@ð$×"Ñ"Ð"ôŸ*™*Ð%pÓq�ØŸ<™<×.Ô.�CÛ+.˜Ø*¨6Ñ2×9Ñ9¸]ÓJØ$3°GÑ$<×$CÑ$C˜EØ&Ÿ}™}¨UÕ3Ø $× 3Ñ 3× :Ñ :¸5Õ Añ ,/ð/ð×"Ñ"Ð"rDcóä—|j€Yg|_|jrF|jD]7}|jdk(sŒ|jj|j«Œ9|jS)zj :return: A list of unicode strings of valid IP addresses for the certificate r,)Ú _valid_ipsrÏròrJrd)r?res rAÚ valid_ipszCertificate.valid_ipsÆ sa€ð �?‰?Ð "Ø ˆDŒOà×*Ò*Ø$(×$?Ô$?�LØ#×(Ñ(¨LÓ8ØŸ™×.Ñ.¨|×/BÑ/BÕCð%@ð�‰ÐrDcóP—|jxr|jdjS)zW :return; A boolean - if the certificate is marked as a CA r:)rÕrdrjs rAr:zCertificate.ca× s&€ð×+Ñ+ÒY°×0LÑ0LÈTÑ0R×0YÑ0YÐYrDcóN—|jsy|jdjS)zT :return; None or an integer of the maximum path length Nr<)r:rÕrdrjs rAÚmax_path_lengthzCertificate.max_path_lengthà s&€ð�wŠwØØ×+Ñ+Ð,AÑB×IÑIÐIrDcón—|j€|j|jk(|_|jS)zx :return: A boolean - if the certificate is self-issued, as defined by RFC 5280 )Ú _self_issuedrªr¨rjs rAÚ self_issuedzCertificate.self_issuedë s1€ð × Ñ Ð $Ø $§ ¡ °· ± Ñ ;ˆDÔ Ø× Ñ Ð rDcó—|j€qd|_|jr^|jrK|jsd|_|jS|j|jk(rd|_|jSd|_|jS)aõ :return: A unicode string of "no" or "maybe". The "maybe" result will be returned if the certificate issuer and subject are the same. If a key identifier and authority key identifier are present, they will need to match otherwise "no" will be returned. To verify is a certificate is truly self-signed, the signature will need to be verified. See the certvalidator package for one possible solution. ÚnoÚmaybe)Ú _self_signedr4r?r‘rjs rAÚ self_signedzCertificate.self_signed÷ s‹€ð × Ñ Ð $Ø $ˆDÔ Ø×ÒØ×&Ò&Ø×8Ò8Ø,3˜Ô)ð × Ñ Ð ð ×6Ñ6¸$×:MÑ:MÒMØ,3˜Ô)ð× Ñ Ð ð)0�DÔ%Ø× Ñ Ð rDcóž—|j€6tj|j««j «|_|jS)zk :return: The SHA-1 hash of the DER-encoded bytes of this complete certificate r�rjs rAr’zCertificate.sha1 r•rDcóX—djd„t|j«D««S)z¯ :return: A unicode string of the SHA-1 hash, formatted using hex encoding with a space between each pair of characters, all uppercase r%c3ó&K—|] }d|z–—Œ y­w©z%02XNr=©r`Úcs rAraz/Certificate.sha1_fingerprint..$ sèø€ÐEÑ,D q˜ � Ñ,Dùó‚)r,rr’rjs rAÚsha1_fingerprintzCertificate.sha1_fingerprint s"€ð�x‰xÑE¬M¸$¿)¹)Ô,DÓEÓEÐErDcóž—|j€6tj|j««j «|_|jS)zy :return: The SHA-256 hash of the DER-encoded bytes of this complete certificate r—rjs rAr™zCertificate.sha256& s7€ð �<‰<Ð Ü"Ÿ>™>¨$¯)©)«+Ó6×=Ñ=Ó?ˆDŒLØ�|‰|ÐrDcóX—djd„t|j«D««S)z± :return: A unicode string of the SHA-256 hash, formatted using hex encoding with a space between each pair of characters, all uppercase r%c3ó&K—|] }d|z–—Œ y­wr=r=r>s rAraz1Certificate.sha256_fingerprint..: sèø€ÐGÑ,F q˜ � Ñ,Fùr@)r,rr™rjs rAÚsha256_fingerprintzCertificate.sha256_fingerprint2 s"€ð�x‰xÑG¬M¸$¿+¹+Ô,FÓGÓGÐGrDcóÀ—t|t«sttdt |«««‚|j d«j d«j«}|jd«dk7}| xrtjd|«}| xr| }|r¶|jsy|jd«}|jD]ˆ}|j d«j d«j«}|jd«} t| «t|«k7rŒZ| |k(ry |j|«} | sŒu|j|| «sŒˆy y|j sy|rt"j$nt"j&} t)| |«} |j D]I} | jd«dk7rt"j$nt"j&}t)|| «}|| k(sŒIy y) a Check if a domain name or IP address is valid according to the certificate :param domain_ip: A unicode string of a domain name or IP address :return: A boolean - if the domain or IP is valid for the certificate zL domain_ip must be a unicode string, not %s rrtrŒrsz^\d+\.\d+\.\d+\.\d+$FrLT)rFrrNr rrPr|rHrvr'r(r+r”r™Ú_is_wildcard_domainÚ_is_wildcard_matchr.r–r˜r—r5)r?Ú domain_ipÚencoded_domain_ipÚis_ipv6Úis_ipv4Ú is_domainÚ domain_labelsÚ valid_domainÚencoded_valid_domainÚvalid_domain_labelsÚ is_wildcardr Ú normalized_ipÚvalid_ipÚ valid_familyÚnormalized_valid_ips rAÚis_valid_domain_ipzCertificate.is_valid_domain_ip< s¾€ô˜)¤WÔ-ÜœFðô˜)Ó$ó óð ð&×,Ñ,¨VÓ4×;Ñ;¸GÓD×JÑJÓLÐà#×(Ñ(¨Ó-°Ñ3ˆØ�+Ò\¤"§(¡(Ð+HÐJ[Ó"\ˆØ�KÒ/¨ Kˆ ñ Ø×%Ò%Øà-×3Ñ3°CÓ8ˆMà $× 2Ô 2� Ø'3×':Ñ':¸6Ó'B×'IÑ'IÈ'Ó'R×'XÑ'XÓ'ZÐ$Ø&:×&@Ñ&@ÀÓ&EÐ#ôÐ*Ó+¬s°=Ó/AÒAØà&¨-Ò7Ùà"×6Ñ6Ð7KÓL� Ú 4×#:Ñ#:¸=ÐJ]Õ#^Ùð!3ðð�~Š~Øá#*”—’´·±ˆÜ! &Ð*;Ó<ˆ àŸœˆHØ-5¯]©]¸3Ó-?À2Ò-Eœ6Ÿ>š>Ì6Ï?É?ˆLÜ"+¨L¸(Ó"CÐ à" mÓ3Ùð 'ðrDcóº—|jd«dk7ry|j«jd«}|sy|djd«dk(ry|ddddk(ryy ) af Checks if a domain is a valid wildcard according to https://tools.ietf.org/html/rfc6125#section-6.4.3 :param domain: A unicode string of the domain name, where any U-labels from an IDN have been converted to A-labels :return: A boolean - if the domain is a valid wildcard domain Ú*r FrLrrsr¦zxn--T)ÚcountrHr”rv)r?ÚdomainÚlabelss rArGzCertificate._is_wildcard_domain~ sh€ð �<‰<˜Ó  Ò !Øà—‘“×%Ñ% cÓ*ˆáØð �!‰9�>‰>˜#Ó  "Ò $Øð �!‰9�Q�qˆ>˜VÒ #ØàrDcó¾—|d}|dd}|d}|dd}||k7ry|dk(rytjd|jdd«zd z«}|j|«ryy) aÿ Determines if the labels in a domain are a match for labels from a wildcard valid domain name :param domain_labels: A list of unicode strings, with A-label form for IDNs, of the labels in the domain name to check :param valid_domain_labels: A list of unicode strings, with A-label form for IDNs, of the labels in a wildcard domain pattern :return: A boolean - if the domain matches the valid domain rr NFrYTÚ^z.*Ú$)r'r'r+r()r?rNrQÚfirst_domain_labelÚother_domain_labelsÚwildcard_labelÚother_valid_domain_labelsÚwildcard_regexs rArHzCertificate._is_wildcard_matchŸ s†€ð"+¨1Ñ-ÐØ+¨A¨BÐ/Ðà,¨QÑ/ˆØ$7¸¸Ð$;Ð!ð Ð";Ò ;Øà ˜SÒ ØäŸ™ C¨.×*@Ñ*@ÀÀdÓ*KÑ$KÈcÑ$QÓRˆØ × Ñ Ð 2Ô 3ØàrD)\rYrZr[r¦rr#r´rºrµrÄrÈrËrÎrÑrÔr×rÚrÝràrãrærêrírðrórörÀrùrür rrrr&r-r3r8r�r˜r¼r�r¾rÁrÅrÉrÌrÏrÒrÕrØrÛrÞrárärçrërîrñrôr÷rúrýr§rrrrªr¨rçr?r rrr‘rrŽrrr$r+r.r:r1r4r9r’rAr™rErWrGrHr=rDrAr°r°`s¶„à ˜NÐ+Ø Ð 5Ð6Ø ˜NÐ+ð€Gð "ÐØÐØ*.Ð'Ø ÐØÐØ"ÐØ!ÐØ#ÐØ"ÐØ%)Ð"Ø"&ÐØ!ÐØ&*Ð#Ø $ÐØÐØ $ÐØ $ÐØ*.Ð'Ø(,Ð%Ø&*Ð#ØÐØÐØ€NØ$ÐØ#ÐØ%)Ð"Ø€NØ€JØ€LØ€LØ €EØ€Gò*ð$ñ )óð )ðñ 4óð 4ðñ 8óð 8ðñ *óð *ðñ %óð %ðñ ,óð ,ðñ +óð +ðñ -óð -ðñ ,óð ,ðñ 3óð 3ðñ 0óð 0ðñ +óð +ðñ 4óð 4ðñ .óð .ðñ (óð (ðñ .óð .ðñ .óð .ðñ 8óð 8ðñ 6óð 6ðñ 'óð 'ðñ )óð )ðñ.óð.ðñ:óð:ðñ5óð5ðñBóðBðñ2óð2ðñ1óð1ðñ?óð?ðñ 0óð 0ðñ #óð #ðñGóðGðñHóðHðñ Lóð Lðñ-óð-ð*ñ -óð -ðñ 3óð 3òð>ñóðð*ñ #óð #ðDñóðð ñZóðZðñJóðJðñ !óð !ðñ!óð!ð2ñóððñFóðFðñ óð ðñHóðHò@òDóB#rDr°có—eZdZeZy)ÚKeyPurposeIdentifiersNrñr=rDrArfrfÉ ròrDrfcó—eZdZeZy)ÚSequenceOfAlgorithmIdentifiersN)rYrZr[rr·r=rDrArhrhÍ rƒrDrhc óP—eZdZdeddifdedddœfdeddifdeddifd ed ddœfgZy ) ÚCertificateAuxÚtrustrÐTÚrejectrrÎÚaliasÚkeyidr@r N)rYrZr[rfr.r$rhr´r=rDrArjrjÑ sW„à Ð'¨*°dÐ);Ð<Ø Ð(°qÀdÑ*KÐLØ �*˜z¨4Ð0Ð1Ø �+  ¨DÐ1Ð2Ø Ð0¸qÈdÑ2SÐTð �GrDrjcó—eZdZeegZy)ÚTrustedCertificateN)rYrZr[r°rjÚ _child_specsr=rDrArprpÛ s „Ø Ð0�LrDrp)¶rÖÚ __future__rrrrÚ contextlibrÚ encodingsrr‘r'r–r-r)r/Ú_errorsr Ú_irir r Ú _ordereddictr Ú_typesrrrÚalgosrrrrÚcorerrrrrrrrrrrr r!r"r#r$r%r&r'r(r)r*r+r,r-r.r/r0rIr1Úutilr2r3r4r5r7r^rlr„r±r¶rºrÌrÓrÙrÛrärrBr\rr›rŸr¦rªr­r°r³r·rºrÄrÆrÉrËrÍrÏrÓrÕr×rÚrÞrárçrëròrrrr r$r1r3r7r9r>rCrGrRrXrZr^rhrkrnrrrvrzr~r‚r…rˆrŒrŽr’r”r™rðrôrùrýrrrrrrrrr"r&r(r.r2r4r=rBrGrKrUrWrYrcrerqrsrurwr|r~r„r†rŸr¤r¦r°rfrhrjrpr=rDrAÚr|súðñ ÷SÓRå%ÝÛÛ Û ÛÛ Ûåß(Ý%ß5Ñ5ßfÓf÷÷÷÷÷÷÷óõ< ßDÓDô2 ˆiô2 ôj6ˆ)ô6ôrn�9ônôbB5� ôB5ôJ�ôô�ôô ˆyô ô˜Hôô˜]ôð0ñ=óð=ô �fô ôQ(ÐôQ(ôh~�xô~ôBR ôRôj'�*ô'ôT@ˆ6ô@ôF�(ôô�&ôô˜vôô˜ôô�3ôô˜#ôô"˜jô"ô  Zô ô  ô ô Hôô0 Zô0ô Hôô0 Zô0ô &ôô�ôô�3ôô"�zô"ô˜sôô�8ôô�ôô˜(ôô˜Vôô�7ôô˜Wôô8˜ôôD%˜*ô%ô�ôô�8ôô/+�&ô/+ôd�:ôôˆ6ôôˆxôô�xôô˜Xôô˜Fôô �)ô ô�Xôô!�jô!ô�hôô"˜ô"ôJ$˜Jô$ô�&ôô�Jôô�hôô�ôôÐ(ôô ˜(ô ô&˜:ô&ôÐ'ôô ˜ôô$˜*ô$ô�Hôô �Zô ô˜ôômÐ#ômô`˜ ôôÐ#ôô˜ôô$  ô$ô$˜jô$ô ˆzôô˜ôô ˜iô ôˆgôô�xôô#˜Eô#ô˜hôô˜xôô+ Eô+ô�zôô˜:ôô jôô ˜zô ô�zôô˜ôô�8ôô ˜Xô ô�Jôô�ôô ˜Hô ô( ô(ôÐ"2ôô&"˜5ô"ô"˜5ô"ô"˜5ô"ô˜ôô%˜eô%ô ôô<, ô,ôÐ"ôô@#�ô#ôL�ôô �Xô ôb �(ôb ôR˜Jôô& Zô&ô�Xôô1˜õ1rD