1# -*- coding: utf-8 -*-
2#
3# (c) 2016, Yanis Guenane <yanis+ansible@guenane.org>
4#
5# Ansible is free software: you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation, either version 3 of the License, or
8# (at your option) any later version.
9#
10# Ansible is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
17#
18# ----------------------------------------------------------------------
19# A clearly marked portion of this file is licensed under the BSD license
20# Copyright (c) 2015, 2016 Paul Kehrer (@reaperhulk)
21# Copyright (c) 2017 Fraser Tweedale (@frasertweedale)
22# For more details, search for the function _obj2txt().
23# ---------------------------------------------------------------------
24# A clearly marked portion of this file is extracted from a project that
25# is licensed under the Apache License 2.0
26# Copyright (c) the OpenSSL contributors
27# For more details, search for the function _OID_MAP.
28
29from __future__ import absolute_import, division, print_function
30__metaclass__ = type
31
32
33import sys
34from distutils.version import LooseVersion
35
36try:
37    import OpenSSL
38    from OpenSSL import crypto
39except ImportError:
40    # An error will be raised in the calling class to let the end
41    # user know that OpenSSL couldn't be found.
42    pass
43
44try:
45    import cryptography
46    from cryptography import x509
47    from cryptography.hazmat.backends import default_backend as cryptography_backend
48    from cryptography.hazmat.primitives.serialization import load_pem_private_key
49    from cryptography.hazmat.primitives import hashes
50    from cryptography.hazmat.primitives import serialization
51    import ipaddress
52
53    # Older versions of cryptography (< 2.1) do not have __hash__ functions for
54    # general name objects (DNSName, IPAddress, ...), while providing overloaded
55    # equality and string representation operations. This makes it impossible to
56    # use them in hash-based data structures such as set or dict. Since we are
57    # actually doing that in openssl_certificate, and potentially in other code,
58    # we need to monkey-patch __hash__ for these classes to make sure our code
59    # works fine.
60    if LooseVersion(cryptography.__version__) < LooseVersion('2.1'):
61        # A very simply hash function which relies on the representation
62        # of an object to be implemented. This is the case since at least
63        # cryptography 1.0, see
64        # https://github.com/pyca/cryptography/commit/7a9abce4bff36c05d26d8d2680303a6f64a0e84f
65        def simple_hash(self):
66            return hash(repr(self))
67
68        # The hash functions for the following types were added for cryptography 2.1:
69        # https://github.com/pyca/cryptography/commit/fbfc36da2a4769045f2373b004ddf0aff906cf38
70        x509.DNSName.__hash__ = simple_hash
71        x509.DirectoryName.__hash__ = simple_hash
72        x509.GeneralName.__hash__ = simple_hash
73        x509.IPAddress.__hash__ = simple_hash
74        x509.OtherName.__hash__ = simple_hash
75        x509.RegisteredID.__hash__ = simple_hash
76
77        if LooseVersion(cryptography.__version__) < LooseVersion('1.2'):
78            # The hash functions for the following types were added for cryptography 1.2:
79            # https://github.com/pyca/cryptography/commit/b642deed88a8696e5f01ce6855ccf89985fc35d0
80            # https://github.com/pyca/cryptography/commit/d1b5681f6db2bde7a14625538bd7907b08dfb486
81            x509.RFC822Name.__hash__ = simple_hash
82            x509.UniformResourceIdentifier.__hash__ = simple_hash
83
84    # Test whether we have support for X25519, X448, Ed25519 and/or Ed448
85    try:
86        import cryptography.hazmat.primitives.asymmetric.x25519
87        CRYPTOGRAPHY_HAS_X25519 = True
88        try:
89            cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.private_bytes
90            CRYPTOGRAPHY_HAS_X25519_FULL = True
91        except AttributeError:
92            CRYPTOGRAPHY_HAS_X25519_FULL = False
93    except ImportError:
94        CRYPTOGRAPHY_HAS_X25519 = False
95        CRYPTOGRAPHY_HAS_X25519_FULL = False
96    try:
97        import cryptography.hazmat.primitives.asymmetric.x448
98        CRYPTOGRAPHY_HAS_X448 = True
99    except ImportError:
100        CRYPTOGRAPHY_HAS_X448 = False
101    try:
102        import cryptography.hazmat.primitives.asymmetric.ed25519
103        CRYPTOGRAPHY_HAS_ED25519 = True
104    except ImportError:
105        CRYPTOGRAPHY_HAS_ED25519 = False
106    try:
107        import cryptography.hazmat.primitives.asymmetric.ed448
108        CRYPTOGRAPHY_HAS_ED448 = True
109    except ImportError:
110        CRYPTOGRAPHY_HAS_ED448 = False
111
112    HAS_CRYPTOGRAPHY = True
113except ImportError:
114    # Error handled in the calling module.
115    CRYPTOGRAPHY_HAS_X25519 = False
116    CRYPTOGRAPHY_HAS_X25519_FULL = False
117    CRYPTOGRAPHY_HAS_X448 = False
118    CRYPTOGRAPHY_HAS_ED25519 = False
119    CRYPTOGRAPHY_HAS_ED448 = False
120    HAS_CRYPTOGRAPHY = False
121
122
123import abc
124import base64
125import binascii
126import datetime
127import errno
128import hashlib
129import os
130import re
131import tempfile
132
133from ansible.module_utils import six
134from ansible.module_utils._text import to_native, to_bytes, to_text
135
136
137class OpenSSLObjectError(Exception):
138    pass
139
140
141class OpenSSLBadPassphraseError(OpenSSLObjectError):
142    pass
143
144
145def get_fingerprint_of_bytes(source):
146    """Generate the fingerprint of the given bytes."""
147
148    fingerprint = {}
149
150    try:
151        algorithms = hashlib.algorithms
152    except AttributeError:
153        try:
154            algorithms = hashlib.algorithms_guaranteed
155        except AttributeError:
156            return None
157
158    for algo in algorithms:
159        f = getattr(hashlib, algo)
160        try:
161            h = f(source)
162        except ValueError:
163            # This can happen for hash algorithms not supported in FIPS mode
164            # (https://github.com/ansible/ansible/issues/67213)
165            continue
166        try:
167            # Certain hash functions have a hexdigest() which expects a length parameter
168            pubkey_digest = h.hexdigest()
169        except TypeError:
170            pubkey_digest = h.hexdigest(32)
171        fingerprint[algo] = ':'.join(pubkey_digest[i:i + 2] for i in range(0, len(pubkey_digest), 2))
172
173    return fingerprint
174
175
176def get_fingerprint(path, passphrase=None, content=None, backend='pyopenssl'):
177    """Generate the fingerprint of the public key. """
178
179    privatekey = load_privatekey(path, passphrase=passphrase, content=content, check_passphrase=False, backend=backend)
180
181    if backend == 'pyopenssl':
182        try:
183            publickey = crypto.dump_publickey(crypto.FILETYPE_ASN1, privatekey)
184        except AttributeError:
185            # If PyOpenSSL < 16.0 crypto.dump_publickey() will fail.
186            try:
187                bio = crypto._new_mem_buf()
188                rc = crypto._lib.i2d_PUBKEY_bio(bio, privatekey._pkey)
189                if rc != 1:
190                    crypto._raise_current_error()
191                publickey = crypto._bio_to_string(bio)
192            except AttributeError:
193                # By doing this we prevent the code from raising an error
194                # yet we return no value in the fingerprint hash.
195                return None
196    elif backend == 'cryptography':
197        publickey = privatekey.public_key().public_bytes(
198            serialization.Encoding.DER,
199            serialization.PublicFormat.SubjectPublicKeyInfo
200        )
201
202    return get_fingerprint_of_bytes(publickey)
203
204
205def load_file_if_exists(path, module=None, ignore_errors=False):
206    try:
207        with open(path, 'rb') as f:
208            return f.read()
209    except EnvironmentError as exc:
210        if exc.errno == errno.ENOENT:
211            return None
212        if ignore_errors:
213            return None
214        if module is None:
215            raise
216        module.fail_json('Error while loading {0} - {1}'.format(path, str(exc)))
217    except Exception as exc:
218        if ignore_errors:
219            return None
220        if module is None:
221            raise
222        module.fail_json('Error while loading {0} - {1}'.format(path, str(exc)))
223
224
225def load_privatekey(path, passphrase=None, check_passphrase=True, content=None, backend='pyopenssl'):
226    """Load the specified OpenSSL private key.
227
228    The content can also be specified via content; in that case,
229    this function will not load the key from disk.
230    """
231
232    try:
233        if content is None:
234            with open(path, 'rb') as b_priv_key_fh:
235                priv_key_detail = b_priv_key_fh.read()
236        else:
237            priv_key_detail = content
238
239        if backend == 'pyopenssl':
240
241            # First try: try to load with real passphrase (resp. empty string)
242            # Will work if this is the correct passphrase, or the key is not
243            # password-protected.
244            try:
245                result = crypto.load_privatekey(crypto.FILETYPE_PEM,
246                                                priv_key_detail,
247                                                to_bytes(passphrase or ''))
248            except crypto.Error as e:
249                if len(e.args) > 0 and len(e.args[0]) > 0:
250                    if e.args[0][0][2] in ('bad decrypt', 'bad password read'):
251                        # This happens in case we have the wrong passphrase.
252                        if passphrase is not None:
253                            raise OpenSSLBadPassphraseError('Wrong passphrase provided for private key!')
254                        else:
255                            raise OpenSSLBadPassphraseError('No passphrase provided, but private key is password-protected!')
256                raise OpenSSLObjectError('Error while deserializing key: {0}'.format(e))
257            if check_passphrase:
258                # Next we want to make sure that the key is actually protected by
259                # a passphrase (in case we did try the empty string before, make
260                # sure that the key is not protected by the empty string)
261                try:
262                    crypto.load_privatekey(crypto.FILETYPE_PEM,
263                                           priv_key_detail,
264                                           to_bytes('y' if passphrase == 'x' else 'x'))
265                    if passphrase is not None:
266                        # Since we can load the key without an exception, the
267                        # key isn't password-protected
268                        raise OpenSSLBadPassphraseError('Passphrase provided, but private key is not password-protected!')
269                except crypto.Error as e:
270                    if passphrase is None and len(e.args) > 0 and len(e.args[0]) > 0:
271                        if e.args[0][0][2] in ('bad decrypt', 'bad password read'):
272                            # The key is obviously protected by the empty string.
273                            # Don't do this at home (if it's possible at all)...
274                            raise OpenSSLBadPassphraseError('No passphrase provided, but private key is password-protected!')
275        elif backend == 'cryptography':
276            try:
277                result = load_pem_private_key(priv_key_detail,
278                                              None if passphrase is None else to_bytes(passphrase),
279                                              cryptography_backend())
280            except TypeError as dummy:
281                raise OpenSSLBadPassphraseError('Wrong or empty passphrase provided for private key')
282            except ValueError as dummy:
283                raise OpenSSLBadPassphraseError('Wrong passphrase provided for private key')
284
285        return result
286    except (IOError, OSError) as exc:
287        raise OpenSSLObjectError(exc)
288
289
290def load_certificate(path, content=None, backend='pyopenssl'):
291    """Load the specified certificate."""
292
293    try:
294        if content is None:
295            with open(path, 'rb') as cert_fh:
296                cert_content = cert_fh.read()
297        else:
298            cert_content = content
299        if backend == 'pyopenssl':
300            return crypto.load_certificate(crypto.FILETYPE_PEM, cert_content)
301        elif backend == 'cryptography':
302            return x509.load_pem_x509_certificate(cert_content, cryptography_backend())
303    except (IOError, OSError) as exc:
304        raise OpenSSLObjectError(exc)
305
306
307def load_certificate_request(path, content=None, backend='pyopenssl'):
308    """Load the specified certificate signing request."""
309    try:
310        if content is None:
311            with open(path, 'rb') as csr_fh:
312                csr_content = csr_fh.read()
313        else:
314            csr_content = content
315    except (IOError, OSError) as exc:
316        raise OpenSSLObjectError(exc)
317    if backend == 'pyopenssl':
318        return crypto.load_certificate_request(crypto.FILETYPE_PEM, csr_content)
319    elif backend == 'cryptography':
320        return x509.load_pem_x509_csr(csr_content, cryptography_backend())
321
322
323def parse_name_field(input_dict):
324    """Take a dict with key: value or key: list_of_values mappings and return a list of tuples"""
325
326    result = []
327    for key in input_dict:
328        if isinstance(input_dict[key], list):
329            for entry in input_dict[key]:
330                result.append((key, entry))
331        else:
332            result.append((key, input_dict[key]))
333    return result
334
335
336def convert_relative_to_datetime(relative_time_string):
337    """Get a datetime.datetime or None from a string in the time format described in sshd_config(5)"""
338
339    parsed_result = re.match(
340        r"^(?P<prefix>[+-])((?P<weeks>\d+)[wW])?((?P<days>\d+)[dD])?((?P<hours>\d+)[hH])?((?P<minutes>\d+)[mM])?((?P<seconds>\d+)[sS]?)?$",
341        relative_time_string)
342
343    if parsed_result is None or len(relative_time_string) == 1:
344        # not matched or only a single "+" or "-"
345        return None
346
347    offset = datetime.timedelta(0)
348    if parsed_result.group("weeks") is not None:
349        offset += datetime.timedelta(weeks=int(parsed_result.group("weeks")))
350    if parsed_result.group("days") is not None:
351        offset += datetime.timedelta(days=int(parsed_result.group("days")))
352    if parsed_result.group("hours") is not None:
353        offset += datetime.timedelta(hours=int(parsed_result.group("hours")))
354    if parsed_result.group("minutes") is not None:
355        offset += datetime.timedelta(
356            minutes=int(parsed_result.group("minutes")))
357    if parsed_result.group("seconds") is not None:
358        offset += datetime.timedelta(
359            seconds=int(parsed_result.group("seconds")))
360
361    if parsed_result.group("prefix") == "+":
362        return datetime.datetime.utcnow() + offset
363    else:
364        return datetime.datetime.utcnow() - offset
365
366
367def get_relative_time_option(input_string, input_name, backend='cryptography'):
368    """Return an absolute timespec if a relative timespec or an ASN1 formatted
369       string is provided.
370
371       The return value will be a datetime object for the cryptography backend,
372       and a ASN1 formatted string for the pyopenssl backend."""
373    result = to_native(input_string)
374    if result is None:
375        raise OpenSSLObjectError(
376            'The timespec "%s" for %s is not valid' %
377            input_string, input_name)
378    # Relative time
379    if result.startswith("+") or result.startswith("-"):
380        result_datetime = convert_relative_to_datetime(result)
381        if backend == 'pyopenssl':
382            return result_datetime.strftime("%Y%m%d%H%M%SZ")
383        elif backend == 'cryptography':
384            return result_datetime
385    # Absolute time
386    if backend == 'pyopenssl':
387        return input_string
388    elif backend == 'cryptography':
389        for date_fmt in ['%Y%m%d%H%M%SZ', '%Y%m%d%H%MZ', '%Y%m%d%H%M%S%z', '%Y%m%d%H%M%z']:
390            try:
391                return datetime.datetime.strptime(result, date_fmt)
392            except ValueError:
393                pass
394
395        raise OpenSSLObjectError(
396            'The time spec "%s" for %s is invalid' %
397            (input_string, input_name)
398        )
399
400
401def select_message_digest(digest_string):
402    digest = None
403    if digest_string == 'sha256':
404        digest = hashes.SHA256()
405    elif digest_string == 'sha384':
406        digest = hashes.SHA384()
407    elif digest_string == 'sha512':
408        digest = hashes.SHA512()
409    elif digest_string == 'sha1':
410        digest = hashes.SHA1()
411    elif digest_string == 'md5':
412        digest = hashes.MD5()
413    return digest
414
415
416def write_file(module, content, default_mode=None, path=None):
417    '''
418    Writes content into destination file as securely as possible.
419    Uses file arguments from module.
420    '''
421    # Find out parameters for file
422    file_args = module.load_file_common_arguments(module.params, path=path)
423    if file_args['mode'] is None:
424        file_args['mode'] = default_mode
425    # Create tempfile name
426    tmp_fd, tmp_name = tempfile.mkstemp(prefix=b'.ansible_tmp')
427    try:
428        os.close(tmp_fd)
429    except Exception as dummy:
430        pass
431    module.add_cleanup_file(tmp_name)  # if we fail, let Ansible try to remove the file
432    try:
433        try:
434            # Create tempfile
435            file = os.open(tmp_name, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600)
436            os.write(file, content)
437            os.close(file)
438        except Exception as e:
439            try:
440                os.remove(tmp_name)
441            except Exception as dummy:
442                pass
443            module.fail_json(msg='Error while writing result into temporary file: {0}'.format(e))
444        # Update destination to wanted permissions
445        if os.path.exists(file_args['path']):
446            module.set_fs_attributes_if_different(file_args, False)
447        # Move tempfile to final destination
448        module.atomic_move(tmp_name, file_args['path'])
449        # Try to update permissions again
450        module.set_fs_attributes_if_different(file_args, False)
451    except Exception as e:
452        try:
453            os.remove(tmp_name)
454        except Exception as dummy:
455            pass
456        module.fail_json(msg='Error while writing result: {0}'.format(e))
457
458
459@six.add_metaclass(abc.ABCMeta)
460class OpenSSLObject(object):
461
462    def __init__(self, path, state, force, check_mode):
463        self.path = path
464        self.state = state
465        self.force = force
466        self.name = os.path.basename(path)
467        self.changed = False
468        self.check_mode = check_mode
469
470    def check(self, module, perms_required=True):
471        """Ensure the resource is in its desired state."""
472
473        def _check_state():
474            return os.path.exists(self.path)
475
476        def _check_perms(module):
477            file_args = module.load_file_common_arguments(module.params)
478            return not module.set_fs_attributes_if_different(file_args, False)
479
480        if not perms_required:
481            return _check_state()
482
483        return _check_state() and _check_perms(module)
484
485    @abc.abstractmethod
486    def dump(self):
487        """Serialize the object into a dictionary."""
488
489        pass
490
491    @abc.abstractmethod
492    def generate(self):
493        """Generate the resource."""
494
495        pass
496
497    def remove(self, module):
498        """Remove the resource from the filesystem."""
499
500        try:
501            os.remove(self.path)
502            self.changed = True
503        except OSError as exc:
504            if exc.errno != errno.ENOENT:
505                raise OpenSSLObjectError(exc)
506            else:
507                pass
508
509
510# #####################################################################################
511# #####################################################################################
512# This has been extracted from the OpenSSL project's objects.txt:
513#     https://github.com/openssl/openssl/blob/9537fe5757bb07761fa275d779bbd40bcf5530e4/crypto/objects/objects.txt
514# Extracted with https://gist.github.com/felixfontein/376748017ad65ead093d56a45a5bf376
515#
516# In case the following data structure has any copyrightable content, note that it is licensed as follows:
517# Copyright (c) the OpenSSL contributors
518# Licensed under the Apache License 2.0
519# https://github.com/openssl/openssl/blob/master/LICENSE
520_OID_MAP = {
521    '0': ('itu-t', 'ITU-T', 'ccitt'),
522    '0.3.4401.5': ('ntt-ds', ),
523    '0.3.4401.5.3.1.9': ('camellia', ),
524    '0.3.4401.5.3.1.9.1': ('camellia-128-ecb', 'CAMELLIA-128-ECB'),
525    '0.3.4401.5.3.1.9.3': ('camellia-128-ofb', 'CAMELLIA-128-OFB'),
526    '0.3.4401.5.3.1.9.4': ('camellia-128-cfb', 'CAMELLIA-128-CFB'),
527    '0.3.4401.5.3.1.9.6': ('camellia-128-gcm', 'CAMELLIA-128-GCM'),
528    '0.3.4401.5.3.1.9.7': ('camellia-128-ccm', 'CAMELLIA-128-CCM'),
529    '0.3.4401.5.3.1.9.9': ('camellia-128-ctr', 'CAMELLIA-128-CTR'),
530    '0.3.4401.5.3.1.9.10': ('camellia-128-cmac', 'CAMELLIA-128-CMAC'),
531    '0.3.4401.5.3.1.9.21': ('camellia-192-ecb', 'CAMELLIA-192-ECB'),
532    '0.3.4401.5.3.1.9.23': ('camellia-192-ofb', 'CAMELLIA-192-OFB'),
533    '0.3.4401.5.3.1.9.24': ('camellia-192-cfb', 'CAMELLIA-192-CFB'),
534    '0.3.4401.5.3.1.9.26': ('camellia-192-gcm', 'CAMELLIA-192-GCM'),
535    '0.3.4401.5.3.1.9.27': ('camellia-192-ccm', 'CAMELLIA-192-CCM'),
536    '0.3.4401.5.3.1.9.29': ('camellia-192-ctr', 'CAMELLIA-192-CTR'),
537    '0.3.4401.5.3.1.9.30': ('camellia-192-cmac', 'CAMELLIA-192-CMAC'),
538    '0.3.4401.5.3.1.9.41': ('camellia-256-ecb', 'CAMELLIA-256-ECB'),
539    '0.3.4401.5.3.1.9.43': ('camellia-256-ofb', 'CAMELLIA-256-OFB'),
540    '0.3.4401.5.3.1.9.44': ('camellia-256-cfb', 'CAMELLIA-256-CFB'),
541    '0.3.4401.5.3.1.9.46': ('camellia-256-gcm', 'CAMELLIA-256-GCM'),
542    '0.3.4401.5.3.1.9.47': ('camellia-256-ccm', 'CAMELLIA-256-CCM'),
543    '0.3.4401.5.3.1.9.49': ('camellia-256-ctr', 'CAMELLIA-256-CTR'),
544    '0.3.4401.5.3.1.9.50': ('camellia-256-cmac', 'CAMELLIA-256-CMAC'),
545    '0.9': ('data', ),
546    '0.9.2342': ('pss', ),
547    '0.9.2342.19200300': ('ucl', ),
548    '0.9.2342.19200300.100': ('pilot', ),
549    '0.9.2342.19200300.100.1': ('pilotAttributeType', ),
550    '0.9.2342.19200300.100.1.1': ('userId', 'UID'),
551    '0.9.2342.19200300.100.1.2': ('textEncodedORAddress', ),
552    '0.9.2342.19200300.100.1.3': ('rfc822Mailbox', 'mail'),
553    '0.9.2342.19200300.100.1.4': ('info', ),
554    '0.9.2342.19200300.100.1.5': ('favouriteDrink', ),
555    '0.9.2342.19200300.100.1.6': ('roomNumber', ),
556    '0.9.2342.19200300.100.1.7': ('photo', ),
557    '0.9.2342.19200300.100.1.8': ('userClass', ),
558    '0.9.2342.19200300.100.1.9': ('host', ),
559    '0.9.2342.19200300.100.1.10': ('manager', ),
560    '0.9.2342.19200300.100.1.11': ('documentIdentifier', ),
561    '0.9.2342.19200300.100.1.12': ('documentTitle', ),
562    '0.9.2342.19200300.100.1.13': ('documentVersion', ),
563    '0.9.2342.19200300.100.1.14': ('documentAuthor', ),
564    '0.9.2342.19200300.100.1.15': ('documentLocation', ),
565    '0.9.2342.19200300.100.1.20': ('homeTelephoneNumber', ),
566    '0.9.2342.19200300.100.1.21': ('secretary', ),
567    '0.9.2342.19200300.100.1.22': ('otherMailbox', ),
568    '0.9.2342.19200300.100.1.23': ('lastModifiedTime', ),
569    '0.9.2342.19200300.100.1.24': ('lastModifiedBy', ),
570    '0.9.2342.19200300.100.1.25': ('domainComponent', 'DC'),
571    '0.9.2342.19200300.100.1.26': ('aRecord', ),
572    '0.9.2342.19200300.100.1.27': ('pilotAttributeType27', ),
573    '0.9.2342.19200300.100.1.28': ('mXRecord', ),
574    '0.9.2342.19200300.100.1.29': ('nSRecord', ),
575    '0.9.2342.19200300.100.1.30': ('sOARecord', ),
576    '0.9.2342.19200300.100.1.31': ('cNAMERecord', ),
577    '0.9.2342.19200300.100.1.37': ('associatedDomain', ),
578    '0.9.2342.19200300.100.1.38': ('associatedName', ),
579    '0.9.2342.19200300.100.1.39': ('homePostalAddress', ),
580    '0.9.2342.19200300.100.1.40': ('personalTitle', ),
581    '0.9.2342.19200300.100.1.41': ('mobileTelephoneNumber', ),
582    '0.9.2342.19200300.100.1.42': ('pagerTelephoneNumber', ),
583    '0.9.2342.19200300.100.1.43': ('friendlyCountryName', ),
584    '0.9.2342.19200300.100.1.44': ('uniqueIdentifier', 'uid'),
585    '0.9.2342.19200300.100.1.45': ('organizationalStatus', ),
586    '0.9.2342.19200300.100.1.46': ('janetMailbox', ),
587    '0.9.2342.19200300.100.1.47': ('mailPreferenceOption', ),
588    '0.9.2342.19200300.100.1.48': ('buildingName', ),
589    '0.9.2342.19200300.100.1.49': ('dSAQuality', ),
590    '0.9.2342.19200300.100.1.50': ('singleLevelQuality', ),
591    '0.9.2342.19200300.100.1.51': ('subtreeMinimumQuality', ),
592    '0.9.2342.19200300.100.1.52': ('subtreeMaximumQuality', ),
593    '0.9.2342.19200300.100.1.53': ('personalSignature', ),
594    '0.9.2342.19200300.100.1.54': ('dITRedirect', ),
595    '0.9.2342.19200300.100.1.55': ('audio', ),
596    '0.9.2342.19200300.100.1.56': ('documentPublisher', ),
597    '0.9.2342.19200300.100.3': ('pilotAttributeSyntax', ),
598    '0.9.2342.19200300.100.3.4': ('iA5StringSyntax', ),
599    '0.9.2342.19200300.100.3.5': ('caseIgnoreIA5StringSyntax', ),
600    '0.9.2342.19200300.100.4': ('pilotObjectClass', ),
601    '0.9.2342.19200300.100.4.3': ('pilotObject', ),
602    '0.9.2342.19200300.100.4.4': ('pilotPerson', ),
603    '0.9.2342.19200300.100.4.5': ('account', ),
604    '0.9.2342.19200300.100.4.6': ('document', ),
605    '0.9.2342.19200300.100.4.7': ('room', ),
606    '0.9.2342.19200300.100.4.9': ('documentSeries', ),
607    '0.9.2342.19200300.100.4.13': ('Domain', 'domain'),
608    '0.9.2342.19200300.100.4.14': ('rFC822localPart', ),
609    '0.9.2342.19200300.100.4.15': ('dNSDomain', ),
610    '0.9.2342.19200300.100.4.17': ('domainRelatedObject', ),
611    '0.9.2342.19200300.100.4.18': ('friendlyCountry', ),
612    '0.9.2342.19200300.100.4.19': ('simpleSecurityObject', ),
613    '0.9.2342.19200300.100.4.20': ('pilotOrganization', ),
614    '0.9.2342.19200300.100.4.21': ('pilotDSA', ),
615    '0.9.2342.19200300.100.4.22': ('qualityLabelledData', ),
616    '0.9.2342.19200300.100.10': ('pilotGroups', ),
617    '1': ('iso', 'ISO'),
618    '1.0.9797.3.4': ('gmac', 'GMAC'),
619    '1.0.10118.3.0.55': ('whirlpool', ),
620    '1.2': ('ISO Member Body', 'member-body'),
621    '1.2.156': ('ISO CN Member Body', 'ISO-CN'),
622    '1.2.156.10197': ('oscca', ),
623    '1.2.156.10197.1': ('sm-scheme', ),
624    '1.2.156.10197.1.104.1': ('sm4-ecb', 'SM4-ECB'),
625    '1.2.156.10197.1.104.2': ('sm4-cbc', 'SM4-CBC'),
626    '1.2.156.10197.1.104.3': ('sm4-ofb', 'SM4-OFB'),
627    '1.2.156.10197.1.104.4': ('sm4-cfb', 'SM4-CFB'),
628    '1.2.156.10197.1.104.5': ('sm4-cfb1', 'SM4-CFB1'),
629    '1.2.156.10197.1.104.6': ('sm4-cfb8', 'SM4-CFB8'),
630    '1.2.156.10197.1.104.7': ('sm4-ctr', 'SM4-CTR'),
631    '1.2.156.10197.1.301': ('sm2', 'SM2'),
632    '1.2.156.10197.1.401': ('sm3', 'SM3'),
633    '1.2.156.10197.1.501': ('SM2-with-SM3', 'SM2-SM3'),
634    '1.2.156.10197.1.504': ('sm3WithRSAEncryption', 'RSA-SM3'),
635    '1.2.392.200011.61.1.1.1.2': ('camellia-128-cbc', 'CAMELLIA-128-CBC'),
636    '1.2.392.200011.61.1.1.1.3': ('camellia-192-cbc', 'CAMELLIA-192-CBC'),
637    '1.2.392.200011.61.1.1.1.4': ('camellia-256-cbc', 'CAMELLIA-256-CBC'),
638    '1.2.392.200011.61.1.1.3.2': ('id-camellia128-wrap', ),
639    '1.2.392.200011.61.1.1.3.3': ('id-camellia192-wrap', ),
640    '1.2.392.200011.61.1.1.3.4': ('id-camellia256-wrap', ),
641    '1.2.410.200004': ('kisa', 'KISA'),
642    '1.2.410.200004.1.3': ('seed-ecb', 'SEED-ECB'),
643    '1.2.410.200004.1.4': ('seed-cbc', 'SEED-CBC'),
644    '1.2.410.200004.1.5': ('seed-cfb', 'SEED-CFB'),
645    '1.2.410.200004.1.6': ('seed-ofb', 'SEED-OFB'),
646    '1.2.410.200046.1.1': ('aria', ),
647    '1.2.410.200046.1.1.1': ('aria-128-ecb', 'ARIA-128-ECB'),
648    '1.2.410.200046.1.1.2': ('aria-128-cbc', 'ARIA-128-CBC'),
649    '1.2.410.200046.1.1.3': ('aria-128-cfb', 'ARIA-128-CFB'),
650    '1.2.410.200046.1.1.4': ('aria-128-ofb', 'ARIA-128-OFB'),
651    '1.2.410.200046.1.1.5': ('aria-128-ctr', 'ARIA-128-CTR'),
652    '1.2.410.200046.1.1.6': ('aria-192-ecb', 'ARIA-192-ECB'),
653    '1.2.410.200046.1.1.7': ('aria-192-cbc', 'ARIA-192-CBC'),
654    '1.2.410.200046.1.1.8': ('aria-192-cfb', 'ARIA-192-CFB'),
655    '1.2.410.200046.1.1.9': ('aria-192-ofb', 'ARIA-192-OFB'),
656    '1.2.410.200046.1.1.10': ('aria-192-ctr', 'ARIA-192-CTR'),
657    '1.2.410.200046.1.1.11': ('aria-256-ecb', 'ARIA-256-ECB'),
658    '1.2.410.200046.1.1.12': ('aria-256-cbc', 'ARIA-256-CBC'),
659    '1.2.410.200046.1.1.13': ('aria-256-cfb', 'ARIA-256-CFB'),
660    '1.2.410.200046.1.1.14': ('aria-256-ofb', 'ARIA-256-OFB'),
661    '1.2.410.200046.1.1.15': ('aria-256-ctr', 'ARIA-256-CTR'),
662    '1.2.410.200046.1.1.34': ('aria-128-gcm', 'ARIA-128-GCM'),
663    '1.2.410.200046.1.1.35': ('aria-192-gcm', 'ARIA-192-GCM'),
664    '1.2.410.200046.1.1.36': ('aria-256-gcm', 'ARIA-256-GCM'),
665    '1.2.410.200046.1.1.37': ('aria-128-ccm', 'ARIA-128-CCM'),
666    '1.2.410.200046.1.1.38': ('aria-192-ccm', 'ARIA-192-CCM'),
667    '1.2.410.200046.1.1.39': ('aria-256-ccm', 'ARIA-256-CCM'),
668    '1.2.643.2.2': ('cryptopro', ),
669    '1.2.643.2.2.3': ('GOST R 34.11-94 with GOST R 34.10-2001', 'id-GostR3411-94-with-GostR3410-2001'),
670    '1.2.643.2.2.4': ('GOST R 34.11-94 with GOST R 34.10-94', 'id-GostR3411-94-with-GostR3410-94'),
671    '1.2.643.2.2.9': ('GOST R 34.11-94', 'md_gost94'),
672    '1.2.643.2.2.10': ('HMAC GOST 34.11-94', 'id-HMACGostR3411-94'),
673    '1.2.643.2.2.14.0': ('id-Gost28147-89-None-KeyMeshing', ),
674    '1.2.643.2.2.14.1': ('id-Gost28147-89-CryptoPro-KeyMeshing', ),
675    '1.2.643.2.2.19': ('GOST R 34.10-2001', 'gost2001'),
676    '1.2.643.2.2.20': ('GOST R 34.10-94', 'gost94'),
677    '1.2.643.2.2.20.1': ('id-GostR3410-94-a', ),
678    '1.2.643.2.2.20.2': ('id-GostR3410-94-aBis', ),
679    '1.2.643.2.2.20.3': ('id-GostR3410-94-b', ),
680    '1.2.643.2.2.20.4': ('id-GostR3410-94-bBis', ),
681    '1.2.643.2.2.21': ('GOST 28147-89', 'gost89'),
682    '1.2.643.2.2.22': ('GOST 28147-89 MAC', 'gost-mac'),
683    '1.2.643.2.2.23': ('GOST R 34.11-94 PRF', 'prf-gostr3411-94'),
684    '1.2.643.2.2.30.0': ('id-GostR3411-94-TestParamSet', ),
685    '1.2.643.2.2.30.1': ('id-GostR3411-94-CryptoProParamSet', ),
686    '1.2.643.2.2.31.0': ('id-Gost28147-89-TestParamSet', ),
687    '1.2.643.2.2.31.1': ('id-Gost28147-89-CryptoPro-A-ParamSet', ),
688    '1.2.643.2.2.31.2': ('id-Gost28147-89-CryptoPro-B-ParamSet', ),
689    '1.2.643.2.2.31.3': ('id-Gost28147-89-CryptoPro-C-ParamSet', ),
690    '1.2.643.2.2.31.4': ('id-Gost28147-89-CryptoPro-D-ParamSet', ),
691    '1.2.643.2.2.31.5': ('id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet', ),
692    '1.2.643.2.2.31.6': ('id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet', ),
693    '1.2.643.2.2.31.7': ('id-Gost28147-89-CryptoPro-RIC-1-ParamSet', ),
694    '1.2.643.2.2.32.0': ('id-GostR3410-94-TestParamSet', ),
695    '1.2.643.2.2.32.2': ('id-GostR3410-94-CryptoPro-A-ParamSet', ),
696    '1.2.643.2.2.32.3': ('id-GostR3410-94-CryptoPro-B-ParamSet', ),
697    '1.2.643.2.2.32.4': ('id-GostR3410-94-CryptoPro-C-ParamSet', ),
698    '1.2.643.2.2.32.5': ('id-GostR3410-94-CryptoPro-D-ParamSet', ),
699    '1.2.643.2.2.33.1': ('id-GostR3410-94-CryptoPro-XchA-ParamSet', ),
700    '1.2.643.2.2.33.2': ('id-GostR3410-94-CryptoPro-XchB-ParamSet', ),
701    '1.2.643.2.2.33.3': ('id-GostR3410-94-CryptoPro-XchC-ParamSet', ),
702    '1.2.643.2.2.35.0': ('id-GostR3410-2001-TestParamSet', ),
703    '1.2.643.2.2.35.1': ('id-GostR3410-2001-CryptoPro-A-ParamSet', ),
704    '1.2.643.2.2.35.2': ('id-GostR3410-2001-CryptoPro-B-ParamSet', ),
705    '1.2.643.2.2.35.3': ('id-GostR3410-2001-CryptoPro-C-ParamSet', ),
706    '1.2.643.2.2.36.0': ('id-GostR3410-2001-CryptoPro-XchA-ParamSet', ),
707    '1.2.643.2.2.36.1': ('id-GostR3410-2001-CryptoPro-XchB-ParamSet', ),
708    '1.2.643.2.2.98': ('GOST R 34.10-2001 DH', 'id-GostR3410-2001DH'),
709    '1.2.643.2.2.99': ('GOST R 34.10-94 DH', 'id-GostR3410-94DH'),
710    '1.2.643.2.9': ('cryptocom', ),
711    '1.2.643.2.9.1.3.3': ('GOST R 34.11-94 with GOST R 34.10-94 Cryptocom', 'id-GostR3411-94-with-GostR3410-94-cc'),
712    '1.2.643.2.9.1.3.4': ('GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom', 'id-GostR3411-94-with-GostR3410-2001-cc'),
713    '1.2.643.2.9.1.5.3': ('GOST 34.10-94 Cryptocom', 'gost94cc'),
714    '1.2.643.2.9.1.5.4': ('GOST 34.10-2001 Cryptocom', 'gost2001cc'),
715    '1.2.643.2.9.1.6.1': ('GOST 28147-89 Cryptocom ParamSet', 'id-Gost28147-89-cc'),
716    '1.2.643.2.9.1.8.1': ('GOST R 3410-2001 Parameter Set Cryptocom', 'id-GostR3410-2001-ParamSet-cc'),
717    '1.2.643.3.131.1.1': ('INN', 'INN'),
718    '1.2.643.7.1': ('id-tc26', ),
719    '1.2.643.7.1.1': ('id-tc26-algorithms', ),
720    '1.2.643.7.1.1.1': ('id-tc26-sign', ),
721    '1.2.643.7.1.1.1.1': ('GOST R 34.10-2012 with 256 bit modulus', 'gost2012_256'),
722    '1.2.643.7.1.1.1.2': ('GOST R 34.10-2012 with 512 bit modulus', 'gost2012_512'),
723    '1.2.643.7.1.1.2': ('id-tc26-digest', ),
724    '1.2.643.7.1.1.2.2': ('GOST R 34.11-2012 with 256 bit hash', 'md_gost12_256'),
725    '1.2.643.7.1.1.2.3': ('GOST R 34.11-2012 with 512 bit hash', 'md_gost12_512'),
726    '1.2.643.7.1.1.3': ('id-tc26-signwithdigest', ),
727    '1.2.643.7.1.1.3.2': ('GOST R 34.10-2012 with GOST R 34.11-2012 (256 bit)', 'id-tc26-signwithdigest-gost3410-2012-256'),
728    '1.2.643.7.1.1.3.3': ('GOST R 34.10-2012 with GOST R 34.11-2012 (512 bit)', 'id-tc26-signwithdigest-gost3410-2012-512'),
729    '1.2.643.7.1.1.4': ('id-tc26-mac', ),
730    '1.2.643.7.1.1.4.1': ('HMAC GOST 34.11-2012 256 bit', 'id-tc26-hmac-gost-3411-2012-256'),
731    '1.2.643.7.1.1.4.2': ('HMAC GOST 34.11-2012 512 bit', 'id-tc26-hmac-gost-3411-2012-512'),
732    '1.2.643.7.1.1.5': ('id-tc26-cipher', ),
733    '1.2.643.7.1.1.5.1': ('id-tc26-cipher-gostr3412-2015-magma', ),
734    '1.2.643.7.1.1.5.1.1': ('id-tc26-cipher-gostr3412-2015-magma-ctracpkm', ),
735    '1.2.643.7.1.1.5.1.2': ('id-tc26-cipher-gostr3412-2015-magma-ctracpkm-omac', ),
736    '1.2.643.7.1.1.5.2': ('id-tc26-cipher-gostr3412-2015-kuznyechik', ),
737    '1.2.643.7.1.1.5.2.1': ('id-tc26-cipher-gostr3412-2015-kuznyechik-ctracpkm', ),
738    '1.2.643.7.1.1.5.2.2': ('id-tc26-cipher-gostr3412-2015-kuznyechik-ctracpkm-omac', ),
739    '1.2.643.7.1.1.6': ('id-tc26-agreement', ),
740    '1.2.643.7.1.1.6.1': ('id-tc26-agreement-gost-3410-2012-256', ),
741    '1.2.643.7.1.1.6.2': ('id-tc26-agreement-gost-3410-2012-512', ),
742    '1.2.643.7.1.1.7': ('id-tc26-wrap', ),
743    '1.2.643.7.1.1.7.1': ('id-tc26-wrap-gostr3412-2015-magma', ),
744    '1.2.643.7.1.1.7.1.1': ('id-tc26-wrap-gostr3412-2015-magma-kexp15', 'id-tc26-wrap-gostr3412-2015-kuznyechik-kexp15'),
745    '1.2.643.7.1.1.7.2': ('id-tc26-wrap-gostr3412-2015-kuznyechik', ),
746    '1.2.643.7.1.2': ('id-tc26-constants', ),
747    '1.2.643.7.1.2.1': ('id-tc26-sign-constants', ),
748    '1.2.643.7.1.2.1.1': ('id-tc26-gost-3410-2012-256-constants', ),
749    '1.2.643.7.1.2.1.1.1': ('GOST R 34.10-2012 (256 bit) ParamSet A', 'id-tc26-gost-3410-2012-256-paramSetA'),
750    '1.2.643.7.1.2.1.1.2': ('GOST R 34.10-2012 (256 bit) ParamSet B', 'id-tc26-gost-3410-2012-256-paramSetB'),
751    '1.2.643.7.1.2.1.1.3': ('GOST R 34.10-2012 (256 bit) ParamSet C', 'id-tc26-gost-3410-2012-256-paramSetC'),
752    '1.2.643.7.1.2.1.1.4': ('GOST R 34.10-2012 (256 bit) ParamSet D', 'id-tc26-gost-3410-2012-256-paramSetD'),
753    '1.2.643.7.1.2.1.2': ('id-tc26-gost-3410-2012-512-constants', ),
754    '1.2.643.7.1.2.1.2.0': ('GOST R 34.10-2012 (512 bit) testing parameter set', 'id-tc26-gost-3410-2012-512-paramSetTest'),
755    '1.2.643.7.1.2.1.2.1': ('GOST R 34.10-2012 (512 bit) ParamSet A', 'id-tc26-gost-3410-2012-512-paramSetA'),
756    '1.2.643.7.1.2.1.2.2': ('GOST R 34.10-2012 (512 bit) ParamSet B', 'id-tc26-gost-3410-2012-512-paramSetB'),
757    '1.2.643.7.1.2.1.2.3': ('GOST R 34.10-2012 (512 bit) ParamSet C', 'id-tc26-gost-3410-2012-512-paramSetC'),
758    '1.2.643.7.1.2.2': ('id-tc26-digest-constants', ),
759    '1.2.643.7.1.2.5': ('id-tc26-cipher-constants', ),
760    '1.2.643.7.1.2.5.1': ('id-tc26-gost-28147-constants', ),
761    '1.2.643.7.1.2.5.1.1': ('GOST 28147-89 TC26 parameter set', 'id-tc26-gost-28147-param-Z'),
762    '1.2.643.100.1': ('OGRN', 'OGRN'),
763    '1.2.643.100.3': ('SNILS', 'SNILS'),
764    '1.2.643.100.111': ('Signing Tool of Subject', 'subjectSignTool'),
765    '1.2.643.100.112': ('Signing Tool of Issuer', 'issuerSignTool'),
766    '1.2.804': ('ISO-UA', ),
767    '1.2.804.2.1.1.1': ('ua-pki', ),
768    '1.2.804.2.1.1.1.1.1.1': ('DSTU Gost 28147-2009', 'dstu28147'),
769    '1.2.804.2.1.1.1.1.1.1.2': ('DSTU Gost 28147-2009 OFB mode', 'dstu28147-ofb'),
770    '1.2.804.2.1.1.1.1.1.1.3': ('DSTU Gost 28147-2009 CFB mode', 'dstu28147-cfb'),
771    '1.2.804.2.1.1.1.1.1.1.5': ('DSTU Gost 28147-2009 key wrap', 'dstu28147-wrap'),
772    '1.2.804.2.1.1.1.1.1.2': ('HMAC DSTU Gost 34311-95', 'hmacWithDstu34311'),
773    '1.2.804.2.1.1.1.1.2.1': ('DSTU Gost 34311-95', 'dstu34311'),
774    '1.2.804.2.1.1.1.1.3.1.1': ('DSTU 4145-2002 little endian', 'dstu4145le'),
775    '1.2.804.2.1.1.1.1.3.1.1.1.1': ('DSTU 4145-2002 big endian', 'dstu4145be'),
776    '1.2.804.2.1.1.1.1.3.1.1.2.0': ('DSTU curve 0', 'uacurve0'),
777    '1.2.804.2.1.1.1.1.3.1.1.2.1': ('DSTU curve 1', 'uacurve1'),
778    '1.2.804.2.1.1.1.1.3.1.1.2.2': ('DSTU curve 2', 'uacurve2'),
779    '1.2.804.2.1.1.1.1.3.1.1.2.3': ('DSTU curve 3', 'uacurve3'),
780    '1.2.804.2.1.1.1.1.3.1.1.2.4': ('DSTU curve 4', 'uacurve4'),
781    '1.2.804.2.1.1.1.1.3.1.1.2.5': ('DSTU curve 5', 'uacurve5'),
782    '1.2.804.2.1.1.1.1.3.1.1.2.6': ('DSTU curve 6', 'uacurve6'),
783    '1.2.804.2.1.1.1.1.3.1.1.2.7': ('DSTU curve 7', 'uacurve7'),
784    '1.2.804.2.1.1.1.1.3.1.1.2.8': ('DSTU curve 8', 'uacurve8'),
785    '1.2.804.2.1.1.1.1.3.1.1.2.9': ('DSTU curve 9', 'uacurve9'),
786    '1.2.840': ('ISO US Member Body', 'ISO-US'),
787    '1.2.840.10040': ('X9.57', 'X9-57'),
788    '1.2.840.10040.2': ('holdInstruction', ),
789    '1.2.840.10040.2.1': ('Hold Instruction None', 'holdInstructionNone'),
790    '1.2.840.10040.2.2': ('Hold Instruction Call Issuer', 'holdInstructionCallIssuer'),
791    '1.2.840.10040.2.3': ('Hold Instruction Reject', 'holdInstructionReject'),
792    '1.2.840.10040.4': ('X9.57 CM ?', 'X9cm'),
793    '1.2.840.10040.4.1': ('dsaEncryption', 'DSA'),
794    '1.2.840.10040.4.3': ('dsaWithSHA1', 'DSA-SHA1'),
795    '1.2.840.10045': ('ANSI X9.62', 'ansi-X9-62'),
796    '1.2.840.10045.1': ('id-fieldType', ),
797    '1.2.840.10045.1.1': ('prime-field', ),
798    '1.2.840.10045.1.2': ('characteristic-two-field', ),
799    '1.2.840.10045.1.2.3': ('id-characteristic-two-basis', ),
800    '1.2.840.10045.1.2.3.1': ('onBasis', ),
801    '1.2.840.10045.1.2.3.2': ('tpBasis', ),
802    '1.2.840.10045.1.2.3.3': ('ppBasis', ),
803    '1.2.840.10045.2': ('id-publicKeyType', ),
804    '1.2.840.10045.2.1': ('id-ecPublicKey', ),
805    '1.2.840.10045.3': ('ellipticCurve', ),
806    '1.2.840.10045.3.0': ('c-TwoCurve', ),
807    '1.2.840.10045.3.0.1': ('c2pnb163v1', ),
808    '1.2.840.10045.3.0.2': ('c2pnb163v2', ),
809    '1.2.840.10045.3.0.3': ('c2pnb163v3', ),
810    '1.2.840.10045.3.0.4': ('c2pnb176v1', ),
811    '1.2.840.10045.3.0.5': ('c2tnb191v1', ),
812    '1.2.840.10045.3.0.6': ('c2tnb191v2', ),
813    '1.2.840.10045.3.0.7': ('c2tnb191v3', ),
814    '1.2.840.10045.3.0.8': ('c2onb191v4', ),
815    '1.2.840.10045.3.0.9': ('c2onb191v5', ),
816    '1.2.840.10045.3.0.10': ('c2pnb208w1', ),
817    '1.2.840.10045.3.0.11': ('c2tnb239v1', ),
818    '1.2.840.10045.3.0.12': ('c2tnb239v2', ),
819    '1.2.840.10045.3.0.13': ('c2tnb239v3', ),
820    '1.2.840.10045.3.0.14': ('c2onb239v4', ),
821    '1.2.840.10045.3.0.15': ('c2onb239v5', ),
822    '1.2.840.10045.3.0.16': ('c2pnb272w1', ),
823    '1.2.840.10045.3.0.17': ('c2pnb304w1', ),
824    '1.2.840.10045.3.0.18': ('c2tnb359v1', ),
825    '1.2.840.10045.3.0.19': ('c2pnb368w1', ),
826    '1.2.840.10045.3.0.20': ('c2tnb431r1', ),
827    '1.2.840.10045.3.1': ('primeCurve', ),
828    '1.2.840.10045.3.1.1': ('prime192v1', ),
829    '1.2.840.10045.3.1.2': ('prime192v2', ),
830    '1.2.840.10045.3.1.3': ('prime192v3', ),
831    '1.2.840.10045.3.1.4': ('prime239v1', ),
832    '1.2.840.10045.3.1.5': ('prime239v2', ),
833    '1.2.840.10045.3.1.6': ('prime239v3', ),
834    '1.2.840.10045.3.1.7': ('prime256v1', ),
835    '1.2.840.10045.4': ('id-ecSigType', ),
836    '1.2.840.10045.4.1': ('ecdsa-with-SHA1', ),
837    '1.2.840.10045.4.2': ('ecdsa-with-Recommended', ),
838    '1.2.840.10045.4.3': ('ecdsa-with-Specified', ),
839    '1.2.840.10045.4.3.1': ('ecdsa-with-SHA224', ),
840    '1.2.840.10045.4.3.2': ('ecdsa-with-SHA256', ),
841    '1.2.840.10045.4.3.3': ('ecdsa-with-SHA384', ),
842    '1.2.840.10045.4.3.4': ('ecdsa-with-SHA512', ),
843    '1.2.840.10046.2.1': ('X9.42 DH', 'dhpublicnumber'),
844    '1.2.840.113533.7.66.10': ('cast5-cbc', 'CAST5-CBC'),
845    '1.2.840.113533.7.66.12': ('pbeWithMD5AndCast5CBC', ),
846    '1.2.840.113533.7.66.13': ('password based MAC', 'id-PasswordBasedMAC'),
847    '1.2.840.113533.7.66.30': ('Diffie-Hellman based MAC', 'id-DHBasedMac'),
848    '1.2.840.113549': ('RSA Data Security, Inc.', 'rsadsi'),
849    '1.2.840.113549.1': ('RSA Data Security, Inc. PKCS', 'pkcs'),
850    '1.2.840.113549.1.1': ('pkcs1', ),
851    '1.2.840.113549.1.1.1': ('rsaEncryption', ),
852    '1.2.840.113549.1.1.2': ('md2WithRSAEncryption', 'RSA-MD2'),
853    '1.2.840.113549.1.1.3': ('md4WithRSAEncryption', 'RSA-MD4'),
854    '1.2.840.113549.1.1.4': ('md5WithRSAEncryption', 'RSA-MD5'),
855    '1.2.840.113549.1.1.5': ('sha1WithRSAEncryption', 'RSA-SHA1'),
856    '1.2.840.113549.1.1.6': ('rsaOAEPEncryptionSET', ),
857    '1.2.840.113549.1.1.7': ('rsaesOaep', 'RSAES-OAEP'),
858    '1.2.840.113549.1.1.8': ('mgf1', 'MGF1'),
859    '1.2.840.113549.1.1.9': ('pSpecified', 'PSPECIFIED'),
860    '1.2.840.113549.1.1.10': ('rsassaPss', 'RSASSA-PSS'),
861    '1.2.840.113549.1.1.11': ('sha256WithRSAEncryption', 'RSA-SHA256'),
862    '1.2.840.113549.1.1.12': ('sha384WithRSAEncryption', 'RSA-SHA384'),
863    '1.2.840.113549.1.1.13': ('sha512WithRSAEncryption', 'RSA-SHA512'),
864    '1.2.840.113549.1.1.14': ('sha224WithRSAEncryption', 'RSA-SHA224'),
865    '1.2.840.113549.1.1.15': ('sha512-224WithRSAEncryption', 'RSA-SHA512/224'),
866    '1.2.840.113549.1.1.16': ('sha512-256WithRSAEncryption', 'RSA-SHA512/256'),
867    '1.2.840.113549.1.3': ('pkcs3', ),
868    '1.2.840.113549.1.3.1': ('dhKeyAgreement', ),
869    '1.2.840.113549.1.5': ('pkcs5', ),
870    '1.2.840.113549.1.5.1': ('pbeWithMD2AndDES-CBC', 'PBE-MD2-DES'),
871    '1.2.840.113549.1.5.3': ('pbeWithMD5AndDES-CBC', 'PBE-MD5-DES'),
872    '1.2.840.113549.1.5.4': ('pbeWithMD2AndRC2-CBC', 'PBE-MD2-RC2-64'),
873    '1.2.840.113549.1.5.6': ('pbeWithMD5AndRC2-CBC', 'PBE-MD5-RC2-64'),
874    '1.2.840.113549.1.5.10': ('pbeWithSHA1AndDES-CBC', 'PBE-SHA1-DES'),
875    '1.2.840.113549.1.5.11': ('pbeWithSHA1AndRC2-CBC', 'PBE-SHA1-RC2-64'),
876    '1.2.840.113549.1.5.12': ('PBKDF2', ),
877    '1.2.840.113549.1.5.13': ('PBES2', ),
878    '1.2.840.113549.1.5.14': ('PBMAC1', ),
879    '1.2.840.113549.1.7': ('pkcs7', ),
880    '1.2.840.113549.1.7.1': ('pkcs7-data', ),
881    '1.2.840.113549.1.7.2': ('pkcs7-signedData', ),
882    '1.2.840.113549.1.7.3': ('pkcs7-envelopedData', ),
883    '1.2.840.113549.1.7.4': ('pkcs7-signedAndEnvelopedData', ),
884    '1.2.840.113549.1.7.5': ('pkcs7-digestData', ),
885    '1.2.840.113549.1.7.6': ('pkcs7-encryptedData', ),
886    '1.2.840.113549.1.9': ('pkcs9', ),
887    '1.2.840.113549.1.9.1': ('emailAddress', ),
888    '1.2.840.113549.1.9.2': ('unstructuredName', ),
889    '1.2.840.113549.1.9.3': ('contentType', ),
890    '1.2.840.113549.1.9.4': ('messageDigest', ),
891    '1.2.840.113549.1.9.5': ('signingTime', ),
892    '1.2.840.113549.1.9.6': ('countersignature', ),
893    '1.2.840.113549.1.9.7': ('challengePassword', ),
894    '1.2.840.113549.1.9.8': ('unstructuredAddress', ),
895    '1.2.840.113549.1.9.9': ('extendedCertificateAttributes', ),
896    '1.2.840.113549.1.9.14': ('Extension Request', 'extReq'),
897    '1.2.840.113549.1.9.15': ('S/MIME Capabilities', 'SMIME-CAPS'),
898    '1.2.840.113549.1.9.16': ('S/MIME', 'SMIME'),
899    '1.2.840.113549.1.9.16.0': ('id-smime-mod', ),
900    '1.2.840.113549.1.9.16.0.1': ('id-smime-mod-cms', ),
901    '1.2.840.113549.1.9.16.0.2': ('id-smime-mod-ess', ),
902    '1.2.840.113549.1.9.16.0.3': ('id-smime-mod-oid', ),
903    '1.2.840.113549.1.9.16.0.4': ('id-smime-mod-msg-v3', ),
904    '1.2.840.113549.1.9.16.0.5': ('id-smime-mod-ets-eSignature-88', ),
905    '1.2.840.113549.1.9.16.0.6': ('id-smime-mod-ets-eSignature-97', ),
906    '1.2.840.113549.1.9.16.0.7': ('id-smime-mod-ets-eSigPolicy-88', ),
907    '1.2.840.113549.1.9.16.0.8': ('id-smime-mod-ets-eSigPolicy-97', ),
908    '1.2.840.113549.1.9.16.1': ('id-smime-ct', ),
909    '1.2.840.113549.1.9.16.1.1': ('id-smime-ct-receipt', ),
910    '1.2.840.113549.1.9.16.1.2': ('id-smime-ct-authData', ),
911    '1.2.840.113549.1.9.16.1.3': ('id-smime-ct-publishCert', ),
912    '1.2.840.113549.1.9.16.1.4': ('id-smime-ct-TSTInfo', ),
913    '1.2.840.113549.1.9.16.1.5': ('id-smime-ct-TDTInfo', ),
914    '1.2.840.113549.1.9.16.1.6': ('id-smime-ct-contentInfo', ),
915    '1.2.840.113549.1.9.16.1.7': ('id-smime-ct-DVCSRequestData', ),
916    '1.2.840.113549.1.9.16.1.8': ('id-smime-ct-DVCSResponseData', ),
917    '1.2.840.113549.1.9.16.1.9': ('id-smime-ct-compressedData', ),
918    '1.2.840.113549.1.9.16.1.19': ('id-smime-ct-contentCollection', ),
919    '1.2.840.113549.1.9.16.1.23': ('id-smime-ct-authEnvelopedData', ),
920    '1.2.840.113549.1.9.16.1.27': ('id-ct-asciiTextWithCRLF', ),
921    '1.2.840.113549.1.9.16.1.28': ('id-ct-xml', ),
922    '1.2.840.113549.1.9.16.2': ('id-smime-aa', ),
923    '1.2.840.113549.1.9.16.2.1': ('id-smime-aa-receiptRequest', ),
924    '1.2.840.113549.1.9.16.2.2': ('id-smime-aa-securityLabel', ),
925    '1.2.840.113549.1.9.16.2.3': ('id-smime-aa-mlExpandHistory', ),
926    '1.2.840.113549.1.9.16.2.4': ('id-smime-aa-contentHint', ),
927    '1.2.840.113549.1.9.16.2.5': ('id-smime-aa-msgSigDigest', ),
928    '1.2.840.113549.1.9.16.2.6': ('id-smime-aa-encapContentType', ),
929    '1.2.840.113549.1.9.16.2.7': ('id-smime-aa-contentIdentifier', ),
930    '1.2.840.113549.1.9.16.2.8': ('id-smime-aa-macValue', ),
931    '1.2.840.113549.1.9.16.2.9': ('id-smime-aa-equivalentLabels', ),
932    '1.2.840.113549.1.9.16.2.10': ('id-smime-aa-contentReference', ),
933    '1.2.840.113549.1.9.16.2.11': ('id-smime-aa-encrypKeyPref', ),
934    '1.2.840.113549.1.9.16.2.12': ('id-smime-aa-signingCertificate', ),
935    '1.2.840.113549.1.9.16.2.13': ('id-smime-aa-smimeEncryptCerts', ),
936    '1.2.840.113549.1.9.16.2.14': ('id-smime-aa-timeStampToken', ),
937    '1.2.840.113549.1.9.16.2.15': ('id-smime-aa-ets-sigPolicyId', ),
938    '1.2.840.113549.1.9.16.2.16': ('id-smime-aa-ets-commitmentType', ),
939    '1.2.840.113549.1.9.16.2.17': ('id-smime-aa-ets-signerLocation', ),
940    '1.2.840.113549.1.9.16.2.18': ('id-smime-aa-ets-signerAttr', ),
941    '1.2.840.113549.1.9.16.2.19': ('id-smime-aa-ets-otherSigCert', ),
942    '1.2.840.113549.1.9.16.2.20': ('id-smime-aa-ets-contentTimestamp', ),
943    '1.2.840.113549.1.9.16.2.21': ('id-smime-aa-ets-CertificateRefs', ),
944    '1.2.840.113549.1.9.16.2.22': ('id-smime-aa-ets-RevocationRefs', ),
945    '1.2.840.113549.1.9.16.2.23': ('id-smime-aa-ets-certValues', ),
946    '1.2.840.113549.1.9.16.2.24': ('id-smime-aa-ets-revocationValues', ),
947    '1.2.840.113549.1.9.16.2.25': ('id-smime-aa-ets-escTimeStamp', ),
948    '1.2.840.113549.1.9.16.2.26': ('id-smime-aa-ets-certCRLTimestamp', ),
949    '1.2.840.113549.1.9.16.2.27': ('id-smime-aa-ets-archiveTimeStamp', ),
950    '1.2.840.113549.1.9.16.2.28': ('id-smime-aa-signatureType', ),
951    '1.2.840.113549.1.9.16.2.29': ('id-smime-aa-dvcs-dvc', ),
952    '1.2.840.113549.1.9.16.2.47': ('id-smime-aa-signingCertificateV2', ),
953    '1.2.840.113549.1.9.16.3': ('id-smime-alg', ),
954    '1.2.840.113549.1.9.16.3.1': ('id-smime-alg-ESDHwith3DES', ),
955    '1.2.840.113549.1.9.16.3.2': ('id-smime-alg-ESDHwithRC2', ),
956    '1.2.840.113549.1.9.16.3.3': ('id-smime-alg-3DESwrap', ),
957    '1.2.840.113549.1.9.16.3.4': ('id-smime-alg-RC2wrap', ),
958    '1.2.840.113549.1.9.16.3.5': ('id-smime-alg-ESDH', ),
959    '1.2.840.113549.1.9.16.3.6': ('id-smime-alg-CMS3DESwrap', ),
960    '1.2.840.113549.1.9.16.3.7': ('id-smime-alg-CMSRC2wrap', ),
961    '1.2.840.113549.1.9.16.3.8': ('zlib compression', 'ZLIB'),
962    '1.2.840.113549.1.9.16.3.9': ('id-alg-PWRI-KEK', ),
963    '1.2.840.113549.1.9.16.4': ('id-smime-cd', ),
964    '1.2.840.113549.1.9.16.4.1': ('id-smime-cd-ldap', ),
965    '1.2.840.113549.1.9.16.5': ('id-smime-spq', ),
966    '1.2.840.113549.1.9.16.5.1': ('id-smime-spq-ets-sqt-uri', ),
967    '1.2.840.113549.1.9.16.5.2': ('id-smime-spq-ets-sqt-unotice', ),
968    '1.2.840.113549.1.9.16.6': ('id-smime-cti', ),
969    '1.2.840.113549.1.9.16.6.1': ('id-smime-cti-ets-proofOfOrigin', ),
970    '1.2.840.113549.1.9.16.6.2': ('id-smime-cti-ets-proofOfReceipt', ),
971    '1.2.840.113549.1.9.16.6.3': ('id-smime-cti-ets-proofOfDelivery', ),
972    '1.2.840.113549.1.9.16.6.4': ('id-smime-cti-ets-proofOfSender', ),
973    '1.2.840.113549.1.9.16.6.5': ('id-smime-cti-ets-proofOfApproval', ),
974    '1.2.840.113549.1.9.16.6.6': ('id-smime-cti-ets-proofOfCreation', ),
975    '1.2.840.113549.1.9.20': ('friendlyName', ),
976    '1.2.840.113549.1.9.21': ('localKeyID', ),
977    '1.2.840.113549.1.9.22': ('certTypes', ),
978    '1.2.840.113549.1.9.22.1': ('x509Certificate', ),
979    '1.2.840.113549.1.9.22.2': ('sdsiCertificate', ),
980    '1.2.840.113549.1.9.23': ('crlTypes', ),
981    '1.2.840.113549.1.9.23.1': ('x509Crl', ),
982    '1.2.840.113549.1.12': ('pkcs12', ),
983    '1.2.840.113549.1.12.1': ('pkcs12-pbeids', ),
984    '1.2.840.113549.1.12.1.1': ('pbeWithSHA1And128BitRC4', 'PBE-SHA1-RC4-128'),
985    '1.2.840.113549.1.12.1.2': ('pbeWithSHA1And40BitRC4', 'PBE-SHA1-RC4-40'),
986    '1.2.840.113549.1.12.1.3': ('pbeWithSHA1And3-KeyTripleDES-CBC', 'PBE-SHA1-3DES'),
987    '1.2.840.113549.1.12.1.4': ('pbeWithSHA1And2-KeyTripleDES-CBC', 'PBE-SHA1-2DES'),
988    '1.2.840.113549.1.12.1.5': ('pbeWithSHA1And128BitRC2-CBC', 'PBE-SHA1-RC2-128'),
989    '1.2.840.113549.1.12.1.6': ('pbeWithSHA1And40BitRC2-CBC', 'PBE-SHA1-RC2-40'),
990    '1.2.840.113549.1.12.10': ('pkcs12-Version1', ),
991    '1.2.840.113549.1.12.10.1': ('pkcs12-BagIds', ),
992    '1.2.840.113549.1.12.10.1.1': ('keyBag', ),
993    '1.2.840.113549.1.12.10.1.2': ('pkcs8ShroudedKeyBag', ),
994    '1.2.840.113549.1.12.10.1.3': ('certBag', ),
995    '1.2.840.113549.1.12.10.1.4': ('crlBag', ),
996    '1.2.840.113549.1.12.10.1.5': ('secretBag', ),
997    '1.2.840.113549.1.12.10.1.6': ('safeContentsBag', ),
998    '1.2.840.113549.2.2': ('md2', 'MD2'),
999    '1.2.840.113549.2.4': ('md4', 'MD4'),
1000    '1.2.840.113549.2.5': ('md5', 'MD5'),
1001    '1.2.840.113549.2.6': ('hmacWithMD5', ),
1002    '1.2.840.113549.2.7': ('hmacWithSHA1', ),
1003    '1.2.840.113549.2.8': ('hmacWithSHA224', ),
1004    '1.2.840.113549.2.9': ('hmacWithSHA256', ),
1005    '1.2.840.113549.2.10': ('hmacWithSHA384', ),
1006    '1.2.840.113549.2.11': ('hmacWithSHA512', ),
1007    '1.2.840.113549.2.12': ('hmacWithSHA512-224', ),
1008    '1.2.840.113549.2.13': ('hmacWithSHA512-256', ),
1009    '1.2.840.113549.3.2': ('rc2-cbc', 'RC2-CBC'),
1010    '1.2.840.113549.3.4': ('rc4', 'RC4'),
1011    '1.2.840.113549.3.7': ('des-ede3-cbc', 'DES-EDE3-CBC'),
1012    '1.2.840.113549.3.8': ('rc5-cbc', 'RC5-CBC'),
1013    '1.2.840.113549.3.10': ('des-cdmf', 'DES-CDMF'),
1014    '1.3': ('identified-organization', 'org', 'ORG'),
1015    '1.3.6': ('dod', 'DOD'),
1016    '1.3.6.1': ('iana', 'IANA', 'internet'),
1017    '1.3.6.1.1': ('Directory', 'directory'),
1018    '1.3.6.1.2': ('Management', 'mgmt'),
1019    '1.3.6.1.3': ('Experimental', 'experimental'),
1020    '1.3.6.1.4': ('Private', 'private'),
1021    '1.3.6.1.4.1': ('Enterprises', 'enterprises'),
1022    '1.3.6.1.4.1.188.7.1.1.2': ('idea-cbc', 'IDEA-CBC'),
1023    '1.3.6.1.4.1.311.2.1.14': ('Microsoft Extension Request', 'msExtReq'),
1024    '1.3.6.1.4.1.311.2.1.21': ('Microsoft Individual Code Signing', 'msCodeInd'),
1025    '1.3.6.1.4.1.311.2.1.22': ('Microsoft Commercial Code Signing', 'msCodeCom'),
1026    '1.3.6.1.4.1.311.10.3.1': ('Microsoft Trust List Signing', 'msCTLSign'),
1027    '1.3.6.1.4.1.311.10.3.3': ('Microsoft Server Gated Crypto', 'msSGC'),
1028    '1.3.6.1.4.1.311.10.3.4': ('Microsoft Encrypted File System', 'msEFS'),
1029    '1.3.6.1.4.1.311.17.1': ('Microsoft CSP Name', 'CSPName'),
1030    '1.3.6.1.4.1.311.17.2': ('Microsoft Local Key set', 'LocalKeySet'),
1031    '1.3.6.1.4.1.311.20.2.2': ('Microsoft Smartcardlogin', 'msSmartcardLogin'),
1032    '1.3.6.1.4.1.311.20.2.3': ('Microsoft Universal Principal Name', 'msUPN'),
1033    '1.3.6.1.4.1.311.60.2.1.1': ('jurisdictionLocalityName', 'jurisdictionL'),
1034    '1.3.6.1.4.1.311.60.2.1.2': ('jurisdictionStateOrProvinceName', 'jurisdictionST'),
1035    '1.3.6.1.4.1.311.60.2.1.3': ('jurisdictionCountryName', 'jurisdictionC'),
1036    '1.3.6.1.4.1.1466.344': ('dcObject', 'dcobject'),
1037    '1.3.6.1.4.1.1722.12.2.1.16': ('blake2b512', 'BLAKE2b512'),
1038    '1.3.6.1.4.1.1722.12.2.2.8': ('blake2s256', 'BLAKE2s256'),
1039    '1.3.6.1.4.1.3029.1.2': ('bf-cbc', 'BF-CBC'),
1040    '1.3.6.1.4.1.11129.2.4.2': ('CT Precertificate SCTs', 'ct_precert_scts'),
1041    '1.3.6.1.4.1.11129.2.4.3': ('CT Precertificate Poison', 'ct_precert_poison'),
1042    '1.3.6.1.4.1.11129.2.4.4': ('CT Precertificate Signer', 'ct_precert_signer'),
1043    '1.3.6.1.4.1.11129.2.4.5': ('CT Certificate SCTs', 'ct_cert_scts'),
1044    '1.3.6.1.4.1.11591.4.11': ('scrypt', 'id-scrypt'),
1045    '1.3.6.1.5': ('Security', 'security'),
1046    '1.3.6.1.5.2.3': ('id-pkinit', ),
1047    '1.3.6.1.5.2.3.4': ('PKINIT Client Auth', 'pkInitClientAuth'),
1048    '1.3.6.1.5.2.3.5': ('Signing KDC Response', 'pkInitKDC'),
1049    '1.3.6.1.5.5.7': ('PKIX', ),
1050    '1.3.6.1.5.5.7.0': ('id-pkix-mod', ),
1051    '1.3.6.1.5.5.7.0.1': ('id-pkix1-explicit-88', ),
1052    '1.3.6.1.5.5.7.0.2': ('id-pkix1-implicit-88', ),
1053    '1.3.6.1.5.5.7.0.3': ('id-pkix1-explicit-93', ),
1054    '1.3.6.1.5.5.7.0.4': ('id-pkix1-implicit-93', ),
1055    '1.3.6.1.5.5.7.0.5': ('id-mod-crmf', ),
1056    '1.3.6.1.5.5.7.0.6': ('id-mod-cmc', ),
1057    '1.3.6.1.5.5.7.0.7': ('id-mod-kea-profile-88', ),
1058    '1.3.6.1.5.5.7.0.8': ('id-mod-kea-profile-93', ),
1059    '1.3.6.1.5.5.7.0.9': ('id-mod-cmp', ),
1060    '1.3.6.1.5.5.7.0.10': ('id-mod-qualified-cert-88', ),
1061    '1.3.6.1.5.5.7.0.11': ('id-mod-qualified-cert-93', ),
1062    '1.3.6.1.5.5.7.0.12': ('id-mod-attribute-cert', ),
1063    '1.3.6.1.5.5.7.0.13': ('id-mod-timestamp-protocol', ),
1064    '1.3.6.1.5.5.7.0.14': ('id-mod-ocsp', ),
1065    '1.3.6.1.5.5.7.0.15': ('id-mod-dvcs', ),
1066    '1.3.6.1.5.5.7.0.16': ('id-mod-cmp2000', ),
1067    '1.3.6.1.5.5.7.1': ('id-pe', ),
1068    '1.3.6.1.5.5.7.1.1': ('Authority Information Access', 'authorityInfoAccess'),
1069    '1.3.6.1.5.5.7.1.2': ('Biometric Info', 'biometricInfo'),
1070    '1.3.6.1.5.5.7.1.3': ('qcStatements', ),
1071    '1.3.6.1.5.5.7.1.4': ('ac-auditEntity', ),
1072    '1.3.6.1.5.5.7.1.5': ('ac-targeting', ),
1073    '1.3.6.1.5.5.7.1.6': ('aaControls', ),
1074    '1.3.6.1.5.5.7.1.7': ('sbgp-ipAddrBlock', ),
1075    '1.3.6.1.5.5.7.1.8': ('sbgp-autonomousSysNum', ),
1076    '1.3.6.1.5.5.7.1.9': ('sbgp-routerIdentifier', ),
1077    '1.3.6.1.5.5.7.1.10': ('ac-proxying', ),
1078    '1.3.6.1.5.5.7.1.11': ('Subject Information Access', 'subjectInfoAccess'),
1079    '1.3.6.1.5.5.7.1.14': ('Proxy Certificate Information', 'proxyCertInfo'),
1080    '1.3.6.1.5.5.7.1.24': ('TLS Feature', 'tlsfeature'),
1081    '1.3.6.1.5.5.7.2': ('id-qt', ),
1082    '1.3.6.1.5.5.7.2.1': ('Policy Qualifier CPS', 'id-qt-cps'),
1083    '1.3.6.1.5.5.7.2.2': ('Policy Qualifier User Notice', 'id-qt-unotice'),
1084    '1.3.6.1.5.5.7.2.3': ('textNotice', ),
1085    '1.3.6.1.5.5.7.3': ('id-kp', ),
1086    '1.3.6.1.5.5.7.3.1': ('TLS Web Server Authentication', 'serverAuth'),
1087    '1.3.6.1.5.5.7.3.2': ('TLS Web Client Authentication', 'clientAuth'),
1088    '1.3.6.1.5.5.7.3.3': ('Code Signing', 'codeSigning'),
1089    '1.3.6.1.5.5.7.3.4': ('E-mail Protection', 'emailProtection'),
1090    '1.3.6.1.5.5.7.3.5': ('IPSec End System', 'ipsecEndSystem'),
1091    '1.3.6.1.5.5.7.3.6': ('IPSec Tunnel', 'ipsecTunnel'),
1092    '1.3.6.1.5.5.7.3.7': ('IPSec User', 'ipsecUser'),
1093    '1.3.6.1.5.5.7.3.8': ('Time Stamping', 'timeStamping'),
1094    '1.3.6.1.5.5.7.3.9': ('OCSP Signing', 'OCSPSigning'),
1095    '1.3.6.1.5.5.7.3.10': ('dvcs', 'DVCS'),
1096    '1.3.6.1.5.5.7.3.17': ('ipsec Internet Key Exchange', 'ipsecIKE'),
1097    '1.3.6.1.5.5.7.3.18': ('Ctrl/provision WAP Access', 'capwapAC'),
1098    '1.3.6.1.5.5.7.3.19': ('Ctrl/Provision WAP Termination', 'capwapWTP'),
1099    '1.3.6.1.5.5.7.3.21': ('SSH Client', 'secureShellClient'),
1100    '1.3.6.1.5.5.7.3.22': ('SSH Server', 'secureShellServer'),
1101    '1.3.6.1.5.5.7.3.23': ('Send Router', 'sendRouter'),
1102    '1.3.6.1.5.5.7.3.24': ('Send Proxied Router', 'sendProxiedRouter'),
1103    '1.3.6.1.5.5.7.3.25': ('Send Owner', 'sendOwner'),
1104    '1.3.6.1.5.5.7.3.26': ('Send Proxied Owner', 'sendProxiedOwner'),
1105    '1.3.6.1.5.5.7.3.27': ('CMC Certificate Authority', 'cmcCA'),
1106    '1.3.6.1.5.5.7.3.28': ('CMC Registration Authority', 'cmcRA'),
1107    '1.3.6.1.5.5.7.4': ('id-it', ),
1108    '1.3.6.1.5.5.7.4.1': ('id-it-caProtEncCert', ),
1109    '1.3.6.1.5.5.7.4.2': ('id-it-signKeyPairTypes', ),
1110    '1.3.6.1.5.5.7.4.3': ('id-it-encKeyPairTypes', ),
1111    '1.3.6.1.5.5.7.4.4': ('id-it-preferredSymmAlg', ),
1112    '1.3.6.1.5.5.7.4.5': ('id-it-caKeyUpdateInfo', ),
1113    '1.3.6.1.5.5.7.4.6': ('id-it-currentCRL', ),
1114    '1.3.6.1.5.5.7.4.7': ('id-it-unsupportedOIDs', ),
1115    '1.3.6.1.5.5.7.4.8': ('id-it-subscriptionRequest', ),
1116    '1.3.6.1.5.5.7.4.9': ('id-it-subscriptionResponse', ),
1117    '1.3.6.1.5.5.7.4.10': ('id-it-keyPairParamReq', ),
1118    '1.3.6.1.5.5.7.4.11': ('id-it-keyPairParamRep', ),
1119    '1.3.6.1.5.5.7.4.12': ('id-it-revPassphrase', ),
1120    '1.3.6.1.5.5.7.4.13': ('id-it-implicitConfirm', ),
1121    '1.3.6.1.5.5.7.4.14': ('id-it-confirmWaitTime', ),
1122    '1.3.6.1.5.5.7.4.15': ('id-it-origPKIMessage', ),
1123    '1.3.6.1.5.5.7.4.16': ('id-it-suppLangTags', ),
1124    '1.3.6.1.5.5.7.5': ('id-pkip', ),
1125    '1.3.6.1.5.5.7.5.1': ('id-regCtrl', ),
1126    '1.3.6.1.5.5.7.5.1.1': ('id-regCtrl-regToken', ),
1127    '1.3.6.1.5.5.7.5.1.2': ('id-regCtrl-authenticator', ),
1128    '1.3.6.1.5.5.7.5.1.3': ('id-regCtrl-pkiPublicationInfo', ),
1129    '1.3.6.1.5.5.7.5.1.4': ('id-regCtrl-pkiArchiveOptions', ),
1130    '1.3.6.1.5.5.7.5.1.5': ('id-regCtrl-oldCertID', ),
1131    '1.3.6.1.5.5.7.5.1.6': ('id-regCtrl-protocolEncrKey', ),
1132    '1.3.6.1.5.5.7.5.2': ('id-regInfo', ),
1133    '1.3.6.1.5.5.7.5.2.1': ('id-regInfo-utf8Pairs', ),
1134    '1.3.6.1.5.5.7.5.2.2': ('id-regInfo-certReq', ),
1135    '1.3.6.1.5.5.7.6': ('id-alg', ),
1136    '1.3.6.1.5.5.7.6.1': ('id-alg-des40', ),
1137    '1.3.6.1.5.5.7.6.2': ('id-alg-noSignature', ),
1138    '1.3.6.1.5.5.7.6.3': ('id-alg-dh-sig-hmac-sha1', ),
1139    '1.3.6.1.5.5.7.6.4': ('id-alg-dh-pop', ),
1140    '1.3.6.1.5.5.7.7': ('id-cmc', ),
1141    '1.3.6.1.5.5.7.7.1': ('id-cmc-statusInfo', ),
1142    '1.3.6.1.5.5.7.7.2': ('id-cmc-identification', ),
1143    '1.3.6.1.5.5.7.7.3': ('id-cmc-identityProof', ),
1144    '1.3.6.1.5.5.7.7.4': ('id-cmc-dataReturn', ),
1145    '1.3.6.1.5.5.7.7.5': ('id-cmc-transactionId', ),
1146    '1.3.6.1.5.5.7.7.6': ('id-cmc-senderNonce', ),
1147    '1.3.6.1.5.5.7.7.7': ('id-cmc-recipientNonce', ),
1148    '1.3.6.1.5.5.7.7.8': ('id-cmc-addExtensions', ),
1149    '1.3.6.1.5.5.7.7.9': ('id-cmc-encryptedPOP', ),
1150    '1.3.6.1.5.5.7.7.10': ('id-cmc-decryptedPOP', ),
1151    '1.3.6.1.5.5.7.7.11': ('id-cmc-lraPOPWitness', ),
1152    '1.3.6.1.5.5.7.7.15': ('id-cmc-getCert', ),
1153    '1.3.6.1.5.5.7.7.16': ('id-cmc-getCRL', ),
1154    '1.3.6.1.5.5.7.7.17': ('id-cmc-revokeRequest', ),
1155    '1.3.6.1.5.5.7.7.18': ('id-cmc-regInfo', ),
1156    '1.3.6.1.5.5.7.7.19': ('id-cmc-responseInfo', ),
1157    '1.3.6.1.5.5.7.7.21': ('id-cmc-queryPending', ),
1158    '1.3.6.1.5.5.7.7.22': ('id-cmc-popLinkRandom', ),
1159    '1.3.6.1.5.5.7.7.23': ('id-cmc-popLinkWitness', ),
1160    '1.3.6.1.5.5.7.7.24': ('id-cmc-confirmCertAcceptance', ),
1161    '1.3.6.1.5.5.7.8': ('id-on', ),
1162    '1.3.6.1.5.5.7.8.1': ('id-on-personalData', ),
1163    '1.3.6.1.5.5.7.8.3': ('Permanent Identifier', 'id-on-permanentIdentifier'),
1164    '1.3.6.1.5.5.7.9': ('id-pda', ),
1165    '1.3.6.1.5.5.7.9.1': ('id-pda-dateOfBirth', ),
1166    '1.3.6.1.5.5.7.9.2': ('id-pda-placeOfBirth', ),
1167    '1.3.6.1.5.5.7.9.3': ('id-pda-gender', ),
1168    '1.3.6.1.5.5.7.9.4': ('id-pda-countryOfCitizenship', ),
1169    '1.3.6.1.5.5.7.9.5': ('id-pda-countryOfResidence', ),
1170    '1.3.6.1.5.5.7.10': ('id-aca', ),
1171    '1.3.6.1.5.5.7.10.1': ('id-aca-authenticationInfo', ),
1172    '1.3.6.1.5.5.7.10.2': ('id-aca-accessIdentity', ),
1173    '1.3.6.1.5.5.7.10.3': ('id-aca-chargingIdentity', ),
1174    '1.3.6.1.5.5.7.10.4': ('id-aca-group', ),
1175    '1.3.6.1.5.5.7.10.5': ('id-aca-role', ),
1176    '1.3.6.1.5.5.7.10.6': ('id-aca-encAttrs', ),
1177    '1.3.6.1.5.5.7.11': ('id-qcs', ),
1178    '1.3.6.1.5.5.7.11.1': ('id-qcs-pkixQCSyntax-v1', ),
1179    '1.3.6.1.5.5.7.12': ('id-cct', ),
1180    '1.3.6.1.5.5.7.12.1': ('id-cct-crs', ),
1181    '1.3.6.1.5.5.7.12.2': ('id-cct-PKIData', ),
1182    '1.3.6.1.5.5.7.12.3': ('id-cct-PKIResponse', ),
1183    '1.3.6.1.5.5.7.21': ('id-ppl', ),
1184    '1.3.6.1.5.5.7.21.0': ('Any language', 'id-ppl-anyLanguage'),
1185    '1.3.6.1.5.5.7.21.1': ('Inherit all', 'id-ppl-inheritAll'),
1186    '1.3.6.1.5.5.7.21.2': ('Independent', 'id-ppl-independent'),
1187    '1.3.6.1.5.5.7.48': ('id-ad', ),
1188    '1.3.6.1.5.5.7.48.1': ('OCSP', 'OCSP', 'id-pkix-OCSP'),
1189    '1.3.6.1.5.5.7.48.1.1': ('Basic OCSP Response', 'basicOCSPResponse'),
1190    '1.3.6.1.5.5.7.48.1.2': ('OCSP Nonce', 'Nonce'),
1191    '1.3.6.1.5.5.7.48.1.3': ('OCSP CRL ID', 'CrlID'),
1192    '1.3.6.1.5.5.7.48.1.4': ('Acceptable OCSP Responses', 'acceptableResponses'),
1193    '1.3.6.1.5.5.7.48.1.5': ('OCSP No Check', 'noCheck'),
1194    '1.3.6.1.5.5.7.48.1.6': ('OCSP Archive Cutoff', 'archiveCutoff'),
1195    '1.3.6.1.5.5.7.48.1.7': ('OCSP Service Locator', 'serviceLocator'),
1196    '1.3.6.1.5.5.7.48.1.8': ('Extended OCSP Status', 'extendedStatus'),
1197    '1.3.6.1.5.5.7.48.1.9': ('valid', ),
1198    '1.3.6.1.5.5.7.48.1.10': ('path', ),
1199    '1.3.6.1.5.5.7.48.1.11': ('Trust Root', 'trustRoot'),
1200    '1.3.6.1.5.5.7.48.2': ('CA Issuers', 'caIssuers'),
1201    '1.3.6.1.5.5.7.48.3': ('AD Time Stamping', 'ad_timestamping'),
1202    '1.3.6.1.5.5.7.48.4': ('ad dvcs', 'AD_DVCS'),
1203    '1.3.6.1.5.5.7.48.5': ('CA Repository', 'caRepository'),
1204    '1.3.6.1.5.5.8.1.1': ('hmac-md5', 'HMAC-MD5'),
1205    '1.3.6.1.5.5.8.1.2': ('hmac-sha1', 'HMAC-SHA1'),
1206    '1.3.6.1.6': ('SNMPv2', 'snmpv2'),
1207    '1.3.6.1.7': ('Mail', ),
1208    '1.3.6.1.7.1': ('MIME MHS', 'mime-mhs'),
1209    '1.3.6.1.7.1.1': ('mime-mhs-headings', 'mime-mhs-headings'),
1210    '1.3.6.1.7.1.1.1': ('id-hex-partial-message', 'id-hex-partial-message'),
1211    '1.3.6.1.7.1.1.2': ('id-hex-multipart-message', 'id-hex-multipart-message'),
1212    '1.3.6.1.7.1.2': ('mime-mhs-bodies', 'mime-mhs-bodies'),
1213    '1.3.14.3.2': ('algorithm', 'algorithm'),
1214    '1.3.14.3.2.3': ('md5WithRSA', 'RSA-NP-MD5'),
1215    '1.3.14.3.2.6': ('des-ecb', 'DES-ECB'),
1216    '1.3.14.3.2.7': ('des-cbc', 'DES-CBC'),
1217    '1.3.14.3.2.8': ('des-ofb', 'DES-OFB'),
1218    '1.3.14.3.2.9': ('des-cfb', 'DES-CFB'),
1219    '1.3.14.3.2.11': ('rsaSignature', ),
1220    '1.3.14.3.2.12': ('dsaEncryption-old', 'DSA-old'),
1221    '1.3.14.3.2.13': ('dsaWithSHA', 'DSA-SHA'),
1222    '1.3.14.3.2.15': ('shaWithRSAEncryption', 'RSA-SHA'),
1223    '1.3.14.3.2.17': ('des-ede', 'DES-EDE'),
1224    '1.3.14.3.2.18': ('sha', 'SHA'),
1225    '1.3.14.3.2.26': ('sha1', 'SHA1'),
1226    '1.3.14.3.2.27': ('dsaWithSHA1-old', 'DSA-SHA1-old'),
1227    '1.3.14.3.2.29': ('sha1WithRSA', 'RSA-SHA1-2'),
1228    '1.3.36.3.2.1': ('ripemd160', 'RIPEMD160'),
1229    '1.3.36.3.3.1.2': ('ripemd160WithRSA', 'RSA-RIPEMD160'),
1230    '1.3.36.3.3.2.8.1.1.1': ('brainpoolP160r1', ),
1231    '1.3.36.3.3.2.8.1.1.2': ('brainpoolP160t1', ),
1232    '1.3.36.3.3.2.8.1.1.3': ('brainpoolP192r1', ),
1233    '1.3.36.3.3.2.8.1.1.4': ('brainpoolP192t1', ),
1234    '1.3.36.3.3.2.8.1.1.5': ('brainpoolP224r1', ),
1235    '1.3.36.3.3.2.8.1.1.6': ('brainpoolP224t1', ),
1236    '1.3.36.3.3.2.8.1.1.7': ('brainpoolP256r1', ),
1237    '1.3.36.3.3.2.8.1.1.8': ('brainpoolP256t1', ),
1238    '1.3.36.3.3.2.8.1.1.9': ('brainpoolP320r1', ),
1239    '1.3.36.3.3.2.8.1.1.10': ('brainpoolP320t1', ),
1240    '1.3.36.3.3.2.8.1.1.11': ('brainpoolP384r1', ),
1241    '1.3.36.3.3.2.8.1.1.12': ('brainpoolP384t1', ),
1242    '1.3.36.3.3.2.8.1.1.13': ('brainpoolP512r1', ),
1243    '1.3.36.3.3.2.8.1.1.14': ('brainpoolP512t1', ),
1244    '1.3.36.8.3.3': ('Professional Information or basis for Admission', 'x509ExtAdmission'),
1245    '1.3.101.1.4.1': ('Strong Extranet ID', 'SXNetID'),
1246    '1.3.101.110': ('X25519', ),
1247    '1.3.101.111': ('X448', ),
1248    '1.3.101.112': ('ED25519', ),
1249    '1.3.101.113': ('ED448', ),
1250    '1.3.111': ('ieee', ),
1251    '1.3.111.2.1619': ('IEEE Security in Storage Working Group', 'ieee-siswg'),
1252    '1.3.111.2.1619.0.1.1': ('aes-128-xts', 'AES-128-XTS'),
1253    '1.3.111.2.1619.0.1.2': ('aes-256-xts', 'AES-256-XTS'),
1254    '1.3.132': ('certicom-arc', ),
1255    '1.3.132.0': ('secg_ellipticCurve', ),
1256    '1.3.132.0.1': ('sect163k1', ),
1257    '1.3.132.0.2': ('sect163r1', ),
1258    '1.3.132.0.3': ('sect239k1', ),
1259    '1.3.132.0.4': ('sect113r1', ),
1260    '1.3.132.0.5': ('sect113r2', ),
1261    '1.3.132.0.6': ('secp112r1', ),
1262    '1.3.132.0.7': ('secp112r2', ),
1263    '1.3.132.0.8': ('secp160r1', ),
1264    '1.3.132.0.9': ('secp160k1', ),
1265    '1.3.132.0.10': ('secp256k1', ),
1266    '1.3.132.0.15': ('sect163r2', ),
1267    '1.3.132.0.16': ('sect283k1', ),
1268    '1.3.132.0.17': ('sect283r1', ),
1269    '1.3.132.0.22': ('sect131r1', ),
1270    '1.3.132.0.23': ('sect131r2', ),
1271    '1.3.132.0.24': ('sect193r1', ),
1272    '1.3.132.0.25': ('sect193r2', ),
1273    '1.3.132.0.26': ('sect233k1', ),
1274    '1.3.132.0.27': ('sect233r1', ),
1275    '1.3.132.0.28': ('secp128r1', ),
1276    '1.3.132.0.29': ('secp128r2', ),
1277    '1.3.132.0.30': ('secp160r2', ),
1278    '1.3.132.0.31': ('secp192k1', ),
1279    '1.3.132.0.32': ('secp224k1', ),
1280    '1.3.132.0.33': ('secp224r1', ),
1281    '1.3.132.0.34': ('secp384r1', ),
1282    '1.3.132.0.35': ('secp521r1', ),
1283    '1.3.132.0.36': ('sect409k1', ),
1284    '1.3.132.0.37': ('sect409r1', ),
1285    '1.3.132.0.38': ('sect571k1', ),
1286    '1.3.132.0.39': ('sect571r1', ),
1287    '1.3.132.1': ('secg-scheme', ),
1288    '1.3.132.1.11.0': ('dhSinglePass-stdDH-sha224kdf-scheme', ),
1289    '1.3.132.1.11.1': ('dhSinglePass-stdDH-sha256kdf-scheme', ),
1290    '1.3.132.1.11.2': ('dhSinglePass-stdDH-sha384kdf-scheme', ),
1291    '1.3.132.1.11.3': ('dhSinglePass-stdDH-sha512kdf-scheme', ),
1292    '1.3.132.1.14.0': ('dhSinglePass-cofactorDH-sha224kdf-scheme', ),
1293    '1.3.132.1.14.1': ('dhSinglePass-cofactorDH-sha256kdf-scheme', ),
1294    '1.3.132.1.14.2': ('dhSinglePass-cofactorDH-sha384kdf-scheme', ),
1295    '1.3.132.1.14.3': ('dhSinglePass-cofactorDH-sha512kdf-scheme', ),
1296    '1.3.133.16.840.63.0': ('x9-63-scheme', ),
1297    '1.3.133.16.840.63.0.2': ('dhSinglePass-stdDH-sha1kdf-scheme', ),
1298    '1.3.133.16.840.63.0.3': ('dhSinglePass-cofactorDH-sha1kdf-scheme', ),
1299    '2': ('joint-iso-itu-t', 'JOINT-ISO-ITU-T', 'joint-iso-ccitt'),
1300    '2.5': ('directory services (X.500)', 'X500'),
1301    '2.5.1.5': ('Selected Attribute Types', 'selected-attribute-types'),
1302    '2.5.1.5.55': ('clearance', ),
1303    '2.5.4': ('X509', ),
1304    '2.5.4.3': ('commonName', 'CN'),
1305    '2.5.4.4': ('surname', 'SN'),
1306    '2.5.4.5': ('serialNumber', ),
1307    '2.5.4.6': ('countryName', 'C'),
1308    '2.5.4.7': ('localityName', 'L'),
1309    '2.5.4.8': ('stateOrProvinceName', 'ST'),
1310    '2.5.4.9': ('streetAddress', 'street'),
1311    '2.5.4.10': ('organizationName', 'O'),
1312    '2.5.4.11': ('organizationalUnitName', 'OU'),
1313    '2.5.4.12': ('title', 'title'),
1314    '2.5.4.13': ('description', ),
1315    '2.5.4.14': ('searchGuide', ),
1316    '2.5.4.15': ('businessCategory', ),
1317    '2.5.4.16': ('postalAddress', ),
1318    '2.5.4.17': ('postalCode', ),
1319    '2.5.4.18': ('postOfficeBox', ),
1320    '2.5.4.19': ('physicalDeliveryOfficeName', ),
1321    '2.5.4.20': ('telephoneNumber', ),
1322    '2.5.4.21': ('telexNumber', ),
1323    '2.5.4.22': ('teletexTerminalIdentifier', ),
1324    '2.5.4.23': ('facsimileTelephoneNumber', ),
1325    '2.5.4.24': ('x121Address', ),
1326    '2.5.4.25': ('internationaliSDNNumber', ),
1327    '2.5.4.26': ('registeredAddress', ),
1328    '2.5.4.27': ('destinationIndicator', ),
1329    '2.5.4.28': ('preferredDeliveryMethod', ),
1330    '2.5.4.29': ('presentationAddress', ),
1331    '2.5.4.30': ('supportedApplicationContext', ),
1332    '2.5.4.31': ('member', ),
1333    '2.5.4.32': ('owner', ),
1334    '2.5.4.33': ('roleOccupant', ),
1335    '2.5.4.34': ('seeAlso', ),
1336    '2.5.4.35': ('userPassword', ),
1337    '2.5.4.36': ('userCertificate', ),
1338    '2.5.4.37': ('cACertificate', ),
1339    '2.5.4.38': ('authorityRevocationList', ),
1340    '2.5.4.39': ('certificateRevocationList', ),
1341    '2.5.4.40': ('crossCertificatePair', ),
1342    '2.5.4.41': ('name', 'name'),
1343    '2.5.4.42': ('givenName', 'GN'),
1344    '2.5.4.43': ('initials', 'initials'),
1345    '2.5.4.44': ('generationQualifier', ),
1346    '2.5.4.45': ('x500UniqueIdentifier', ),
1347    '2.5.4.46': ('dnQualifier', 'dnQualifier'),
1348    '2.5.4.47': ('enhancedSearchGuide', ),
1349    '2.5.4.48': ('protocolInformation', ),
1350    '2.5.4.49': ('distinguishedName', ),
1351    '2.5.4.50': ('uniqueMember', ),
1352    '2.5.4.51': ('houseIdentifier', ),
1353    '2.5.4.52': ('supportedAlgorithms', ),
1354    '2.5.4.53': ('deltaRevocationList', ),
1355    '2.5.4.54': ('dmdName', ),
1356    '2.5.4.65': ('pseudonym', ),
1357    '2.5.4.72': ('role', 'role'),
1358    '2.5.4.97': ('organizationIdentifier', ),
1359    '2.5.4.98': ('countryCode3c', 'c3'),
1360    '2.5.4.99': ('countryCode3n', 'n3'),
1361    '2.5.4.100': ('dnsName', ),
1362    '2.5.8': ('directory services - algorithms', 'X500algorithms'),
1363    '2.5.8.1.1': ('rsa', 'RSA'),
1364    '2.5.8.3.100': ('mdc2WithRSA', 'RSA-MDC2'),
1365    '2.5.8.3.101': ('mdc2', 'MDC2'),
1366    '2.5.29': ('id-ce', ),
1367    '2.5.29.9': ('X509v3 Subject Directory Attributes', 'subjectDirectoryAttributes'),
1368    '2.5.29.14': ('X509v3 Subject Key Identifier', 'subjectKeyIdentifier'),
1369    '2.5.29.15': ('X509v3 Key Usage', 'keyUsage'),
1370    '2.5.29.16': ('X509v3 Private Key Usage Period', 'privateKeyUsagePeriod'),
1371    '2.5.29.17': ('X509v3 Subject Alternative Name', 'subjectAltName'),
1372    '2.5.29.18': ('X509v3 Issuer Alternative Name', 'issuerAltName'),
1373    '2.5.29.19': ('X509v3 Basic Constraints', 'basicConstraints'),
1374    '2.5.29.20': ('X509v3 CRL Number', 'crlNumber'),
1375    '2.5.29.21': ('X509v3 CRL Reason Code', 'CRLReason'),
1376    '2.5.29.23': ('Hold Instruction Code', 'holdInstructionCode'),
1377    '2.5.29.24': ('Invalidity Date', 'invalidityDate'),
1378    '2.5.29.27': ('X509v3 Delta CRL Indicator', 'deltaCRL'),
1379    '2.5.29.28': ('X509v3 Issuing Distribution Point', 'issuingDistributionPoint'),
1380    '2.5.29.29': ('X509v3 Certificate Issuer', 'certificateIssuer'),
1381    '2.5.29.30': ('X509v3 Name Constraints', 'nameConstraints'),
1382    '2.5.29.31': ('X509v3 CRL Distribution Points', 'crlDistributionPoints'),
1383    '2.5.29.32': ('X509v3 Certificate Policies', 'certificatePolicies'),
1384    '2.5.29.32.0': ('X509v3 Any Policy', 'anyPolicy'),
1385    '2.5.29.33': ('X509v3 Policy Mappings', 'policyMappings'),
1386    '2.5.29.35': ('X509v3 Authority Key Identifier', 'authorityKeyIdentifier'),
1387    '2.5.29.36': ('X509v3 Policy Constraints', 'policyConstraints'),
1388    '2.5.29.37': ('X509v3 Extended Key Usage', 'extendedKeyUsage'),
1389    '2.5.29.37.0': ('Any Extended Key Usage', 'anyExtendedKeyUsage'),
1390    '2.5.29.46': ('X509v3 Freshest CRL', 'freshestCRL'),
1391    '2.5.29.54': ('X509v3 Inhibit Any Policy', 'inhibitAnyPolicy'),
1392    '2.5.29.55': ('X509v3 AC Targeting', 'targetInformation'),
1393    '2.5.29.56': ('X509v3 No Revocation Available', 'noRevAvail'),
1394    '2.16.840.1.101.3': ('csor', ),
1395    '2.16.840.1.101.3.4': ('nistAlgorithms', ),
1396    '2.16.840.1.101.3.4.1': ('aes', ),
1397    '2.16.840.1.101.3.4.1.1': ('aes-128-ecb', 'AES-128-ECB'),
1398    '2.16.840.1.101.3.4.1.2': ('aes-128-cbc', 'AES-128-CBC'),
1399    '2.16.840.1.101.3.4.1.3': ('aes-128-ofb', 'AES-128-OFB'),
1400    '2.16.840.1.101.3.4.1.4': ('aes-128-cfb', 'AES-128-CFB'),
1401    '2.16.840.1.101.3.4.1.5': ('id-aes128-wrap', ),
1402    '2.16.840.1.101.3.4.1.6': ('aes-128-gcm', 'id-aes128-GCM'),
1403    '2.16.840.1.101.3.4.1.7': ('aes-128-ccm', 'id-aes128-CCM'),
1404    '2.16.840.1.101.3.4.1.8': ('id-aes128-wrap-pad', ),
1405    '2.16.840.1.101.3.4.1.21': ('aes-192-ecb', 'AES-192-ECB'),
1406    '2.16.840.1.101.3.4.1.22': ('aes-192-cbc', 'AES-192-CBC'),
1407    '2.16.840.1.101.3.4.1.23': ('aes-192-ofb', 'AES-192-OFB'),
1408    '2.16.840.1.101.3.4.1.24': ('aes-192-cfb', 'AES-192-CFB'),
1409    '2.16.840.1.101.3.4.1.25': ('id-aes192-wrap', ),
1410    '2.16.840.1.101.3.4.1.26': ('aes-192-gcm', 'id-aes192-GCM'),
1411    '2.16.840.1.101.3.4.1.27': ('aes-192-ccm', 'id-aes192-CCM'),
1412    '2.16.840.1.101.3.4.1.28': ('id-aes192-wrap-pad', ),
1413    '2.16.840.1.101.3.4.1.41': ('aes-256-ecb', 'AES-256-ECB'),
1414    '2.16.840.1.101.3.4.1.42': ('aes-256-cbc', 'AES-256-CBC'),
1415    '2.16.840.1.101.3.4.1.43': ('aes-256-ofb', 'AES-256-OFB'),
1416    '2.16.840.1.101.3.4.1.44': ('aes-256-cfb', 'AES-256-CFB'),
1417    '2.16.840.1.101.3.4.1.45': ('id-aes256-wrap', ),
1418    '2.16.840.1.101.3.4.1.46': ('aes-256-gcm', 'id-aes256-GCM'),
1419    '2.16.840.1.101.3.4.1.47': ('aes-256-ccm', 'id-aes256-CCM'),
1420    '2.16.840.1.101.3.4.1.48': ('id-aes256-wrap-pad', ),
1421    '2.16.840.1.101.3.4.2': ('nist_hashalgs', ),
1422    '2.16.840.1.101.3.4.2.1': ('sha256', 'SHA256'),
1423    '2.16.840.1.101.3.4.2.2': ('sha384', 'SHA384'),
1424    '2.16.840.1.101.3.4.2.3': ('sha512', 'SHA512'),
1425    '2.16.840.1.101.3.4.2.4': ('sha224', 'SHA224'),
1426    '2.16.840.1.101.3.4.2.5': ('sha512-224', 'SHA512-224'),
1427    '2.16.840.1.101.3.4.2.6': ('sha512-256', 'SHA512-256'),
1428    '2.16.840.1.101.3.4.2.7': ('sha3-224', 'SHA3-224'),
1429    '2.16.840.1.101.3.4.2.8': ('sha3-256', 'SHA3-256'),
1430    '2.16.840.1.101.3.4.2.9': ('sha3-384', 'SHA3-384'),
1431    '2.16.840.1.101.3.4.2.10': ('sha3-512', 'SHA3-512'),
1432    '2.16.840.1.101.3.4.2.11': ('shake128', 'SHAKE128'),
1433    '2.16.840.1.101.3.4.2.12': ('shake256', 'SHAKE256'),
1434    '2.16.840.1.101.3.4.2.13': ('hmac-sha3-224', 'id-hmacWithSHA3-224'),
1435    '2.16.840.1.101.3.4.2.14': ('hmac-sha3-256', 'id-hmacWithSHA3-256'),
1436    '2.16.840.1.101.3.4.2.15': ('hmac-sha3-384', 'id-hmacWithSHA3-384'),
1437    '2.16.840.1.101.3.4.2.16': ('hmac-sha3-512', 'id-hmacWithSHA3-512'),
1438    '2.16.840.1.101.3.4.3': ('dsa_with_sha2', 'sigAlgs'),
1439    '2.16.840.1.101.3.4.3.1': ('dsa_with_SHA224', ),
1440    '2.16.840.1.101.3.4.3.2': ('dsa_with_SHA256', ),
1441    '2.16.840.1.101.3.4.3.3': ('dsa_with_SHA384', 'id-dsa-with-sha384'),
1442    '2.16.840.1.101.3.4.3.4': ('dsa_with_SHA512', 'id-dsa-with-sha512'),
1443    '2.16.840.1.101.3.4.3.5': ('dsa_with_SHA3-224', 'id-dsa-with-sha3-224'),
1444    '2.16.840.1.101.3.4.3.6': ('dsa_with_SHA3-256', 'id-dsa-with-sha3-256'),
1445    '2.16.840.1.101.3.4.3.7': ('dsa_with_SHA3-384', 'id-dsa-with-sha3-384'),
1446    '2.16.840.1.101.3.4.3.8': ('dsa_with_SHA3-512', 'id-dsa-with-sha3-512'),
1447    '2.16.840.1.101.3.4.3.9': ('ecdsa_with_SHA3-224', 'id-ecdsa-with-sha3-224'),
1448    '2.16.840.1.101.3.4.3.10': ('ecdsa_with_SHA3-256', 'id-ecdsa-with-sha3-256'),
1449    '2.16.840.1.101.3.4.3.11': ('ecdsa_with_SHA3-384', 'id-ecdsa-with-sha3-384'),
1450    '2.16.840.1.101.3.4.3.12': ('ecdsa_with_SHA3-512', 'id-ecdsa-with-sha3-512'),
1451    '2.16.840.1.101.3.4.3.13': ('RSA-SHA3-224', 'id-rsassa-pkcs1-v1_5-with-sha3-224'),
1452    '2.16.840.1.101.3.4.3.14': ('RSA-SHA3-256', 'id-rsassa-pkcs1-v1_5-with-sha3-256'),
1453    '2.16.840.1.101.3.4.3.15': ('RSA-SHA3-384', 'id-rsassa-pkcs1-v1_5-with-sha3-384'),
1454    '2.16.840.1.101.3.4.3.16': ('RSA-SHA3-512', 'id-rsassa-pkcs1-v1_5-with-sha3-512'),
1455    '2.16.840.1.113730': ('Netscape Communications Corp.', 'Netscape'),
1456    '2.16.840.1.113730.1': ('Netscape Certificate Extension', 'nsCertExt'),
1457    '2.16.840.1.113730.1.1': ('Netscape Cert Type', 'nsCertType'),
1458    '2.16.840.1.113730.1.2': ('Netscape Base Url', 'nsBaseUrl'),
1459    '2.16.840.1.113730.1.3': ('Netscape Revocation Url', 'nsRevocationUrl'),
1460    '2.16.840.1.113730.1.4': ('Netscape CA Revocation Url', 'nsCaRevocationUrl'),
1461    '2.16.840.1.113730.1.7': ('Netscape Renewal Url', 'nsRenewalUrl'),
1462    '2.16.840.1.113730.1.8': ('Netscape CA Policy Url', 'nsCaPolicyUrl'),
1463    '2.16.840.1.113730.1.12': ('Netscape SSL Server Name', 'nsSslServerName'),
1464    '2.16.840.1.113730.1.13': ('Netscape Comment', 'nsComment'),
1465    '2.16.840.1.113730.2': ('Netscape Data Type', 'nsDataType'),
1466    '2.16.840.1.113730.2.5': ('Netscape Certificate Sequence', 'nsCertSequence'),
1467    '2.16.840.1.113730.4.1': ('Netscape Server Gated Crypto', 'nsSGC'),
1468    '2.23': ('International Organizations', 'international-organizations'),
1469    '2.23.42': ('Secure Electronic Transactions', 'id-set'),
1470    '2.23.42.0': ('content types', 'set-ctype'),
1471    '2.23.42.0.0': ('setct-PANData', ),
1472    '2.23.42.0.1': ('setct-PANToken', ),
1473    '2.23.42.0.2': ('setct-PANOnly', ),
1474    '2.23.42.0.3': ('setct-OIData', ),
1475    '2.23.42.0.4': ('setct-PI', ),
1476    '2.23.42.0.5': ('setct-PIData', ),
1477    '2.23.42.0.6': ('setct-PIDataUnsigned', ),
1478    '2.23.42.0.7': ('setct-HODInput', ),
1479    '2.23.42.0.8': ('setct-AuthResBaggage', ),
1480    '2.23.42.0.9': ('setct-AuthRevReqBaggage', ),
1481    '2.23.42.0.10': ('setct-AuthRevResBaggage', ),
1482    '2.23.42.0.11': ('setct-CapTokenSeq', ),
1483    '2.23.42.0.12': ('setct-PInitResData', ),
1484    '2.23.42.0.13': ('setct-PI-TBS', ),
1485    '2.23.42.0.14': ('setct-PResData', ),
1486    '2.23.42.0.16': ('setct-AuthReqTBS', ),
1487    '2.23.42.0.17': ('setct-AuthResTBS', ),
1488    '2.23.42.0.18': ('setct-AuthResTBSX', ),
1489    '2.23.42.0.19': ('setct-AuthTokenTBS', ),
1490    '2.23.42.0.20': ('setct-CapTokenData', ),
1491    '2.23.42.0.21': ('setct-CapTokenTBS', ),
1492    '2.23.42.0.22': ('setct-AcqCardCodeMsg', ),
1493    '2.23.42.0.23': ('setct-AuthRevReqTBS', ),
1494    '2.23.42.0.24': ('setct-AuthRevResData', ),
1495    '2.23.42.0.25': ('setct-AuthRevResTBS', ),
1496    '2.23.42.0.26': ('setct-CapReqTBS', ),
1497    '2.23.42.0.27': ('setct-CapReqTBSX', ),
1498    '2.23.42.0.28': ('setct-CapResData', ),
1499    '2.23.42.0.29': ('setct-CapRevReqTBS', ),
1500    '2.23.42.0.30': ('setct-CapRevReqTBSX', ),
1501    '2.23.42.0.31': ('setct-CapRevResData', ),
1502    '2.23.42.0.32': ('setct-CredReqTBS', ),
1503    '2.23.42.0.33': ('setct-CredReqTBSX', ),
1504    '2.23.42.0.34': ('setct-CredResData', ),
1505    '2.23.42.0.35': ('setct-CredRevReqTBS', ),
1506    '2.23.42.0.36': ('setct-CredRevReqTBSX', ),
1507    '2.23.42.0.37': ('setct-CredRevResData', ),
1508    '2.23.42.0.38': ('setct-PCertReqData', ),
1509    '2.23.42.0.39': ('setct-PCertResTBS', ),
1510    '2.23.42.0.40': ('setct-BatchAdminReqData', ),
1511    '2.23.42.0.41': ('setct-BatchAdminResData', ),
1512    '2.23.42.0.42': ('setct-CardCInitResTBS', ),
1513    '2.23.42.0.43': ('setct-MeAqCInitResTBS', ),
1514    '2.23.42.0.44': ('setct-RegFormResTBS', ),
1515    '2.23.42.0.45': ('setct-CertReqData', ),
1516    '2.23.42.0.46': ('setct-CertReqTBS', ),
1517    '2.23.42.0.47': ('setct-CertResData', ),
1518    '2.23.42.0.48': ('setct-CertInqReqTBS', ),
1519    '2.23.42.0.49': ('setct-ErrorTBS', ),
1520    '2.23.42.0.50': ('setct-PIDualSignedTBE', ),
1521    '2.23.42.0.51': ('setct-PIUnsignedTBE', ),
1522    '2.23.42.0.52': ('setct-AuthReqTBE', ),
1523    '2.23.42.0.53': ('setct-AuthResTBE', ),
1524    '2.23.42.0.54': ('setct-AuthResTBEX', ),
1525    '2.23.42.0.55': ('setct-AuthTokenTBE', ),
1526    '2.23.42.0.56': ('setct-CapTokenTBE', ),
1527    '2.23.42.0.57': ('setct-CapTokenTBEX', ),
1528    '2.23.42.0.58': ('setct-AcqCardCodeMsgTBE', ),
1529    '2.23.42.0.59': ('setct-AuthRevReqTBE', ),
1530    '2.23.42.0.60': ('setct-AuthRevResTBE', ),
1531    '2.23.42.0.61': ('setct-AuthRevResTBEB', ),
1532    '2.23.42.0.62': ('setct-CapReqTBE', ),
1533    '2.23.42.0.63': ('setct-CapReqTBEX', ),
1534    '2.23.42.0.64': ('setct-CapResTBE', ),
1535    '2.23.42.0.65': ('setct-CapRevReqTBE', ),
1536    '2.23.42.0.66': ('setct-CapRevReqTBEX', ),
1537    '2.23.42.0.67': ('setct-CapRevResTBE', ),
1538    '2.23.42.0.68': ('setct-CredReqTBE', ),
1539    '2.23.42.0.69': ('setct-CredReqTBEX', ),
1540    '2.23.42.0.70': ('setct-CredResTBE', ),
1541    '2.23.42.0.71': ('setct-CredRevReqTBE', ),
1542    '2.23.42.0.72': ('setct-CredRevReqTBEX', ),
1543    '2.23.42.0.73': ('setct-CredRevResTBE', ),
1544    '2.23.42.0.74': ('setct-BatchAdminReqTBE', ),
1545    '2.23.42.0.75': ('setct-BatchAdminResTBE', ),
1546    '2.23.42.0.76': ('setct-RegFormReqTBE', ),
1547    '2.23.42.0.77': ('setct-CertReqTBE', ),
1548    '2.23.42.0.78': ('setct-CertReqTBEX', ),
1549    '2.23.42.0.79': ('setct-CertResTBE', ),
1550    '2.23.42.0.80': ('setct-CRLNotificationTBS', ),
1551    '2.23.42.0.81': ('setct-CRLNotificationResTBS', ),
1552    '2.23.42.0.82': ('setct-BCIDistributionTBS', ),
1553    '2.23.42.1': ('message extensions', 'set-msgExt'),
1554    '2.23.42.1.1': ('generic cryptogram', 'setext-genCrypt'),
1555    '2.23.42.1.3': ('merchant initiated auth', 'setext-miAuth'),
1556    '2.23.42.1.4': ('setext-pinSecure', ),
1557    '2.23.42.1.5': ('setext-pinAny', ),
1558    '2.23.42.1.7': ('setext-track2', ),
1559    '2.23.42.1.8': ('additional verification', 'setext-cv'),
1560    '2.23.42.3': ('set-attr', ),
1561    '2.23.42.3.0': ('setAttr-Cert', ),
1562    '2.23.42.3.0.0': ('set-rootKeyThumb', ),
1563    '2.23.42.3.0.1': ('set-addPolicy', ),
1564    '2.23.42.3.1': ('payment gateway capabilities', 'setAttr-PGWYcap'),
1565    '2.23.42.3.2': ('setAttr-TokenType', ),
1566    '2.23.42.3.2.1': ('setAttr-Token-EMV', ),
1567    '2.23.42.3.2.2': ('setAttr-Token-B0Prime', ),
1568    '2.23.42.3.3': ('issuer capabilities', 'setAttr-IssCap'),
1569    '2.23.42.3.3.3': ('setAttr-IssCap-CVM', ),
1570    '2.23.42.3.3.3.1': ('generate cryptogram', 'setAttr-GenCryptgrm'),
1571    '2.23.42.3.3.4': ('setAttr-IssCap-T2', ),
1572    '2.23.42.3.3.4.1': ('encrypted track 2', 'setAttr-T2Enc'),
1573    '2.23.42.3.3.4.2': ('cleartext track 2', 'setAttr-T2cleartxt'),
1574    '2.23.42.3.3.5': ('setAttr-IssCap-Sig', ),
1575    '2.23.42.3.3.5.1': ('ICC or token signature', 'setAttr-TokICCsig'),
1576    '2.23.42.3.3.5.2': ('secure device signature', 'setAttr-SecDevSig'),
1577    '2.23.42.5': ('set-policy', ),
1578    '2.23.42.5.0': ('set-policy-root', ),
1579    '2.23.42.7': ('certificate extensions', 'set-certExt'),
1580    '2.23.42.7.0': ('setCext-hashedRoot', ),
1581    '2.23.42.7.1': ('setCext-certType', ),
1582    '2.23.42.7.2': ('setCext-merchData', ),
1583    '2.23.42.7.3': ('setCext-cCertRequired', ),
1584    '2.23.42.7.4': ('setCext-tunneling', ),
1585    '2.23.42.7.5': ('setCext-setExt', ),
1586    '2.23.42.7.6': ('setCext-setQualf', ),
1587    '2.23.42.7.7': ('setCext-PGWYcapabilities', ),
1588    '2.23.42.7.8': ('setCext-TokenIdentifier', ),
1589    '2.23.42.7.9': ('setCext-Track2Data', ),
1590    '2.23.42.7.10': ('setCext-TokenType', ),
1591    '2.23.42.7.11': ('setCext-IssuerCapabilities', ),
1592    '2.23.42.8': ('set-brand', ),
1593    '2.23.42.8.1': ('set-brand-IATA-ATA', ),
1594    '2.23.42.8.4': ('set-brand-Visa', ),
1595    '2.23.42.8.5': ('set-brand-MasterCard', ),
1596    '2.23.42.8.30': ('set-brand-Diners', ),
1597    '2.23.42.8.34': ('set-brand-AmericanExpress', ),
1598    '2.23.42.8.35': ('set-brand-JCB', ),
1599    '2.23.42.8.6011': ('set-brand-Novus', ),
1600    '2.23.43': ('wap', ),
1601    '2.23.43.1': ('wap-wsg', ),
1602    '2.23.43.1.4': ('wap-wsg-idm-ecid', ),
1603    '2.23.43.1.4.1': ('wap-wsg-idm-ecid-wtls1', ),
1604    '2.23.43.1.4.3': ('wap-wsg-idm-ecid-wtls3', ),
1605    '2.23.43.1.4.4': ('wap-wsg-idm-ecid-wtls4', ),
1606    '2.23.43.1.4.5': ('wap-wsg-idm-ecid-wtls5', ),
1607    '2.23.43.1.4.6': ('wap-wsg-idm-ecid-wtls6', ),
1608    '2.23.43.1.4.7': ('wap-wsg-idm-ecid-wtls7', ),
1609    '2.23.43.1.4.8': ('wap-wsg-idm-ecid-wtls8', ),
1610    '2.23.43.1.4.9': ('wap-wsg-idm-ecid-wtls9', ),
1611    '2.23.43.1.4.10': ('wap-wsg-idm-ecid-wtls10', ),
1612    '2.23.43.1.4.11': ('wap-wsg-idm-ecid-wtls11', ),
1613    '2.23.43.1.4.12': ('wap-wsg-idm-ecid-wtls12', ),
1614}
1615# #####################################################################################
1616# #####################################################################################
1617
1618_OID_LOOKUP = dict()
1619_NORMALIZE_NAMES = dict()
1620_NORMALIZE_NAMES_SHORT = dict()
1621
1622for dotted, names in _OID_MAP.items():
1623    for name in names:
1624        if name in _NORMALIZE_NAMES and _OID_LOOKUP[name] != dotted:
1625            raise AssertionError(
1626                'Name collision during setup: "{0}" for OIDs {1} and {2}'
1627                .format(name, dotted, _OID_LOOKUP[name])
1628            )
1629        _NORMALIZE_NAMES[name] = names[0]
1630        _NORMALIZE_NAMES_SHORT[name] = names[-1]
1631        _OID_LOOKUP[name] = dotted
1632for alias, original in [('userID', 'userId')]:
1633    if alias in _NORMALIZE_NAMES:
1634        raise AssertionError(
1635            'Name collision during adding aliases: "{0}" (alias for "{1}") is already mapped to OID {2}'
1636            .format(alias, original, _OID_LOOKUP[alias])
1637        )
1638    _NORMALIZE_NAMES[alias] = original
1639    _NORMALIZE_NAMES_SHORT[alias] = _NORMALIZE_NAMES_SHORT[original]
1640    _OID_LOOKUP[alias] = _OID_LOOKUP[original]
1641
1642
1643def pyopenssl_normalize_name(name, short=False):
1644    nid = OpenSSL._util.lib.OBJ_txt2nid(to_bytes(name))
1645    if nid != 0:
1646        b_name = OpenSSL._util.lib.OBJ_nid2ln(nid)
1647        name = to_text(OpenSSL._util.ffi.string(b_name))
1648    if short:
1649        return _NORMALIZE_NAMES_SHORT.get(name, name)
1650    else:
1651        return _NORMALIZE_NAMES.get(name, name)
1652
1653
1654# #####################################################################################
1655# #####################################################################################
1656# # This excerpt is dual licensed under the terms of the Apache License, Version
1657# # 2.0, and the BSD License. See the LICENSE file at
1658# # https://github.com/pyca/cryptography/blob/master/LICENSE for complete details.
1659# #
1660# # Adapted from cryptography's hazmat/backends/openssl/decode_asn1.py
1661# #
1662# # Copyright (c) 2015, 2016 Paul Kehrer (@reaperhulk)
1663# # Copyright (c) 2017 Fraser Tweedale (@frasertweedale)
1664# #
1665# # Relevant commits from cryptography project (https://github.com/pyca/cryptography):
1666# #    pyca/cryptography@719d536dd691e84e208534798f2eb4f82aaa2e07
1667# #    pyca/cryptography@5ab6d6a5c05572bd1c75f05baf264a2d0001894a
1668# #    pyca/cryptography@2e776e20eb60378e0af9b7439000d0e80da7c7e3
1669# #    pyca/cryptography@fb309ed24647d1be9e319b61b1f2aa8ebb87b90b
1670# #    pyca/cryptography@2917e460993c475c72d7146c50dc3bbc2414280d
1671# #    pyca/cryptography@3057f91ea9a05fb593825006d87a391286a4d828
1672# #    pyca/cryptography@d607dd7e5bc5c08854ec0c9baff70ba4a35be36f
1673def _obj2txt(openssl_lib, openssl_ffi, obj):
1674    # Set to 80 on the recommendation of
1675    # https://www.openssl.org/docs/crypto/OBJ_nid2ln.html#return_values
1676    #
1677    # But OIDs longer than this occur in real life (e.g. Active
1678    # Directory makes some very long OIDs).  So we need to detect
1679    # and properly handle the case where the default buffer is not
1680    # big enough.
1681    #
1682    buf_len = 80
1683    buf = openssl_ffi.new("char[]", buf_len)
1684
1685    # 'res' is the number of bytes that *would* be written if the
1686    # buffer is large enough.  If 'res' > buf_len - 1, we need to
1687    # alloc a big-enough buffer and go again.
1688    res = openssl_lib.OBJ_obj2txt(buf, buf_len, obj, 1)
1689    if res > buf_len - 1:  # account for terminating null byte
1690        buf_len = res + 1
1691        buf = openssl_ffi.new("char[]", buf_len)
1692        res = openssl_lib.OBJ_obj2txt(buf, buf_len, obj, 1)
1693    return openssl_ffi.buffer(buf, res)[:].decode()
1694# #####################################################################################
1695# #####################################################################################
1696
1697
1698def cryptography_get_extensions_from_cert(cert):
1699    # Since cryptography won't give us the DER value for an extension
1700    # (that is only stored for unrecognized extensions), we have to re-do
1701    # the extension parsing outselves.
1702    result = dict()
1703    backend = cert._backend
1704    x509_obj = cert._x509
1705
1706    for i in range(backend._lib.X509_get_ext_count(x509_obj)):
1707        ext = backend._lib.X509_get_ext(x509_obj, i)
1708        if ext == backend._ffi.NULL:
1709            continue
1710        crit = backend._lib.X509_EXTENSION_get_critical(ext)
1711        data = backend._lib.X509_EXTENSION_get_data(ext)
1712        backend.openssl_assert(data != backend._ffi.NULL)
1713        der = backend._ffi.buffer(data.data, data.length)[:]
1714        entry = dict(
1715            critical=(crit == 1),
1716            value=base64.b64encode(der),
1717        )
1718        oid = _obj2txt(backend._lib, backend._ffi, backend._lib.X509_EXTENSION_get_object(ext))
1719        result[oid] = entry
1720    return result
1721
1722
1723def cryptography_get_extensions_from_csr(csr):
1724    # Since cryptography won't give us the DER value for an extension
1725    # (that is only stored for unrecognized extensions), we have to re-do
1726    # the extension parsing outselves.
1727    result = dict()
1728    backend = csr._backend
1729
1730    extensions = backend._lib.X509_REQ_get_extensions(csr._x509_req)
1731    extensions = backend._ffi.gc(
1732        extensions,
1733        lambda ext: backend._lib.sk_X509_EXTENSION_pop_free(
1734            ext,
1735            backend._ffi.addressof(backend._lib._original_lib, "X509_EXTENSION_free")
1736        )
1737    )
1738
1739    for i in range(backend._lib.sk_X509_EXTENSION_num(extensions)):
1740        ext = backend._lib.sk_X509_EXTENSION_value(extensions, i)
1741        if ext == backend._ffi.NULL:
1742            continue
1743        crit = backend._lib.X509_EXTENSION_get_critical(ext)
1744        data = backend._lib.X509_EXTENSION_get_data(ext)
1745        backend.openssl_assert(data != backend._ffi.NULL)
1746        der = backend._ffi.buffer(data.data, data.length)[:]
1747        entry = dict(
1748            critical=(crit == 1),
1749            value=base64.b64encode(der),
1750        )
1751        oid = _obj2txt(backend._lib, backend._ffi, backend._lib.X509_EXTENSION_get_object(ext))
1752        result[oid] = entry
1753    return result
1754
1755
1756def pyopenssl_get_extensions_from_cert(cert):
1757    # While pyOpenSSL allows us to get an extension's DER value, it won't
1758    # give us the dotted string for an OID. So we have to do some magic to
1759    # get hold of it.
1760    result = dict()
1761    ext_count = cert.get_extension_count()
1762    for i in range(0, ext_count):
1763        ext = cert.get_extension(i)
1764        entry = dict(
1765            critical=bool(ext.get_critical()),
1766            value=base64.b64encode(ext.get_data()),
1767        )
1768        oid = _obj2txt(
1769            OpenSSL._util.lib,
1770            OpenSSL._util.ffi,
1771            OpenSSL._util.lib.X509_EXTENSION_get_object(ext._extension)
1772        )
1773        # This could also be done a bit simpler:
1774        #
1775        #   oid = _obj2txt(OpenSSL._util.lib, OpenSSL._util.ffi, OpenSSL._util.lib.OBJ_nid2obj(ext._nid))
1776        #
1777        # Unfortunately this gives the wrong result in case the linked OpenSSL
1778        # doesn't know the OID. That's why we have to get the OID dotted string
1779        # similarly to how cryptography does it.
1780        result[oid] = entry
1781    return result
1782
1783
1784def pyopenssl_get_extensions_from_csr(csr):
1785    # While pyOpenSSL allows us to get an extension's DER value, it won't
1786    # give us the dotted string for an OID. So we have to do some magic to
1787    # get hold of it.
1788    result = dict()
1789    for ext in csr.get_extensions():
1790        entry = dict(
1791            critical=bool(ext.get_critical()),
1792            value=base64.b64encode(ext.get_data()),
1793        )
1794        oid = _obj2txt(
1795            OpenSSL._util.lib,
1796            OpenSSL._util.ffi,
1797            OpenSSL._util.lib.X509_EXTENSION_get_object(ext._extension)
1798        )
1799        # This could also be done a bit simpler:
1800        #
1801        #   oid = _obj2txt(OpenSSL._util.lib, OpenSSL._util.ffi, OpenSSL._util.lib.OBJ_nid2obj(ext._nid))
1802        #
1803        # Unfortunately this gives the wrong result in case the linked OpenSSL
1804        # doesn't know the OID. That's why we have to get the OID dotted string
1805        # similarly to how cryptography does it.
1806        result[oid] = entry
1807    return result
1808
1809
1810def cryptography_name_to_oid(name):
1811    dotted = _OID_LOOKUP.get(name)
1812    if dotted is None:
1813        raise OpenSSLObjectError('Cannot find OID for "{0}"'.format(name))
1814    return x509.oid.ObjectIdentifier(dotted)
1815
1816
1817def cryptography_oid_to_name(oid, short=False):
1818    dotted_string = oid.dotted_string
1819    names = _OID_MAP.get(dotted_string)
1820    name = names[0] if names else oid._name
1821    if short:
1822        return _NORMALIZE_NAMES_SHORT.get(name, name)
1823    else:
1824        return _NORMALIZE_NAMES.get(name, name)
1825
1826
1827def cryptography_get_name(name):
1828    '''
1829    Given a name string, returns a cryptography x509.Name object.
1830    Raises an OpenSSLObjectError if the name is unknown or cannot be parsed.
1831    '''
1832    try:
1833        if name.startswith('DNS:'):
1834            return x509.DNSName(to_text(name[4:]))
1835        if name.startswith('IP:'):
1836            return x509.IPAddress(ipaddress.ip_address(to_text(name[3:])))
1837        if name.startswith('email:'):
1838            return x509.RFC822Name(to_text(name[6:]))
1839        if name.startswith('URI:'):
1840            return x509.UniformResourceIdentifier(to_text(name[4:]))
1841    except Exception as e:
1842        raise OpenSSLObjectError('Cannot parse Subject Alternative Name "{0}": {1}'.format(name, e))
1843    if ':' not in name:
1844        raise OpenSSLObjectError('Cannot parse Subject Alternative Name "{0}" (forgot "DNS:" prefix?)'.format(name))
1845    raise OpenSSLObjectError('Cannot parse Subject Alternative Name "{0}" (potentially unsupported by cryptography backend)'.format(name))
1846
1847
1848def _get_hex(bytesstr):
1849    if bytesstr is None:
1850        return bytesstr
1851    data = binascii.hexlify(bytesstr)
1852    data = to_text(b':'.join(data[i:i + 2] for i in range(0, len(data), 2)))
1853    return data
1854
1855
1856def cryptography_decode_name(name):
1857    '''
1858    Given a cryptography x509.Name object, returns a string.
1859    Raises an OpenSSLObjectError if the name is not supported.
1860    '''
1861    if isinstance(name, x509.DNSName):
1862        return 'DNS:{0}'.format(name.value)
1863    if isinstance(name, x509.IPAddress):
1864        return 'IP:{0}'.format(name.value.compressed)
1865    if isinstance(name, x509.RFC822Name):
1866        return 'email:{0}'.format(name.value)
1867    if isinstance(name, x509.UniformResourceIdentifier):
1868        return 'URI:{0}'.format(name.value)
1869    if isinstance(name, x509.DirectoryName):
1870        # FIXME: test
1871        return 'DirName:' + ''.join(['/{0}:{1}'.format(attribute.oid._name, attribute.value) for attribute in name.value])
1872    if isinstance(name, x509.RegisteredID):
1873        # FIXME: test
1874        return 'RegisteredID:{0}'.format(name.value)
1875    if isinstance(name, x509.OtherName):
1876        # FIXME: test
1877        return '{0}:{1}'.format(name.type_id.dotted_string, _get_hex(name.value))
1878    raise OpenSSLObjectError('Cannot decode name "{0}"'.format(name))
1879
1880
1881def _cryptography_get_keyusage(usage):
1882    '''
1883    Given a key usage identifier string, returns the parameter name used by cryptography's x509.KeyUsage().
1884    Raises an OpenSSLObjectError if the identifier is unknown.
1885    '''
1886    if usage in ('Digital Signature', 'digitalSignature'):
1887        return 'digital_signature'
1888    if usage in ('Non Repudiation', 'nonRepudiation'):
1889        return 'content_commitment'
1890    if usage in ('Key Encipherment', 'keyEncipherment'):
1891        return 'key_encipherment'
1892    if usage in ('Data Encipherment', 'dataEncipherment'):
1893        return 'data_encipherment'
1894    if usage in ('Key Agreement', 'keyAgreement'):
1895        return 'key_agreement'
1896    if usage in ('Certificate Sign', 'keyCertSign'):
1897        return 'key_cert_sign'
1898    if usage in ('CRL Sign', 'cRLSign'):
1899        return 'crl_sign'
1900    if usage in ('Encipher Only', 'encipherOnly'):
1901        return 'encipher_only'
1902    if usage in ('Decipher Only', 'decipherOnly'):
1903        return 'decipher_only'
1904    raise OpenSSLObjectError('Unknown key usage "{0}"'.format(usage))
1905
1906
1907def cryptography_parse_key_usage_params(usages):
1908    '''
1909    Given a list of key usage identifier strings, returns the parameters for cryptography's x509.KeyUsage().
1910    Raises an OpenSSLObjectError if an identifier is unknown.
1911    '''
1912    params = dict(
1913        digital_signature=False,
1914        content_commitment=False,
1915        key_encipherment=False,
1916        data_encipherment=False,
1917        key_agreement=False,
1918        key_cert_sign=False,
1919        crl_sign=False,
1920        encipher_only=False,
1921        decipher_only=False,
1922    )
1923    for usage in usages:
1924        params[_cryptography_get_keyusage(usage)] = True
1925    return params
1926
1927
1928def cryptography_get_basic_constraints(constraints):
1929    '''
1930    Given a list of constraints, returns a tuple (ca, path_length).
1931    Raises an OpenSSLObjectError if a constraint is unknown or cannot be parsed.
1932    '''
1933    ca = False
1934    path_length = None
1935    if constraints:
1936        for constraint in constraints:
1937            if constraint.startswith('CA:'):
1938                if constraint == 'CA:TRUE':
1939                    ca = True
1940                elif constraint == 'CA:FALSE':
1941                    ca = False
1942                else:
1943                    raise OpenSSLObjectError('Unknown basic constraint value "{0}" for CA'.format(constraint[3:]))
1944            elif constraint.startswith('pathlen:'):
1945                v = constraint[len('pathlen:'):]
1946                try:
1947                    path_length = int(v)
1948                except Exception as e:
1949                    raise OpenSSLObjectError('Cannot parse path length constraint "{0}" ({1})'.format(v, e))
1950            else:
1951                raise OpenSSLObjectError('Unknown basic constraint "{0}"'.format(constraint))
1952    return ca, path_length
1953
1954
1955def binary_exp_mod(f, e, m):
1956    '''Computes f^e mod m in O(log e) multiplications modulo m.'''
1957    # Compute len_e = floor(log_2(e))
1958    len_e = -1
1959    x = e
1960    while x > 0:
1961        x >>= 1
1962        len_e += 1
1963    # Compute f**e mod m
1964    result = 1
1965    for k in range(len_e, -1, -1):
1966        result = (result * result) % m
1967        if ((e >> k) & 1) != 0:
1968            result = (result * f) % m
1969    return result
1970
1971
1972def simple_gcd(a, b):
1973    '''Compute GCD of its two inputs.'''
1974    while b != 0:
1975        a, b = b, a % b
1976    return a
1977
1978
1979def quick_is_not_prime(n):
1980    '''Does some quick checks to see if we can poke a hole into the primality of n.
1981
1982    A result of `False` does **not** mean that the number is prime; it just means
1983    that we couldn't detect quickly whether it is not prime.
1984    '''
1985    if n <= 2:
1986        return True
1987    # The constant in the next line is the product of all primes < 200
1988    if simple_gcd(n, 7799922041683461553249199106329813876687996789903550945093032474868511536164700810) > 1:
1989        return True
1990    # TODO: maybe do some iterations of Miller-Rabin to increase confidence
1991    # (https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test)
1992    return False
1993
1994
1995python_version = (sys.version_info[0], sys.version_info[1])
1996if python_version >= (2, 7) or python_version >= (3, 1):
1997    # Ansible still supports Python 2.6 on remote nodes
1998    def count_bits(no):
1999        no = abs(no)
2000        if no == 0:
2001            return 0
2002        return no.bit_length()
2003else:
2004    # Slow, but works
2005    def count_bits(no):
2006        no = abs(no)
2007        count = 0
2008        while no > 0:
2009            no >>= 1
2010            count += 1
2011        return count
2012
2013
2014PEM_START = '-----BEGIN '
2015PEM_END = '-----'
2016PKCS8_PRIVATEKEY_NAMES = ('PRIVATE KEY', 'ENCRYPTED PRIVATE KEY')
2017PKCS1_PRIVATEKEY_SUFFIX = ' PRIVATE KEY'
2018
2019
2020def identify_private_key_format(content):
2021    '''Given the contents of a private key file, identifies its format.'''
2022    # See https://github.com/openssl/openssl/blob/master/crypto/pem/pem_pkey.c#L40-L85
2023    # (PEM_read_bio_PrivateKey)
2024    # and https://github.com/openssl/openssl/blob/master/include/openssl/pem.h#L46-L47
2025    # (PEM_STRING_PKCS8, PEM_STRING_PKCS8INF)
2026    try:
2027        lines = content.decode('utf-8').splitlines(False)
2028        if lines[0].startswith(PEM_START) and lines[0].endswith(PEM_END) and len(lines[0]) > len(PEM_START) + len(PEM_END):
2029            name = lines[0][len(PEM_START):-len(PEM_END)]
2030            if name in PKCS8_PRIVATEKEY_NAMES:
2031                return 'pkcs8'
2032            if len(name) > len(PKCS1_PRIVATEKEY_SUFFIX) and name.endswith(PKCS1_PRIVATEKEY_SUFFIX):
2033                return 'pkcs1'
2034            return 'unknown-pem'
2035    except UnicodeDecodeError:
2036        pass
2037    return 'raw'
2038
2039
2040def cryptography_key_needs_digest_for_signing(key):
2041    '''Tests whether the given private key requires a digest algorithm for signing.
2042
2043    Ed25519 and Ed448 keys do not; they need None to be passed as the digest algorithm.
2044    '''
2045    if CRYPTOGRAPHY_HAS_ED25519 and isinstance(key, cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey):
2046        return False
2047    if CRYPTOGRAPHY_HAS_ED448 and isinstance(key, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey):
2048        return False
2049    return True
2050
2051
2052def cryptography_compare_public_keys(key1, key2):
2053    '''Tests whether two public keys are the same.
2054
2055    Needs special logic for Ed25519 and Ed448 keys, since they do not have public_numbers().
2056    '''
2057    if CRYPTOGRAPHY_HAS_ED25519:
2058        a = isinstance(key1, cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey)
2059        b = isinstance(key2, cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey)
2060        if a or b:
2061            if not a or not b:
2062                return False
2063            a = key1.public_bytes(serialization.Encoding.Raw, serialization.PublicFormat.Raw)
2064            b = key2.public_bytes(serialization.Encoding.Raw, serialization.PublicFormat.Raw)
2065            return a == b
2066    if CRYPTOGRAPHY_HAS_ED448:
2067        a = isinstance(key1, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey)
2068        b = isinstance(key2, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey)
2069        if a or b:
2070            if not a or not b:
2071                return False
2072            a = key1.public_bytes(serialization.Encoding.Raw, serialization.PublicFormat.Raw)
2073            b = key2.public_bytes(serialization.Encoding.Raw, serialization.PublicFormat.Raw)
2074            return a == b
2075    return key1.public_numbers() == key2.public_numbers()
2076
2077
2078if HAS_CRYPTOGRAPHY:
2079    REVOCATION_REASON_MAP = {
2080        'unspecified': x509.ReasonFlags.unspecified,
2081        'key_compromise': x509.ReasonFlags.key_compromise,
2082        'ca_compromise': x509.ReasonFlags.ca_compromise,
2083        'affiliation_changed': x509.ReasonFlags.affiliation_changed,
2084        'superseded': x509.ReasonFlags.superseded,
2085        'cessation_of_operation': x509.ReasonFlags.cessation_of_operation,
2086        'certificate_hold': x509.ReasonFlags.certificate_hold,
2087        'privilege_withdrawn': x509.ReasonFlags.privilege_withdrawn,
2088        'aa_compromise': x509.ReasonFlags.aa_compromise,
2089        'remove_from_crl': x509.ReasonFlags.remove_from_crl,
2090    }
2091    REVOCATION_REASON_MAP_INVERSE = dict()
2092    for k, v in REVOCATION_REASON_MAP.items():
2093        REVOCATION_REASON_MAP_INVERSE[v] = k
2094
2095
2096def cryptography_decode_revoked_certificate(cert):
2097    result = {
2098        'serial_number': cert.serial_number,
2099        'revocation_date': cert.revocation_date,
2100        'issuer': None,
2101        'issuer_critical': False,
2102        'reason': None,
2103        'reason_critical': False,
2104        'invalidity_date': None,
2105        'invalidity_date_critical': False,
2106    }
2107    try:
2108        ext = cert.extensions.get_extension_for_class(x509.CertificateIssuer)
2109        result['issuer'] = list(ext.value)
2110        result['issuer_critical'] = ext.critical
2111    except x509.ExtensionNotFound:
2112        pass
2113    try:
2114        ext = cert.extensions.get_extension_for_class(x509.CRLReason)
2115        result['reason'] = ext.value.reason
2116        result['reason_critical'] = ext.critical
2117    except x509.ExtensionNotFound:
2118        pass
2119    try:
2120        ext = cert.extensions.get_extension_for_class(x509.InvalidityDate)
2121        result['invalidity_date'] = ext.value.invalidity_date
2122        result['invalidity_date_critical'] = ext.critical
2123    except x509.ExtensionNotFound:
2124        pass
2125    return result
2126