docs: Update README to enhance clarity on CA management tools and usage examples

This commit is contained in:
2026-05-24 21:45:47 +02:00
parent 935167ca8c
commit 2da0c7428d
+148 -40
View File
@@ -2,63 +2,169 @@
[![test](https://gitea.koszewscy.waw.pl/slawek/simple-ca/actions/workflows/test.yaml/badge.svg)](https://gitea.koszewscy.waw.pl/slawek/simple-ca/actions?workflow=test.yaml)
`simple-ca.sh` is a Bash script that provides functions for creating and managing a simple Certificate Authority (CA) and generating certificates. It can create a single or two-level CA hierarchy, and generate client-server TLS certificates. The script is designed to be simple and easy to use, making it suitable for testing and development purposes, where a self-signed certificate is not sufficient.
Tools for creating and managing a simple Certificate Authority for testing and development. Three implementations are provided — pick whichever fits your environment:
All certificates generated by this script have a random serial number.
| | `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 |
| PFX (`--apple-openssl`) | yes | yes | yes |
| Requires | bash/zsh + openssl | Python 3.8+ + openssl | none (native crypto) |
## Functions
All variants share the same directory layout and produce interchangeable files.
### `make_ca()`
## Directory layout
This function creates a root CA certificate and private key. It can optionally create an intermediate CA certificate and private key, which is signed by the root CA. The function takes several parameters to customize the CA creation process, such as the CA name, validity period, and whether to create an intermediate CA.
Usage:
```bash
make_ca [--days <validity_days>] [--issuing-ca <name>] <ca_directory> <ca_name>
```
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)
{name}_cert.pem certificate issued by root CA
{name}_key.pem key for certificate issued by root CA
{issuing_ca}/
ca_cert.pem issuing CA certificate
ca_key.pem issuing CA private key
{name}_cert.pem certificate issued by issuing CA
{name}_key.pem key for certificate issued by issuing CA
```
- `<ca_directory>`: The directory where the CA files will be stored.
- `<ca_name>`: The name of the CA.
- `--days <validity_days>`: Optional. The number of days the CA certificate will be valid. Default is 3650 days (10 years).
- `--issuing-ca <name>`: Optional. If specified, creates an intermediate CA with <ca_name> as the intermediate CA name and using <name> as certificate and key file prefix for the issuing CA (instead of root's `ca`).
Python additionally writes:
It also maintains a `ca_bundle.pem` file in the CA directory containing the root CA and any issuing CA certificates concatenated together. Use this bundle with `openssl verify -CAfile <ca_directory>/ca_bundle.pem` instead of relying on hash symlinks — this works identically on Linux, macOS, and Windows without symlink privileges.
### `make_cert()`
This function generates a certificate and private key with TLS Web Server Authentication and Client Authentication EKUs. The certificate is signed by the specified CA (either root or intermediate).
Usage:
```bash
make_cert --ca-dir <ca_directory> [--days <validity_days>] [--issuing-ca <name>] <cert_directory> <subject_name>
```
CA_DIR/
simple-ca.json config + certificate history
crl.pem root CA CRL (make-crl)
{issuing_ca}/
crl.pem issuing CA CRL (make-crl)
```
- `<ca_directory>`: The directory where the CA files are stored (used to find the CA certificate and key for signing).
- `<cert_directory>`: The directory where the generated certificate and key will be stored.
- `<subject_name>`: The subject name (Common Name) for the certificate.
- `--days <validity_days>`: Optional. The number of days the certificate will be valid. Default is 365 days.
- `--issuing-ca <name>`: Optional. If specified, uses the CA with the key `<name>_key.pem` and certificate `<name>_cert.pem` for signing instead of the root 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.
### `make_pfx()`
---
This function creates a PKCS#12 (PFX) file containing the certificate, private key, and CA certificate chain. This is useful for importing the certificate into applications that require a PFX file.
## Shell — `simple-ca.sh`
Usage:
Source the file and call the functions directly. `SIMPLE_CA_DIR` is set by the first `--ca-dir` call and inherited by all subsequent calls in the same session. It can also be set in the environment before sourcing.
```bash
make_pfx --ca-dir <ca_directory> [--issuing-ca <file_prefix>] --path <pfx_file_path> [--password <pfx_password>]
source simple-ca.sh
```
- `--ca-dir <ca_directory>`: The directory where the CA files are stored (used to find the CA certificate for the chain).
- `--issuing-ca <file_prefix>`: The file prefix of the issuing CA to include in the chain.
- `--path <pfx_file_path>`: The path where the generated PFX file will be saved.
- `--password <pfx_password>`: Optional. The custom password to protect the PFX, instead of the default `changeit`.
### `make_ca`
```bash
make_ca [--ca-dir DIR] [--days N] [--aia-base-url URL] [--issuing-ca NAME] CA_NAME
```
Without `--issuing-ca`: creates the root CA in `DIR`.
With `--issuing-ca NAME`: creates an issuing CA in `DIR/NAME/`, signed by the root CA.
### `make_cert`
```bash
make_cert [--ca-dir DIR] [--cert-dir DIR] [--days N] [--issuing-ca NAME] SUBJECT [SAN ...]
```
Creates a TLS certificate (serverAuth + clientAuth). `SUBJECT` is used as the CN and first SAN. Additional SANs can be DNS names or IPv4 addresses. Without `--cert-dir`, files are written to the signing CA's directory.
### `make_pfx`
```bash
make_pfx [--ca-dir DIR] [--issuing-ca NAME] [--password PASS] [--apple-openssl] CERT_PATH
```
Creates a PKCS#12 bundle from an existing certificate. `--apple-openssl` uses `/usr/bin/openssl` to produce a PFX that Apple Keychain and iOS accept (legacy RC2/3DES encryption instead of modern PBES2).
### Example — two-level CA
```bash
source simple-ca.sh
make_ca --ca-dir /tmp/ca "My Root CA"
make_ca --issuing-ca servers "My Servers CA"
make_cert --issuing-ca servers web.example.com web.example.com 192.168.1.1
make_pfx --issuing-ca servers --password s3cr3t /tmp/ca/servers/web_cert.pem
```
---
## Python — `simple-ca.py`
A standalone CLI with the same commands as the shell variant plus CRL generation and revocation. Configuration and certificate history are stored in `simple-ca.json` inside the CA directory.
```bash
python3 simple-ca.py COMMAND [OPTIONS] [ARGS]
```
### Commands
```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-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
```
`--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.
### Example — two-level CA with CRL
```bash
python3 simple-ca.py make-ca --ca-dir /tmp/ca "My Root CA"
python3 simple-ca.py make-ca --ca-dir /tmp/ca --issuing-ca servers "My Servers CA"
python3 simple-ca.py make-cert --ca-dir /tmp/ca --issuing-ca servers web.example.com web.example.com 192.168.1.1
python3 simple-ca.py make-cert --ca-dir /tmp/ca --issuing-ca servers alice.example.com alice.example.com
python3 simple-ca.py revoke-cert --ca-dir /tmp/ca --issuing-ca servers /tmp/ca/servers/alice_cert.pem
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.
```bash
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_DIR` environment variable is used as the default CA directory when `--ca-dir` is not specified.
### Example — two-level CA
```bash
export SIMPLE_CA_DIR=/tmp/ca
simple-ca make-ca "My Root CA"
simple-ca make-ca --issuing-ca servers "My Servers CA"
simple-ca make-cert --issuing-ca servers web.example.com web.example.com 192.168.1.1
simple-ca make-pfx --issuing-ca servers --password s3cr3t /tmp/ca/servers/web_cert.pem
```
---
## generate-mobileconfig.py
`generate-mobileconfig.py` generates Apple `.mobileconfig` profiles for distributing CA certificates and optionally client certificates and IKEv2 VPN configuration to Apple devices (macOS / iOS / iPadOS).
Generates Apple `.mobileconfig` profiles for distributing CA certificates and optionally client certificates and IKEv2 VPN configuration to Apple devices (macOS / iOS / iPadOS).
### Modes
@@ -141,9 +247,11 @@ python3 generate-mobileconfig.py \
--output alice-vpn.mobileconfig
```
## Self Signed Ceritifcate
---
The following command will create a *full-featured* self-signed certificate that can act as CA certificate and be used for client and server authentication:
## Self-signed certificate
The following command creates a full-featured self-signed certificate usable as a CA and for client/server authentication:
```bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \