231 lines
6.6 KiB
Markdown
231 lines
6.6 KiB
Markdown
# Lab CA
|
|
|
|
This repository contains a simple CLI tool for managing a Certificate Authority (CA).
|
|
|
|
It is designed to be easy to use and provides a basic set of CA features:
|
|
|
|
- Create a CA and a self-signed CA certificate
|
|
- Create and sign common types of certificates:
|
|
- Server certificate
|
|
- Client certificate
|
|
- Code signing certificate
|
|
- Email certificate
|
|
- Revoke a certificate
|
|
- List issued certificates
|
|
- Create a CRL (Certificate Revocation List)
|
|
|
|
> **NOTE:** Certificate types can be combined (e.g. `server,client`).
|
|
|
|
## Usage
|
|
|
|
The tool is used from the command line. It has a simple command structure:
|
|
|
|
```bash
|
|
lab-ca <command> [options]
|
|
```
|
|
|
|
The main commands available are:
|
|
|
|
- `initca` — Initialize a new CA and create a self-signed CA certificate and key.
|
|
- `issue` — Issue a new certificate signed by the CA (single certificate, command-line options).
|
|
- `provision` — Provision multiple certificates from a batch file (HCL) in one go.
|
|
- `revoke` — Revoke a certificate by name or serial number.
|
|
- `crl` — Generate a Certificate Revocation List (CRL) from revoked certificates.
|
|
- `list` — List issued certificates (optionally including revoked).
|
|
- `version` — Show version information for the tool.
|
|
|
|
Run the command with `-h` or `--help` or without any arguments to see usage information. Each command has its own set of options, arguments, and a help message.
|
|
|
|
---
|
|
|
|
### CA Initialization
|
|
|
|
Create a new CA configuration file (HCL):
|
|
|
|
```hcl
|
|
ca "example_ca" {
|
|
name = "Example CA"
|
|
country = "US"
|
|
organization = "ACME Corp"
|
|
key_size = 4096
|
|
validity = "10y"
|
|
|
|
paths {
|
|
certificates = "certs"
|
|
private_keys = "private"
|
|
state_file = "ca_state.json"
|
|
}
|
|
}
|
|
```
|
|
|
|
- The `ca` block's label is used as a logical name for the CA and for the default state file name.
|
|
- The `paths` block defines where certificates, private keys, and the CA state file are stored.
|
|
- On Linux/macOS, the private keys directory is created with `0700` permissions.
|
|
- The command does not encrypt private keys. Do not use in production.
|
|
|
|
---
|
|
|
|
### Listing Certificates
|
|
|
|
List all issued (non-revoked) certificates:
|
|
|
|
```bash
|
|
lab-ca list
|
|
```
|
|
|
|
To include revoked certificates:
|
|
|
|
```bash
|
|
lab-ca list --revoked
|
|
```
|
|
|
|
---
|
|
|
|
### Issuing a Certificate
|
|
|
|
Issue a new certificate from the command line:
|
|
|
|
```bash
|
|
lab-ca issue --name <name> [--subject <subject>] [--type <type>] [--validity <period>] [--san <SAN> ...] [--overwrite] [--dry-run] [--verbose]
|
|
```
|
|
|
|
- `--name` (required): Name for the certificate and key files (used as subject if `--subject` is omitted)
|
|
- `--subject`: Subject Common Name or full DN (optional, defaults to `--name`)
|
|
- `--type`: Certificate type: `client`, `server`, `code-signing`, `email` (comma-separated for multiple usages; default: `server`)
|
|
- `--validity`: Validity period (e.g. `2y`, `6m`, `30d`; default: `1y`)
|
|
- `--san`: Subject Alternative Name (repeatable; e.g. `dns:example.com`, `ip:1.2.3.4`, `email:user@example.com`)
|
|
- `--overwrite`: Allow overwriting existing files
|
|
- `--dry-run`: Validate and show what would be created, but do not write files
|
|
- `--verbose`: Print detailed information
|
|
|
|
---
|
|
|
|
### Provisioning Certificates (Batch)
|
|
|
|
Provision multiple certificates from a batch file (HCL):
|
|
|
|
```bash
|
|
lab-ca provision --file <certificates.hcl> [--overwrite] [--verbose]
|
|
```
|
|
|
|
#### Example HCL Provisioning File
|
|
|
|
```hcl
|
|
defaults {
|
|
subject = "{{ .Name }}.example.org"
|
|
type = "server,client"
|
|
validity = "1y"
|
|
san = ["DNS:{{ .Name }}.example.org"]
|
|
}
|
|
|
|
variables = {
|
|
Domain = "example.net"
|
|
Country = "EX"
|
|
}
|
|
|
|
certificate "service1" {
|
|
# from default: subject = "{{ .Name }}.example.org"
|
|
# from default: type = "server,client"
|
|
# from default: validity = "1y"
|
|
# from default: san = ["DNS:service1.example.org"]
|
|
}
|
|
|
|
certificate "service2" {
|
|
subject = "{{ .Name }}.{{ .Domain }}" # result: service2.example.net
|
|
san = ["DNS:{{ .Name }}.{{ .Domain }}"] # result: [ "DNS:service2.example.net" ]
|
|
}
|
|
|
|
certificate "service3" {}
|
|
|
|
certificate "user1" {
|
|
subject = "CN=User One,emailAddress=user1@example.org,O=Example,C=US"
|
|
type = "client,email"
|
|
validity = "1y"
|
|
san = ["email:user1@example.net"]
|
|
}
|
|
```
|
|
|
|
- The `defaults` block provides default values for all certificates unless overridden.
|
|
- The `variables` map can be used in Go template expressions in any field.
|
|
- Each `certificate` block defines a certificate to be issued. The block label is available as `{{ .Name }}` in templates.
|
|
- Fields:
|
|
- `subject`: Subject string (can be a template)
|
|
- `type`: Comma-separated usages (server, client, code-signing, email)
|
|
- `validity`: Validity period (e.g. `1y`, `6m`, `30d`)
|
|
- `san`: List of SANs (e.g. `DNS:...`, `IP:...`, `email:...`)
|
|
|
|
---
|
|
|
|
### Revoking a Certificate
|
|
|
|
Revoke a certificate by name or serial number:
|
|
|
|
```bash
|
|
lab-ca revoke --name <name> [--reason <reason>]
|
|
lab-ca revoke --serial <serial> [--reason <reason>]
|
|
```
|
|
|
|
- `--reason` can be one of: `unspecified`, `keyCompromise`, `caCompromise`, `affiliationChanged`, `superseded`, `cessationOfOperation`, `certificateHold`, `removeFromCRL` (default: `cessationOfOperation`)
|
|
|
|
---
|
|
|
|
### Generating a CRL
|
|
|
|
Generate a Certificate Revocation List (CRL) from revoked certificates:
|
|
|
|
```bash
|
|
lab-ca crl [--crl-file <path>] [--validity-days <days>]
|
|
```
|
|
|
|
- `--crl-file`: Output path for CRL file (default: `crl.pem`)
|
|
- `--validity-days`: CRL validity in days (default: 30)
|
|
|
|
---
|
|
|
|
### Version
|
|
|
|
Show version information:
|
|
|
|
```bash
|
|
lab-ca version
|
|
```
|
|
|
|
---
|
|
|
|
## Configuration and Templates
|
|
|
|
- All configuration and provisioning files use HCL (HashiCorp Configuration Language).
|
|
- Go template syntax is supported in `subject`, `san`, and other string fields. The following variables are available:
|
|
- `.Name`: The certificate name (from the block label)
|
|
- Any key from the `variables` map
|
|
|
|
Example:
|
|
|
|
```hcl
|
|
subject = "{{ .Name }}.{{ .Domain }}"
|
|
san = ["DNS:{{ .Name }}.{{ .Domain }}"]
|
|
```
|
|
|
|
## Certificate Types and SANs
|
|
|
|
- `server`: For server certificates. SANs should be DNS or IP.
|
|
- `client`: For client certificates. SANs can be email or DNS.
|
|
- `email`: For S/MIME/email certificates. SANs should be email.
|
|
- `code-signing`: For code signing certificates.
|
|
|
|
The tool checks that SANs are valid for the selected certificate type(s). Certificate usage can be combined (e.g. `server,client`).
|
|
|
|
---
|
|
|
|
## Example: Real-World Provisioning File
|
|
|
|
See `examples/example-certificates.hcl` for a more advanced provisioning file with templates and variables.
|
|
|
|
---
|
|
|
|
## Notes
|
|
|
|
- The tool does not encrypt private keys. Protect your private keys directory.
|
|
- Not intended for production use.
|
|
- For more information about HCL, see: https://github.com/hashicorp/hcl
|