blob: fda2966b9c8013f4a11b352abc8819e61bdeed9d [file] [log] [blame]
# onfca Makefile
#
# SPDX-FileCopyrightText: © 2022 Open Networking Foundation <support@opennetworking.org>
# SPDX-License-Identifier: Apache-2.0
# openssl onfiguration is also given in pki.cnf
#
# NOTE: This makefile makes heavy use of Automatic Variables
# https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html
# and order-only prerequisites
# https://www.gnu.org/software/make/manual/html_node/Prerequisite-Types.html
# Please review and understand this documentation before making changes
SHELL = bash -eu -o pipefail
# see bottom for help generation
.DEFAULT_GOAL := help
.PHONY: test license help
# common parameters for all options
KEY_SIZE ?= 2048
OPENSSL_CNF ?= pki.cnf
# base dir
BASE_DIR ?= onf_pki
# default CA to use when verifying leaf certs, by default the IM CA
DEFAULT_CA ?= im_ca
# root CA
ROOT_CA_NAME ?= root_ca
ROOT_CA_PASSPHRASE ?= "TestingRootCAPassPhrase"
ROOT_CA_SUBJECT ?= /C=US/ST=California/L=Menlo Park/O=ONF/OU=Infra/CN=ONF Test Root CA
ROOT_EXPIRATION_DAYS ?= 1825
# intermediate CA
IM_CA_NAME ?= im_ca
IM_CA_PASSPHRASE ?= "TestingIMCAPassPhrase"
IM_CA_SUBJECT ?= /C=US/ST=California/L=Menlo Park/O=ONF/OU=Infra/CN=ONF Test IM CA
IM_EXPIRATION_DAYS ?= 1095
IM_REVOKE_REASON ?= CACompromise
# leaf certs
LEAF_EXPIRATION_DAYS ?= 730
LEAF_PURPOSE ?= server_cert_ext # alternatively, use client_cert_ext for client certs
LEAF_SUBJECT_PARTIAL ?= /C=US/ST=California/L=Menlo Park/O=ONF/OU=Infra/CN=
LEAF_KEYPAIR ?= core
LEAF_SAN ?= DNS:core.example.com,DNS:core.example.net
LEAF_REVOKE_REASON ?= keyCompromise
# utility/validation targets
valid_server: ## Check Server Cert validity (set LEAF_KEYPAIR, DEFAULT_CA)
openssl verify -verbose -x509_strict -show_chain \
-purpose sslserver \
-CAfile $(BASE_DIR)/$(DEFAULT_CA)/chain.pem \
-CRLfile $(BASE_DIR)/$(DEFAULT_CA)/ca.crl -crl_check \
$(BASE_DIR)/certout/$(LEAF_KEYPAIR).pem
valid_client: ## Check Client Cert validity (set LEAF_KEYPAIR, DEFAULT_CA)
openssl verify -verbose -x509_strict -show_chain \
-purpose sslclient \
-CAfile $(BASE_DIR)/$(DEFAULT_CA)/chain.pem \
-CRLfile $(BASE_DIR)/$(DEFAULT_CA)/ca.crl -crl_check \
$(BASE_DIR)/certout/$(LEAF_KEYPAIR).pem
valid_im: ## Check IM CA validity (set IM_CA_NAME, ROOT_CA_NAME)
openssl verify -verbose -x509_strict -purpose any \
-CAfile $(BASE_DIR)/$(ROOT_CA_NAME)/ca.pem \
-CRLfile $(BASE_DIR)/$(ROOT_CA_NAME)/ca.crl -crl_check_all \
$(BASE_DIR)/$(IM_CA_NAME)/ca.pem
printca: $(BASE_DIR)/$(DEFAULT_CA)/ca.pem ## Print CA Public Key (PEM) for DEFAULT_CA
openssl x509 -in $< -text -noout
printcrl: $(BASE_DIR)/$(DEFAULT_CA)/ca.crl ## Print CRL (Revoke List) for DEFAULT_CA
openssl crl -in $< -text -noout
printkey: ## Print KEY (Private Key) for LEAF_KEYPAIR
openssl rsa -in $(BASE_DIR)/certout/$(LEAF_KEYPAIR).key -text -noout -check
printcsr: ## Print CSR (Sign Request) for LEAF_KEYPAIR
openssl req -in $(BASE_DIR)/certout/$(LEAF_KEYPAIR).csr -text -noout -verify
printpem: ## Print PEM (Public Key) for LEAF_KEYPAIR
openssl x509 -in $(BASE_DIR)/certout/$(LEAF_KEYPAIR).pem -text -noout
revoke_leaf: ## Revoke Leaf Cert (set IM_CA_NAME, LEAF_KEYPAIR, LEAF_REVOKE_REASON)
BASE_DIR=$(BASE_DIR) CA_NAME=$(IM_CA_NAME) openssl ca \
-config $(OPENSSL_CNF) \
-passin file:$(BASE_DIR)/$(IM_CA_NAME)/private/ca_passphrase \
-revoke $(BASE_DIR)/certout/$(LEAF_KEYPAIR).pem \
-crl_reason $(LEAF_REVOKE_REASON)
BASE_DIR=$(BASE_DIR) CA_NAME=$(IM_CA_NAME) openssl ca -gencrl \
-config $(OPENSSL_CNF) \
-passin file:$(BASE_DIR)/$(IM_CA_NAME)/private/ca_passphrase \
-out $(BASE_DIR)/$(IM_CA_NAME)/ca.crl
revoke_im: ## Revoke Intermediate CA Cert (set IM_CA_NAME, IM_REVOKE_REASON, ROOT_CA_NAME)
BASE_DIR=$(BASE_DIR) CA_NAME=$(ROOT_CA_NAME) openssl ca \
-config $(OPENSSL_CNF) \
-passin file:$(BASE_DIR)/$(ROOT_CA_NAME)/private/ca_passphrase \
-revoke $(BASE_DIR)/$(IM_CA_NAME)/ca.pem \
-crl_reason $(IM_REVOKE_REASON)
BASE_DIR=$(BASE_DIR) CA_NAME=$(ROOT_CA_NAME) openssl ca -gencrl \
-config $(OPENSSL_CNF) \
-passin file:$(BASE_DIR)/$(ROOT_CA_NAME)/private/ca_passphrase \
-out $(BASE_DIR)/$(ROOT_CA_NAME)/ca.crl
destroy: ## Delete all certificates and data
rm -rf $(BASE_DIR)
# don't delete intermediate files
.PRECIOUS: ca_passphrase $(BASE_DIR)/certout/%.csr $(BASE_DIR)/certout/%.key
# Generic CA directory creation
$(BASE_DIR)/%_ca:
mkdir -p $@/private $@/db $@/crl/db $@/certs
chmod 700 $@/private
touch $@/db/ca.db
printf "unique_subject = no\ncopy_extensions = copy\n" > $@/db/ca.db.attr
echo 01 > $@/db/ca.srl
echo 01 > $@/crl/db/ca.crl.srl
touch $@/index.txt
# Root CA creation
$(BASE_DIR)/$(ROOT_CA_NAME)/private/ca_passphrase: | $(BASE_DIR)/$(ROOT_CA_NAME)
@echo $(ROOT_CA_PASSPHRASE) > $@
$(BASE_DIR)/$(ROOT_CA_NAME)/private/ca_key.pem: | $(BASE_DIR)/$(ROOT_CA_NAME)/private/ca_passphrase
@echo "## Creating root CA private key, $@"
BASE_DIR=$(BASE_DIR) CA_NAME=$(ROOT_CA_NAME) openssl genrsa -aes256 \
-passout file:$(BASE_DIR)/$(ROOT_CA_NAME)/private/ca_passphrase \
-out $@ $(KEY_SIZE)
$(BASE_DIR)/$(ROOT_CA_NAME)/ca.pem: | $(BASE_DIR)/$(ROOT_CA_NAME)/private/ca_key.pem
@echo "## Creating self-signed root CA cert: $@"
BASE_DIR=$(BASE_DIR) CA_NAME=$(ROOT_CA_NAME) openssl req -config $(OPENSSL_CNF) \
-extensions root_ca_ext \
-new -x509 -sha256 \
-days $(ROOT_EXPIRATION_DAYS) \
-key $(@D)/private/ca_key.pem \
-passin file:$(BASE_DIR)/$(ROOT_CA_NAME)/private/ca_passphrase \
-subj "$(ROOT_CA_SUBJECT)" \
-out $@
@echo "## Creating root CA revocation list: $(@D)/ca.crl"
BASE_DIR=$(BASE_DIR) CA_NAME=$(ROOT_CA_NAME) openssl ca -gencrl \
-config $(OPENSSL_CNF) \
-passin file:$(BASE_DIR)/$(ROOT_CA_NAME)/private/ca_passphrase \
-out $(@D)/ca.crl
# Intermediate CA creation
$(BASE_DIR)/$(IM_CA_NAME)/private/ca_passphrase: | $(BASE_DIR)/$(IM_CA_NAME)
@echo $(IM_CA_PASSPHRASE) > $@
$(BASE_DIR)/$(IM_CA_NAME)/private/ca_key.pem: | $(BASE_DIR)/$(IM_CA_NAME)/private/ca_passphrase
@echo "## Creating intermediate CA private key: $@"
BASE_DIR=$(BASE_DIR) CA_NAME=$(IM_CA_NAME) openssl genrsa -aes256 \
-passout file:$(@D)/ca_passphrase \
-out $@ $(KEY_SIZE)
$(BASE_DIR)/$(IM_CA_NAME)/private/im_ca.csr: | $(BASE_DIR)/$(IM_CA_NAME)/private/ca_key.pem
@echo "## Creating intermediate CA signing request $@ from $<"
BASE_DIR=$(BASE_DIR) CA_NAME=$(IM_CA_NAME) openssl req -config $(OPENSSL_CNF) \
-new -sha256 \
-key $(@D)/ca_key.pem \
-passin file:$(@D)/ca_passphrase \
-subj "$(IM_CA_SUBJECT)" \
-out $@
$(BASE_DIR)/$(IM_CA_NAME)/ca.pem: | $(BASE_DIR)/$(IM_CA_NAME)/private/im_ca.csr $(BASE_DIR)/$(ROOT_CA_NAME)/ca.pem
@echo "## Signing $< with root CA key to create intermediate CA cert: $@"
BASE_DIR=$(BASE_DIR) CA_NAME=$(ROOT_CA_NAME) openssl ca -config $(OPENSSL_CNF) \
-extensions im_ca_ext \
-notext -batch -md sha256 \
-days $(IM_EXPIRATION_DAYS) \
-passin file:$(BASE_DIR)/$(ROOT_CA_NAME)/private/ca_passphrase \
-in $(@D)/private/im_ca.csr \
-out $@
@echo "## Creating chain with Root CA and IM CA: $@"
cat $@ $(BASE_DIR)/$(ROOT_CA_NAME)/ca.pem > $(@D)/chain.pem
openssl crl2pkcs7 -nocrl -certfile $(@D)/chain.pem | openssl pkcs7 -print_certs -noout
@echo "## Creating IM CA revocation list: $(@D)/ca.crl"
BASE_DIR=$(BASE_DIR) CA_NAME=$(IM_CA_NAME) openssl ca -gencrl \
-config $(OPENSSL_CNF) \
-passin file:$(BASE_DIR)/$(IM_CA_NAME)/private/ca_passphrase \
-out $(@D)/ca.crl
# Leaf cert creation
$(BASE_DIR)/certout:
mkdir -p $@
$(BASE_DIR)/certout/%.key: | $(BASE_DIR)/certout
@echo "## Creating leaf private key: $@"
openssl genrsa -out $@ $(KEY_SIZE)
$(BASE_DIR)/certout/%.csr: | $(BASE_DIR)/certout/%.key
@echo "## Creating signing request $@ from $<"
BASE_DIR=$(BASE_DIR) CA_NAME=$(IM_CA_NAME) openssl req -config $(OPENSSL_CNF) \
-new -sha256 \
-key $(@D)/$(*F).key \
-subj "$(LEAF_SUBJECT_PARTIAL)$*" \
-addext "subjectAltName = $(LEAF_SAN)" \
-out $@
$(BASE_DIR)/certout/%.pem: | $(BASE_DIR)/certout/%.csr $(BASE_DIR)/$(IM_CA_NAME)/ca.pem
@echo "## Signing $< with IM CA key to create signed leaf cert: $@"
BASE_DIR=$(BASE_DIR) CA_NAME=$(IM_CA_NAME) openssl ca -config $(OPENSSL_CNF) \
-extensions $(LEAF_PURPOSE) \
-policy any_pol \
-notext -batch -md sha256 \
-days $(LEAF_EXPIRATION_DAYS) \
-passin file:$(BASE_DIR)/$(IM_CA_NAME)/private/ca_passphrase \
-in $(@D)/$(*F).csr \
-out $@
@echo "## Creating bundle with IM CA and Leaf: $(basename $@)_bundle.pem"
cat $@ $(BASE_DIR)/$(IM_CA_NAME)/ca.pem > $(basename $@)_bundle.pem
openssl crl2pkcs7 -nocrl -certfile $(basename $@)_bundle.pem | openssl pkcs7 -print_certs -noout
# testing and license tasks
test: license
license: $(VENV_NAME) ## Check license with the reuse tool
reuse --version ;\
reuse --root . lint
help: ## Print help for each target
@echo onfca make targets
@echo See README.md for more detailed instructions
@echo
@grep '^[[:alnum:]_-]*:.* ##' $(MAKEFILE_LIST) \
| sort | awk 'BEGIN {FS=":.* ## "}; {printf "%-25s %s\n", $$1, $$2};'