from OpenSSL import crypto class CA: """Generate a Certificate Authority Defaults based off the doc "OpenSSL Certificate Authority" by Jamie Nguyen - https://jamielinux.com/docs/openssl-certificate-authority/ """ __next_serial = 1000 def __init__(self): # CA key key = crypto.PKey() key.generate_key(crypto.TYPE_RSA, 2048) # CA cert cert = crypto.X509() cert.set_serial_number(self.__next_serial) cert.set_version(2) cert.set_pubkey(key) cert.gmtime_adj_notBefore(0) cert.gmtime_adj_notAfter(10*365*24*60*60) cacert_subject = cert.get_subject() cacert_subject.O = 'kOVHernetes' cacert_subject.OU = 'kOVHernetes Certificate Authority' cacert_subject.CN = 'kOVHernetes Root CA' cert.set_issuer(cacert_subject) cert.add_extensions((crypto.X509Extension(b'subjectKeyIdentifier', False, b'hash', cert),)) cacert_ext = [] cacert_ext.append(crypto.X509Extension(b'authorityKeyIdentifier', True, b'keyid:always,issuer', issuer=cert)) cacert_ext.append(crypto.X509Extension(b'basicConstraints', True, b'CA:TRUE')) cacert_ext.append(crypto.X509Extension(b'keyUsage', True, b'digitalSignature, cRLSign, keyCertSign')) cert.add_extensions(cacert_ext) # sign CA cert with CA key cert.sign(key, 'sha256') type(self).__next_serial += 1 self.cert = cert self.key = key def create_key(self): """Issue a X.509 key""" key = crypto.PKey() key.generate_key(crypto.TYPE_RSA, 2048) return key def create_client_cert(self, key, o, cn): """Issue a X.509 client certificate""" cert = crypto.X509() cert.set_serial_number(self.__next_serial) cert.set_version(2) cert.set_pubkey(key) cert.gmtime_adj_notBefore(0) cert.gmtime_adj_notAfter(365*24*60*60) cert_subject = cert.get_subject() cert_subject.O = o cert_subject.OU = 'kOVHernetes' cert_subject.CN = cn cert.set_issuer(self.cert.get_issuer()) cert_ext = [] cert_ext.append(crypto.X509Extension(b'subjectKeyIdentifier', False, b'hash', cert)) cert_ext.append(crypto.X509Extension(b'authorityKeyIdentifier', False, b'keyid,issuer', issuer=self.cert)) cert_ext.append(crypto.X509Extension(b'basicConstraints', False, b'CA:FALSE')) cert_ext.append(crypto.X509Extension(b'keyUsage', True, b'nonRepudiation, digitalSignature, keyEncipherment')) cert_ext.append(crypto.X509Extension(b'extendedKeyUsage', True, b'clientAuth')) cert.add_extensions(cert_ext) # sign cert with CA key cert.sign(self.key, 'sha256') type(self).__next_serial += 1 return cert def create_server_cert(self, key, o, cn, san=[]): """Issue a X.509 server certificate""" cert = crypto.X509() cert.set_serial_number(self.__next_serial) cert.set_version(2) cert.set_pubkey(key) cert.gmtime_adj_notBefore(0) cert.gmtime_adj_notAfter(365*24*60*60) cert_subject = cert.get_subject() cert_subject.O = o cert_subject.OU = 'kOVHernetes' cert_subject.CN = cn cert.set_issuer(self.cert.get_issuer()) cert_ext = [] cert_ext.append(crypto.X509Extension(b'subjectKeyIdentifier', False, b'hash', cert)) cert_ext.append(crypto.X509Extension(b'authorityKeyIdentifier', False, b'keyid,issuer:always', issuer=self.cert)) cert_ext.append(crypto.X509Extension(b'basicConstraints', False, b'CA:FALSE')) cert_ext.append(crypto.X509Extension(b'keyUsage', True, b'digitalSignature, keyEncipherment')) cert_ext.append(crypto.X509Extension(b'extendedKeyUsage', True, b'serverAuth')) if san: cert_ext.append(crypto.X509Extension(b'subjectAltName', False, ','.join(san).encode())) cert.add_extensions(cert_ext) # sign cert with CA key cert.sign(self.key, 'sha256') type(self).__next_serial += 1 return cert def create_client_pair(self, o, cn): """Issue a X.509 client key/certificate pair""" # key key = crypto.PKey() key.generate_key(crypto.TYPE_RSA, 2048) # cert cert = crypto.X509() cert.set_serial_number(self.__next_serial) cert.set_version(2) cert.set_pubkey(key) cert.gmtime_adj_notBefore(0) cert.gmtime_adj_notAfter(365*24*60*60) cert_subject = cert.get_subject() cert_subject.O = o cert_subject.OU = 'kOVHernetes' cert_subject.CN = cn cert.set_issuer(self.cert.get_issuer()) cert_ext = [] cert_ext.append(crypto.X509Extension(b'subjectKeyIdentifier', False, b'hash', cert)) cert_ext.append(crypto.X509Extension(b'authorityKeyIdentifier', False, b'keyid,issuer', issuer=self.cert)) cert_ext.append(crypto.X509Extension(b'basicConstraints', False, b'CA:FALSE')) cert_ext.append(crypto.X509Extension(b'keyUsage', True, b'nonRepudiation, digitalSignature, keyEncipherment')) cert_ext.append(crypto.X509Extension(b'extendedKeyUsage', True, b'clientAuth')) cert.add_extensions(cert_ext) # sign cert with CA key cert.sign(self.key, 'sha256') type(self).__next_serial += 1 return key, cert def create_server_pair(self, o, cn, san=[]): """Issue a X.509 server key/certificate pair""" # key key = crypto.PKey() key.generate_key(crypto.TYPE_RSA, 2048) # cert cert = crypto.X509() cert.set_serial_number(self.__next_serial) cert.set_version(2) cert.set_pubkey(key) cert.gmtime_adj_notBefore(0) cert.gmtime_adj_notAfter(365*24*60*60) cert_subject = cert.get_subject() cert_subject.O = o cert_subject.OU = 'kOVHernetes' cert_subject.CN = cn cert.set_issuer(self.cert.get_issuer()) cert_ext = [] cert_ext.append(crypto.X509Extension(b'subjectKeyIdentifier', False, b'hash', cert)) cert_ext.append(crypto.X509Extension(b'authorityKeyIdentifier', False, b'keyid,issuer:always', issuer=self.cert)) cert_ext.append(crypto.X509Extension(b'basicConstraints', False, b'CA:FALSE')) cert_ext.append(crypto.X509Extension(b'keyUsage', True, b'digitalSignature, keyEncipherment')) cert_ext.append(crypto.X509Extension(b'extendedKeyUsage', True, b'serverAuth')) if san: cert_ext.append(crypto.X509Extension(b'subjectAltName', False, ','.join(san).encode())) cert.add_extensions(cert_ext) # sign cert with CA key cert.sign(self.key, 'sha256') type(self).__next_serial += 1 return key, cert