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, )
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")
def test_add_unsupported_extension(self): builder = x509.CertificateSigningRequestBuilder() with pytest.raises(NotImplementedError): builder.add_extension( x509.AuthorityKeyIdentifier('keyid', None, None), critical=False, )
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, )
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 )
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))
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)
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, )
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)
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()
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())
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
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)
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 )
def test_authority_issuer_none_serial_not_none(self): with pytest.raises(ValueError): x509.AuthorityKeyIdentifier(b"identifier", None, 3)