# 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 [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 [--subject ] [--type ] [--validity ] [--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 [--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 [--reason ] lab-ca revoke --serial [--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 ] [--validity-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. ## Building the Tool The repository includes a `build.sh` script to build the CLI tool. It updates the version in `version.go` and builds the binary. To ignore changes made to `version.go` in Git, you can run: ```bash git update-index --assume-unchanged version.go ``` --- ## 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