| # 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};' |