Exemple #1
0
 def verify_ca_cert_validity(self, nickname):
     certdb = cert = None
     if nss.nss_is_initialized():
         nss.nss_shutdown()
     nss.nss_init(self.secdir)
     try:
         certdb = nss.get_default_certdb()
         cert = nss.find_cert_from_nickname(nickname)
         if not cert.subject:
             raise ValueError("has empty subject")
         try:
             bc = cert.get_extension(nss.SEC_OID_X509_BASIC_CONSTRAINTS)
         except KeyError:
             raise ValueError("missing basic constraints")
         bc = nss.BasicConstraints(bc.value)
         if not bc.is_ca:
             raise ValueError("not a CA certificate")
         intended_usage = nss.certificateUsageSSLCA
         try:
             approved_usage = cert.verify_now(certdb, True, intended_usage)
         except NSPRError as e:
             if e.errno != -8102:  # SEC_ERROR_INADEQUATE_KEY_USAGE
                 raise ValueError(e.strerror)
             approved_usage = 0
         if approved_usage & intended_usage != intended_usage:
             raise ValueError('invalid for a CA')
     finally:
         del certdb, cert
         nss.nss_shutdown()
Exemple #2
0
    def test_csr_parse(self):
        csr = self.csr

        # Validate basic CSR information
        self.assertEqual(str(csr.subject), 'CN=localhost')
        self.assertEqual(csr.version, 0)

        # Validate the CSR Subject Public Key
        pub_key = csr.subject_public_key_info
        pub_key_algorithm = pub_key.algorithm

        self.assertEqual(pub_key_algorithm.id_tag,
                         nss.SEC_OID_PKCS1_RSA_ENCRYPTION)
        self.assertEqual(pub_key.public_key.rsa.exponent.get_integer(), 65537)

        # Validate the extensions, the number of extensions should
        # match, the order of extensions should match, and the
        # contents of each extension should match.
        #
        # Note, extensions are contained in an attribute, in essence
        # the extensions are a special case of one attribute.
        extensions = csr.extensions
        self.assertEqual(len(extensions), 2)

        extension = extensions[0]
        self.assertIsInstance(extension, nss.CertificateExtension)
        self.assertEqual(extension.oid_tag, nss.SEC_OID_X509_BASIC_CONSTRAINTS)
        bc = nss.BasicConstraints(extension.value)
        self.assertEqual(bc.is_ca, False)
        self.assertEqual(bc.path_len, 0)

        extension = extensions[1]
        self.assertIsInstance(extension, nss.CertificateExtension)
        self.assertEqual(extension.oid_tag, nss.SEC_OID_X509_SUBJECT_KEY_ID)
        self.assertEqual(
            extension.value.der_to_hex().upper(),
            '8B:84:44:E2:3B:21:CD:54:37:95:2D:B7:E8:D1:B1:D8:0E:96:56:10',
        )

        # Validate the attributes, the number of attributes should
        # match and the order of the attributes should match. Each
        # attribute has a type and a set of values. Confirm each
        # attribute has the correct number of values and each value is
        # what we expect.
        #
        # Note, one of the attributes is a set of extension requests,
        # this should be identical to CertificateRequest.extensions
        # property. The extenions property is just a shorthand for
        # accessing the attribute containing extensions.
        #
        # NSS has an odd behavior with attributes that is heavily
        # weighted toward extensions. If the attribute contains
        # extensions then the attribute values are
        # CertificateExtension's, otherwise they are SecItem's
        # and need to be interpreted according to the attribute.type.
        attributes = csr.attributes
        self.assertEqual(len(attributes), 2)

        attribute = attributes[0]
        self.assertIsInstance(attribute, nss.CertAttribute)
        self.assertEqual(attribute.type_tag, nss.SEC_OID_PKCS9_FRIENDLY_NAME)

        attribute_values = attribute.values
        self.assertEqual(len(attribute_values), 1)

        attribute_value = attribute.values[0]
        self.assertIsInstance(attribute_value, nss.SecItem)
        self.assertEqual(str(attribute_value), 'Test')

        attribute = attributes[1]
        self.assertIsInstance(attribute, nss.CertAttribute)
        self.assertEqual(attribute.type_tag,
                         nss.SEC_OID_PKCS9_EXTENSION_REQUEST)

        attribute_values = attribute.values
        self.assertEqual(len(attribute_values), 2)

        attribute_value = attribute.values[0]
        self.assertIsInstance(attribute_value, nss.CertificateExtension)
        self.assertEqual(attribute_value.oid_tag,
                         nss.SEC_OID_X509_BASIC_CONSTRAINTS)

        attribute_value = attribute.values[1]
        self.assertIsInstance(attribute_value, nss.CertificateExtension)
        self.assertEqual(attribute_value.oid_tag,
                         nss.SEC_OID_X509_SUBJECT_KEY_ID)
Exemple #3
0
def print_extension(level, extension):
    print(
        nss.indented_format([(level, 'Name: %s' % extension.name),
                             (level, 'Critical: %s' % extension.critical)]))

    oid_tag = extension.oid_tag

    if oid_tag == nss.SEC_OID_PKCS12_KEY_USAGE:
        print(nss.indented_format([(level, 'Usages:')]))
        print(
            nss.indented_format(
                nss.make_line_fmt_tuples(level + 1,
                                         nss.x509_key_usage(extension.value))))

    elif oid_tag == nss.SEC_OID_NS_CERT_EXT_CERT_TYPE:
        print(nss.indented_format([(level, 'Types:')]))
        print(
            nss.indented_format(
                nss.make_line_fmt_tuples(level + 1,
                                         nss.x509_cert_type(extension.value))))

    elif oid_tag == nss.SEC_OID_X509_SUBJECT_KEY_ID:
        print(nss.indented_format([(level, 'Data:')]))
        print(
            nss.indented_format(
                nss.make_line_fmt_tuples(
                    level + 1,
                    extension.value.der_to_hex(nss.OCTETS_PER_LINE_DEFAULT))))

    elif oid_tag == nss.SEC_OID_X509_CRL_DIST_POINTS:
        pts = nss.CRLDistributionPts(extension.value)
        print(
            nss.indented_format([
                (level, 'CRL Distribution Points: [%d total]' % len(pts))
            ]))
        for i, pt in enumerate(pts):
            print(nss.indented_format([(level + 1, 'Point[%d]:' % i)]))
            names = pt.get_general_names()
            print(
                nss.indented_format([
                    (level + 2, 'General Names: [%d total]' % len(names))
                ]))
            for name in names:
                print(nss.indented_format([(level + 3, '%s:' % name)]))
            print(
                nss.indented_format([(level + 2,
                                      'Reasons: %s' % (pt.get_reasons(), ))]))
            print(nss.indented_format([(level + 2, 'Issuer: %s' % pt.issuer)]))

    elif oid_tag == nss.SEC_OID_X509_AUTH_INFO_ACCESS:
        aias = nss.AuthorityInfoAccesses(extension.value)
        print(
            nss.indented_format([
                (level, 'Authority Information Access: [%d total]' % len(aias))
            ]))
        for i, aia in enumerate(aias):
            print(nss.indented_format([(level + 1, 'Info[%d]:' % i)]))
            print(
                nss.indented_format([(level + 2,
                                      'Method: %s' % (aia.method_str, ))]))
            print(
                nss.indented_format([
                    (level + 2, 'Location: (%s) %s' %
                     (aia.location.type_string, aia.location.name))
                ]))

    elif oid_tag == nss.SEC_OID_X509_AUTH_KEY_ID:
        auth_key_id = nss.AuthKeyID(extension.value)
        print(nss.indented_format([(level + 1, 'Key ID:')]))
        print(
            nss.indented_format(
                nss.make_line_fmt_tuples(
                    level + 2,
                    auth_key_id.key_id.to_hex(nss.OCTETS_PER_LINE_DEFAULT))))
        print(
            nss.indented_format([
                (level + 1, 'Serial Number: %s' % (auth_key_id.serial_number))
            ]))
        print(
            nss.indented_format([
                (level + 1, 'Issuer:' % auth_key_id.get_general_names())
            ]))

    elif oid_tag == nss.SEC_OID_X509_BASIC_CONSTRAINTS:
        bc = nss.BasicConstraints(extension.value)
        print(nss.indented_format([(level, '%s' % str(bc))]))

    elif oid_tag == nss.SEC_OID_X509_EXT_KEY_USAGE:
        print(nss.indented_format([(level, 'Usages:')]))
        print(
            nss.indented_format(
                nss.make_line_fmt_tuples(
                    level + 1, nss.x509_ext_key_usage(extension.value))))

    elif oid_tag in (nss.SEC_OID_X509_SUBJECT_ALT_NAME,
                     nss.SEC_OID_X509_ISSUER_ALT_NAME):
        names = nss.x509_alt_name(extension.value)
        print(
            nss.indented_format([
                (level + 2, 'Alternate Names: [%d total]' % len(names))
            ]))
        for name in names:
            print(nss.indented_format([(level + 3, '%s:' % name)]))

    print()
Exemple #4
0
def print_extension(level, extension):
    print nss.indented_format([(level, 'Name: %s' % extension.name),
                               (level, 'Critical: %s' % extension.critical)])

    oid_tag = extension.oid_tag

    if oid_tag == nss.SEC_OID_PKCS12_KEY_USAGE:
        print nss.indented_format([(level, 'Usages:')])
        print nss.indented_format(
            nss.make_line_fmt_tuples(level + 1,
                                     nss.x509_key_usage(extension.value)))

    elif oid_tag == nss.SEC_OID_X509_SUBJECT_KEY_ID:
        print nss.indented_format([(level, 'Data:')])
        print nss.indented_format(
            nss.make_line_fmt_tuples(
                level + 1,
                extension.value.der_to_hex(nss.OCTETS_PER_LINE_DEFAULT)))

    elif oid_tag == nss.SEC_OID_X509_CRL_DIST_POINTS:
        pts = nss.CRLDistributionPts(extension.value)
        i = 1
        print nss.indented_format([
            (level, 'CRL Distribution Points: [%d total]' % len(pts))
        ])
        for pt in pts:
            print nss.indented_format([(level + 1, 'Point[%d]:' % i)])
            names = pt.get_general_names()
            print nss.indented_format([
                (level + 2, 'General Names: [%d total]' % len(names))
            ])
            for name in names:
                print nss.indented_format([(level + 3, '%s:' % name)])
            print nss.indented_format([(level + 2,
                                        'Reasons: %s' % (pt.get_reasons(), ))])
            print nss.indented_format([(level + 2, 'Issuer: %s' % pt.issuer)])

    elif oid_tag == nss.SEC_OID_X509_AUTH_KEY_ID:
        auth_key_id = nss.AuthKeyID(extension.value)
        print nss.indented_format([(level + 1, 'Key ID:')])
        print nss.indented_format(
            nss.make_line_fmt_tuples(
                level + 2,
                auth_key_id.key_id.to_hex(nss.OCTETS_PER_LINE_DEFAULT)))
        print nss.indented_format([
            (level + 1, 'Serial Number: %s' % (auth_key_id.serial_number))
        ])
        print nss.indented_format([
            (level + 1, 'Issuer:' % auth_key_id.get_general_names())
        ])

    elif oid_tag == nss.SEC_OID_X509_BASIC_CONSTRAINTS:
        bc = nss.BasicConstraints(extension.value)
        print nss.indented_format([(level, '%s' % str(bc))])

    elif oid_tag == nss.SEC_OID_X509_EXT_KEY_USAGE:
        print nss.indented_format([(level, 'Usages:')])
        print nss.indented_format(
            nss.make_line_fmt_tuples(level + 1,
                                     nss.x509_ext_key_usage(extension.value)))

    elif oid_tag in (nss.SEC_OID_X509_SUBJECT_ALT_NAME,
                     nss.SEC_OID_X509_ISSUER_ALT_NAME):
        names = nss.x509_alt_name(extension.value)
        print nss.indented_format([
            (level + 2, 'Alternate Names: [%d total]' % len(names))
        ])
        for name in names:
            print nss.indented_format([(level + 3, '%s:' % name)])

    print