Package: picoca
PicoCA is a simple CA intended for use in situations where the CA operator
also operates each host where a certificate will be used. It automatically
generates both a key and a certificate when asked to produce a certificate.
It does not offer OCSP or CRL services. PicoCA is appropriate, for instance,
for generating certificates for RPC systems or microservices.On first run, PicoCA will generate a keypair and a root certificate in thecertificatessubdirectory, and will reuse that same keypair and root
certificate unless they are deleted.On each further run, PicoCA will generate a keypair and sign an end-entity (leaf)
certificate for that keypair. The certificate will contain a list of DNS names
and/or IP addresses from the command line flags. The key and certificate are
placed in the same directory as the root key and certificate, with a file name
chosen based upon the first domain name or IP address specified on the command
line. It will overwrite existing keys and certificates, e.g. for renewals.The certificate will have a validity of 366 days, although this can be changed
by using the--lifespanflag. You can also change the directory where the
root and end-entity certificates are stored by using the--cert-pathflag.The code is designed to be simple and easy-to-read, for educational purposes.
If you stumble across a decision that doesn't make sense, please open anissueso that it may be addressed.PicoCA should work with Python 2.7, despite the incredible soul-rendering pain
this has caused me.Installation$pythonsetup.pyinstall

$picoca--help
usage:picoca[-h][--cert-pathpath][--lifespandays]hostname[hostname...]positionalarguments:hostnamedomainsandIPaddressestoaddtocertificate

optionalarguments:-h,--helpshowthishelpmessageandexit--cert-pathpathDirectorytostorekeysandcertificates(default:"./certificates")--lifespandaysNumberofdaysforcertificatetobevalid(default:366)Usage# Initialize the certificate authority and sign a certificate for "foo.com":$picocafoo.com
SuccessfullyinitializedPicoCAto:certificates/__root__.keyandcertificates/__root__.pem
Successfullywrotefilesto:certificates/foo.com.pemandcertificates/foo.com.key# Generate another certificate using the same certificate authority generated above$picocabar.orgbaz.net127.0.0.12001:0db8:85a3:0000:0000:8a2e:0370:7334qux.io
Successfullywrotefilesto:certificates/bar.org.pemandcertificates/bar.org.key# Store the certs in /etc/picoca instead, for use by multiple applications$picoca--cert-path/etc/picocabar.orgbaz.net127.0.0.1qux.io
SuccessfullyinitializedPicoCAto:/etc/picoca/__root__.pemand/etc/picoca/__root__.key
Successfullywrotefilesto:/etc/picoca/bar.org.pemand/etc/picoca/bar.org.keyVerification# Verify that a proper certificate was generated$opensslverify-x509_strict-purposesslclient-purposesslserver-CAfilecertificates/__root__.pemcertificates/bar.org.pem
certificates/bar.org.pem:OK# Look at the final generated certificate$opensslx509-incertificates/bar.org.pem-noout-text
Certificate:Data:Version:3(0x2)SerialNumber:4d:c5:c9:d7:ca:7e:48:40:85:36:d3:1d:79:69:70:2eSignatureAlgorithm:ecdsa-with-SHA256Issuer:CN=PicoCARootCertificateAuthority,OU=PicoCA,O=PicoCAValidityNotBefore:Jul3011:36:312020GMTNotAfter:Aug111:36:312021GMTSubject:CN=bar.orgSubjectPublicKeyInfo:PublicKeyAlgorithm:id-ecPublicKeyPublic-Key:(256bit)pub:04:cd:36:8b:e2:10:50:4d:a5:90:d1:e5:9f:43:56:c2:55:b0:df:55:a5:e1:61:a8:9a:fd:4a:be:f5:9c:75:dc:b6:8b:98:d0:ed:70:41:ed:1b:9b:8d:cf:85:6c:e0:fd:78:a9:06:a0:d8:70:00:0b:18:7b:2e:2c:f4:aa:5d:2d:8bASN1OID:prime256v1NISTCURVE:P-256X509v3extensions:X509v3SubjectKeyIdentifier:2D:B2:48:97:2E:D7:81:5B:D9:A1:91:C5:79:58:A3:03:2C:68:CF:E2X509v3BasicConstraints:criticalCA:FALSEX509v3SubjectAlternativeName:DNS:bar.org,DNS:baz.net,DNS:qux.io,IPAddress:127.0.0.1,IPAddress:2001:DB8:85A3:0:0:8A2E:370:7334X509v3KeyUsage:criticalDigitalSignature,KeyEnciphermentX509v3ExtendedKeyUsage:TLSWebServerAuthentication,TLSWebClientAuthenticationX509v3AuthorityKeyIdentifier:keyid:48:02:99:16:C6:6E:5B:BA:89:AD:AB:24:14:51:F9:7E:1C:88:8D:5ASignatureAlgorithm:ecdsa-with-SHA25630:64:02:30:30:5a:7b:b8:5c:d5:19:62:90:a6:16:86:c4:5a:4a:fd:9c:7a:1f:97:56:ea:21:17:50:6c:47:ab:fa:9d:71:38:ae:b0:fe:f1:8a:ca:75:40:37:02:86:49:0d:f3:c9:d5:02:30:58:e7:97:e6:c3:95:15:c6:11:94:a2:a2:e2:78:f7:e7:b8:d0:74:b5:64:47:1b:91:33:a4:99:c6:bc:fe:1b:b3:47:03:af:b4:95:6e:aa:05:44:b3:d5:84:92:f4:45:46# And the generated certificate authority, verifying the aKI field matches$opensslx509-incertificates/__root__.pem-noout-text
Certificate:Data:Version:3(0x2)SerialNumber:f4:c4:4d:84:5f:b8:42:03:b6:cf:56:ad:ac:09:14:ddSignatureAlgorithm:ecdsa-with-SHA384Issuer:CN=PicoCARootCertificateAuthority,OU=PicoCA,O=PicoCAValidityNotBefore:Jul3011:36:312020GMTNotAfter:Jul3011:36:312040GMTSubject:CN=PicoCARootCertificateAuthority,OU=PicoCA,O=PicoCASubjectPublicKeyInfo:PublicKeyAlgorithm:id-ecPublicKeyPublic-Key:(384bit)pub:04:39:e6:3d:66:cd:15:ad:c7:65:38:02:20:71:f8:8f:11:fa:f2:d6:25:80:05:f4:37:a2:35:84:72:fc:27:45:f5:f2:3d:5f:8f:23:cc:e3:b0:7c:e9:3a:3f:f9:a1:b4:b2:22:ba:0f:54:30:b7:52:15:a0:dc:48:3c:ff:1c:ab:de:2e:4f:98:3e:a9:1e:f7:9c:d8:fc:2b:cb:00:1f:53:40:bb:5a:9f:3c:05:1f:03:1c:47:ee:68:df:c1:a4:87:11ASN1OID:secp384r1NISTCURVE:P-384X509v3extensions:X509v3SubjectKeyIdentifier:48:02:99:16:C6:6E:5B:BA:89:AD:AB:24:14:51:F9:7E:1C:88:8D:5AX509v3BasicConstraints:criticalCA:TRUE,pathlen:0X509v3KeyUsage:criticalDigitalSignature,CertificateSignSignatureAlgorithm:ecdsa-with-SHA38430:64:02:30:5b:fc:75:2b:03:82:30:0b:3e:f8:ec:e5:ee:07:e8:c1:81:9b:a6:ff:50:49:fb:44:d5:a7:57:0b:55:22:0c:8d:81:cb:fe:22:af:03:cc:eb:a6:0c:ec:67:1d:58:9f:8e:02:30:46:fc:e8:1b:1c:dd:00:54:24:03:f5:c4:93:9c:26:8e:a7:ea:74:ee:7b:17:29:a5:4c:37:91:89:57:1c:10:5a:5f:c1:19:55:bd:43:23:f7:9f:33:35:51:82:fb:7c:ad# Verify that TLS works$openssls_server-quiet-www-port443-certcertificates/bar.org.pem-keycertificates/bar.org.key# And launching curl in a separate terminal$curl--cacertcertificates/__root__.pem--output/dev/null"https://127.0.0.1/"%Total%Received%XferdAverageSpeedTimeTimeTimeCurrentDloadUploadTotalSpentLeftSpeed100507005070001650k0--:--:----:--:----:--:--1650kAuthorsThus far,April King(april@pokeinthe.io) is the only author.CreditsPicoCA was directly inspired byJacob Hoffman-Andrew'sminica, and builds on top of the towering amount
of work done inpyca/cryptographybyAlex Gaynor,Paul Kehrerand
a ton of other heroicvolunteers.