Python Own Certificate Authority (ownca)¶
OwnCA makes easy handle Certificate Authority (CA) and manage certificates for hosts, servers or clients.
An example of high level usage:
>>> from ownca import CertificateAuthority
>>> ca = CertificateAuthority(ca_storage='/opt/CA', common_name='MyCorp CA')
>>> example_com = ca.issue_certificate('www.example.com', dns_names=['www.example.com', 'w3.example.com')
Basically in this three lines steps:
Imported the ownca Certificate Authority library
Created a new CA named as Corp CA that uses
/opt/CA
as CA storage for certificates, keys etc.Create a signed certificates by Corp CA server www.mycorp.com, the files are also stored in
/opt/CA/certs//www.example.com
.>>> example_com.cert <Certificate(subject=<Name(CN=www.example.com)>, ...)>
Usage¶
Creating a Certificate Authority¶
The creation of a Certificate Authority (CA) is done by class
CertificateAuthority.
Code example:
>>> from ownca import CertificateAuthority
>>> ca_corp = CertificateAuthority(ca_storage='/opt/corp_CA', common_name='Corp CA')
It will create the CA files in in /opt/CA
.
Creating an Intermediate Certificate Authority¶
If a Certificate Authority (CA) needs to be Intermediate, it means the certificate needs to
be signed by another CA, you can create that using the option intermendiate=True
.
This action will generate only the Certificate Signing Request (CSR). Given the csr to
the Root CA to be signed and having the certificate file, it needs to be added to the
ca_storage
folder as ca.crt
and after that can be used.
Code example:
>>> from ownca import CertificateAuthority
>>> ica_corp = CertificateAuthority(ca_storage='/opt/corp_CA', common_name='Corp CA', intermediate=True)
>>> ica_corp.csr_bytes
b'-----BEGIN CERTIFICATE REQUEST-----\nMIICijCCAXICAQAwEjEQMA4GA1UEAwwHQ29ycCBDQTCCASIwDQYJKoZIhvcNAQEB\n
BQADggEPADCCAQoCggEBANErvwkteBXe0PybgWT7Su3Bduig/73Y75kEOzz+Ph4G\nz3a4GEG6Gowgb5TXBpPMp6JVqo7uiSqpOV9f8SJW21CWCGu518Sit5BRFJ4wFf3P\nzEtffb1i7fMr9H2JqjXVyQnVdrIAicWLJo3uF1P5RI5fm8tk5Cq1jRk/2CdfU3nP\n6UANjoE9FAVT1tA2F84TVuGlKBXvsF8OJcCU+HoQhy9suMiTJikaK5Qeti+JBvrZ\nfbijLk8L4u1cUYVVCAzFH+xtwg3TGeH02OmlybJKkm63cre4ixdSNm6AS+o456Mb\nIKn8ksja7orH9lYyocxaitUax0b3iHNPsRFF/M0Q8XsCAwEAAaAzMDEGCSqGSIb3\nDQEJDjEkMCIwEgYDVR0RBAswCYIHQ29ycCBDQTAMBgNVHRMEBTADAQH/MA0GCSqG\nSIb3DQEBCwUAA4IBAQAu9OYSeZMrJZFXrBLqdv60STmyRx+s2/7cq9khOMdayItu\n/kUAw0EIEoB3+uCRm4tvRrZeK2rgDKp4InyJ3cCPMcU02H84OOHen1V3H9WWUEBP\nuxkecQiFpGLzj/gisFjqGOuV/PzeuB/VhfiCJm7tG0PVK9n/JzZ1WBVL9u3GxDHY\n37328J7GniD4XDidevMY/3Gq+lZI9X/OHMSIMh2Q12FG/Ol8mBVdksp4gDbNs98D\nctzfHrmGBTF/f94JX/p94xerjp3NvcAIkzrm9Tfa05BDfpq8RsGgvPAZo4S8Hphz\nKHokUqabqsIC76VBMDFTb6GU3Vv80nBYTN+LrXmr\n-----END CERTIFICATE REQUEST-----\n'
Note
Note that this Intermediate CA is not ready to be used, certificate file is missing.
>>> ica_corp.issue_certificate('qa.dev.ownca.org')
Traceback (most recent call last):
...
ownca.exceptions.OwnCAIntermediate: Intermediate Certificate Authority has not a signed certificate file in CA Storage
Is necessary get the certificate signed from the CA to have this Intermediate CA ready.
Add the certificate to ca_storage
folder as ca.crt
.
Available methods¶
The Certificate Authority has built in methods such as
See CertificateAuthority for more details.
Code Example:
>>> ca_corp.cert
<Certificate(subject=<Name(CN=Corp CA)>, ...)>
>>> ca_corp.cert_bytes
b'-----BEGIN CERTIFICATE-----\nMIIC2TCCAcGgAwIBAgIUXn4msF6ONA8lWcehVqd1xxdRvYkwDQYJKoZIhvcNAQEL\nBQAwEjEQMA4GA1UEAwwHQ29ycCBDQTAeFw0yMDA0MjcxODA0MjBaFw0yMjA4MDEx\nODA0MjBaMBIxEDAOBgNVBAMMB0NvcnAgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB\nDwAwggEKAoIBAQC8JqeBHwVnmJkeOKLwqMcil/nY4QBLDsAg4LKhhzFAB/SvJ16F\norqip2jLuRhpxrPNUYa9p8+ZPZziAL7ir68csnJI+UlLU7XV3+TghiaHVsd4lVz7\nHBRhMLQcFQvnEyC5sfm84fptetlL4HN8jJUda/M26kxlHidJRCL221R9g+/RI113\n73tBX7iZSAcBTv/sOndEjVquYipOQXIZwRJ4ZXZ29K4UdoW+9iMCvhtVPCHz4FEl\nPBFn2vuqRg13EcZ6X3/83VJaO5TSh7Qzl87MVmfBtGBWvib5gXxPEY1zOnhojfxc\nEPkffyHauwyORFkpaE00LkrkNjxNEQ5qhCKHAgMBAAGjJzAlMBIGA1UdEQQLMAmC\nB0NvcnAgQ0EwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAZyMd\n5eu76geBT8yobTyovhPUq63+9BWvmUViNhukZSFX1zKI/8NG1QrAEwG1Rai2yTU/\n07s5XBRwGIcRuFC1tcT7oqAjHYDQw+3RgYYd+isPUo3Mi7SSWQYpJWmk7ICmqYzy\nlS5uk4iZatPWFVwL4XcH9ssgTVTK3kIdG9LKPPz/4KwlBQISxYi5u9pSwCum+gIS\nx2+Vc7jJGCUEP1iMLPuxpOHIns9FusfzPfRfApFQRqZfxBO2Hpewoj1pbb6HckAJ\nVlOyV5KcAunC9UsUtliwN3eFef+U/tNakYtcZjzqn1R5hlLBfaENCwdG4pdvuFw7\na/a5r9CF+SDw0tldZw==\n-----END CERTIFICATE-----\n'
Loading a existent Certificate Authority¶
In the same way if the /opt/CA
exists and the file is there, it will load
and it does not overwrite the files.
Code example:
>>> from ownca import CertificateAuthority
>>> ca_corp = CertificateAuthority(ca_storage='/opt/corp_CA', common_name='Corp CA')
>>> ca_corp.cert
<Certificate(subject=<Name(CN=Corp CA)>, ...)>
>>> ca_corp.key_bytes
b'-----BEGIN CERTIFICATE-----\nMIIC2TCCAcGgAwIBAgIUXn4msF6ONA8lWcehVqd1xxdRvYkwDQYJKoZIhvcNAQEL\nBQAwEjEQMA4GA1UEAwwHQ29ycCBDQTAeFw0yMDA0MjcxODA0MjBaFw0yMjA4MDEx\nODA0MjBaMBIxEDAOBgNVBAMMB0NvcnAgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB\nDwAwggEKAoIBAQC8JqeBHwVnmJkeOKLwqMcil/nY4QBLDsAg4LKhhzFAB/SvJ16F\norqip2jLuRhpxrPNUYa9p8+ZPZziAL7ir68csnJI+UlLU7XV3+TghiaHVsd4lVz7\nHBRhMLQcFQvnEyC5sfm84fptetlL4HN8jJUda/M26kxlHidJRCL221R9g+/RI113\n73tBX7iZSAcBTv/sOndEjVquYipOQXIZwRJ4ZXZ29K4UdoW+9iMCvhtVPCHz4FEl\nPBFn2vuqRg13EcZ6X3/83VJaO5TSh7Qzl87MVmfBtGBWvib5gXxPEY1zOnhojfxc\nEPkffyHauwyORFkpaE00LkrkNjxNEQ5qhCKHAgMBAAGjJzAlMBIGA1UdEQQLMAmC\nB0NvcnAgQ0EwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAZyMd\n5eu76geBT8yobTyovhPUq63+9BWvmUViNhukZSFX1zKI/8NG1QrAEwG1Rai2yTU/\n07s5XBRwGIcRuFC1tcT7oqAjHYDQw+3RgYYd+isPUo3Mi7SSWQYpJWmk7ICmqYzy\nlS5uk4iZatPWFVwL4XcH9ssgTVTK3kIdG9LKPPz/4KwlBQISxYi5u9pSwCum+gIS\nx2+Vc7jJGCUEP1iMLPuxpOHIns9FusfzPfRfApFQRqZfxBO2Hpewoj1pbb6HckAJ\nVlOyV5KcAunC9UsUtliwN3eFef+U/tNakYtcZjzqn1R5hlLBfaENCwdG4pdvuFw7\na/a5r9CF+SDw0tldZw==\n-----END CERTIFICATE-----\n'
>>>
>>> load_ca = CertificateAuthority(ca_storage='/opt/corp_CA', common_name='Corp CA')
>>> load_ca.cert
<Certificate(subject=<Name(CN=Corp CA)>, ...)>
>>> load_ca.key_bytes
b'-----BEGIN CERTIFICATE-----\nMIIC2TCCAcGgAwIBAgIUXn4msF6ONA8lWcehVqd1xxdRvYkwDQYJKoZIhvcNAQEL\nBQAwEjEQMA4GA1UEAwwHQ29ycCBDQTAeFw0yMDA0MjcxODA0MjBaFw0yMjA4MDEx\nODA0MjBaMBIxEDAOBgNVBAMMB0NvcnAgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB\nDwAwggEKAoIBAQC8JqeBHwVnmJkeOKLwqMcil/nY4QBLDsAg4LKhhzFAB/SvJ16F\norqip2jLuRhpxrPNUYa9p8+ZPZziAL7ir68csnJI+UlLU7XV3+TghiaHVsd4lVz7\nHBRhMLQcFQvnEyC5sfm84fptetlL4HN8jJUda/M26kxlHidJRCL221R9g+/RI113\n73tBX7iZSAcBTv/sOndEjVquYipOQXIZwRJ4ZXZ29K4UdoW+9iMCvhtVPCHz4FEl\nPBFn2vuqRg13EcZ6X3/83VJaO5TSh7Qzl87MVmfBtGBWvib5gXxPEY1zOnhojfxc\nEPkffyHauwyORFkpaE00LkrkNjxNEQ5qhCKHAgMBAAGjJzAlMBIGA1UdEQQLMAmC\nB0NvcnAgQ0EwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAZyMd\n5eu76geBT8yobTyovhPUq63+9BWvmUViNhukZSFX1zKI/8NG1QrAEwG1Rai2yTU/\n07s5XBRwGIcRuFC1tcT7oqAjHYDQw+3RgYYd+isPUo3Mi7SSWQYpJWmk7ICmqYzy\nlS5uk4iZatPWFVwL4XcH9ssgTVTK3kIdG9LKPPz/4KwlBQISxYi5u9pSwCum+gIS\nx2+Vc7jJGCUEP1iMLPuxpOHIns9FusfzPfRfApFQRqZfxBO2Hpewoj1pbb6HckAJ\nVlOyV5KcAunC9UsUtliwN3eFef+U/tNakYtcZjzqn1R5hlLBfaENCwdG4pdvuFw7\na/a5r9CF+SDw0tldZw==\n-----END CERTIFICATE-----\n'
Multiple Certificate Authorities¶
Just use different ca_storage
and you can have/manage multiple CAs
Code example:
>>> from ownca import CertificateAuthority
>>> ca_corp = CertificateAuthority(ca_storage='/opt/corp_CA', common_name='Corp CA')
>>> ca_edu = CertificateAuthority(ca_storage='/opt/edu_CA', common_name='Edu CA')
>>> ca_edu.cert
<Certificate(subject=<Name(CN=Edu CA)>, ...)>
>>> ca_corp.cert
<Certificate(subject=<Name(CN=Corp CA)>, ...)>
Issuing certificate¶
To issue a new certificate, you need use an existent instance of
class
CertificateAuthority and
use the function
issue_certificate().
Code example:
>>> from ownca import CertificateAuthority
>>> ca_corp = CertificateAuthority(ca_storage='/opt/corp_CA', common_name='Corp CA')
>>> example_com = ca_corp.issue_certificate("www.example.com", dns_names=["www.example.com", "w3.example.com"], oids={"country_name": "BR", "locality_name": "Uba"})
Available methods¶
The Certificate Authority has built in methods such as
See HostCertificate for more details.
Checking the certificate
>>> example_com.cert
<Certificate(subject=<Name(C=BR,L=Uba,CN=www.example.com)>, ...)>
Loading host/client certificate¶
Same as the CA, if you use an existent certificate, it will be loaded and not overwrited.
Example:
>>> load_cert = ca_corp.load_certificate("www.example.com")
>>> load_cert.cert == example_com.cert
True
The motivation¶
The ownca was created in 2017 as a group of scripts to manage certificates, in 2018 it was moved to a very simple library (mostly hardcoded actions) and now 2019 was decide to open and be a library that could help others.
Basically, OwnCA uses the powerful library http://cryptography.io .