feat: Bring Go and Python implementations to feature parity
Go: - Read and write simple-ca.json shared with the Python implementation - Add make-crl and revoke-cert commands and record certificate history - Rename --aia-base-url to --ca-publish-base-url - Add CRL Distribution Point extension to issuing CA and leaf certificates - Take days and issuing_ca defaults from simple-ca.json - Include email SANs in server certificates - Reject IPv4 SANs with out-of-range octets - Record existing issuing CAs and rebuild the CA bundle - Print errors once Python: - Add make-cert --type server|user and email SANs - Reject IPv4 SANs with out-of-range octets - Skip make-ca when the root CA exists and no issuing CA is given - Build ca_bundle.pem from issuing CA subdirectories - Accept a bare filename in make-pfx and drop the root key requirement - Honour explicit --days values and reject values below 1 - Persist and increment CRL numbers in simple-ca.json Update README and add tests for the new behaviour.
This commit is contained in:
1 parent
27461a0fbe
commit
9c84e82672
5 files changed
+757
-170
No files matched your search
@@ -9,15 +9,16 @@ Tools for creating and managing a simple Certificate Authority for testing and d
|
||||
| | `simple-ca.sh` | `simple-ca.py` | Go binary |
|
||||
|---|---|---|---|
|
||||
| Usage | sourced function library | CLI | compiled CLI |
|
||||
| Config file | none | `simple-ca.json` | none |
|
||||
| AIA base URL | `aia_base_url.txt` | `simple-ca.json` | `aia_base_url.txt` |
|
||||
| Certificate history | no | yes | no |
|
||||
| CRL generation | no | yes | no |
|
||||
| Revocation | no | yes | no |
|
||||
| Config file | none | `simple-ca.json` | `simple-ca.json` |
|
||||
| Publish base URL | `aia_base_url.txt` (AIA) | `simple-ca.json` (AIA + CDP) | `simple-ca.json` (AIA + CDP) |
|
||||
| Server and user certificates | yes | yes | yes |
|
||||
| Certificate history | no | yes | yes |
|
||||
| CRL generation | no | yes | yes |
|
||||
| Revocation | no | yes | yes |
|
||||
| PFX (`--apple-openssl`) | yes | yes | yes |
|
||||
| Requires | bash/zsh + openssl | Python 3.8+ + openssl | none (native crypto) |
|
||||
|
||||
All variants share the same directory layout and produce interchangeable files.
|
||||
All variants share the same directory layout and produce interchangeable files. The Python and Go variants share `simple-ca.json`, so a CA directory can be managed by either of them.
|
||||
|
||||
## Directory layout
|
||||
|
||||
@@ -26,7 +27,7 @@ CA_DIR/
|
||||
ca_cert.pem root CA certificate
|
||||
ca_key.pem root CA private key
|
||||
ca_bundle.pem root + all issuing CA certs concatenated
|
||||
aia_base_url.txt base URL for AIA extension (shell/Go only)
|
||||
aia_base_url.txt base URL for AIA extension (shell only)
|
||||
{name}_cert.pem certificate issued by root CA
|
||||
{name}_key.pem key for certificate issued by root CA
|
||||
{issuing_ca}/
|
||||
@@ -36,7 +37,7 @@ CA_DIR/
|
||||
{name}_key.pem key for certificate issued by issuing CA
|
||||
```
|
||||
|
||||
Python additionally writes:
|
||||
Python and Go additionally write:
|
||||
|
||||
```
|
||||
CA_DIR/
|
||||
@@ -46,6 +47,17 @@ CA_DIR/
|
||||
crl.pem issuing CA CRL (make-crl)
|
||||
```
|
||||
|
||||
`simple-ca.json` keys:
|
||||
|
||||
- `name`, `created` - root CA name and creation time.
|
||||
- `ca_publish_base_url` - base URL for AIA and CRL Distribution Point extensions.
|
||||
- `subordinates` - issuing CA directory names.
|
||||
- `issuing_ca` - default for `--issuing-ca`.
|
||||
- `days` - defaults for `--days`: `ca`, `cert`, `crl`.
|
||||
- `openssl` - path to the openssl binary (Python only).
|
||||
- `history` - issued certificates per CA (`ca` for the root CA): `name`, `serial`, `created`, `expires`, `revoked`.
|
||||
- `crl_number` - last CRL number issued per CA.
|
||||
|
||||
Use `ca_bundle.pem` with `openssl verify -CAfile CA_DIR/ca_bundle.pem` — this works identically on Linux, macOS, and Windows without relying on hash symlinks.
|
||||
|
||||
---
|
||||
@@ -109,7 +121,7 @@ python3 simple-ca.py COMMAND [OPTIONS] [ARGS]
|
||||
|
||||
```bash
|
||||
make-ca [--ca-dir DIR] [--days N] [--ca-publish-base-url URL] [--issuing-ca NAME] CA_NAME
|
||||
make-cert [--ca-dir DIR] [--cert-dir DIR] [--days N] [--issuing-ca NAME] SUBJECT [SAN ...]
|
||||
make-cert [--ca-dir DIR] [--cert-dir DIR] [--days N] [--issuing-ca NAME] [--type server|user] SUBJECT [SAN ...]
|
||||
make-pfx [--ca-dir DIR] [--issuing-ca NAME] [--password PASS] [--apple-openssl] CERT_PATH
|
||||
make-crl [--ca-dir DIR] [--issuing-ca NAME] [--days N]
|
||||
revoke-cert [--ca-dir DIR] [--issuing-ca NAME] CERT_PATH
|
||||
@@ -117,6 +129,8 @@ revoke-cert [--ca-dir DIR] [--issuing-ca NAME] CERT_PATH
|
||||
|
||||
`--ca-publish-base-url` embeds both AIA (Authority Information Access) and CRL Distribution Point extensions in issued certificates, pointing to the published location of the CA cert and CRL file.
|
||||
|
||||
`--type server` (default) creates a TLS certificate (serverAuth + clientAuth) with `SUBJECT` as the CN and first SAN, which must be a DNS name. `--type user` creates a certificate with clientAuth, emailProtection and codeSigning, where `SUBJECT` is any CN. SANs can be DNS names, IPv4 addresses or email addresses.
|
||||
|
||||
### Example — two-level CA with CRL
|
||||
|
||||
```bash
|
||||
@@ -134,7 +148,7 @@ python3 simple-ca.py make-crl --ca-dir /tmp/ca --issuing-ca servers
|
||||
|
||||
## Go binary
|
||||
|
||||
Equivalent to the shell variant in features. Uses native Go crypto — no `openssl` subprocess required except for `--apple-openssl` PFX generation.
|
||||
Equivalent to the Python variant in features and shares its `simple-ca.json`. Uses native Go crypto — no `openssl` subprocess required except for `--apple-openssl` PFX generation.
|
||||
|
||||
```bash
|
||||
cd src/simple-ca && go build -o simple-ca .
|
||||
@@ -143,9 +157,11 @@ cd src/simple-ca && go build -o simple-ca .
|
||||
### Commands
|
||||
|
||||
```bash
|
||||
simple-ca make-ca [--ca-dir DIR] [--days N] [--aia-base-url URL] [--issuing-ca NAME] CA_NAME
|
||||
simple-ca make-cert [--ca-dir DIR] [--cert-dir DIR] [--days N] [--issuing-ca NAME] SUBJECT [SAN ...]
|
||||
simple-ca make-pfx [--ca-dir DIR] [--issuing-ca NAME] [--password PASS] [--apple-openssl] CERT_PATH
|
||||
simple-ca make-ca [--ca-dir DIR] [--days N] [--ca-publish-base-url URL] [--issuing-ca NAME] CA_NAME
|
||||
simple-ca make-cert [--ca-dir DIR] [--cert-dir DIR] [--days N] [--issuing-ca NAME] [--type server|user] SUBJECT [SAN ...]
|
||||
simple-ca make-pfx [--ca-dir DIR] [--issuing-ca NAME] [--password PASS] [--apple-openssl] CERT_PATH
|
||||
simple-ca make-crl [--ca-dir DIR] [--issuing-ca NAME] [--days N]
|
||||
simple-ca revoke-cert [--ca-dir DIR] [--issuing-ca NAME] CERT_PATH
|
||||
```
|
||||
|
||||
`SIMPLE_CA_DIR` environment variable is used as the default CA directory when `--ca-dir` is not specified.
|
||||
|
||||
Reference in new issue
Block a user