Exemplo n.º 1
0
    def test_policy_identifier_setter(self) -> None:
        """Test setting a policy identifier."""
        value = "1.2.3"
        expected = ObjectIdentifier(value)
        pinfo = PolicyInformation({"policy_identifier": value, "policy_qualifiers": []})
        pinfo.policy_identifier = value
        self.assertEqual(pinfo.policy_identifier, expected)

        pinfo = PolicyInformation({"policy_identifier": expected})
        self.assertEqual(pinfo.policy_identifier, expected)

        new_value = "2.3.4"
        new_expected = ObjectIdentifier(new_value)
        pinfo.policy_identifier = new_value
        self.assertEqual(pinfo.policy_identifier, new_expected)
Exemplo n.º 2
0
    def test_policy_identifier_setter(self):
        """Test setting a policy identifier."""
        value = '1.2.3'
        expected = ObjectIdentifier(value)
        pinfo = PolicyInformation({'policy_identifier': value})
        pinfo.policy_identifier = value
        self.assertEqual(pinfo.policy_identifier, expected)

        pinfo = PolicyInformation({'policy_identifier': expected})
        self.assertEqual(pinfo.policy_identifier, expected)

        new_value = '2.3.4'
        new_expected = ObjectIdentifier(new_value)
        pinfo.policy_identifier = new_value
        self.assertEqual(pinfo.policy_identifier, new_expected)
    def get_root_ca_crl(self, pem):
        self._data = {}
        cert = x509.load_pem_x509_certificate(pem, default_backend())
        cdpext = cert.extensions.get_extension_for_oid(
            ObjectIdentifier(self.id_cdp_extension))

        return getattr(getattr(cdpext.value[0], "_full_name")[0], "value")
Exemplo n.º 4
0
def generate_android_extensions(data: bytes) -> List[Extension]:
    android_key_oid = ObjectIdentifier('1.3.6.1.4.1.11129.2.1.17')
    android_key_description = KeyDescription()
    android_key_description['attestationVersion'] = 0
    android_key_description['attestationSecurityLevel'] = 0
    android_key_description['keymasterVersion'] = 0
    android_key_description['keymasterSecurityLevel'] = 0
    android_key_description['attestationChallenge'] = data
    android_key_description['uniqueId'] = b'unique'

    software_enforced = AuthorizationList()
    software_enforced['origin'] = KM_ORIGIN_GENERATED
    software_enforced['purpose'].append(KM_PURPOSE_SIGN)
    android_key_description['softwareEnforced'] = software_enforced

    tee_enforced = AuthorizationList()
    tee_enforced['origin'] = KM_ORIGIN_GENERATED
    tee_enforced['purpose'].append(KM_PURPOSE_SIGN)
    android_key_description['teeEnforced'] = tee_enforced

    der_key = encode(android_key_description)
    extensions = [
        Extension(android_key_oid, False,
                  UnrecognizedExtension(android_key_oid, der_key))
    ]

    return extensions
    def parse_pem_certificate(self, pem):
        self._data = {}
        cert = x509.load_pem_x509_certificate(pem, default_backend())
        sgxext = cert.extensions.get_extension_for_oid(
            ObjectIdentifier(self.id_ce_sGXExtensions))

        self.decoder.start(sgxext.value.value)
        self._parse_asn1(self._data, self.id_ce_sGXExtensions)
Exemplo n.º 6
0
def oid(x):
    """
    Returns object identifier if not already
    :param x:
    :return:
    """
    if not isinstance(x, ObjectIdentifier):
        return ObjectIdentifier(x)
    return x
Exemplo n.º 7
0
def der_to_subject(der):
    """Convert Name() ASN.1 into a DN type"""
    name, _ = decode(der, asn1Spec=Name())

    subject = DN()

    for item in name.getComponentByPosition(0):
        data = item.getComponentByPosition(0)

        rdn = data.getComponentByPosition(0).prettyPrint()
        value = data.getComponentByPosition(1).asOctets()[2:].decode('utf-8')

        subject += (DN((ATTR_NAME_BY_OID[ObjectIdentifier(rdn)], value)))

    return subject
Exemplo n.º 8
0
def generate_elliptic_curve_x509_certificate_android_raw(
        curve: EllipticCurve,
        data: bytes) -> Tuple[x509.Certificate, EC2PrivateKey, EC2PublicKey]:
    android_key_oid = ObjectIdentifier('1.3.6.1.4.1.11129.2.1.17')

    extensions = [
        Extension(android_key_oid, False,
                  UnrecognizedExtension(android_key_oid, data))
    ]

    private_key = generate_private_key(curve, default_backend())
    public_key = private_key.public_key()
    return generate_x509_certificate(
        public_key, private_key, hashes.SHA256(),
        extensions=extensions), private_key, public_key
    def parse_pem_certificate(self, pem):
        self._data = {}
        cert = x509.load_pem_x509_certificate(pem, default_backend())
        issuerCN = cert.issuer.rfc4514_string()
        if (issuerCN.find('Processor') != -1):
            self.ca = 'PROCESSOR'
        elif (issuerCN.find('Platform') != -1):
            self.ca = 'PLATFORM'
        else:
            self.ca = None

        sgxext = cert.extensions.get_extension_for_oid(
            ObjectIdentifier(self.id_ce_sGXExtensions))

        self.decoder.start(sgxext.value.value)
        self._parse_asn1(self._data, self.id_ce_sGXExtensions)
Exemplo n.º 10
0
    def _parse_na(self) -> NameAttribute:
        try:
            oid_value = self._read_re(self._OID_RE)
        except ValueError:
            name = self._read_re(self._DESCR_RE)
            oid = _NAME_TO_NAMEOID.get(name)
            if oid is None:
                raise ValueError
        else:
            oid = ObjectIdentifier(oid_value)

        self._read_char("=")
        if self._peek() == "#":
            value = self._read_re(self._HEXSTRING_RE)
            value = binascii.unhexlify(value[1:]).decode()
        else:
            raw_value = self._read_re(self._STRING_RE)
            value = _unescape_dn_value(raw_value)

        return NameAttribute(oid, value)
Exemplo n.º 11
0
 def _get_extended_key_usage_object_identifier(cls, eku):
     oid = cls.EXTENDED_KEY_USAGES_OID_MAP.get(eku)
     if not oid:
         oid = ObjectIdentifier(eku)
     return oid
Exemplo n.º 12
0
    'secp384r1': ec.SECP384R1,
    'secp521r1': ec.SECP521R1,
    # aliases
    'prime256v1': ec.SECP256R1,
}

DN_CODE_TO_OID = {
    'CN': NameOID.COMMON_NAME,

    'O': NameOID.ORGANIZATION_NAME,
    'OU': NameOID.ORGANIZATIONAL_UNIT_NAME,

    'C': NameOID.COUNTRY_NAME,
    'L': NameOID.LOCALITY_NAME,
    'ST': NameOID.STATE_OR_PROVINCE_NAME,
    'SA': ObjectIdentifier('2.5.4.9'),      # streetAddress

    'SN': NameOID.SURNAME,
    'GN': NameOID.GIVEN_NAME,
    'T': NameOID.TITLE,
    'GQ': NameOID.GENERATION_QUALIFIER,
    'DQ': NameOID.DN_QUALIFIER,
    'P': NameOID.PSEUDONYM,
}

KU_FIELDS = [
    'digital_signature',
    'content_commitment',
    'key_encipherment',
    'data_encipherment',
    'key_agreement',
Exemplo n.º 13
0
 def __parse_ev_oids(self) -> None:
     if self.__ev_oids_as_str:
         self.ev_oids = [
             ObjectIdentifier(oid) for oid in self.__ev_oids_as_str
         ]
Exemplo n.º 14
0
class PolicyInformationTestCase(DjangoCATestCase):
    """Test PolicyInformation class."""

    oid = '2.5.29.32.0'

    # various qualifiers
    q1 = 'text1'
    q2 = x509.UserNotice(explicit_text='text2', notice_reference=None)
    q3 = x509.UserNotice(explicit_text=None,
                         notice_reference=x509.NoticeReference(
                             organization='text3', notice_numbers=[1]))
    q4 = 'text4'
    q5 = x509.UserNotice(explicit_text='text5',
                         notice_reference=x509.NoticeReference(
                             organization='text6', notice_numbers=[1, 2, 3]))

    x1 = x509.PolicyInformation(policy_identifier=ObjectIdentifier(oid),
                                policy_qualifiers=[q1])
    x2 = x509.PolicyInformation(
        policy_identifier=ObjectIdentifier(oid),
        policy_qualifiers=[q2],
    )
    x3 = x509.PolicyInformation(
        policy_identifier=ObjectIdentifier(oid),
        policy_qualifiers=[q3],
    )
    x4 = x509.PolicyInformation(
        policy_identifier=ObjectIdentifier(oid),
        policy_qualifiers=[q4, q5],
    )
    s1 = {
        'policy_identifier': oid,
        'policy_qualifiers': ['text1'],
    }
    s2 = {
        'policy_identifier': oid,
        'policy_qualifiers': [{
            'explicit_text': 'text2',
        }],
    }
    s3 = {
        'policy_identifier':
        oid,
        'policy_qualifiers': [{
            'notice_reference': {
                'organization': 'text3',
                'notice_numbers': [
                    1,
                ],
            }
        }],
    }
    s4 = {
        'policy_identifier':
        oid,
        'policy_qualifiers': [
            'text4', {
                'explicit_text': 'text5',
                'notice_reference': {
                    'organization': 'text6',
                    'notice_numbers': [1, 2, 3],
                }
            }
        ],
    }

    def setUp(self):
        super().setUp()

        self.pi1 = PolicyInformation(self.s1)
        self.pi2 = PolicyInformation(self.s2)
        self.pi3 = PolicyInformation(self.s3)
        self.pi4 = PolicyInformation(self.s4)
        self.pi_empty = PolicyInformation()

    def test_append(self):
        """Test PolicyInformation.append()."""
        self.pi1.append(self.q2)
        self.pi1.append(self.s3['policy_qualifiers'][0])
        self.assertEqual(
            self.pi1,
            PolicyInformation({
                'policy_identifier': self.oid,
                'policy_qualifiers': [self.q1, self.q2, self.q3],
            }))

        self.pi_empty.policy_identifier = self.oid
        self.pi_empty.append(self.q3)
        self.assertEqual(self.pi3, self.pi_empty)

    def test_as_text(self):
        """Test as_text()."""
        self.assertEqual(
            self.pi1.as_text(), 'Policy Identifier: 2.5.29.32.0\n'
            'Policy Qualifiers:\n* text1')
        self.assertEqual(
            self.pi2.as_text(), 'Policy Identifier: 2.5.29.32.0\n'
            'Policy Qualifiers:\n'
            '* UserNotice:\n'
            '  * Explicit text: text2')
        self.assertEqual(
            self.pi3.as_text(), 'Policy Identifier: 2.5.29.32.0\n'
            'Policy Qualifiers:\n'
            '* UserNotice:\n'
            '  * Reference:\n'
            '    * Organiziation: text3\n'
            '    * Notice Numbers: [1]')
        self.assertEqual(
            self.pi4.as_text(), 'Policy Identifier: 2.5.29.32.0\n'
            'Policy Qualifiers:\n'
            '* text4\n'
            '* UserNotice:\n'
            '  * Explicit text: text5\n'
            '  * Reference:\n'
            '    * Organiziation: text6\n'
            '    * Notice Numbers: [1, 2, 3]')
        self.assertEqual(self.pi_empty.as_text(),
                         'Policy Identifier: None\nNo Policy Qualifiers')

        self.load_all_cas()
        self.load_all_certs()
        for name, cert in list(self.cas.items()) + list(self.certs.items()):
            try:
                ext = cert.x509.extensions.get_extension_for_oid(
                    ExtensionOID.CERTIFICATE_POLICIES).value
            except x509.ExtensionNotFound:
                continue

            for index, policy in enumerate(ext):
                pinfo = PolicyInformation(policy)
                self.assertEqual(pinfo.as_text(),
                                 certs[name]['policy_texts'][index])

    def test_certs(self):
        """Test for all known certs."""
        self.load_all_cas()
        self.load_all_certs()
        for _name, cert in list(self.cas.items()) + list(self.certs.items()):
            try:
                val = cert.x509.extensions.get_extension_for_oid(
                    ExtensionOID.CERTIFICATE_POLICIES).value
            except x509.ExtensionNotFound:
                continue

            for policy in val:
                pi1 = PolicyInformation(policy)
                self.assertEqual(pi1.for_extension_type, policy)

                # pass the serialized value to the constructor and see if it's still the same
                pi2 = PolicyInformation(pi1.serialize())
                self.assertEqual(pi1, pi2)
                self.assertEqual(pi1.serialize(), pi2.serialize())
                self.assertEqual(pi2.for_extension_type, policy)

    def test_clear(self):
        """Test PolicyInformation.clear()."""
        self.pi1.clear()
        self.assertIsNone(self.pi1.policy_qualifiers)

    def test_constructor(self):
        """Test some constructors that are otherwise not called."""
        pinfo = PolicyInformation()
        self.assertIsNone(pinfo.policy_identifier)
        self.assertIsNone(pinfo.policy_qualifiers)

        pinfo = PolicyInformation({
            'policy_identifier':
            '1.2.3',
            'policy_qualifiers': [
                x509.UserNotice(notice_reference=None, explicit_text='foobar'),
            ],
        })
        self.assertEqual(len(pinfo), 1)

        pinfo = PolicyInformation({
            'policy_identifier':
            '1.2.3',
            'policy_qualifiers': [{
                'notice_reference':
                x509.NoticeReference(organization='foobar',
                                     notice_numbers=[1]),
            }],
        })
        self.assertEqual(len(pinfo), 1)

    def test_constructor_errors(self):
        """Test various invalid values for the constructor."""
        with self.assertRaisesRegex(
                ValueError,
                r'^PolicyInformation data must be either x509.PolicyInformation or dict$'
        ):
            PolicyInformation(True)

        with self.assertRaisesRegex(
                ValueError,
                r'^PolicyQualifier must be string, dict or x509.UserNotice$'):
            PolicyInformation({
                'policy_identifier': '1.2.3',
                'policy_qualifiers': [True]
            })

        with self.assertRaisesRegex(
                ValueError,
                r'^NoticeReference must be either None, a dict or an x509.NoticeReference$'
        ):
            PolicyInformation({
                'policy_identifier':
                '1.2.3',
                'policy_qualifiers': [{
                    'notice_reference': True,
                }]
            })

    def test_contains(self):
        """Test PolicyInformation.contains()."""
        self.assertIn(self.q1, self.pi1)
        self.assertIn(self.q2, self.pi2)
        self.assertIn(self.q3, self.pi3)
        self.assertIn(self.q4, self.pi4)
        self.assertIn(self.q5, self.pi4)
        self.assertIn(self.s1['policy_qualifiers'][0], self.pi1)
        self.assertIn(self.s2['policy_qualifiers'][0], self.pi2)
        self.assertIn(self.s3['policy_qualifiers'][0], self.pi3)
        self.assertIn(self.s4['policy_qualifiers'][0], self.pi4)
        self.assertIn(self.s4['policy_qualifiers'][1], self.pi4)

        self.assertNotIn(self.q2, self.pi1)
        self.assertNotIn(self.q1, self.pi_empty)
        self.assertNotIn(self.s1['policy_qualifiers'][0], self.pi2)
        self.assertNotIn(self.s2['policy_qualifiers'][0], self.pi1)
        self.assertNotIn(self.s2['policy_qualifiers'][0], self.pi_empty)

    def test_count(self):
        """Test PolicyInformation.count()."""
        self.assertEqual(self.pi1.count(self.s1['policy_qualifiers'][0]), 1)
        self.assertEqual(self.pi1.count(self.q1), 1)
        self.assertEqual(self.pi1.count(self.s2), 0)
        self.assertEqual(self.pi1.count(self.q2), 0)
        self.assertEqual(self.pi_empty.count(self.q2), 0)
        self.assertEqual(self.pi1.count(True), 0)  # pass an unparseable value

    def test_delitem(self):
        """Test item deletion (e.g. ``del pi[0]``)."""
        del self.pi1[0]
        self.pi_empty.policy_identifier = self.oid
        self.assertEqual(self.pi1, self.pi_empty)

        self.assertEqual(len(self.pi4), 2)
        del self.pi4[0]
        self.assertEqual(len(self.pi4), 1)

        with self.assertRaisesRegex(IndexError,
                                    r'^list assignment index out of range$'):
            del self.pi1[0]

    def test_extend(self):
        """Test PolicyInformation.extend()."""
        self.pi1.extend([self.q2, self.q4])
        self.assertEqual(
            self.pi1,
            PolicyInformation({
                'policy_identifier': self.oid,
                'policy_qualifiers': [self.q1, self.q2, self.q4],
            }))

        self.pi2.extend([self.s1['policy_qualifiers'][0]])
        self.assertEqual(
            self.pi2,
            PolicyInformation({
                'policy_identifier': self.oid,
                'policy_qualifiers': [self.q2, self.q1],
            }))

        # extend an empty list
        self.pi_empty.extend([self.s1['policy_qualifiers'][0]])
        self.assertEqual(
            self.pi_empty,
            PolicyInformation({
                'policy_identifier': None,
                'policy_qualifiers': [self.q1],
            }))

    def test_getitem(self):
        """Test item getter (e.g. ``x = ext[0]``)."""
        self.assertEqual(self.pi1[0], self.s1['policy_qualifiers'][0])
        self.assertEqual(self.pi4[0], self.s4['policy_qualifiers'][0])
        self.assertEqual(self.pi4[1], self.s4['policy_qualifiers'][1])
        self.assertEqual(self.pi4[1:], [self.s4['policy_qualifiers'][1]])

        with self.assertRaisesRegex(IndexError, r'^list index out of range$'):
            self.pi_empty[0]  # pylint: disable=pointless-statement
        with self.assertRaisesRegex(IndexError, r'^list index out of range$'):
            self.pi_empty[2:]  # pylint: disable=pointless-statement

    def test_hash(self):
        """Test hash()."""
        self.assertEqual(hash(self.pi1), hash(self.pi1))
        self.assertEqual(hash(self.pi2), hash(self.pi2))
        self.assertEqual(hash(self.pi3), hash(self.pi3))
        self.assertEqual(hash(self.pi4), hash(self.pi4))
        self.assertEqual(hash(self.pi_empty), hash(self.pi_empty))

        self.assertEqual(hash(self.pi1), hash(PolicyInformation(self.s1)))
        self.assertEqual(hash(self.pi2), hash(PolicyInformation(self.s2)))
        self.assertEqual(hash(self.pi3), hash(PolicyInformation(self.s3)))
        self.assertEqual(hash(self.pi4), hash(PolicyInformation(self.s4)))
        self.assertEqual(hash(self.pi_empty), hash(PolicyInformation()))

        self.assertNotEqual(hash(self.pi1), hash(self.pi2))
        self.assertNotEqual(hash(self.pi1), hash(self.pi3))
        self.assertNotEqual(hash(self.pi1), hash(self.pi4))
        self.assertNotEqual(hash(self.pi2), hash(self.pi3))
        self.assertNotEqual(hash(self.pi2), hash(self.pi4))
        self.assertNotEqual(hash(self.pi3), hash(self.pi4))

    def test_insert(self):
        """Test PolicyInformation.insert()."""
        self.pi1.insert(0, self.q2)
        self.assertEqual(
            self.pi1,
            PolicyInformation({
                'policy_identifier': self.oid,
                'policy_qualifiers': [self.q2, self.q1],
            }))
        self.pi1.insert(1, self.s3['policy_qualifiers'][0])
        self.assertEqual(
            self.pi1,
            PolicyInformation({
                'policy_identifier': self.oid,
                'policy_qualifiers': [self.q2, self.q3, self.q1],
            }))

        self.pi_empty.insert(1, self.q2)
        self.pi_empty.policy_identifier = self.oid
        self.assertEqual(self.pi2, self.pi_empty)

    def test_len(self):
        """Test len(ext)."""
        self.assertEqual(len(self.pi1), 1)
        self.assertEqual(len(self.pi2), 1)
        self.assertEqual(len(self.pi3), 1)
        self.assertEqual(len(self.pi4), 2)
        self.assertEqual(len(self.pi_empty), 0)

    def test_policy_identifier_setter(self):
        """Test setting a policy identifier."""
        value = '1.2.3'
        expected = ObjectIdentifier(value)
        pinfo = PolicyInformation({'policy_identifier': value})
        pinfo.policy_identifier = value
        self.assertEqual(pinfo.policy_identifier, expected)

        pinfo = PolicyInformation({'policy_identifier': expected})
        self.assertEqual(pinfo.policy_identifier, expected)

        new_value = '2.3.4'
        new_expected = ObjectIdentifier(new_value)
        pinfo.policy_identifier = new_value
        self.assertEqual(pinfo.policy_identifier, new_expected)

    def test_pop(self):
        """Test PolicyInformation.pop()."""
        self.pi_empty.policy_identifier = self.oid
        self.assertEqual(self.pi1.pop(), self.s1['policy_qualifiers'][0])
        self.assertEqual(self.pi1, self.pi_empty)

        self.assertEqual(self.pi4.pop(1), self.s4['policy_qualifiers'][1])
        self.assertEqual(
            self.pi4,
            PolicyInformation({
                'policy_identifier': self.oid,
                'policy_qualifiers': [self.q4],
            }))

        self.assertEqual(self.pi4.pop(), self.s4['policy_qualifiers'][0])
        self.assertEqual(self.pi4, self.pi_empty)

        with self.assertRaisesRegex(IndexError, r'^pop from empty list$'):
            self.pi_empty.pop()

    def test_remove(self):
        """Test PolicyInformation.remove()."""
        self.pi_empty.policy_identifier = self.oid
        self.pi1.remove(self.q1)
        self.assertEqual(self.pi1, self.pi_empty)

        self.pi2.remove(self.s2['policy_qualifiers'][0])
        self.assertEqual(self.pi1, self.pi_empty)

        self.pi4.remove(self.q4)
        self.assertEqual(
            self.pi4,
            PolicyInformation({
                'policy_identifier': self.oid,
                'policy_qualifiers': [self.q5],
            }))

        with self.assertRaisesRegex(ValueError, r'^.*: not in list\.$'):
            self.pi_empty.remove(self.s3['policy_qualifiers'][0])

    def _test_repr(self, func):
        self.assertEqual(
            func(self.pi1),
            "<PolicyInformation(oid=2.5.29.32.0, qualifiers=['text1'])>")
        self.assertEqual(
            func(self.pi2),
            "<PolicyInformation(oid=2.5.29.32.0, qualifiers=[{'explicit_text': 'text2'}])>"
        )
        self.assertEqual(func(self.pi_empty),
                         "<PolicyInformation(oid=None, qualifiers=None)>")

        # NOTE: order of dict is different here, so we do not test output, just make sure there's no exception
        func(self.pi3)
        func(self.pi4)

    def test_repr(self):
        """Test repr()."""
        self._test_repr(repr)

    def test_str(self):
        """Test str()."""
        self._test_repr(str)
Exemplo n.º 15
0
class PolicyInformationTestCase(TestCaseMixin, TestCase):
    """Test PolicyInformation class."""

    oid = "2.5.29.32.0"

    # various qualifiers
    q1 = "text1"
    q2 = x509.UserNotice(explicit_text="text2", notice_reference=None)
    q3 = x509.UserNotice(explicit_text=None,
                         notice_reference=x509.NoticeReference(
                             organization="text3", notice_numbers=[1]))
    q4 = "text4"
    q5 = x509.UserNotice(
        explicit_text="text5",
        notice_reference=x509.NoticeReference(organization="text6",
                                              notice_numbers=[1, 2, 3]),
    )

    x1 = x509.PolicyInformation(policy_identifier=ObjectIdentifier(oid),
                                policy_qualifiers=[q1])
    x2 = x509.PolicyInformation(
        policy_identifier=ObjectIdentifier(oid),
        policy_qualifiers=[q2],
    )
    x3 = x509.PolicyInformation(
        policy_identifier=ObjectIdentifier(oid),
        policy_qualifiers=[q3],
    )
    x4 = x509.PolicyInformation(
        policy_identifier=ObjectIdentifier(oid),
        policy_qualifiers=[q4, q5],
    )
    s1: ParsablePolicyInformation = {
        "policy_identifier": oid,
        "policy_qualifiers": ["text1"],
    }
    s2: ParsablePolicyInformation = {
        "policy_identifier": oid,
        "policy_qualifiers": [{
            "explicit_text": "text2",
        }],
    }
    s3: ParsablePolicyInformation = {
        "policy_identifier":
        oid,
        "policy_qualifiers": [{
            "notice_reference": {
                "organization": "text3",
                "notice_numbers": [
                    1,
                ],
            }
        }],
    }
    s4: ParsablePolicyInformation = {
        "policy_identifier":
        oid,
        "policy_qualifiers": [
            "text4",
            {
                "explicit_text": "text5",
                "notice_reference": {
                    "organization": "text6",
                    "notice_numbers": [1, 2, 3],
                },
            },
        ],
    }
    s5: ParsablePolicyInformation = {
        "policy_identifier":
        oid,
        "policy_qualifiers": [{
            "explicit_text": "text5",
            "notice_reference": {
                "notice_numbers": [1, 2, 3],
            },
        }],
    }

    def setUp(self) -> None:
        super().setUp()

        self.pi1 = PolicyInformation(self.s1)
        self.pi2 = PolicyInformation(self.s2)
        self.pi3 = PolicyInformation(self.s3)
        self.pi4 = PolicyInformation(self.s4)
        self.pi5 = PolicyInformation(self.s5)
        self.pi_empty = PolicyInformation()

    def test_append(self) -> None:
        """Test PolicyInformation.append()."""
        self.pi1.append(self.q2)
        self.pi1.append(self.s3["policy_qualifiers"][0])
        self.assertEqual(
            self.pi1,
            PolicyInformation({
                "policy_identifier": self.oid,
                "policy_qualifiers": [self.q1, self.q2, self.q3],
            }),
        )

        self.pi_empty.policy_identifier = self.oid
        self.pi_empty.append(self.q3)
        self.assertEqual(self.pi3, self.pi_empty)

    def test_as_text(self) -> None:
        """Test as_text()."""
        self.assertEqual(
            self.pi1.as_text(), "Policy Identifier: 2.5.29.32.0\n"
            "Policy Qualifiers:\n* text1")
        self.assertEqual(
            self.pi2.as_text(),
            "Policy Identifier: 2.5.29.32.0\n"
            "Policy Qualifiers:\n"
            "* UserNotice:\n"
            "  * Explicit text: text2",
        )
        self.assertEqual(
            self.pi3.as_text(),
            "Policy Identifier: 2.5.29.32.0\n"
            "Policy Qualifiers:\n"
            "* UserNotice:\n"
            "  * Reference:\n"
            "    * Organiziation: text3\n"
            "    * Notice Numbers: [1]",
        )
        self.assertEqual(
            self.pi4.as_text(),
            "Policy Identifier: 2.5.29.32.0\n"
            "Policy Qualifiers:\n"
            "* text4\n"
            "* UserNotice:\n"
            "  * Explicit text: text5\n"
            "  * Reference:\n"
            "    * Organiziation: text6\n"
            "    * Notice Numbers: [1, 2, 3]",
        )
        self.assertEqual(self.pi_empty.as_text(),
                         "Policy Identifier: None\nNo Policy Qualifiers")

        self.load_named_cas("__all__")
        self.load_named_certs("__all__")
        for name, cert in list(self.new_cas.items()) + list(
                self.new_certs.items()):  # type: ignore[arg-type]
            try:
                ext = cert.pub.loaded.extensions.get_extension_for_class(
                    x509.CertificatePolicies).value
            except x509.ExtensionNotFound:
                continue

            for index, policy in enumerate(ext):
                pinfo = PolicyInformation(policy)
                self.assertEqual(pinfo.as_text(),
                                 certs[name]["policy_texts"][index])

    def test_certs(self) -> None:
        """Test for all known certs."""
        self.load_named_cas("__all__")
        self.load_named_certs("__all__")
        for cert in list(self.new_cas.values()) + list(
                self.new_certs.values()):  # type: ignore[arg-type]
            try:
                val = cert.pub.loaded.extensions.get_extension_for_class(
                    x509.CertificatePolicies).value
            except x509.ExtensionNotFound:
                continue

            for policy in val:
                pi1 = PolicyInformation(policy)
                self.assertEqual(pi1.for_extension_type, policy)

                # pass the serialized value to the constructor and see if it's still the same
                pi2 = PolicyInformation(
                    typing.cast(ParsablePolicyInformation, pi1.serialize()))
                self.assertEqual(pi1, pi2)
                self.assertEqual(pi1.serialize(), pi2.serialize())
                self.assertEqual(pi2.for_extension_type, policy)

    def test_clear(self) -> None:
        """Test PolicyInformation.clear()."""
        self.pi1.clear()
        self.assertIsNone(self.pi1.policy_qualifiers)

    def test_constructor(self) -> None:
        """Test some constructors that are otherwise not called."""
        pinfo = PolicyInformation()
        self.assertIsNone(pinfo.policy_identifier)
        self.assertIsNone(pinfo.policy_qualifiers)

        pinfo = PolicyInformation({
            "policy_identifier":
            "1.2.3",
            "policy_qualifiers": [
                x509.UserNotice(notice_reference=None, explicit_text="foobar"),
            ],
        })
        self.assertEqual(len(pinfo), 1)

        pinfo = PolicyInformation({
            "policy_identifier":
            "1.2.3",
            "policy_qualifiers": [{
                "notice_reference":
                x509.NoticeReference(organization="foobar",
                                     notice_numbers=[1]),
            }],
        })
        self.assertEqual(len(pinfo), 1)

    def test_constructor_errors(self) -> None:
        """Test various invalid values for the constructor."""
        # type ignores are because we're testing exactly that here
        with self.assertRaisesRegex(
                ValueError,
                r"^PolicyInformation data must be either x509.PolicyInformation or dict$"
        ):
            PolicyInformation(True)  # type: ignore[arg-type]

        with self.assertRaisesRegex(
                ValueError,
                r"^PolicyQualifier must be string, dict or x509.UserNotice$"):
            PolicyInformation({
                "policy_identifier": "1.2.3",
                "policy_qualifiers": [True]
            }  # type: ignore[list-item]
                              )

        with self.assertRaisesRegex(
                ValueError,
                r"^NoticeReference must be either None, a dict or an x509.NoticeReference$"
        ):
            PolicyInformation({
                "policy_identifier":
                "1.2.3",
                "policy_qualifiers": [{
                    "notice_reference": True,  # type: ignore[typeddict-item]
                }],
            })

    def test_contains(self) -> None:
        """Test PolicyInformation.contains()."""
        self.assertIn(self.q1, self.pi1)
        self.assertIn(self.q2, self.pi2)
        self.assertIn(self.q3, self.pi3)
        self.assertIn(self.q4, self.pi4)
        self.assertIn(self.q5, self.pi4)
        self.assertIn(self.s1["policy_qualifiers"][0], self.pi1)
        self.assertIn(self.s2["policy_qualifiers"][0], self.pi2)
        self.assertIn(self.s3["policy_qualifiers"][0], self.pi3)
        self.assertIn(self.s4["policy_qualifiers"][0], self.pi4)
        self.assertIn(self.s4["policy_qualifiers"][1], self.pi4)

        self.assertNotIn(self.q2, self.pi1)
        self.assertNotIn(self.q1, self.pi_empty)
        self.assertNotIn(self.s1["policy_qualifiers"][0], self.pi2)
        self.assertNotIn(self.s2["policy_qualifiers"][0], self.pi1)
        self.assertNotIn(self.s2["policy_qualifiers"][0], self.pi_empty)

        # Invalid values are always false:
        self.assertNotIn(True, self.pi1)

    def test_count(self) -> None:
        """Test PolicyInformation.count()."""
        self.assertEqual(self.pi1.count(self.s1["policy_qualifiers"][0]), 1)
        self.assertEqual(self.pi1.count(self.q1), 1)
        self.assertEqual(self.pi1.count(self.s2),
                         0)  # type: ignore[arg-type] # full pi is wrong
        self.assertEqual(self.pi1.count(self.q2), 0)
        self.assertEqual(self.pi_empty.count(self.q2), 0)
        self.assertEqual(
            self.pi1.count(True),
            0)  # type: ignore[arg-type] # what we're testing here!

    def test_delitem(self) -> None:
        """Test item deletion (e.g. ``del pi[0]``)."""
        del self.pi1[0]
        self.pi_empty.policy_identifier = self.oid
        self.assertEqual(self.pi1, self.pi_empty)

        self.assertEqual(len(self.pi4), 2)
        del self.pi4[0]
        self.assertEqual(len(self.pi4), 1)

        with self.assertRaisesRegex(IndexError,
                                    r"^list assignment index out of range$"):
            del self.pi1[0]

    def test_extend(self) -> None:
        """Test PolicyInformation.extend()."""
        self.pi1.extend([self.q2, self.q4])
        self.assertEqual(
            self.pi1,
            PolicyInformation({
                "policy_identifier": self.oid,
                "policy_qualifiers": [self.q1, self.q2, self.q4],
            }),
        )

        self.pi2.extend([self.s1["policy_qualifiers"][0]])
        self.assertEqual(
            self.pi2,
            PolicyInformation({
                "policy_identifier": self.oid,
                "policy_qualifiers": [self.q2, self.q1],
            }),
        )

        # extend an empty list
        self.pi_empty.extend([self.s1["policy_qualifiers"][0]])
        self.assertEqual(
            self.pi_empty,
            PolicyInformation({
                "policy_identifier": None,
                "policy_qualifiers": [self.q1],
            }),
        )

    def test_getitem(self) -> None:
        """Test item getter (e.g. ``x = ext[0]``)."""
        self.assertEqual(self.pi1[0], self.s1["policy_qualifiers"][0])
        self.assertEqual(self.pi4[0], self.s4["policy_qualifiers"][0])
        self.assertEqual(self.pi4[1], self.s4["policy_qualifiers"][1])
        self.assertEqual(self.pi4[1:], [self.s4["policy_qualifiers"][1]])

        with self.assertRaisesRegex(IndexError, r"^list index out of range$"):
            self.pi_empty[0]  # pylint: disable=pointless-statement
        with self.assertRaisesRegex(IndexError, r"^list index out of range$"):
            self.pi_empty[2:]  # pylint: disable=pointless-statement

    def test_hash(self) -> None:
        """Test hash()."""
        self.assertEqual(hash(self.pi1), hash(self.pi1))
        self.assertEqual(hash(self.pi2), hash(self.pi2))
        self.assertEqual(hash(self.pi3), hash(self.pi3))
        self.assertEqual(hash(self.pi4), hash(self.pi4))
        self.assertEqual(hash(self.pi5), hash(self.pi5))
        self.assertEqual(hash(self.pi_empty), hash(self.pi_empty))

        self.assertEqual(hash(self.pi1), hash(PolicyInformation(self.s1)))
        self.assertEqual(hash(self.pi2), hash(PolicyInformation(self.s2)))
        self.assertEqual(hash(self.pi3), hash(PolicyInformation(self.s3)))
        self.assertEqual(hash(self.pi4), hash(PolicyInformation(self.s4)))
        self.assertEqual(hash(self.pi5), hash(PolicyInformation(self.s5)))
        self.assertEqual(hash(self.pi_empty), hash(PolicyInformation()))

        self.assertNotEqual(hash(self.pi1), hash(self.pi2))
        self.assertNotEqual(hash(self.pi1), hash(self.pi3))
        self.assertNotEqual(hash(self.pi1), hash(self.pi4))
        self.assertNotEqual(hash(self.pi2), hash(self.pi3))
        self.assertNotEqual(hash(self.pi2), hash(self.pi4))
        self.assertNotEqual(hash(self.pi3), hash(self.pi4))

    def test_insert(self) -> None:
        """Test PolicyInformation.insert()."""
        self.pi1.insert(0, self.q2)
        self.assertEqual(
            self.pi1,
            PolicyInformation({
                "policy_identifier": self.oid,
                "policy_qualifiers": [self.q2, self.q1],
            }),
        )
        self.pi1.insert(1, self.s3["policy_qualifiers"][0])
        self.assertEqual(
            self.pi1,
            PolicyInformation({
                "policy_identifier": self.oid,
                "policy_qualifiers": [self.q2, self.q3, self.q1],
            }),
        )

        self.pi_empty.insert(1, self.q2)
        self.pi_empty.policy_identifier = self.oid
        self.assertEqual(self.pi2, self.pi_empty)

    def test_iter(self) -> None:
        """Test iter(pi)."""
        self.assertEqual(list(self.pi1), [self.q1])
        self.assertEqual(list(self.pi2), [self.q2])
        self.assertEqual(list(self.pi4), [self.q4, self.q5])
        self.assertEqual(list(self.pi_empty), [])

    def test_len(self) -> None:
        """Test len(ext)."""
        self.assertEqual(len(self.pi1), 1)
        self.assertEqual(len(self.pi2), 1)
        self.assertEqual(len(self.pi3), 1)
        self.assertEqual(len(self.pi4), 2)
        self.assertEqual(len(self.pi5), 1)
        self.assertEqual(len(self.pi_empty), 0)

    def test_policy_identifier_setter(self) -> None:
        """Test setting a policy identifier."""
        value = "1.2.3"
        expected = ObjectIdentifier(value)
        pinfo = PolicyInformation({
            "policy_identifier": value,
            "policy_qualifiers": []
        })
        pinfo.policy_identifier = value
        self.assertEqual(pinfo.policy_identifier, expected)

        pinfo = PolicyInformation({"policy_identifier": expected})
        self.assertEqual(pinfo.policy_identifier, expected)

        new_value = "2.3.4"
        new_expected = ObjectIdentifier(new_value)
        pinfo.policy_identifier = new_value
        self.assertEqual(pinfo.policy_identifier, new_expected)

    def test_pop(self) -> None:
        """Test PolicyInformation.pop()."""
        self.pi_empty.policy_identifier = self.oid
        self.assertEqual(self.pi1.pop(), self.s1["policy_qualifiers"][0])
        self.assertEqual(self.pi1, self.pi_empty)

        self.assertEqual(self.pi4.pop(1), self.s4["policy_qualifiers"][1])
        self.assertEqual(
            self.pi4,
            PolicyInformation({
                "policy_identifier": self.oid,
                "policy_qualifiers": [self.q4],
            }),
        )

        self.assertEqual(self.pi4.pop(), self.s4["policy_qualifiers"][0])
        self.assertEqual(self.pi4, self.pi_empty)

        with self.assertRaisesRegex(IndexError, r"^pop from empty list$"):
            self.pi_empty.pop()

    def test_remove(self) -> None:
        """Test PolicyInformation.remove()."""
        self.pi_empty.policy_identifier = self.oid
        self.pi1.remove(self.q1)
        self.assertEqual(self.pi1, self.pi_empty)

        self.pi2.remove(self.s2["policy_qualifiers"][0])
        self.assertEqual(self.pi1, self.pi_empty)

        self.pi4.remove(self.q4)
        self.assertEqual(
            self.pi4,
            PolicyInformation({
                "policy_identifier": self.oid,
                "policy_qualifiers": [self.q5],
            }),
        )

        with self.assertRaisesRegex(ValueError, r"^.*: not in list\.$"):
            self.pi_empty.remove(self.s3["policy_qualifiers"][0])

    def _test_repr(self, func: typing.Callable[[typing.Any], str]) -> None:
        self.assertEqual(
            func(self.pi1),
            "<PolicyInformation(oid=2.5.29.32.0, qualifiers=['text1'])>")
        self.assertEqual(
            func(self.pi2),
            "<PolicyInformation(oid=2.5.29.32.0, qualifiers=[{'explicit_text': 'text2'}])>"
        )
        self.assertEqual(func(self.pi_empty),
                         "<PolicyInformation(oid=None, qualifiers=None)>")

        # NOTE: order of dict is different here, so we do not test output, just make sure there's no exception
        func(self.pi3)
        func(self.pi4)

    def test_repr(self) -> None:
        """Test repr()."""
        self._test_repr(repr)

    def test_serialize(self) -> None:
        """Test serialization."""
        self.assertEqual(self.pi1.serialize(), {
            "policy_identifier": "2.5.29.32.0",
            "policy_qualifiers": ["text1"]
        })
        self.assertEqual(
            self.pi2.serialize(),
            {
                "policy_identifier": "2.5.29.32.0",
                "policy_qualifiers": [{
                    "explicit_text": "text2"
                }]
            },
        )
        self.assertEqual(
            self.pi3.serialize(),
            {
                "policy_identifier":
                "2.5.29.32.0",
                "policy_qualifiers": [{
                    "notice_reference": {
                        "notice_numbers": [1],
                        "organization": "text3"
                    }
                }],
            },
        )
        self.assertEqual(
            self.pi4.serialize(),
            {
                "policy_identifier":
                "2.5.29.32.0",
                "policy_qualifiers": [
                    "text4",
                    {
                        "explicit_text": "text5",
                        "notice_reference": {
                            "notice_numbers": [1, 2, 3],
                            "organization": "text6"
                        },
                    },
                ],
            },
        )
        self.assertEqual(
            self.pi5.serialize(),
            {
                "policy_identifier":
                "2.5.29.32.0",
                "policy_qualifiers": [{
                    "explicit_text": "text5",
                    "notice_reference": {
                        "notice_numbers": [1, 2, 3]
                    }
                }],
            },
        )

    def test_setitem(self) -> None:
        """Test __setitem__()."""
        # pylint: disable=invalid-name; let's just use pi here
        pi = PolicyInformation(self.s1)
        self.assertEqual(pi, self.pi1)
        pi[0] = self.q2
        self.assertEqual(pi, self.pi2)

        pi = PolicyInformation(self.s1)
        pi[0:1] = [self.q2]
        self.assertEqual(pi, self.pi2)

        # list()[0:1] = "x" also works
        pi = PolicyInformation({"policy_identifier": "2.5.29.32.0"})
        pi[0:1] = [self.q2]
        self.assertEqual(pi, self.pi2)

        pi = PolicyInformation()
        with self.assertRaisesRegex(ValueError, r"^Index out of range$"):
            pi[0] = self.q1
        self.assertEqual(len(pi), 0)

        pi = PolicyInformation(self.s1)
        with self.assertRaisesRegex(
                ValueError,
                r"^PolicyQualifier must be string, dict or x509.UserNotice$"):
            pi[0] = True  # type: ignore[assignment]
        self.assertEqual(pi, self.pi1)

        pi = PolicyInformation(self.s1)
        with self.assertRaisesRegex(
                TypeError, r"^bar/%s: Invalid key/value type$" % self.q1):
            pi["bar"] = self.q1  # type: ignore[index]
        self.assertEqual(pi, self.pi1)

    def test_str(self) -> None:
        """Test str()."""
        self._test_repr(str)
Exemplo n.º 16
0
 def __parse_ev_oids(self):
     if self.__ev_oids_arg:
         self.ev_oids = [
             ObjectIdentifier(oid) for oid in self.__ev_oids_arg
         ]
Exemplo n.º 17
0
    'encipherOnly': 'encipher_only',
    'keyAgreement': 'key_agreement',
    'keyCertSign': 'key_cert_sign',
    'keyEncipherment': 'key_encipherment',
    'nonRepudiation':
    'content_commitment',  # http://marc.info/?t=107176106300005&r=1&w=2
}

EXTENDED_KEY_USAGE_MAPPING = {
    'serverAuth': ExtendedKeyUsageOID.SERVER_AUTH,
    'clientAuth': ExtendedKeyUsageOID.CLIENT_AUTH,
    'codeSigning': ExtendedKeyUsageOID.CODE_SIGNING,
    'emailProtection': ExtendedKeyUsageOID.EMAIL_PROTECTION,
    'timeStamping': ExtendedKeyUsageOID.TIME_STAMPING,
    'OCSPSigning': ExtendedKeyUsageOID.OCSP_SIGNING,
    'smartcardLogon': ObjectIdentifier("1.3.6.1.4.1.311.20.2.2"),
    'msKDC': ObjectIdentifier("1.3.6.1.5.2.3.5"),
}
EXTENDED_KEY_USAGE_REVERSED = {
    v: k
    for k, v in EXTENDED_KEY_USAGE_MAPPING.items()
}

TLS_FEATURE_MAPPING = {
    # https://tools.ietf.org/html/rfc6066.html:
    'OCSPMustStaple': TLSFeatureType.status_request,
    # https://tools.ietf.org/html/rfc6961.html (not commonly used):
    'MultipleCertStatusRequest': TLSFeatureType.status_request_v2,
}

Exemplo n.º 18
0
 def _set_policy_identifier(self, value: ParsablePolicyIdentifier) -> None:
     if isinstance(value, str):
         self._policy_identifier = ObjectIdentifier(value)
     else:
         self._policy_identifier = value
Exemplo n.º 19
0
:mod:`scionlab.scion.certs` --- SCION Issuer Certificate and AS certificate creation
====================================================================================

See https://scion.docs.anapaya.net/en/latest/cryptography/certificates.html
Permalink: https://github.com/scionproto/scion/blob/835b3683c6e6bdf2a98750ec3a04137053f7f142/doc/cryptography/certificates.rst
""" # noqa

from cryptography import x509
from cryptography.x509 import ExtensionType
from cryptography.x509.oid import NameOID, ObjectIdentifier
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.asymmetric import ec
from datetime import datetime
from typing import List, Tuple, Optional, NamedTuple

OID_ISD_AS = ObjectIdentifier('1.3.6.1.4.1.55324.1.2.1')
OID_SENSITIVE_KEY = ObjectIdentifier('1.3.6.1.4.1.55324.1.3.1')
OID_REGULAR_KEY = ObjectIdentifier('1.3.6.1.4.1.55324.1.3.2')
OID_ROOT_KEY = ObjectIdentifier('1.3.6.1.4.1.55324.1.3.3')  # ca root key

CN_VOTING_SENSITIVE = 'Sensitive Voting Certificate'
CN_VOTING_REGULAR = 'Regular Voting Certificate'
CN_ISSUER_ROOT = 'High Security Root Certificate'
CN_ISSUER_CA = 'Secure CA Certificate'
CN_AS = 'AS Certificate'


class Extension(NamedTuple):
    extension: ExtensionType
    critical: bool
Exemplo n.º 20
0
    b.subject_name(extras['subject']) \
    .public_key(extras['key'].public_key()) \
    .not_valid_before(datetime.utcnow()) \
    .not_valid_after( extras.get('not_valid_after', datetime.utcnow() + timedelta(**extras.get('lifetime', {'days': 15*365})) ) ) \
    .add_extension(x509.BasicConstraints(ca=False, path_length=None), critical=True) \
    .add_extension(x509.KeyUsage(digital_signature=True, content_commitment=False, key_encipherment=True, data_encipherment=False,
        key_agreement=True, key_cert_sign=False, crl_sign=False, encipher_only=False, decipher_only=False), critical=False) \
    .add_extension(
        x509.SubjectAlternativeName(
            [x509.DNSName(name) for name in extras.get('host_names', [])]
            + [x509.RFC822Name(name) for name in extras.get('user_emails', [])]
        ), critical=False)

CERTIFICATE_SETTINGS_IPSEC_SERVER = lambda b, **extras: \
    _CERTIFICATE_SETTINGS_IPSEC_COMMON(b, **extras) \
    .add_extension(x509.ExtendedKeyUsage([ExtendedKeyUsageOID.SERVER_AUTH, ObjectIdentifier("1.3.6.1.5.5.8.2.2")]), critical=False) \

CERTIFICATE_SETTINGS_IPSEC_DEVICE = lambda b, **extras: \
    _CERTIFICATE_SETTINGS_IPSEC_COMMON(b, **extras) \
    .add_extension(x509.ExtendedKeyUsage([ExtendedKeyUsageOID.CLIENT_AUTH, ObjectIdentifier("1.3.6.1.5.5.8.2.2")]), critical=False) \


class CertificateStatus(Enum):
    REQUEST = "request"
    ACTIVE = "active"
    REVOKED = "revoked"


class Certificate(db.Model, CRUDMixin):
    __tablename__ = "certificate"
    id = db.Column(GUID, primary_key=True, default=uuid4)
Exemplo n.º 21
0
class CertCtOID(object):
    PRECERTIFICATE = ObjectIdentifier("1.3.6.1.4.1.11129.2.4.3")
    PRECERTIFICATE_CA = ObjectIdentifier("1.3.6.1.4.1.11129.2.4.4")
Exemplo n.º 22
0
from pprint import pformat

from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.x509.oid import NameOID, ObjectIdentifier

from pyasn1.codec.der import decoder
from pyasn1.type import char, namedtype, tag, univ

from ansible.module_utils.six import PY2
from ansible.module_utils._text import to_bytes, to_text

if PY2:
    FileNotFoundError = IOError  # pylint: disable=redefined-builtin

ANY_EXTENDED_KEY_USAGE = ObjectIdentifier("2.5.29.37.0")
IPSEC_END_SYSTEM = ObjectIdentifier("1.3.6.1.5.5.7.3.5")
IPSEC_TUNNEL = ObjectIdentifier("1.3.6.1.5.5.7.3.6")
IPSEC_USER = ObjectIdentifier("1.3.6.1.5.5.7.3.7")


def _escape_dn_value(val):
    """Escape special characters in RFC4514 Distinguished Name value."""
    if not val:
        return ""

    # See https://tools.ietf.org/html/rfc4514#section-2.4
    val = val.replace("\\", "\\\\")
    val = val.replace('"', '\\"')
    val = val.replace("+", "\\+")
    val = val.replace(",", "\\,")
Exemplo n.º 23
0
from pprint import pformat

from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.x509.oid import NameOID, ObjectIdentifier

from pyasn1.codec.der import decoder
from pyasn1.type import char, namedtype, tag, univ

from ansible.module_utils import six
from ansible.module_utils._text import to_bytes

if six.PY2:
    FileNotFoundError = IOError  # pylint: disable=redefined-builtin

IPSEC_END_SYSTEM = ObjectIdentifier("1.3.6.1.5.5.7.3.5")
IPSEC_TUNNEL = ObjectIdentifier("1.3.6.1.5.5.7.3.6")
IPSEC_USER = ObjectIdentifier("1.3.6.1.5.5.7.3.7")


def _escape_dn_value(val):
    """Escape special characters in RFC4514 Distinguished Name value."""
    if not val:
        return ""

    # See https://tools.ietf.org/html/rfc4514#section-2.4
    val = val.replace("\\", "\\\\")
    val = val.replace('"', '\\"')
    val = val.replace("+", "\\+")
    val = val.replace(",", "\\,")
    val = val.replace(";", "\\;")
Exemplo n.º 24
0
# fmt: off

LDAP_TIMEOUT = 7
LDAP_RETRIES = 5

ORG_NUMBER_REGEX = re.compile(r"(?:\d\s?){9}")
UNDERENHET_REGEX = re.compile(r"(?<!\d)\d{9}(?!\d)")
PERSONAL_SERIAL_REGEX = re.compile(
    r"(?:UN:NO-)?9578-(?:4505|4050|4510)-[A-z0-9]+")
# (This is a bad email regex, but it's good enough
# for this use case.)
EMAIL_REGEX = re.compile(r"[^\s@]+@[\w\d]+(?:\.[\w\d]+)+")
HEX_SERIAL_REGEX = re.compile(r"(?:[0-9a-fA-F][\s:]?){16,}")
INT_SERIAL_REGEX = re.compile(r"[0-9]{19,}")

ORGANIZATION_IDENTIFIER = ObjectIdentifier("2.5.4.97")

SUBJECT_FIELDS = {
    NameOID.COMMON_NAME: "CN",
    NameOID.SERIAL_NUMBER: "serialNumber",
    NameOID.COUNTRY_NAME: "C",
    NameOID.LOCALITY_NAME: "L",
    NameOID.STATE_OR_PROVINCE_NAME: "ST",
    NameOID.ORGANIZATION_NAME: "O",
    NameOID.SURNAME: "SN",
    NameOID.GIVEN_NAME: "GN",
    NameOID.ORGANIZATIONAL_UNIT_NAME: "OU",
    NameOID.EMAIL_ADDRESS: "email",
    ORGANIZATION_IDENTIFIER: "organizationIdentifier",
}
Exemplo n.º 25
0
def attest_android_key(
        att_stmt: AndroidKeyAttestationStatement, att_obj: AttestationObject,
        auth_data: bytes,
        client_data_hash: bytes) -> Tuple[AttestationType, TrustedPath]:
    """Attest an android key.

    Args:
      att_stmt (AndroidKeyAttestationStatement): The attestation statment.
      att_obj (AttestationObject): The attestation object.
      auth_data (bytes): The raw authenticator data.
      client_data_hash (bytes): The client data hash.

    Returns:
      The attestation type and trusted path.
    
    References:
      * https://www.w3.org/TR/webauthn/#android-key-attestation
      * https://source.android.com/security/keystore/attestation
      * https://developer.android.com/training/articles/security-key-attestation
    """
    if len(att_stmt.x5c) == 0:
        raise AttestationError('Must have at least 1 X509 certificate')

    credential_certificate = cryptography.x509.load_der_x509_certificate(
        att_stmt.x5c[0], default_backend())
    cred_cert_pk = credential_certificate.public_key()
    if not isinstance(
            cred_cert_pk,
        (EllipticCurvePublicKey, Ed25519PublicKey, Ed448PublicKey)):
        raise AttestationError(
            'Android key attestation failed: must use an Elliptic Curve Public Key'
        )

    assert att_obj.auth_data is not None
    assert att_obj.auth_data.attested_credential_data is not None

    cpk = cryptography_public_key(
        att_obj.auth_data.attested_credential_data.credential_public_key)

    verification_data = auth_data + client_data_hash
    assert att_stmt.sig is not None

    try:
        if isinstance(cred_cert_pk, (Ed25519PublicKey, Ed448PublicKey)):
            cred_cert_pk.verify(att_stmt.sig, verification_data)
        else:
            assert isinstance(cred_cert_pk, EllipticCurvePublicKey)
            assert att_stmt.alg is not None

            hash_algorithm = ECDSA(ec2_hash_algorithm(att_stmt.alg))
            cred_cert_pk.verify(att_stmt.sig, verification_data,
                                hash_algorithm)
    except cryptography.exceptions.InvalidSignature:
        raise AttestationError(
            'Android Key attestation failed: invalid signature')

    cpk_public_bytes = cpk.public_bytes(Encoding.DER,
                                        PublicFormat.SubjectPublicKeyInfo)
    cred_cert_public_bytes = cred_cert_pk.public_bytes(
        Encoding.DER, PublicFormat.SubjectPublicKeyInfo)
    if cpk_public_bytes != cred_cert_public_bytes:
        raise AttestationError(
            ('Android key attestation failed: certificate public key in '
             'attestation statement must match the '
             'provided credential public key'))

    try:
        extension = credential_certificate.extensions.get_extension_for_oid(
            ObjectIdentifier('1.3.6.1.4.1.11129.2.1.17'))
        assert isinstance(extension.value, UnrecognizedExtension)
    except cryptography.x509.ExtensionNotFound:
        raise AttestationError(
            'Android key attestation failed: could not find android key '
            'attestation certificate extension data')

    try:
        key_description, _ = decode(extension.value.value, KeyDescription())
    except PyAsn1Error:
        raise AttestationError(
            'Android key attestation failed: unable to decode DER-encoded '
            'Android Key Description')

    attestation_challenge = key_description['attestationChallenge'].asOctets()
    if attestation_challenge != client_data_hash:
        raise AttestationError(
            'Android key attestation failed: client data hash does not match '
            'value of attestation extension data')

    all_apps_se = key_description['softwareEnforced']['allApplications']
    all_apps_tee = key_description['teeEnforced']['allApplications']
    if all_apps_se.hasValue() or all_apps_tee.hasValue():
        raise AttestationError(
            'Android key attestation failed: the allApplications field must not be '
            'present in the android key description')

    # TODO: Consider selecting the appropriate AuthorizationList.
    tee_origin = key_description['teeEnforced']['origin']
    tee_purpose = key_description['teeEnforced']['purpose']
    if not tee_origin.hasValue() or int(tee_origin) != KM_ORIGIN_GENERATED:
        raise AttestationError((
            'Android key attestation failed: the teeEnforced origin field must '
            'equal KM_ORIGIN_GENERATED={}').format(KM_ORIGIN_GENERATED))

    # TODO: Determine if other purposes are also allowed in this set.
    if not tee_purpose.hasValue() or tee_purpose.count(KM_PURPOSE_SIGN) == 0:
        raise AttestationError((
            'Android key attestation failed: the teeEnforced purpose field must '
            'contain KM_PURPOSE_SIGN={}').format(KM_PURPOSE_SIGN))

    return AttestationType.BASIC, [credential_certificate]
Exemplo n.º 26
0
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicKey
from cryptography.x509 import ExtensionNotFound, PolicyInformation
from cryptography.x509.oid import ExtensionOID
from cryptography.x509.oid import ObjectIdentifier

from . import consts
from . import util
from .tls_domain_tools import TlsDomainTools

logger = logging.getLogger(__name__)

# Extended validation policy OIDs
#   Per CA defined
#   https://stackoverflow.com/questions/14705157/how-to-check-if-a-x509-certificate-has-extended-validation-switched-on
EV_OIDS = [
    ObjectIdentifier("1.3.6.1.4.1.34697.2.1"),
    ObjectIdentifier("1.3.6.1.4.1.34697.2.2"),
    ObjectIdentifier("1.3.6.1.4.1.34697.2.1"),
    ObjectIdentifier("1.3.6.1.4.1.34697.2.3"),
    ObjectIdentifier("1.3.6.1.4.1.34697.2.4"),
    ObjectIdentifier("1.2.40.0.17.1.22"),
    ObjectIdentifier("2.16.578.1.26.1.3.3"),
    ObjectIdentifier("1.3.6.1.4.1.17326.10.14.2.1.2"),
    ObjectIdentifier("1.3.6.1.4.1.17326.10.8.12.1.2"),
    ObjectIdentifier("1.3.6.1.4.1.6449.1.2.1.5.1"),
    ObjectIdentifier("2.16.840.1.114412.2.1"),
    ObjectIdentifier("2.16.528.1.1001.1.1.1.12.6.1.1.1"),
    ObjectIdentifier("2.16.840.1.114028.10.1.2"),
    ObjectIdentifier("1.3.6.1.4.1.14370.1.6"),
    ObjectIdentifier("1.3.6.1.4.1.4146.1.1"),
    ObjectIdentifier("2.16.840.1.114413.1.7.23.3"),