Slawek Koszewski a2528e0526
Some checks failed
Release / release (push) Failing after 1m6s
Added a new test script.
2025-08-04 22:09:23 +02:00
2025-07-28 11:54:48 +02:00
2025-07-27 18:04:55 +02:00
2025-08-03 12:02:47 +02:00
2025-08-04 22:09:23 +02:00
2025-08-02 13:57:27 +02:00
2025-08-02 13:57:27 +02:00

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:

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):

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:

lab-ca list

To include revoked certificates:

lab-ca list --revoked

Issuing a Certificate

Issue a new certificate from the command line:

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):

lab-ca provision --file <certificates.hcl> [--overwrite] [--verbose]

Example HCL Provisioning File

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:

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:

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:

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:

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:

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
Description
A command-line utility that creates micro-scale Certificate Authority and generates certificates for testing purposes.
Readme MIT 283 KiB
2025-07-28 21:27:05 +02:00
Languages
Go 91.3%
Shell 8.7%