Esempio n. 1
0
    def gen_certificate(self, key, common_name, issuer=None, sign_key=None):
        """generate a certificate with cryptography"""

        now = datetime.datetime.utcnow()

        certificate = x509.CertificateBuilder().subject_name(
            x509.Name([
                x509.NameAttribute(NameOID.COMMON_NAME, common_name),
            ])
        ).issuer_name(
            x509.Name([
                x509.NameAttribute(
                    NameOID.COMMON_NAME,
                    issuer or common_name
                )
            ])
        ).not_valid_before(
            now
        ).not_valid_after(
            now + datetime.timedelta(seconds=86400)
        ).serial_number(
            x509.random_serial_number()
        ).public_key(
            key.public_key()
        ).add_extension(
            x509.BasicConstraints(ca=True, path_length=0), critical=True
        ).sign(
            private_key=sign_key or key,
            algorithm=hashes.SHA256(),
            backend=default_backend()
        )
        return certificate
Esempio n. 2
0
def sns_certificate(sns_privatekey, sns_publickey):
    one_day = datetime.timedelta(1, 0, 0)

    private_key = load_pem_private_key(
        sns_privatekey, password=None, backend=default_backend()
    )
    public_key = load_pem_public_key(sns_publickey, backend=default_backend())

    builder = x509.CertificateBuilder()
    builder = builder.subject_name(
        x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "sns.amazonaws.com")])
    )
    builder = builder.issuer_name(
        x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "sns.amazonaws.com")])
    )
    builder = builder.not_valid_before(datetime.datetime.today() - one_day)
    builder = builder.not_valid_after(datetime.datetime.today() + one_day)
    builder = builder.serial_number(x509.random_serial_number())
    builder = builder.public_key(public_key)
    builder = builder.add_extension(
        x509.SubjectAlternativeName([x509.DNSName("sns.amazonaws.com")]), critical=False
    )
    builder = builder.add_extension(
        x509.BasicConstraints(ca=False, path_length=None), critical=True
    )

    cert = builder.sign(
        private_key=private_key, algorithm=hashes.SHA256(), backend=default_backend()
    )

    return cert.public_bytes(Encoding.PEM)
Esempio n. 3
0
def generate_certificate(hostname):
    """
    Generate self-signed certificate for some DNS name.
    The certificate is valid for 100 days from moment of generation.

    :param hostname: DNS name (str|unicode)
    """
    key = rsa.generate_private_key(
        public_exponent=65537,
        key_size=2048,
        backend=default_backend()
    )
    if isinstance(hostname, bytes):
        hostname = hostname.decode()
    subject = issuer = x509.Name(
        [x509.NameAttribute(NameOID.COMMON_NAME, hostname)]
    )

    cert = x509.CertificateBuilder()
    cert = cert.subject_name(subject).issuer_name(issuer).public_key(
        key.public_key()
    ).serial_number(
        x509.random_serial_number()
    ).not_valid_before(
        datetime.utcnow()
    ).not_valid_after(
        datetime.utcnow() + timedelta(days=100)
    ).add_extension(
        x509.SubjectAlternativeName([x509.DNSName(hostname)]),
        critical=False
    ).sign(key, hashes.SHA256(), default_backend())
    return cert.public_bytes(serialization.Encoding.PEM).decode()
Esempio n. 4
0
    def from_key(cls, private_key, project_id):
        """ Creates a new certificate from a private key.

        Args:
            private_key: An RSAPrivateKey.
            project_id: A string specifying the project ID.
        Returns:
            A PublicCertificate.
        """
        # NameAttribute requires unicode objects in Python 2.
        if not isinstance(project_id, six.text_type):
            project_id = six.u(project_id)

        subject = x509.Name(
            [x509.NameAttribute(NameOID.COMMON_NAME, project_id)])
        issuer = x509.Name(
            [x509.NameAttribute(NameOID.COMMON_NAME, u'AppScale')])

        cert = x509.CertificateBuilder().\
            subject_name(subject).\
            issuer_name(issuer).\
            public_key(private_key.key.public_key()).\
            serial_number(x509.random_serial_number()).\
            not_valid_before(datetime.datetime.utcnow()).\
            not_valid_after(datetime.datetime.utcnow() + CERTIFICATE_TTL).\
            sign(private_key.key, hashes.SHA256(), default_backend())

        return cls(private_key.key_name, cert)
Esempio n. 5
0
    def create_ca(self, cn=ISSUER_CN):
        """Create root CA.

        :returns: bytes -- Root CA in PEM format.
        """
        self.ca_key = rsa.generate_private_key(
            public_exponent=65537,
            key_size=2048,
            backend=default_backend(),
        )

        self.ca_public_key = self.ca_key.public_key()

        subject = self.issuer = x509.Name([
            x509.NameAttribute(NameOID.COMMON_NAME, six.text_type(cn)),
        ])

        builder = x509.CertificateBuilder()
        builder = builder.subject_name(subject)
        builder = builder.issuer_name(self.issuer)
        builder = builder.public_key(self.ca_public_key)
        builder = builder.serial_number(x509.random_serial_number())
        builder = builder.not_valid_before(self.now)
        builder = builder.not_valid_after(self.now + self.delta)

        builder = builder.add_extension(
            x509.KeyUsage(
                digital_signature=False,
                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,
        )

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

        builder = builder.add_extension(
            x509.SubjectKeyIdentifier.from_public_key(self.ca_public_key),
            critical=False,
        )

        builder = builder.add_extension(
            x509.AuthorityKeyIdentifier.from_issuer_public_key(
                 self.ca_public_key
                 ),
            critical=False,
        )

        cert = builder.sign(self.ca_key, hashes.SHA256(), default_backend())

        return cert.public_bytes(serialization.Encoding.PEM)
Esempio n. 6
0
 def create_root_certificate(self, passphrase):
     """
     Create self signed Root CA Certificate
     :param passphrase: Private key pass phrase
     :return:
     """
     node = self._node
     key = self.private_key(passphrase)
     subject = issuer = x509.Name(subject_string(node))
     builder = x509.CertificateBuilder()
     builder = builder.subject_name(subject)
     builder = builder.issuer_name(issuer)
     builder = builder.public_key(key.public_key())
     builder = builder.serial_number(x509.random_serial_number())
     builder = builder.not_valid_before(datetime.datetime.utcnow())
     builder = builder.not_valid_after(datetime.datetime.utcnow() + datetime.timedelta(days=randint(7000, 15000)))
     builder = builder.add_extension(x509.SubjectAlternativeName(subject_alt_name_string(node)), critical=False, )
     builder = builder.add_extension(x509.SubjectKeyIdentifier.from_public_key(key.public_key()), critical=False)
     builder = builder.add_extension(x509.KeyUsage(digital_signature=node.key_usage['digital_signature'],
                                                   content_commitment=node.key_usage['content_commitment'],
                                                   key_encipherment=node.key_usage['key_encipherment'],
                                                   data_encipherment=node.key_usage['data_encipherment'],
                                                   key_agreement=node.key_usage['key_agreement'],
                                                   key_cert_sign=node.key_usage['key_cert_sign'],
                                                   crl_sign=node.key_usage['crl_sign'],
                                                   encipher_only=node.key_usage['encipher_only'],
                                                   decipher_only=node.key_usage['decipher_only']), critical=True)
     builder = builder.add_extension(x509.BasicConstraints(ca=True, path_length=None), critical=True, )
     if self._key_length == 256:
         self.certificate = builder.sign(key, hashes.SHA256(), default_backend())
     elif self._key_length == 384:
         self.certificate = builder.sign(key, hashes.SHA384(), default_backend())
     else:
         raise ValueError
Esempio n. 7
0
    def sign_csr(self, ipa_csr, path_length=1):
        """Sign certificate CSR.

        :param ipa_csr: CSR in PEM format.
        :type ipa_csr: bytes.
        :returns: bytes -- Signed CA in PEM format.
        """
        csr_tbs = x509.load_pem_x509_csr(ipa_csr, default_backend())

        csr_public_key = csr_tbs.public_key()
        csr_subject = csr_tbs.subject

        builder = x509.CertificateBuilder()
        builder = builder.public_key(csr_public_key)
        builder = builder.subject_name(csr_subject)
        builder = builder.serial_number(x509.random_serial_number())
        builder = builder.issuer_name(self.issuer)
        builder = builder.not_valid_before(self.now)
        builder = builder.not_valid_after(self.now + self.delta)

        builder = builder.add_extension(
            x509.KeyUsage(
                digital_signature=False,
                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,
        )

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

        builder = builder.add_extension(
            x509.AuthorityKeyIdentifier.from_issuer_public_key(
                 self.ca_public_key
                 ),
            critical=False,
        )

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

        cert = builder.sign(
            private_key=self.ca_key,
            algorithm=hashes.SHA256(),
            backend=default_backend(),
        )

        return cert.public_bytes(serialization.Encoding.PEM)
    def from_csr(cls, csr: "x509CertSignReq", key: PrivateKey,
                 issuer: "x509Cert" = None,
                 not_valid_before: datetime.datetime = None,
                 not_valid_after: datetime.datetime = None,
                 serial_number: int = None, is_ca: bool = False):

        issuer = issuer or csr                          # type: x509Base
        private_key = serialization.load_der_private_key(
            key.to_bytes(encoding=EncodingType.DER),
            None,
            default_backend()
        )

        builder = x509.CertificateBuilder().subject_name(
            csr._x509_obj.subject
        ).issuer_name(
            issuer._x509_obj.subject
        ).public_key(
            csr._x509_obj.public_key()
        ).not_valid_before(
            not_valid_before or datetime.datetime.today()
        ).not_valid_after(
            # TODO: Will probably want this to max out at the issuer's
            # TODO: not_valid_after value (if provided)
            not_valid_after or (
                datetime.datetime.today() + datetime.timedelta(days=365 * 2))
        ).serial_number(
            serial_number or x509.random_serial_number()
        )

        # Load Extensions
        for e in csr._x509_obj.extensions:
            builder = builder.add_extension(
                e.value,
                critical=e.critical
            )

        if is_ca:
            builder = builder.add_extension(
                x509.BasicConstraints(True, None),
                critical=True
            )

        # Sign and Return a New x509Cert Instance containing the new Cert.
        cert = builder.sign(private_key, hashes.SHA256(), default_backend())
        crt_bytes = cert.public_bytes(EncodingType.DER)
        return cls(data=crt_bytes)
Esempio n. 9
0
def access_keys():
    access_key_data = request.get_json()
    identity = access_key_data['identity']
    csr_data = base64.decodebytes(access_key_data['csr'].encode())
    signature = base64.decodebytes(access_key_data['signature'].encode())

    key_string = database_functions.get_key(DATABASE_FILE, identity)

    # ...and we need to restore the key to the full PEM format that the RSA functions are expecting.
    restored_key = KeyEx_helpers.fixkey(key_string)

    # Now we can import that restored key string into a full RSA key object, get the SAH256 hash for the
    # message (the device ID), and create a verifier object to check the signature...
    pbkey = serialization.load_pem_public_key(restored_key.encode(), backend=default_backend())

    # Validate that the signature is valid for the csr_data signed by this device...
    try:
        pbkey.verify(signature, csr_data,
                     padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH),
                     hashes.SHA256())

        # We're okay – so sign it...
        with open(CA_KEY, 'rb') as f:
            ca_key_data = f.read()
        ca_key = serialization.load_pem_private_key(ca_key_data, b'rabbit', default_backend())

        csr = x509.load_pem_x509_csr(csr_data, default_backend())

        with open(CA_CRT, 'rb') as f:
            ca_crt_data = f.read()
        ca_crt = x509.load_pem_x509_certificate(ca_crt_data, default_backend())

        if isinstance(csr.signature_hash_algorithm, hashes.SHA256):
            cert = x509.CertificateBuilder().subject_name(csr.subject).issuer_name(ca_crt.issuer).public_key\
                (csr.public_key()).serial_number(x509.random_serial_number()).not_valid_before\
                (datetime.datetime.utcnow()).not_valid_after(datetime.datetime.utcnow() + datetime.timedelta(days=365))\
                .sign(ca_key, hashes.SHA256(), default_backend())

            return_data = {'certificate': base64.encodebytes(cert.public_bytes(serialization.Encoding.PEM)).decode(),
                           'CA_certificate': base64.encodebytes(ca_crt_data).decode()}

            rv = KeyExReturn.OK(json.dumps(return_data))
            return rv()

    except (InvalidSignature, ValueError, TypeError) as e:
        rv = KeyExReturn.CSRVerificationError()
        return rv()
Esempio n. 10
0
def _create_dummy_cert():
    key = ec.generate_private_key(ec.SECP384R1(), default_backend())
    subject = issuer = x509.Name([
        x509.NameAttribute(x509.oid.NameOID.COUNTRY_NAME, u"US"),
        x509.NameAttribute(x509.oid.NameOID.STATE_OR_PROVINCE_NAME, u"CA"),
        x509.NameAttribute(x509.oid.NameOID.LOCALITY_NAME, u"San Francisco"),
        x509.NameAttribute(x509.oid.NameOID.ORGANIZATION_NAME, u"My Company"),
        x509.NameAttribute(x509.oid.NameOID.COMMON_NAME, u"mysite.com"),
    ])
    cert = x509.CertificateBuilder().subject_name(subject).issuer_name(
        issuer).public_key(key.public_key()).serial_number(
            x509.random_serial_number()).not_valid_before(
                datetime.datetime.utcnow()).not_valid_after(
                    datetime.datetime.utcnow() +
                    datetime.timedelta(days=10)).sign(key, hashes.SHA256(),
                                                      default_backend())
    return cert
Esempio n. 11
0
def make_cert(netid, pubkey, ca_key = ECE422_CA_KEY, serial=x509.random_serial_number()):
    builder = x509.CertificateBuilder()
    builder = builder.not_valid_before(datetime.datetime(2017, 3, 1))
    builder = builder.not_valid_after (datetime.datetime(2017, 3,27))
    builder = builder.subject_name(x509.Name([
        x509.NameAttribute(NameOID.COMMON_NAME, unicode(netid)),
        x509.NameAttribute(NameOID.PSEUDONYM, u'unused'),
        x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
        x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Illinois'),
    ]))
    builder = builder.issuer_name(x509.Name([
        x509.NameAttribute(NameOID.COMMON_NAME, u'ece422'),
]))
    builder = builder.serial_number(serial)
    builder = builder.public_key(pubkey)
    cert = builder.sign(private_key=ECE422_CA_KEY, algorithm=hashes.MD5(), backend=default_backend())
    return cert
Esempio n. 12
0
def sign_cert():
    """
    csr - PEM-format Certificate Signing Request
    Needs to have the field Organization Name filled
    """

    if not request.files.get(key="csr"):
        abort(400)

    try:
        csr = x509.load_pem_x509_csr(request.files["csr"].stream.read())
    except ValueError:
        logging.info("Invalid CSR")
        abort(415)

    # Check if has organization name
    org = csr.subject.get_attributes_for_oid(
        NameOID.ORGANIZATION_NAME)[0].value
    if org is None:
        abort(415)

    # Sign
    cert = x509.CertificateBuilder() \
               .subject_name(csr.subject) \
               .issuer_name(CA_CERT.subject) \
               .public_key(csr.public_key()) \
               .serial_number(x509.random_serial_number()) \
               .not_valid_before(datetime.datetime.utcnow()) \
               .not_valid_after(datetime.datetime.utcnow() + datetime.timedelta(days=SIGNED_VALIDITY)) \
               .sign(PRIV_KEY, hashes.SHA256())

    # Easier to sign (expensive operation) more certificates and then discard them than
    # to sign only one at a time due to possible colisions
    output = b""
    with CERT_LOCK:
        # Check if there isn't another issued certificate for same organization
        path = os.path.join(PATH_SIGNED, org + ".cert")
        if os.path.isfile(path):
            abort(409)

        # Save certificate
        output = cert.public_bytes(serialization.Encoding.PEM)
        with open(path, "wb") as f:
            f.write(output)

    return output.decode("ascii")
Esempio n. 13
0
def _gen_cryptography():
    import datetime
    from cryptography import x509
    from cryptography.hazmat.backends import default_backend
    from cryptography.hazmat.primitives import hashes
    from cryptography.hazmat.primitives.asymmetric import rsa
    from cryptography.hazmat.primitives import serialization
    from cryptography.x509.oid import NameOID

    one_day = datetime.timedelta(1, 0, 0)
    private_key = rsa.generate_private_key(public_exponent=65537,
                                           key_size=2048,
                                           backend=default_backend())
    public_key = private_key.public_key()

    builder = x509.CertificateBuilder()
    builder = builder.subject_name(
        x509.Name(
            [x509.NameAttribute(NameOID.COMMON_NAME, socket.gethostname())]))
    builder = builder.issuer_name(
        x509.Name(
            [x509.NameAttribute(NameOID.COMMON_NAME, socket.gethostname())]))
    builder = builder.not_valid_before(datetime.datetime.today() - one_day)
    builder = builder.not_valid_after(datetime.datetime.today() +
                                      (one_day * 365 * 5))
    builder = builder.serial_number(x509.random_serial_number())
    builder = builder.public_key(public_key)
    builder = builder.add_extension(x509.SubjectAlternativeName([
        x509.DNSName(socket.gethostname()),
        x509.DNSName('*.%s' % socket.gethostname()),
        x509.DNSName('localhost'),
        x509.DNSName('*.localhost'),
    ]),
                                    critical=False)
    builder = builder.add_extension(x509.BasicConstraints(ca=False,
                                                          path_length=None),
                                    critical=True)

    certificate = builder.sign(private_key=private_key,
                               algorithm=hashes.SHA256(),
                               backend=default_backend())

    return (certificate.public_bytes(serialization.Encoding.PEM),
            private_key.private_bytes(serialization.Encoding.PEM,
                                      serialization.PrivateFormat.PKCS8,
                                      serialization.NoEncryption()))
Esempio n. 14
0
def generate_certs(path, days=3652, key_size=2048, separate_key=False):
    # DO NOT USE THIS FOR ANYTHING PRODUCTION RELATED, EVER!
    # Generate private key
    # 2048 is the minimum that works as of 3.9
    key = rsa.generate_private_key(public_exponent=65537, key_size=key_size)
    key_file = "key.pem" if separate_key else "cert.pem"
    key_path = Path(path).joinpath(key_file)
    with open(key_path, "ab") as f:
        f.write(
            key.private_bytes(
                encoding=serialization.Encoding.PEM,
                encryption_algorithm=serialization.NoEncryption(),
                format=serialization.PrivateFormat.TraditionalOpenSSL))
    log.debug(f"Private key written to {key_path}")

    # Generate public certificate
    hostname = socket.gethostname()
    ip = socket.gethostbyname(hostname)
    subject = Name([NameAttribute(NameOID.COMMON_NAME, "smtpdfix_cert")])
    alt_names = [
        DNSName("localhost"),
        DNSName("localhost.localdomain"),
        DNSName(hostname),
        IPAddress(ip_address("127.0.0.1")),
        IPAddress(ip_address("0.0.0.1")),
        IPAddress(ip_address("::1")),
        IPAddress(ip_address(ip)),
    ]

    cert = (CertificateBuilder().issuer_name(subject).subject_name(
        subject).serial_number(random_serial_number()).not_valid_before(
            datetime.utcnow()).not_valid_after(datetime.utcnow() + timedelta(
                days=days)).add_extension(
                    SubjectAlternativeName(alt_names),
                    critical=False).public_key(key.public_key()).add_extension(
                        BasicConstraints(ca=False, path_length=None),
                        critical=True).add_extension(
                            ExtendedKeyUsage([ExtendedKeyUsageOID.CLIENT_AUTH
                                              ]),
                            critical=True).sign(private_key=key,
                                                algorithm=hashes.SHA256()))

    cert_path = Path(path).joinpath("cert.pem")
    with open(cert_path, "ab") as f:
        f.write(cert.public_bytes(serialization.Encoding.PEM))
    log.debug(f"Certificate written to {cert_path}")
Esempio n. 15
0
def create_self_signed_cert(key_path="./data/key.pem", cert_path="./data/cert.pem"):
    logging.info('Creating self-signed certificate')
    key = rsa.generate_private_key(
        public_exponent=65537,
        key_size=4096,
        backend=default_backend()
    )

    with open(key_path, "wb") as f:
        f.write(key.private_bytes(
                encoding=serialization.Encoding.PEM,
                format=serialization.PrivateFormat.PKCS8,
                encryption_algorithm=serialization.NoEncryption(),
                ))

    subject = issuer = x509.Name([
        x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
        x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"CA"),
        x509.NameAttribute(NameOID.LOCALITY_NAME, u"San Francisco"),
        x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"My Company"),
        x509.NameAttribute(NameOID.COMMON_NAME, u"mysite.com"),
    ])

    cert = x509.CertificateBuilder().subject_name(
        subject
    ).issuer_name(
        issuer
    ).public_key(
        key.public_key()
    ).serial_number(
        x509.random_serial_number()
    ).not_valid_before(
        datetime.datetime.utcnow()
    ).not_valid_after(
        # Our certificate will be valid for 9999 days
        datetime.datetime.utcnow() + datetime.timedelta(days=9999)
    ).add_extension(
        x509.SubjectAlternativeName([x509.DNSName(u"localhost")]),
        critical=False,
    # Sign our certificate with our private key
    ).sign(key, hashes.SHA256(), default_backend())

    with open(cert_path, "wb") as f:
        f.write(cert.public_bytes(serialization.Encoding.PEM))

    logging.info(f"Self-signed certificate written to {key_path} and {cert_path}")
Esempio n. 16
0
def generate_certificat_auto_sign():
    """ Cette fonction permet de générer un certificat auto-signé, il ne prend aucun paramètre,
	elle retoune un certificat.
		
	=====================================================

		Exemple :
			certificat = generate_certificat_auto_sign()	
	"""
    contry_name = input(
        "Entrer le nom de votre pays : [Ex. CM, pour Cameroun] : ")
    city_name = input(
        "Entrer le nom de l'État ou de la province : [Ex. Centre] : ")
    locality_name = input("Entrer le nom de votre ville : [Ex. Yaoundé] : ")
    organi_name = input("Entrer le nom de votre organisation : [Ex. ITS] : ")
    common_name = input("Entrer le nom de votre section : [Ex. SECURITÉ] : ")
    nom_domaine = input("Entrer le nom de domaine : [Ex. groupits.cm] : ")

    key, private, public = generate_keys_rsa()

    # Generation de CSR(Certificate Signing Request)
    # Divers détails sur qui nous sommes. Pour un certificat auto-signé, le sujet et l'émetteur sont toujours les mêmes
    subject = issuer = x509.Name([
        x509.NameAttribute(NameOID.COUNTRY_NAME, contry_name),
        x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, city_name),
        x509.NameAttribute(NameOID.LOCALITY_NAME, locality_name),
        x509.NameAttribute(NameOID.ORGANIZATION_NAME, organi_name),
        x509.NameAttribute(NameOID.COMMON_NAME, common_name),
    ])

    cert = x509.CertificateBuilder().subject_name(subject).issuer_name(
        issuer).public_key(key.public_key()).serial_number(
            x509.random_serial_number()).not_valid_before(
                datetime.datetime.utcnow()).not_valid_after(
                    # notre certificate sera valide pour 10 jours
                    datetime.datetime.utcnow() +
                    datetime.timedelta(days=30)).add_extension(
                        x509.SubjectAlternativeName(
                            [x509.DNSName(nom_domaine)]),
                        critical=False,
                        # Signer notre certificat avec notre clé privé
                    ).sign(key, hashes.SHA256(), default_backend())

    certif = cert.public_bytes(serialization.Encoding.PEM)

    return certif
Esempio n. 17
0
def make_tls_cert(hostname):
    # type: (str) -> Tuple[x509.Certificate, rsa.RSAPrivateKey]
    key = rsa.generate_private_key(public_exponent=65537,
                                   key_size=2048,
                                   backend=default_backend())
    subject = issuer = x509.Name([
        x509.NameAttribute(NameOID.COMMON_NAME, hostname),
    ])
    cert = (x509.CertificateBuilder().subject_name(subject).issuer_name(
        issuer).public_key(key.public_key()).serial_number(
            x509.random_serial_number()).not_valid_before(
                datetime.utcnow()).not_valid_after(
                    datetime.utcnow() + timedelta(days=10)).add_extension(
                        x509.SubjectAlternativeName([x509.DNSName(hostname)]),
                        critical=False,
                    ).sign(key, hashes.SHA256(), default_backend()))
    return cert, key
Esempio n. 18
0
def create_ca(
    organization: str,
    cn: str,
    key_size: int,
) -> Tuple[rsa.RSAPrivateKeyWithSerialization, x509.Certificate]:
    now = datetime.datetime.now()

    private_key = rsa.generate_private_key(
        public_exponent=65537,
        key_size=key_size,
    )  # type: ignore
    name = x509.Name([
        x509.NameAttribute(NameOID.COMMON_NAME, cn),
        x509.NameAttribute(NameOID.ORGANIZATION_NAME, organization)
    ])
    builder = x509.CertificateBuilder()
    builder = builder.serial_number(x509.random_serial_number())
    builder = builder.subject_name(name)
    builder = builder.not_valid_before(now - datetime.timedelta(days=2))
    builder = builder.not_valid_after(now + CA_EXPIRY)
    builder = builder.issuer_name(name)
    builder = builder.public_key(private_key.public_key())
    builder = builder.add_extension(x509.BasicConstraints(ca=True,
                                                          path_length=None),
                                    critical=True)
    builder = builder.add_extension(x509.ExtendedKeyUsage(
        [ExtendedKeyUsageOID.SERVER_AUTH]),
                                    critical=False)
    builder = builder.add_extension(x509.KeyUsage(
        digital_signature=False,
        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)
    builder = builder.add_extension(x509.SubjectKeyIdentifier.from_public_key(
        private_key.public_key()),
                                    critical=False)
    cert = builder.sign(private_key=private_key,
                        algorithm=hashes.SHA256())  # type: ignore
    return private_key, cert
Esempio n. 19
0
    def _create_certificate(self, keys, certificate_data_to_create):
        """
        Create certificate and sign it.

        Args:
            keys (bytes): RSA private and public key
            certificate_data_to_create (dict)

        Returns:
            Signed certificate object.
        """
        private_key, public_key = keys

        subject = issuer = self._create_subject(certificate_data_to_create)

        if 'validity_after' in certificate_data_to_create:
            not_valid_before = datetime.utcnow() + timedelta(
                days=certificate_data_to_create.get('validity_after'))
        else:
            not_valid_before = datetime.utcnow()

        if 'validity' in certificate_data_to_create:
            not_valid_after = not_valid_before + timedelta(
                days=certificate_data_to_create.get('validity'))
        else:
            not_valid_after = not_valid_before + timedelta(days=365)

        certificate_builder = X509CertificateBuilder(
            private_key=private_key_der_to_object(private_key),
            issuer_name=issuer,
            subject_name=subject,
            public_key=public_key_der_to_object(public_key),
            serial_number=x509.random_serial_number(),
            not_valid_before=not_valid_before,
            not_valid_after=not_valid_after,
        )

        certificate = certificate_builder.sign(
            private_key=certificate_builder.private_key,
            algorithm=hashes.SHA256(),
            backend=default_backend(),
        )

        certificate.private_key = certificate_builder.private_key

        return certificate
Esempio n. 20
0
  def setUp(self):
    super(ApiSslServerTestBase, self).setUp()

    key = rdf_crypto.RSAPrivateKey.GenerateKey()
    key_path = os.path.join(self.temp_dir, "key.pem")
    with open(key_path, "wb") as f:
      f.write(key.AsPEM())

    subject = issuer = x509.Name([
        x509.NameAttribute(oid.NameOID.COMMON_NAME, u"localhost"),
    ])

    cert = x509.CertificateBuilder().subject_name(subject).issuer_name(
        issuer).public_key(key.GetPublicKey().GetRawPublicKey()).serial_number(
            x509.random_serial_number()).not_valid_before(
                datetime.datetime.utcnow()).not_valid_after(
                    datetime.datetime.utcnow() +
                    datetime.timedelta(days=1)).add_extension(
                        x509.SubjectAlternativeName(
                            [x509.DNSName(u"localhost")]),
                        critical=False,
                    ).sign(key.GetRawPrivateKey(), hashes.SHA256(),
                           backends.default_backend())

    self.cert_path = os.path.join(self.temp_dir, "certificate.pem")
    with open(self.cert_path, "wb") as f:
      f.write(cert.public_bytes(serialization.Encoding.PEM))

    config_overrider = test_lib.ConfigOverrider({
        "AdminUI.enable_ssl": True,
        "AdminUI.ssl_key_file": key_path,
        "AdminUI.ssl_cert_file": self.cert_path,
    })
    config_overrider.Start()
    self.addCleanup(config_overrider.Stop)

    self.port = portpicker.pick_unused_port()
    thread = wsgiapp_testlib.ServerThread(self.port, name="ApiSslServerTest")
    thread.StartAndWaitUntilServing()
    self.addCleanup(thread.Stop)

    api_auth_manager.APIACLInit.InitApiAuthManager()
    self.token.username = "******"
    webauth.WEBAUTH_MANAGER.SetUserName(self.token.username)

    self.endpoint = "https://localhost:%s" % self.port
Esempio n. 21
0
 def create_cert(self, RSA_private_key):
     subject = issuer = x509.Name([
         x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
         x509.NameAttribute(NameOID.COMMON_NAME, u"Bo Hui"),
     ])
     cert = x509.CertificateBuilder().subject_name(subject).issuer_name(
         issuer).public_key(
             self.RSA_private_key.public_key()).serial_number(
                 x509.random_serial_number()).not_valid_before(
                     datetime.datetime.utcnow()).not_valid_after(
                         datetime.datetime.utcnow() +
                         datetime.timedelta(days=30)).sign(
                             private_key=RSA_private_key,
                             algorithm=hashes.SHA256(),
                             backend=default_backend()).public_bytes(
                                 Encoding.PEM)
     return cert
Esempio n. 22
0
def generate_x509(key_type, key_scope, key_format='der'):

    from cryptography import x509
    from cryptography.hazmat.backends import default_backend
    from cryptography.hazmat.primitives import hashes
    from cryptography.hazmat.primitives.asymmetric import rsa
    from cryptography.x509.oid import NameOID
    import datetime
    from cryptography.hazmat.primitives import serialization


    public_key, private_key = get_keys( key_type, key_scope, \
                                        key_format=key_format )

    subject = x509.Name([\
        x509.NameAttribute(NameOID.COUNTRY_NAME, u"CA"),\
        x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"QC"),\
        x509.NameAttribute(NameOID.LOCALITY_NAME, u"Montreal"),\
        x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"My Company"),\
        x509.NameAttribute(NameOID.COMMON_NAME, u"www.example.com"),\
      ])

    issuer = subject
    builder = x509.CertificateBuilder()
    builder = builder.subject_name(subject)
    builder = builder.issuer_name(issuer)
    #builder.public_key( public_key.public_key() )
    builder = builder.public_key(public_key)
    builder = builder.serial_number(x509.random_serial_number())
    builder = builder.not_valid_before(datetime.datetime.utcnow())
    builder = builder.not_valid_after(
        # Our certificate will be valid for 10 days
        datetime.datetime.utcnow() + datetime.timedelta(days=365 * 100))
    builder = builder.add_extension(x509.SubjectAlternativeName(
        [x509.DNSName(u"www.example.com")]),
                                    critical=False)
    # Sign our certificate with our private key
    cert = builder.sign(private_key, hashes.SHA256(), default_backend())
    # Write our certificate out to disk.
    cert_file = "cert-%s-%s.%s" % (key_type, key_scope, key_format)

    with open(cert_file, "wb") as f:
        if key_format == 'pem':
            f.write(cert.public_bytes(serialization.Encoding.PEM))
        if key_format == 'der':
            f.write(cert.public_bytes(serialization.Encoding.DER))
Esempio n. 23
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()
def _generate_certificate(path, keyfile=None, password=None):
    from cryptography.hazmat.backends import default_backend
    from cryptography.hazmat.primitives import serialization
    from cryptography.hazmat.primitives.asymmetric import rsa
    from cryptography import x509
    from cryptography.x509.oid import NameOID
    from cryptography.hazmat.primitives import hashes

    if keyfile:
        with open(path, "rb") as kf:
            key_bytes = kf.read()
            key = serialization.load_pem_private_key(key_bytes, password,
                                                     default_backend())
    else:
        key = rsa.generate_private_key(public_exponent=65537,
                                       key_size=2048,
                                       backend=default_backend())
        key_bytes = key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.PKCS8,
            encryption_algorithm=serialization.BestAvailableEncryption(
                password) if password else serialization.NoEncryption(),
        )

    # Various details about who we are. For a self-signed certificate the
    # Subject and issuer are always the same.
    subject = issuer = x509.Name([
        x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
        x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'WA'),
        x509.NameAttribute(NameOID.LOCALITY_NAME, u'Redmond'),
        x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"My Company"),
        x509.NameAttribute(NameOID.COMMON_NAME, u"mysite.com")
    ])

    cert = x509.CertificateBuilder().subject_name(subject) \
                                    .issuer_name(issuer) \
                                    .public_key(key.public_key()) \
                                    .serial_number(x509.random_serial_number()) \
                                    .not_valid_before(datetime.utcnow()) \
                                    .not_valid_after(datetime.utcnow() + timedelta(days=10)) \
                                    .sign(key, hashes.SHA256(), default_backend())

    # Write the cert out to disk
    with open(path, "wb") as f:
        f.write(key_bytes)
        f.write(cert.public_bytes(serialization.Encoding.PEM))
Esempio n. 25
0
def create_client(common_name, ca):
    key = rsa.generate_private_key(public_exponent=65537, key_size=2048)

    name = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, common_name)])
    issuer_name = x509.Name(
        ca.cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME))

    now = datetime.utcnow()

    cert = (x509.CertificateBuilder().subject_name(name).issuer_name(
        issuer_name).public_key(key.public_key()).serial_number(
            x509.random_serial_number()).add_extension(
                x509.BasicConstraints(ca=False, path_length=None),
                critical=True).not_valid_before(now).not_valid_after(
                    now + timedelta(days=60)).sign(ca.key, hashes.SHA256()))

    return Identity(key=key, cert=cert)
Esempio n. 26
0
    def generate_and_save(cls):
        dns = conf.settings['api_host']
        private_key = rsa.generate_private_key(public_exponent=65537,
                                               key_size=4096,
                                               backend=default_backend())
        subject = issuer = x509.Name([
            NameAttribute(NameOID.COUNTRY_NAME, "US"),
            NameAttribute(NameOID.ORGANIZATION_NAME, "LBRY"),
            NameAttribute(NameOID.COMMON_NAME, "LBRY API"),
        ])
        alternative_name = x509.SubjectAlternativeName([x509.DNSName(dns)])
        certificate = x509.CertificateBuilder(
            subject_name=subject,
            issuer_name=issuer,
            public_key=private_key.public_key(),
            serial_number=x509.random_serial_number(),
            not_valid_before=datetime.datetime.utcnow(),
            not_valid_after=datetime.datetime.utcnow() +
            datetime.timedelta(days=365),
            extensions=[
                x509.Extension(oid=alternative_name.oid,
                               critical=False,
                               value=alternative_name)
            ]).sign(private_key, hashes.SHA256(), default_backend())
        public_certificate = certificate.public_bytes(cls.encoding).decode()
        private_certificate = ssl.PrivateCertificate.load(
            public_certificate,
            ssl.KeyPair.load(
                private_key.private_bytes(
                    encoding=cls.encoding,
                    format=serialization.PrivateFormat.TraditionalOpenSSL,
                    encryption_algorithm=serialization.NoEncryption()).decode(
                    ), cls.filetype), cls.filetype)

        auth_token = APIKey.create(seed=None, name="api")

        with open(os.path.join(conf.settings.data_dir, 'auth_token'),
                  'wb') as f:
            f.write(auth_token.secret.encode())

        with open(os.path.join(conf.settings.data_dir, 'api_ssl_cert.pem'),
                  'wb') as f:
            f.write(public_certificate.encode())

        return cls(auth_token, public_certificate, private_certificate)
Esempio n. 27
0
    def rsa_ca(self, ca_key_name, ca_crt_name, sign_hash_change):
        with open(ca_key_name + '.key', 'rb') as key_file:
            key = serialization.load_pem_private_key(key_file.read(),
                                                     password=None,
                                                     backend=default_backend())

        if sign_hash_change == 1:
            algorithm = hashes.MD5()
        elif sign_hash_change == 2:
            algorithm = hashes.SHA1()
        elif sign_hash_change == 3:
            algorithm = hashes.SHA224()
        elif sign_hash_change == 4:
            algorithm = hashes.SHA256()
        elif sign_hash_change == 5:
            algorithm = hashes.SHA512()

        subject = issuer = x509.Name([
            x509.NameAttribute(x509.oid.NameOID.COUNTRY_NAME, u"CN"),
            x509.NameAttribute(x509.oid.NameOID.STATE_OR_PROVINCE_NAME,
                               u"ShaanXi"),
            x509.NameAttribute(x509.oid.NameOID.LOCALITY_NAME, u"XiAN"),
            x509.NameAttribute(x509.oid.NameOID.ORGANIZATION_NAME, u"LQtest"),
            x509.NameAttribute(x509.oid.NameOID.COMMON_NAME, u"ca"),
        ])
        cert = x509.CertificateBuilder().subject_name(subject).issuer_name(
            issuer).public_key(key.public_key()).serial_number(
                x509.random_serial_number()
            ).not_valid_before(datetime.datetime.utcnow()).not_valid_after(
                #设置证书有效期
                datetime.datetime.utcnow() +
                datetime.timedelta(days=3650)).add_extension(
                    extension=x509.SubjectKeyIdentifier.from_public_key(
                        key.public_key()),
                    critical=False).add_extension(
                        extension=x509.AuthorityKeyIdentifier.
                        from_issuer_public_key(key.public_key()),
                        critical=False).add_extension(
                            extension=x509.BasicConstraints(ca=True,
                                                            path_length=None),
                            critical=True).sign(key, algorithm,
                                                default_backend())

        with open(ca_crt_name + ".crt", "wb") as f:
            f.write(cert.public_bytes(serialization.Encoding.PEM))
Esempio n. 28
0
def _generate_certificate(path, keyfile=None, password=None):
    from cryptography.hazmat.backends import default_backend
    from cryptography.hazmat.primitives import serialization
    from cryptography.hazmat.primitives.asymmetric import rsa
    from cryptography import x509
    from cryptography.x509.oid import NameOID
    from cryptography.hazmat.primitives import hashes

    if keyfile:
        with open(path, "rb") as kf:
            key_bytes = kf.read()
            key = serialization.load_pem_private_key(key_bytes, password, default_backend())
    else:
        key = rsa.generate_private_key(
            public_exponent=65537,
            key_size=2048,
            backend=default_backend()
        )
        key_bytes = key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.PKCS8,
            encryption_algorithm=serialization.BestAvailableEncryption(password) if password else serialization.NoEncryption(),
        )

    # Various details about who we are. For a self-signed certificate the
    # Subject and issuer are always the same.
    subject = issuer = x509.Name([
        x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
        x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'WA'),
        x509.NameAttribute(NameOID.LOCALITY_NAME, u'Redmond'),
        x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"My Company"),
        x509.NameAttribute(NameOID.COMMON_NAME, u"mysite.com")])

    cert = x509.CertificateBuilder().subject_name(subject) \
                                    .issuer_name(issuer) \
                                    .public_key(key.public_key()) \
                                    .serial_number(x509.random_serial_number()) \
                                    .not_valid_before(datetime.utcnow()) \
                                    .not_valid_after(datetime.utcnow() + timedelta(days=10)) \
                                    .sign(key, hashes.SHA256(), default_backend())

    # Write the cert out to disk
    with open(path, "wb") as f:
        f.write(key_bytes)
        f.write(cert.public_bytes(serialization.Encoding.PEM))
Esempio n. 29
0
  def setUpClass(cls):
    super(ApiSslServerTestBase, cls).setUpClass()

    if ApiSslServerTestBase._api_set_up_done:
      return

    key = rdf_crypto.RSAPrivateKey.GenerateKey()
    key_path = temp.TempFilePath("key.pem")
    with open(key_path, "wb") as f:
      f.write(key.AsPEM())

    subject = issuer = x509.Name([
        x509.NameAttribute(oid.NameOID.COMMON_NAME, u"localhost"),
    ])

    cert = x509.CertificateBuilder().subject_name(subject).issuer_name(
        issuer).public_key(key.GetPublicKey().GetRawPublicKey()).serial_number(
            x509.random_serial_number()).not_valid_before(
                datetime.datetime.utcnow()).not_valid_after(
                    datetime.datetime.utcnow() +
                    datetime.timedelta(days=1)).add_extension(
                        x509.SubjectAlternativeName(
                            [x509.DNSName(u"localhost")]),
                        critical=False,
                    ).sign(key.GetRawPrivateKey(), hashes.SHA256(),
                           backends.default_backend())

    ApiSslServerTestBase.ssl_cert_path = temp.TempFilePath("certificate.pem")
    with open(ApiSslServerTestBase.ssl_cert_path, "wb") as f:
      f.write(cert.public_bytes(serialization.Encoding.PEM))

    ApiSslServerTestBase.ssl_port = portpicker.pick_unused_port()
    with test_lib.ConfigOverrider({
        "AdminUI.enable_ssl": True,
        "AdminUI.ssl_key_file": key_path,
        "AdminUI.ssl_cert_file": ApiSslServerTestBase.ssl_cert_path,
    }):
      ApiSslServerTestBase._ssl_trd = wsgiapp_testlib.ServerThread(
          ApiSslServerTestBase.ssl_port, name="ApiSslServerTest")
      ApiSslServerTestBase._ssl_trd.StartAndWaitUntilServing()

    ApiSslServerTestBase.ssl_endpoint = ("https://localhost:%s" %
                                         ApiSslServerTestBase.ssl_port)

    ApiSslServerTestBase._api_set_up_done = True
Esempio n. 30
0
    def __enter__(self):
        from cryptography import x509
        from cryptography.hazmat.backends import default_backend
        from cryptography.hazmat.primitives import hashes, serialization
        from cryptography.hazmat.primitives.asymmetric import rsa

        subject = issuer = x509.Name(
            [x509.NameAttribute(x509.oid.NameOID.COMMON_NAME, 'localhost')])

        with contextlib.ExitStack() as stack:
            key = rsa.generate_private_key(public_exponent=65537,
                                           key_size=2048,
                                           backend=default_backend())

            key_file = stack.enter_context(tempfile.NamedTemporaryFile())
            key_file.write(
                key.private_bytes(
                    encoding=serialization.Encoding.PEM,
                    format=serialization.PrivateFormat.TraditionalOpenSSL,
                    encryption_algorithm=serialization.NoEncryption(),
                ))
            key_file.flush()

            cert = (x509.CertificateBuilder().subject_name(
                subject).issuer_name(issuer).public_key(
                    key.public_key()).serial_number(
                        x509.random_serial_number()).not_valid_before(
                            datetime.datetime.utcnow()).not_valid_after(
                                datetime.datetime.utcnow() +
                                datetime.timedelta(days=1)).add_extension(
                                    x509.SubjectAlternativeName([
                                        x509.DNSName('localhost'),
                                        x509.DNSName('127.0.0.1'),
                                    ]),
                                    critical=False,
                                ).sign(key, hashes.SHA256(),
                                       default_backend()))

            cert_file = stack.enter_context(tempfile.NamedTemporaryFile())
            cert_file.write(cert.public_bytes(serialization.Encoding.PEM))
            cert_file.flush()

            self._key_file, self._cert_file = key_file, cert_file
            stack.pop_all()
        return self
Esempio n. 31
0
 def ca_create(self, key):
     subject = issuer = x509.Name([
         x509.NameAttribute(NameOID.COMMON_NAME, u"CA"),
     ])
     return x509.CertificateBuilder().subject_name(subject).issuer_name(
         issuer).public_key(key.public_key()).serial_number(
             x509.random_serial_number()).not_valid_before(
                 datetime.datetime.utcnow()).not_valid_after(
                     # Our certificate will be valid for 10 years
                     datetime.datetime.utcnow() +
                     datetime.timedelta(days=10 * 365)).add_extension(
                         extension=x509.BasicConstraints(ca=True,
                                                         path_length=None),
                         critical=True).sign(
                             # Sign our certificate with our private key
                             key,
                             hashes.SHA256(),
                             default_backend())
Esempio n. 32
0
def generate_certificate(*, alternative_names, common_name, hash_algorithm,
                         key):
    subject = issuer = x509.Name(
        [x509.NameAttribute(x509.NameOID.COMMON_NAME, common_name)])

    builder = (x509.CertificateBuilder().subject_name(subject).issuer_name(
        issuer).public_key(key.public_key()).serial_number(
            x509.random_serial_number()).not_valid_before(
                datetime.datetime.utcnow()).not_valid_after(
                    datetime.datetime.utcnow() + datetime.timedelta(days=10)))
    if alternative_names:
        builder = builder.add_extension(
            x509.SubjectAlternativeName(
                [x509.DNSName(name) for name in alternative_names]),
            critical=False,
        )
    cert = builder.sign(key, hash_algorithm, default_backend())
    return cert, key
Esempio n. 33
0
def create_cert(not_before, not_after):
    key = rsa.generate_private_key(65537, 2048, default_backend())

    subject = issuer = x509.Name([
        x509.NameAttribute(x509.oid.NameOID.COUNTRY_NAME, u"US"),
        x509.NameAttribute(x509.oid.NameOID.STATE_OR_PROVINCE_NAME, u"CA"),
        x509.NameAttribute(x509.oid.NameOID.LOCALITY_NAME, u"San Francisco"),
        x509.NameAttribute(x509.oid.NameOID.ORGANIZATION_NAME, u"My Company"),
        x509.NameAttribute(x509.oid.NameOID.COMMON_NAME, u"mysite.com"),
    ])

    cert = x509.CertificateBuilder().subject_name(subject, ).issuer_name(
        issuer, ).public_key(key.public_key(), ).serial_number(
            x509.random_serial_number(), ).not_valid_before(
                not_before, ).not_valid_after(not_after, ).sign(
                    key, hashes.SHA256(), default_backend())

    return cert
Esempio n. 34
0
def test_generate_crl(ca_cert, ca_key):

    revoked_certs =  [
        x509.RevokedCertificateBuilder() \
            .revocation_date(time=datetime.datetime.today()) \
            .serial_number(x509.random_serial_number()) \
            .build(default_backend()) for x in range(10)
    ]

    crl = generate_crl(ca_cert, ca_key, revoked_certs[0])

    crl2 = generate_crl(ca_cert, ca_key, *revoked_certs)

    assert crl[0].serial_number == revoked_certs[0].serial_number
    assert all([
        c.serial_number == r.serial_number
        for c, r in zip(crl2, revoked_certs)
    ])
Esempio n. 35
0
def generate_ec_certificate(curve):
    key = ec.generate_private_key(backend=default_backend(), curve=curve)

    subject = issuer = x509.Name(
        [x509.NameAttribute(x509.NameOID.COMMON_NAME, "example.com")]
    )

    cert = (
        x509.CertificateBuilder()
        .subject_name(subject)
        .issuer_name(issuer)
        .public_key(key.public_key())
        .serial_number(x509.random_serial_number())
        .not_valid_before(datetime.datetime.utcnow())
        .not_valid_after(datetime.datetime.utcnow() + datetime.timedelta(days=10))
        .sign(key, hashes.SHA256(), default_backend())
    )
    return cert, key
Esempio n. 36
0
def generate_ca(common_name):
    private_key = rsa.generate_private_key(public_exponent=65537,
                                           key_size=2048,
                                           backend=default_backend())
    name = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, common_name)] +
                     COMMON_SUBJECT_ATTRIB)
    certificate = (x509.CertificateBuilder().subject_name(name).issuer_name(
        name).not_valid_before(datetime.datetime.today() - datetime.timedelta(
            days=1)).not_valid_after(
                datetime.datetime.today() +
                datetime.timedelta(days=365)).serial_number(
                    x509.random_serial_number()).public_key(
                        private_key.public_key()).add_extension(
                            x509.BasicConstraints(ca=True, path_length=None),
                            critical=True).sign(private_key=private_key,
                                                algorithm=hashes.SHA256(),
                                                backend=default_backend()))
    return certificate, private_key
    def _create_x509_certificate(key_der, subject_name): #type(Union[EllipticCurvePrivateKey,RSAPrivateKey], str) -> Certificate
        signing_key = serialization.load_der_private_key(key_der, password=None, backend=default_backend())
        builder = CertificateBuilder()
        builder = builder.subject_name(x509.Name([
            x509.NameAttribute(NameOID.COMMON_NAME, subject_name),
        ]))
        builder = builder.issuer_name(x509.Name([
            x509.NameAttribute(NameOID.COMMON_NAME, subject_name),
        ]))

        one_day = datetime.timedelta(1, 0, 0)
        builder = builder.not_valid_before(datetime.datetime.today() - one_day)
        builder = builder.not_valid_after(datetime.datetime.today() + (one_day * 30))
        builder = builder.serial_number(x509.random_serial_number())        
        builder = builder.public_key(signing_key.public_key())
        builder = builder.add_extension(SubjectAlternativeName([x509.DNSName(subject_name)]), critical=False)
        builder = builder.add_extension(BasicConstraints(ca=False, path_length=None), critical=True)
        return builder.sign(private_key=signing_key, algorithm=hashes.SHA256(), backend=default_backend()).public_bytes(serialization.Encoding.DER)
 def _create_self_signed_certificate(self, private_key):
     issuer = x509.Name([
         x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
         x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"CA"),
         x509.NameAttribute(NameOID.LOCALITY_NAME, u"San Francisco"),
         x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"My Company"),
         x509.NameAttribute(NameOID.COMMON_NAME, u"Test Certificate"),
     ])
     cert_builder = x509.CertificateBuilder(
         issuer_name=issuer,
         subject_name=issuer,
         public_key=private_key.public_key(),
         serial_number=x509.random_serial_number(),
         not_valid_before=datetime.utcnow(),
         not_valid_after=datetime.utcnow() + timedelta(days=10))
     cert = cert_builder.sign(private_key, hashes.SHA256(),
                              default_backend())
     return cert
Esempio n. 39
0
def create_cert(cred):

    subject = x509.Name([
        x509.NameAttribute(NameOID.COUNTRY_NAME, u'%s' % cred.country),
        x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME,
                           u'%s' % cred.province),
        x509.NameAttribute(NameOID.LOCALITY_NAME, u'%s' % cred.locality),
        x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'%s' % cred.org_name),
        x509.NameAttribute(NameOID.COMMON_NAME, u'%s' % cred.cn),
    ])

    subject_private_key = serialization.load_pem_private_key(open(
        cred.pvt_key_path, 'rb').read(),
                                                             password=None)
    if len(cred.ca_pvt_key_path) == 0:  # Self signed
        signing_private_key = subject_private_key
        issuer = subject
    else:  # Signed by CA
        signing_private_key = serialization.load_pem_private_key(open(
            cred.ca_pvt_key_path, 'rb').read(),
                                                                 password=None)
        ca_cert = x509.load_pem_x509_certificate(
            open(cred.ca_cert_path, 'rb').read())
        issuer = ca_cert.issuer

    builder = x509.CertificateBuilder()
    builder = builder.subject_name(subject)
    builder = builder.issuer_name(issuer)
    builder = builder.not_valid_before(
        dt.datetime.now(dt.timezone.utc) - dt.timedelta(days=1))
    builder = builder.not_valid_after(
        dt.datetime.now(dt.timezone.utc) + dt.timedelta(days=cred.valid_days))
    builder = builder.serial_number(x509.random_serial_number())
    builder = builder.public_key(subject_private_key.public_key())
    builder = builder.add_extension(x509.BasicConstraints(ca=cred.is_ca,
                                                          path_length=None),
                                    critical=True)
    builder = builder.add_extension(x509.SubjectKeyIdentifier.from_public_key(
        subject_private_key.public_key()),
                                    critical=False)
    builder = builder.sign(signing_private_key, hashes.SHA256())
    fd = open(cred.cert_path, 'wb')
    fd.write(builder.public_bytes(serialization.Encoding.PEM))
    fd.close()
Esempio n. 40
0
    def generate_root_cert(self) -> Tuple[str, str]:
        self.root_key = rsa.generate_private_key(public_exponent=65537,
                                                 key_size=4096,
                                                 backend=default_backend())
        root_public_key = self.root_key.public_key()

        root_builder = x509.CertificateBuilder()

        root_builder = root_builder.subject_name(
            x509.Name([
                x509.NameAttribute(NameOID.COMMON_NAME, u'cephadm-root'),
            ]))

        root_builder = root_builder.issuer_name(
            x509.Name([
                x509.NameAttribute(NameOID.COMMON_NAME, u'cephadm-root'),
            ]))

        root_builder = root_builder.not_valid_before(datetime.now())
        root_builder = root_builder.not_valid_after(datetime.now() + timedelta(
            days=(365 * 10 + 3)))
        root_builder = root_builder.serial_number(x509.random_serial_number())
        root_builder = root_builder.public_key(root_public_key)
        root_builder = root_builder.add_extension(x509.SubjectAlternativeName([
            x509.IPAddress(ipaddress.IPv4Address(str(self.mgr.get_mgr_ip())))
        ]),
                                                  critical=False)
        root_builder = root_builder.add_extension(
            x509.BasicConstraints(ca=True, path_length=None),
            critical=True,
        )

        self.root_cert = root_builder.sign(private_key=self.root_key,
                                           algorithm=hashes.SHA256(),
                                           backend=default_backend())

        cert_str = crypto.dump_certificate(crypto.FILETYPE_PEM,
                                           self.root_cert).decode('utf-8')
        key_str = self.root_key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.TraditionalOpenSSL,
            encryption_algorithm=serialization.NoEncryption()).decode('utf-8')

        return (cert_str, key_str)
Esempio n. 41
0
    def cert_gen(self):
        subject = issuer = x509.Name([
            x509.NameAttribute(NameOID.COUNTRY_NAME, u"PT"),
            x509.NameAttribute(NameOID.JURISDICTION_LOCALITY_NAME, u"Aveiro"),
            x509.NameAttribute(NameOID.LOCALITY_NAME, u"Aveiro"),
            x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"SIO"),
            x509.NameAttribute(NameOID.COMMON_NAME, u"serverSIO"),
        ])
        if self.private_key is not None:
            cert = x509.CertificateBuilder().subject_name(subject).issuer_name(
                issuer).public_key(
                    self.private_key.public_key()).serial_number(
                        x509.random_serial_number()).not_valid_before(
                            datetime.datetime.utcnow()).not_valid_after(
                                datetime.datetime.utcnow() +
                                datetime.timedelta(days=10)).add_extension(
                                    x509.SubjectAlternativeName(
                                        [x509.DNSName(u"serversio.io")]),
                                    critical=False,
                                ).add_extension(
                                    x509.BasicConstraints(ca=True,
                                                          path_length=None),
                                    critical=True,
                                ).add_extension(x509.KeyUsage(
                                    digital_signature=True,
                                    key_encipherment=True,
                                    content_commitment=False,
                                    data_encipherment=False,
                                    key_agreement=False,
                                    encipher_only=False,
                                    decipher_only=False,
                                    key_cert_sign=True,
                                    crl_sign=False),
                                                critical=True).sign(
                                                    self.private_key,
                                                    hashes.SHA256(),
                                                    default_backend())

        if not os.path.exists("certs"):
            os.mkdir("certs")
        with open(
                "certs\\server.pem"
                if sys.platform == 'win32' else "certs/server.pem", "wb") as f:
            f.write(cert.public_bytes(serialization.Encoding.PEM))
Esempio n. 42
0
def _generate_certificate(
    ip_address: str, ) -> typing.Tuple[str, bytes, bytes]:
    """Generate a private key and a certificate signed with it
    The key is encrypted before being stored.
    Returns the certificate as a string, the key as bytes (encrypted), and
    the password used for encrypting the key
    """
    # Generate private key
    key = rsa.generate_private_key(public_exponent=65537,
                                   key_size=4096,
                                   backend=default_backend())

    # Generate the certificate and sign it with the private key
    cert_name = get_machine_name()
    subject = issuer = x509.Name([
        x509.NameAttribute(NameOID.COUNTRY_NAME, "NO"),
        x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "Bergen"),
        x509.NameAttribute(NameOID.LOCALITY_NAME, "Sandsli"),
        x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Equinor"),
        x509.NameAttribute(NameOID.COMMON_NAME, "{}".format(cert_name)),
    ])
    cert = (
        x509.CertificateBuilder().subject_name(subject).issuer_name(
            issuer).public_key(key.public_key()).serial_number(
                x509.random_serial_number()).not_valid_before(
                    datetime.utcnow()).not_valid_after(
                        datetime.utcnow() + timedelta(days=365))  # 1 year
        .add_extension(
            x509.SubjectAlternativeName([
                x509.DNSName("{}".format(cert_name)),
                x509.DNSName(ip_address),
                x509.IPAddress(ipaddress.ip_address(ip_address)),
            ]),
            critical=False,
        ).sign(key, hashes.SHA256(), default_backend()))

    cert_str = cert.public_bytes(serialization.Encoding.PEM).decode("utf-8")
    pw = bytes(os.urandom(28))
    key_bytes = key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.TraditionalOpenSSL,
        encryption_algorithm=serialization.BestAvailableEncryption(pw),
    )
    return cert_str, key_bytes, pw
Esempio n. 43
0
def generate_admin_crt(config, host):
    private_key = generate_key()
    public_key = private_key.public_key()
    one_day = datetime.timedelta(1, 0, 0)
    ca_cert = config.get("CA_CERT", None)
    ca_key = config.get("CA_KEY", None)
    cert_expiration = config.get("CERT_ADMIN_EXPIRE", 1825)
    if not ca_cert or not ca_key:
        raise Exception('CA_CERT or CA_KEY not defined')
    ca_key = serialization.load_pem_private_key(str(ca_key), password=None, backend=default_backend())
    ca_cert = x509.load_pem_x509_certificate(str(ca_cert), backend=default_backend())
    builder = x509.CertificateBuilder()
    builder = builder.subject_name(x509.Name([
        x509.NameAttribute(NameOID.COMMON_NAME, host),
    ]))
    builder = builder.issuer_name(ca_cert.subject)
    builder = builder.not_valid_before(datetime.datetime.today() - one_day)
    builder = builder.not_valid_after(datetime.datetime.today() + datetime.timedelta(days=cert_expiration))
    builder = builder.serial_number(x509.random_serial_number())
    builder = builder.public_key(public_key)
    builder = builder.add_extension(
        x509.SubjectAlternativeName(
            [x509.IPAddress(ipaddress.IPv4Address(host))]
        ),
        critical=False
    )
    builder = builder.add_extension(
        x509.BasicConstraints(ca=False, path_length=None), critical=True,
    )
    certificate = builder.sign(
        private_key=ca_key, algorithm=hashes.SHA256(),
        backend=default_backend()
    )
    private_key = private_key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.TraditionalOpenSSL,
            encryption_algorithm=serialization.NoEncryption(),
        )
    certificate = certificate.public_bytes(serialization.Encoding.PEM)
    return private_key, certificate
Esempio n. 44
0
    def generate_ca(cls):
        key = rsa.generate_private_key(
            public_exponent=65537,
            key_size=2048,
            backend=default_backend()
        )
        subject = issuer = x509.Name([
            x509.NameAttribute(NameOID.COUNTRY_NAME, u"BR"),
            x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"RJ"),
            x509.NameAttribute(NameOID.LOCALITY_NAME, u"Rio de Janeiro"),
            x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"Tsuru Inc"),
            x509.NameAttribute(NameOID.COMMON_NAME, u"tsuru.io"),
        ])
        cert = x509.CertificateBuilder().subject_name(
            subject
        ).issuer_name(
            issuer
        ).public_key(
            key.public_key()
        ).serial_number(
            x509.random_serial_number()
        ).not_valid_before(
            datetime.datetime.utcnow()
        ).not_valid_after(
            datetime.datetime.utcnow() + datetime.timedelta(days=10)
        ).add_extension(
            x509.SubjectAlternativeName([x509.DNSName(u"tsuru.io")]),
            critical=False,
        ).sign(key, hashes.SHA256(), default_backend())

        key = key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.TraditionalOpenSSL,
            encryption_algorithm=serialization.NoEncryption(),
        )
        cert = cert.public_bytes(serialization.Encoding.PEM)
        return key, cert
Esempio n. 45
0
def _certificates_for_authority_and_server(service_identity, key_size=1024):
    """
    Create a self-signed CA certificate and server certificate signed
    by the CA.

    :param service_identity: The identity (hostname) of the server.
    :type service_identity: :py:class:`unicode`

    :param key_size: (optional) The size of CA's and server's private
        RSA keys.  Defaults to 1024 bits, which is the minimum allowed
        by OpenSSL Contexts at the default security level as of 1.1.
    :type key_size: :py:class:`int`

    :return: a 3-tuple of ``(certificate_authority_certificate,
             server_private_key, server_certificate)``.
    :rtype: :py:class:`tuple` of (:py:class:`sslverify.Certificate`,
            :py:class:`OpenSSL.crypto.PKey`,
            :py:class:`OpenSSL.crypto.X509`)
    """
    common_name_for_ca = x509.Name(
        [x509.NameAttribute(NameOID.COMMON_NAME, u'Testing Example CA')]
    )
    common_name_for_server = x509.Name(
        [x509.NameAttribute(NameOID.COMMON_NAME, u'Testing Example Server')]
    )
    one_day = datetime.timedelta(1, 0, 0)
    private_key_for_ca = rsa.generate_private_key(
        public_exponent=65537,
        key_size=key_size,
        backend=default_backend()
    )
    public_key_for_ca = private_key_for_ca.public_key()
    ca_certificate = (
        x509.CertificateBuilder()
        .subject_name(common_name_for_ca)
        .issuer_name(common_name_for_ca)
        .not_valid_before(datetime.datetime.today() - one_day)
        .not_valid_after(datetime.datetime.today() + one_day)
        .serial_number(x509.random_serial_number())
        .public_key(public_key_for_ca)
        .add_extension(
            x509.BasicConstraints(ca=True, path_length=9), critical=True,
        )
        .sign(
            private_key=private_key_for_ca, algorithm=hashes.SHA256(),
            backend=default_backend()
        )
    )
    private_key_for_server = rsa.generate_private_key(
        public_exponent=65537,
        key_size=key_size,
        backend=default_backend()
    )
    public_key_for_server = private_key_for_server.public_key()
    server_certificate = (
        x509.CertificateBuilder()
        .subject_name(common_name_for_server)
        .issuer_name(common_name_for_ca)
        .not_valid_before(datetime.datetime.today() - one_day)
        .not_valid_after(datetime.datetime.today() + one_day)
        .serial_number(x509.random_serial_number())
        .public_key(public_key_for_server)
        .add_extension(
            x509.BasicConstraints(ca=False, path_length=None), critical=True,
        )
        .add_extension(
            x509.SubjectAlternativeName(
                [x509.DNSName(service_identity)]
            ),
            critical=True,
        )
        .sign(
            private_key=private_key_for_ca, algorithm=hashes.SHA256(),
            backend=default_backend()
        )
    )

    ca_self_cert = Certificate.loadPEM(
        ca_certificate.public_bytes(Encoding.PEM)
    )

    pkey = PKey.from_cryptography_key(private_key_for_server)
    x509_server_certificate = X509.from_cryptography(server_certificate)

    return ca_self_cert, pkey, x509_server_certificate
Esempio n. 46
0
    public_exponent=65537,
    key_size=2048,
    backend=default_backend()
)

subject = issuer = x509.Name([
    x509.NameAttribute(NameOID.COMMON_NAME, u"hendrix-tls-example"),
])
cert = x509.CertificateBuilder().subject_name(
    subject
).issuer_name(
    issuer
).public_key(
    rsa_key.public_key()
).serial_number(
    x509.random_serial_number()
).not_valid_before(
    datetime.datetime.utcnow()
).not_valid_after(
    datetime.datetime.utcnow() + datetime.timedelta(days=10)
).add_extension(
    x509.SubjectAlternativeName([x509.DNSName(u"localhost")]),
    critical=False,
).sign(rsa_key, hashes.SHA256(), default_backend())

with open("rsa-privkey.pem", "wb") as f:
    f.write(rsa_key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.TraditionalOpenSSL,
        encryption_algorithm=serialization.NoEncryption(),
    ))
Esempio n. 47
0
def make_saml_cert(key, country=None, state=None, locality=None, org=None,
                   domain=None, email=None, alt_names=None, days=365,
                   self_sign=True):
    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()
    name_components = []
    if country:
        name_components.append(x509.NameAttribute(
            NameOID.COUNTRY_NAME, country.decode('utf-8')))
    if state:
        name_components.append(x509.NameAttribute(
            NameOID.STATE_OR_PROVINCE_NAME, state.decode('utf-8')))
    if locality:
        name_components.append(x509.NameAttribute(
            NameOID.LOCALITY_NAME, locality.decode('utf-8')))
    if org:
        name_components.append(x509.NameAttribute(
            NameOID.ORGANIZATION_NAME, org.decode('utf-8')))
    if domain:
        name_components.append(x509.NameAttribute(
            NameOID.COMMON_NAME, domain.decode('utf-8')))
    if email:
        name_components.append(x509.NameAttribute(
            NameOID.EMAIL_ADDRESS, email.decode('utf-8')))
    subject = x509.Name(name_components)
    pkey = key.public_key()
    skid = x509.SubjectKeyIdentifier.from_public_key(pkey)
    if self_sign:
        # Create self-signed
        serial_number = random_serial_number()
        builder = x509.CertificateBuilder()
    else:
        builder = x509.CertificateSigningRequestBuilder()
    builder = builder.subject_name(
        subject
    ).add_extension(
        x509.KeyUsage(True, False, False, False, True, False, False, False, False), False
    )
    if alt_names:
        # Describe what sites we want this certificate for.
        builder = builder.add_extension(
            x509.SubjectAlternativeName([
                x509.DNSName(n) for n in alt_names]),
            critical=False)
    if self_sign:
        builder = builder.public_key(
            pkey
        ).issuer_name(
            subject
        ).serial_number(
            serial_number
        ).not_valid_before(
            datetime.datetime.utcnow()
        ).not_valid_after(
            datetime.datetime.utcnow() + datetime.timedelta(days=days)
        ).add_extension(
            skid, False
        ).add_extension(
            x509.AuthorityKeyIdentifier(
                skid.digest, [x509.DirectoryName(subject)], serial_number), False
        )
    else:
        builder = builder.add_extension(
            x509.BasicConstraints(True, 0), False)

    builder = builder.sign(key, hashes.SHA256(), default_backend())
    builder_text = builder.public_bytes(serialization.Encoding.PEM)
    return (builder_text, builder)
Esempio n. 48
0
def certclone(chain, copy_extensions=False):

    for i in range(len(chain)):
        chain[i] = chain[i].to_cryptography()

    newchain = []

    '''
    key = rsa.generate_private_key(
        public_exponent=65537,
        key_size=2048,
        backend=default_backend()
        )

    pubkey = key.public_key()
    '''

    first = True

    for original in chain[::-1]:

        #print(cert)

        key = rsa.generate_private_key(
            public_exponent=65537,
            key_size=2048,
            backend=default_backend()
            )

        key_pem = key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.TraditionalOpenSSL,
            encryption_algorithm=serialization.NoEncryption()
        ).decode()

        if first:
            print(key_pem)
            first=False

        pubkey = key.public_key()

        # Todo: Code to mimic the private key type of original cert
        # maybe based on pubkey.__class__
        cert = x509.CertificateBuilder()
        cert = cert.subject_name(original.subject)
        cert = cert.issuer_name(original.issuer)
        #cert = cert.serial_number(original.serial_number)
        cert = cert.serial_number(x509.random_serial_number())
        cert = cert.not_valid_before(original.not_valid_before)
        cert = cert.not_valid_after(original.not_valid_after)
        cert = cert.public_key(pubkey)

        if copy_extensions:
            for ext in original.extensions:
                cert = cert.add_extension(ext.value, critical=ext.critical)

        cert = cert.sign(private_key=key, algorithm=original.signature_hash_algorithm, backend=default_backend())
        cert_pem = cert.public_bytes(serialization.Encoding.PEM).decode()
        print(cert_pem)

        newchain.insert(0, cert)
Esempio n. 49
0
def generate_x509_certificate(signing_key, key, subject, issuer, serial,
                              valid_after, valid_before, ca, ca_path_len,
                              purposes, user_principals, host_principals,
                              hash_alg, comment):
    """Generate a new X.509 certificate"""

    builder = x509.CertificateBuilder()

    subject = X509Name(subject)
    issuer = X509Name(issuer) if issuer else subject
    self_signed = subject == issuer

    builder = builder.subject_name(subject)
    builder = builder.issuer_name(issuer)

    if serial is None:
        serial = x509.random_serial_number()

    builder = builder.serial_number(serial)

    builder = builder.not_valid_before(_to_generalized_time(valid_after))
    builder = builder.not_valid_after(_to_generalized_time(valid_before))

    builder = builder.public_key(key.pyca_key)

    if ca:
        basic_constraints = x509.BasicConstraints(ca=True,
                                                  path_length=ca_path_len)
        key_usage = x509.KeyUsage(digital_signature=False,
                                  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)
    else:
        basic_constraints = x509.BasicConstraints(ca=False, path_length=None)
        key_usage = 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)

    builder = builder.add_extension(basic_constraints, critical=True)

    if ca or not self_signed:
        builder = builder.add_extension(key_usage, critical=True)

    purpose_oids = _to_purpose_oids(purposes)

    if purpose_oids:
        builder = builder.add_extension(x509.ExtendedKeyUsage(purpose_oids),
                                        critical=False)

    sans = _encode_user_principals(user_principals) + \
           _encode_host_principals(host_principals)

    if sans:
        builder = builder.add_extension(x509.SubjectAlternativeName(sans),
                                        critical=False)

    if comment:
        if isinstance(comment, str):
            comment = comment.encode('utf-8')

        comment = der_encode(IA5String(comment))
        builder = builder.add_extension(
            x509.UnrecognizedExtension(_nscomment_oid, comment), critical=False)

    try:
        hash_alg = _hashes[hash_alg]()
    except KeyError:
        raise ValueError('Unknown hash algorithm') from None

    cert = builder.sign(signing_key.pyca_key, hash_alg, default_backend())
    data = cert.public_bytes(Encoding.DER)

    return X509Certificate(cert, data)