Example #1
0
 def _set_public_key(self,
                     cert: Certificate_model,
                     private_key: Key,
                     issuer_key: Key = None) -> None:
     self._builder = self._builder.public_key(private_key.key.public_key())
     root_cert = cert.parent if cert.parent and cert.type == CertificateTypes.INTERMEDIATE else \
         cert.parent.parent if cert.parent and cert.parent.parent and \
         (cert.type == CertificateTypes.SERVER_CERT or cert.type == CertificateTypes.CLIENT_CERT) else None
     root_ca_subject = [
         DirectoryName(self._build_subject_names(root_cert.dn))
     ] if root_cert else None
     authority_cert_serial_number = int(
         cert.parent.serial) if root_cert else None
     self._builder = self._builder.add_extension(
         x509.AuthorityKeyIdentifier(
             key_identifier=_key_identifier_from_public_key(
                 issuer_key.key.public_key()),
             authority_cert_issuer=root_ca_subject,
             authority_cert_serial_number=authority_cert_serial_number),
         critical=True,
     )
     self._builder = self._builder.add_extension(
         x509.SubjectKeyIdentifier.from_public_key(
             private_key.key.public_key()),
         critical=True,
     )
Example #2
0
 def test_authority_cert_serial_number_not_integer(self):
     name = x509.Name([
         x509.NameAttribute(x509.ObjectIdentifier('oid'), 'value1'),
         x509.NameAttribute(x509.ObjectIdentifier('oid2'), 'value2'),
     ])
     with pytest.raises(TypeError):
         x509.AuthorityKeyIdentifier(b"identifier", name, "notanint")
Example #3
0
 def test_add_unsupported_extension(self):
     builder = x509.CertificateSigningRequestBuilder()
     with pytest.raises(NotImplementedError):
         builder.add_extension(
             x509.AuthorityKeyIdentifier('keyid', None, None),
             critical=False,
         )
Example #4
0
 def _set_public_key(self, cert: CertificateType, private_key: Key,
                     issuer_key: Key) -> None:
     self._builder = self._builder.public_key(private_key.key.public_key())
     ca_issuer_cert_subject = ca_issuer_cert_serial_number = None
     if cert.type not in [
             CertificateTypes.ROOT, CertificateTypes.INTERMEDIATE
     ]:
         ca_issuer_cert = cert.parent.parent if cert.parent.parent else cert.parent
         issuer_cert = cert.parent
         ca_issuer_cert_subject = [
             DirectoryName(Certificate.build_subject_names(ca_issuer_cert))
         ]
         ca_issuer_cert_serial_number = int(issuer_cert.serial)
     self._builder = self._builder.add_extension(
         x509.AuthorityKeyIdentifier(
             key_identifier=_key_identifier_from_public_key(
                 issuer_key.key.public_key()),
             authority_cert_issuer=ca_issuer_cert_subject,
             authority_cert_serial_number=ca_issuer_cert_serial_number,
         ),
         critical=False,
     )
     self._builder = self._builder.add_extension(
         x509.SubjectKeyIdentifier.from_public_key(
             private_key.key.public_key()),
         critical=False,
     )
Example #5
0
    def _build_authority_key_identifier(self, ext):
        akid = self._backend._lib.X509V3_EXT_d2i(ext)
        assert akid != self._backend._ffi.NULL
        akid = self._backend._ffi.cast("AUTHORITY_KEYID *", akid)
        akid = self._backend._ffi.gc(
            akid, self._backend._lib.AUTHORITY_KEYID_free
        )
        key_identifier = None
        authority_cert_issuer = None
        authority_cert_serial_number = None

        if akid.keyid != self._backend._ffi.NULL:
            key_identifier = self._backend._ffi.buffer(
                akid.keyid.data, akid.keyid.length
            )[:]

        if akid.issuer != self._backend._ffi.NULL:
            authority_cert_issuer = _build_general_names(
                self._backend, akid.issuer
            )

        if akid.serial != self._backend._ffi.NULL:
            bn = self._backend._lib.ASN1_INTEGER_to_BN(
                akid.serial, self._backend._ffi.NULL
            )
            assert bn != self._backend._ffi.NULL
            bn = self._backend._ffi.gc(bn, self._backend._lib.BN_free)
            authority_cert_serial_number = self._backend._bn_to_int(bn)

        return x509.AuthorityKeyIdentifier(
            key_identifier, authority_cert_issuer, authority_cert_serial_number
        )
Example #6
0
    def generate_crl(self, ca, certs, next_update=1):
        # There is a tricky case here - what happens if the root CA is compromised ?
        # In normal world scenarios, that CA is removed from app's trust store and any
        # subsequent certs it had issues wouldn't be validated by the app then. Making a CRL
        # for a revoked root CA in normal cases doesn't make sense as the thief can sign a
        # counter CRL saying that everything is fine. As our environment is controlled,
        # i think we are safe to create a crl for root CA as well which we can publish for
        # services which make use of it i.e openvpn and they'll know that the certs/ca's have been
        # compromised.
        #
        # `ca` is root ca from where the chain `certs` starts.
        # `certs` is a list of all certs ca inclusive which are to be
        # included in the CRL ( if root ca is compromised, it will be in `certs` as well ).
        private_key = load_private_key(ca['privatekey'])
        ca_cert = x509.load_pem_x509_certificate(ca['certificate'].encode(),
                                                 default_backend())

        if not private_key:
            return None

        ca_data = self.middleware.call_sync('cryptokey.load_certificate',
                                            ca['certificate'])
        issuer = {k: ca_data.get(v) for k, v in CERT_BACKEND_MAPPINGS.items()}

        crl_builder = x509.CertificateRevocationListBuilder().issuer_name(
            x509.Name([
                x509.NameAttribute(getattr(NameOID, k.upper()), v)
                for k, v in issuer.items() if v
            ])).last_update(datetime.datetime.utcnow()).next_update(
                datetime.datetime.utcnow() +
                datetime.timedelta(next_update, 300, 0))

        for cert in certs:
            crl_builder = crl_builder.add_revoked_certificate(
                x509.RevokedCertificateBuilder().serial_number(
                    self.middleware.call_sync(
                        'cryptokey.load_certificate',
                        cert['certificate'])['serial']).revocation_date(
                            cert['revoked_date']).build(default_backend()))

        # https://www.ietf.org/rfc/rfc5280.txt
        # We should add AuthorityKeyIdentifier and CRLNumber at the very least

        crl = crl_builder.add_extension(
            x509.AuthorityKeyIdentifier(
                x509.SubjectKeyIdentifier.from_public_key(
                    ca_cert.public_key()).digest,
                [
                    x509.DirectoryName(
                        x509.Name([
                            x509.NameAttribute(getattr(NameOID, k.upper()), v)
                            for k, v in issuer.items() if v
                        ]))
                ], ca_cert.serial_number),
            False).add_extension(x509.CRLNumber(1), False).sign(
                private_key=private_key,
                algorithm=retrieve_signing_algorithm({}, private_key),
                backend=default_backend())

        return crl.public_bytes(serialization.Encoding.PEM).decode()
    def signer_csr(self, nom_fichier_csr, nom_signataire):
        with open('%s.key.pem' % nom_signataire, 'rb') as fichier:
            private_bytes = fichier.read()
            signing_key = serialization.load_pem_private_key(
                private_bytes, password=None, backend=default_backend())
        with open('%s.cert.pem' % nom_signataire, 'rb') as fichier:
            public_bytes = fichier.read()
            signing_cert = x509.load_pem_x509_certificate(
                public_bytes, backend=default_backend())
        with open('%s.csr.pem' % nom_fichier_csr, 'rb') as fichier:
            public_bytes = fichier.read()
            fichier_csr = x509.load_pem_x509_csr(public_bytes,
                                                 backend=default_backend())

        one_day = datetime.timedelta(1, 0, 0)

        builder = x509.CertificateBuilder()
        builder = builder.subject_name(fichier_csr.subject)
        builder = builder.issuer_name(signing_cert.subject)
        builder = builder.not_valid_before(datetime.datetime.today() - one_day)
        builder = builder.not_valid_after(datetime.datetime.today() +
                                          self.__duree_cert_noeud)
        builder = builder.serial_number(x509.random_serial_number())
        builder = builder.public_key(fichier_csr.public_key())
        builder = builder.add_extension(x509.SubjectAlternativeName(
            [x509.DNSName(u'mon_serveur.ca')]),
                                        critical=False)

        builder = builder.add_extension(
            x509.BasicConstraints(ca=False, path_length=None),
            critical=True,
        )

        builder = builder.add_extension(
            x509.SubjectKeyIdentifier.from_public_key(
                fichier_csr.public_key()),
            critical=False)

        ski = signing_cert.extensions.get_extension_for_oid(
            x509.oid.ExtensionOID.SUBJECT_KEY_IDENTIFIER)
        builder = builder.add_extension(x509.AuthorityKeyIdentifier(
            ski.value.digest, None, None),
                                        critical=False)

        builder = builder.add_extension(x509.KeyUsage(digital_signature=True,
                                                      content_commitment=True,
                                                      key_encipherment=True,
                                                      data_encipherment=True,
                                                      key_agreement=True,
                                                      key_cert_sign=False,
                                                      crl_sign=False,
                                                      encipher_only=False,
                                                      decipher_only=False),
                                        critical=False)

        certificate = builder.sign(private_key=signing_key,
                                   algorithm=hashes.SHA512(),
                                   backend=default_backend())
        with open('%s.cert.pem' % nom_fichier_csr, 'wb') as fichier:
            fichier.write(certificate.public_bytes(serialization.Encoding.PEM))
Example #8
0
def test_aki_public_bytes(benchmark):
    aki = x509.AuthorityKeyIdentifier(
        key_identifier=b"\x00" * 16,
        authority_cert_issuer=None,
        authority_cert_serial_number=None,
    )
    benchmark(aki.public_bytes)
Example #9
0
    def extension_type(self) -> x509.AuthorityKeyIdentifier:
        issuer: Optional[GeneralNameList] = self.authority_cert_issuer
        if not issuer:
            issuer = None

        return x509.AuthorityKeyIdentifier(
            key_identifier=self.key_identifier,
            authority_cert_issuer=issuer,
            authority_cert_serial_number=self.authority_cert_serial_number,
        )
Example #10
0
def make_saml_cert(key, country='', state='', locality='', org='', cn='',
                   email='', alt_names=None, days=365):
    if isinstance(key, basestring):
        key = private_key_from_cleaned_text(key)
    if alt_names and isinstance(alt_names, basestring):
        alt_names = alt_names.decode('utf-8').split()
    subject = x509.Name([
        # Provide various details about who we are.
        x509.NameAttribute(NameOID.COUNTRY_NAME, country.decode('utf-8')),
        x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, state.decode('utf-8')),
        x509.NameAttribute(NameOID.LOCALITY_NAME, locality.decode('utf-8')),
        x509.NameAttribute(NameOID.ORGANIZATION_NAME, org.decode('utf-8')),
        x509.NameAttribute(NameOID.COMMON_NAME, cn.decode('utf-8')),
        x509.NameAttribute(NameOID.EMAIL_ADDRESS, email.decode('utf-8')),
    ])
    pkey = key.public_key()
    skid = x509.SubjectKeyIdentifier.from_public_key(pkey)
    # Create self-signed
    serial_number = random_serial_number()
    crt = x509.CertificateBuilder().subject_name(
        subject
    ).issuer_name(
        subject
    ).public_key(
        pkey
    ).serial_number(
        serial_number
    ).not_valid_before(
        datetime.datetime.utcnow()
    ).not_valid_after(
        # Our certificate will be valid for 10 days
        datetime.datetime.utcnow() + datetime.timedelta(days=days)
    ).add_extension(
        x509.BasicConstraints(True, 0), False
    ).add_extension(
        skid, False
    ).add_extension(
        x509.AuthorityKeyIdentifier(
            skid.digest, [x509.DirectoryName(subject)], serial_number), False
    )
    if alt_names:
        # Describe what sites we want this certificate for.
        crt = crt.add_extension(
            x509.SubjectAlternativeName([
                x509.DNSName(n) for n in altnames]),
            critical=False)
    crt = crt.sign(key, hashes.SHA256(), default_backend())
    crt_text = crt.public_bytes(serialization.Encoding.PEM)
    return (cleanup_x509_text(crt_text), crt)
Example #11
0
def gen_self_signed(key: rsa.RSAPrivateKey, cert_opts: Dict,
                    crypto_opts: Dict) -> None:  # noqa
    # subject / issuer
    subject = issuer = _subject(cert_opts)

    # init builder
    builder = x509.CertificateBuilder()

    # set subject and issuer
    builder = builder.subject_name(subject)
    builder = builder.issuer_name(issuer)

    # set public key
    builder = builder.public_key(key.public_key())

    # set serial number
    serial = x509.random_serial_number()
    builder = builder.serial_number(serial)

    # set expiration
    now = datetime.datetime.utcnow()
    days = cert_opts['days']
    builder = builder.not_valid_before(now)
    builder = builder.not_valid_after(now + datetime.timedelta(days=days))

    # add base extensions
    for is_critical, ext in _extensions(key, cert_opts):
        builder = builder.add_extension(ext, critical=is_critical)

    # add AuthorityKeyIdentifier extension (experimental feature)
    pkey = key.public_key()
    key_identifier = x509.extensions._key_identifier_from_public_key(pkey)
    authority_cert_issuer = [x509.DirectoryName(issuer)]
    builder = builder.add_extension(x509.AuthorityKeyIdentifier(
        key_identifier, authority_cert_issuer, serial),
                                    critical=False)

    # sign the certificate
    md_alg = MD_ALGS[crypto_opts['md_alg']]
    crt = builder.sign(key, md_alg)

    # write to file
    crt_out = crypto_opts['crt_out']
    with open(str(crt_out), "wb") as fp:
        fp.write(crt.public_bytes(serialization.Encoding.PEM))
        fp.close()
Example #12
0
def selfsign_req(csr, issuer_pkey, serial=None, days=3650):
    if not serial:  # FIXME: 排重
        serial = random.getrandbits(64)
    cert = x509.CertificateBuilder()\
               .subject_name(csr.subject)\
               .issuer_name(csr.subject)\
               .public_key(csr.public_key())\
               .serial_number(serial)\
               .not_valid_before(datetime.utcnow())\
               .not_valid_after(datetime.utcnow()+timedelta(days=10))
    cert._extensions = csr.extensions._extensions
    subkeyid = x509.SubjectKeyIdentifier.from_public_key(csr.public_key())
    cert = cert.add_extension(subkeyid, critical=False)
    authkeyid = _key_identifier_from_public_key(issuer_pkey.public_key())
    authkeyid = x509.AuthorityKeyIdentifier(
        authkeyid, [x509.DirectoryName(csr.subject), ], serial)
    cert = cert.add_extension(authkeyid, critical=False)
    return cert.sign(issuer_pkey, hashes.SHA256(), default_backend())
Example #13
0
def create_ca_certificate(ca_name,
                          key_size=4096,
                          certificate_validity_days=365):
    key = rsa.generate_private_key(public_exponent=65537,
                                   key_size=key_size,
                                   backend=default_backend())
    key_id = x509.SubjectKeyIdentifier.from_public_key(key.public_key())

    subject = issuer = x509.Name(
        [x509.NameAttribute(NameOID.COMMON_NAME, u"%s" % ca_name)])

    now = datetime.datetime.utcnow()
    serial = x509.random_serial_number()
    cert = x509.CertificateBuilder() \
        .subject_name(subject) \
        .issuer_name(issuer) \
        .public_key(key.public_key()) \
        .serial_number(serial) \
        .not_valid_before(now) \
        .not_valid_after(now + datetime.timedelta(days=certificate_validity_days)) \
        .add_extension(key_id, critical=False) \
        .add_extension(x509.AuthorityKeyIdentifier(key_id.digest,
                                                   [x509.DirectoryName(issuer)],
                                                   serial),
                       critical=False) \
        .add_extension(x509.BasicConstraints(ca=True, path_length=3), critical=True) \
        .add_extension(x509.KeyUsage(digital_signature=True,
                                     content_commitment=False,
                                     key_encipherment=False,
                                     data_encipherment=False,
                                     key_agreement=False,
                                     key_cert_sign=True,
                                     crl_sign=True,
                                     encipher_only=False,
                                     decipher_only=False),
                       critical=True) \
        .sign(key, hashes.SHA256(), default_backend())

    cert = cert.public_bytes(serialization.Encoding.PEM)
    key = key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.TraditionalOpenSSL,
        encryption_algorithm=serialization.NoEncryption())
    return key, cert
Example #14
0
def sign_and_return_certificate(builder,
                                pubkey,
                                sign_key,
                                issuer,
                                subject,
                                caflag=True):
    builder = builder.serial_number(int(uuid.uuid4()))
    builder = builder.public_key(pubkey.public_key())
    builder = my_fix_add_extension_cryptography(builder,
                                                x509.BasicConstraints(
                                                    ca=caflag,
                                                    path_length=None),
                                                critical=True)
    builder = my_fix_add_extension_cryptography(
        builder,
        x509.SubjectKeyIdentifier(
            x509.SubjectKeyIdentifier.from_public_key(
                pubkey.public_key()).digest),
        critical=False)
    builder = my_fix_add_extension_cryptography(
        builder,
        x509.AuthorityKeyIdentifier(
            key_identifier=x509.SubjectKeyIdentifier.from_public_key(
                sign_key.public_key()).digest,
            authority_cert_issuer=None,
            authority_cert_serial_number=None),
        critical=False)

    certificate = None
    try:
        certificate = builder.sign(private_key=sign_key,
                                   algorithm=hashes.SHA256(),
                                   backend=default_backend())
    except ValueError:
        certificate = builder.sign(private_key=sign_key,
                                   algorithm=None,
                                   backend=default_backend())
    return certificate.public_bytes(encoding=serialization.Encoding.PEM)
Example #15
0
def _decode_subject_key_identifier(backend, asn1_string):
  asn1_string = backend._ffi.cast("AUTHORITY_KEYID *", akid)
  asn1_string = backend._ffi.c(akid, backend._lib.AUTHORITY_KEYID_free)
  key_identifier = None
  authority_cert_issuer = None

  if akid.keyid != backend._ffi.NULL:
    key_identifier = backend._ffi.buffer(
      akid.keyid.data, akid.keyid.length     
    )[:]

  if akid.issuer != backend._ffi.NULL:
    authority_cert_issuer = _decode_general_names(
      backend, akid.issuer        
    )

  authority_cert_serial_number = _asn1_integer_to_int_or_none(
    backend, skid.serial        
  )

  return x509.AuthorityKeyIdentifier(
    key_identifier, authority_cert_issuer, authority_cert_seiral_number        
  )
Example #16
0
 def test_authority_issuer_none_serial_not_none(self):
     with pytest.raises(ValueError):
         x509.AuthorityKeyIdentifier(b"identifier", None, 3)