Files
lab-ca/README.md

4.6 KiB

Lab CA

This repository contains a simple CLI tool for managing a Certificate Authority (CA).

It has been designed to be as easy to use as possible and provides a basic set of CA features:

  • Create a CA and a self-signed CA certificate
  • Create and sign a few most common types of certificates:
    • Server certificate
    • Client certificate
    • Code signing certificate
    • Email certificate
  • Sign a CSR to create a certificate
  • Revoke a certificate
  • List issued certificates
  • Create a CRL (Certificate Revocation List)

Usage

The tool is designed to be 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.
  • issue — Issue a new certificate signed by the CA.
  • 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.
  • version — Show version information for the tool.

Run the command with -h or --help or without any arguments to see the usage information. Each command has its own set of options, arguments, and a help message.

CA Initialization

Create a new CA configuration file:

ca "example_ca" {
  name = "Example CA"
  country = "PL"
  organization = "ACME Corp"
  key_size = 4096
  validity = "10y"

  paths {
    certificates = "certs"
    private_keys = "private"
  }
}

NOTE: lab-ca uses HCL (HashiCorp Configuration Language) for configuration files. You can find more information about HCL here.

The ca block's label has no function, but may be used to identify the CA in the future.

The following attributes are available:

  • name - the name of the CA
  • country - the country of the CA
  • organization - the organization of the CA
  • organizational_unit - the organizational unit of the CA (optional)
  • locality - the locality of the CA (optional)
  • province - the province of the CA (optional)
  • email - the email address of the CA (optional)
  • key_size - the size of the CA key in bits (default: 4096)
  • validity - the validity period of the CA certificate (default: 10 years)
  • paths - paths to store certificates and private keys

The paths block defines where the command will store the generated certificates and private keys. On Linux and macOS, the directory specified for private keys will be created with 0700 permissions. However, the command does not check if the directory has correct permissions, so you should ensure that the directory is not accessible by other users. On Windows, both directories will be created with the default ACL for the current user. You have to secure the private keys directory yourself.

NOTE: The command does not encrypt private keys. It is not designed to be used in a production environment.

Certificate Issuance and Provisioning

To issue a new certificate, you can use the issue command and specify the certificate definition on the command line, or use the provision command to provide a file with multiple certificate definitions for batch processing.

The definition file also uses HCL syntax. Here is an example of a certificate definition file:

defaults {
    subject  = "{{ .Name }}.example.org"
    type     = "server"
    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"
    # from default: validity = "1y"
    # from default: san = ["DNS:{{ .Name }}.example.org"]
}

certificate "service2" {
    subject = "{{ .Name }}.example.net"
    # from default: type = "server"
    # from default: validity = "1y"
    san = ["DNS:{{ .Name }}.example.net"]
}

certificate "service3" {}

certificate "service4" {
    subject = "{{ .Name }}.{{ .Domain }}"
    san     = ["DNS:{{ .Name }}.{{ .Domain }}"]
}

Values specified in the defaults block will be used for all certificates unless overridden in individual certificate definitions. Go-style template syntax is also supported, so you can use {{ .Name }} to refer to the certificate name, and variables from the variables map can be used in templates as well.

You can use DNS or IP SANs for server certificates (server and server-only), and email SANs for email certificates (email). The command will check if the SAN is valid based on the type of certificate.