Zack Williams | ec61381 | 2020-11-09 15:49:29 -0700 | [diff] [blame] | 1 | # onfca Makefile |
| 2 | # |
| 3 | # SPDX-FileCopyrightText: © 2022 Open Networking Foundation <support@opennetworking.org> |
| 4 | # SPDX-License-Identifier: Apache-2.0 |
| 5 | |
| 6 | # openssl onfiguration is also given in pki.cnf |
| 7 | # |
| 8 | # NOTE: This makefile makes heavy use of Automatic Variables |
| 9 | # https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html |
Zack Williams | ba5c9d3 | 2022-06-05 21:49:18 -0700 | [diff] [blame] | 10 | # and order-only prerequisites |
| 11 | # https://www.gnu.org/software/make/manual/html_node/Prerequisite-Types.html |
| 12 | # Please review and understand this documentation before making changes |
Zack Williams | ec61381 | 2020-11-09 15:49:29 -0700 | [diff] [blame] | 13 | |
| 14 | SHELL = bash -eu -o pipefail |
| 15 | |
| 16 | # see bottom for help generation |
| 17 | .DEFAULT_GOAL := help |
| 18 | .PHONY: test license help |
| 19 | |
| 20 | # common parameters for all options |
| 21 | KEY_SIZE ?= 2048 |
| 22 | OPENSSL_CNF ?= pki.cnf |
| 23 | |
| 24 | # base dir |
| 25 | BASE_DIR ?= onf_pki |
| 26 | |
| 27 | # default CA to use when verifying leaf certs, by default the IM CA |
| 28 | DEFAULT_CA ?= im_ca |
| 29 | |
| 30 | # root CA |
| 31 | ROOT_CA_NAME ?= root_ca |
| 32 | ROOT_CA_PASSPHRASE ?= "TestingRootCAPassPhrase" |
| 33 | ROOT_CA_SUBJECT ?= /C=US/ST=California/L=Menlo Park/O=ONF/OU=Infra/CN=ONF Test Root CA |
Zack Williams | ba5c9d3 | 2022-06-05 21:49:18 -0700 | [diff] [blame] | 34 | ROOT_EXPIRATION_DAYS ?= 1825 |
Zack Williams | ec61381 | 2020-11-09 15:49:29 -0700 | [diff] [blame] | 35 | |
| 36 | # intermediate CA |
| 37 | IM_CA_NAME ?= im_ca |
| 38 | IM_CA_PASSPHRASE ?= "TestingIMCAPassPhrase" |
| 39 | IM_CA_SUBJECT ?= /C=US/ST=California/L=Menlo Park/O=ONF/OU=Infra/CN=ONF Test IM CA |
| 40 | IM_EXPIRATION_DAYS ?= 1095 |
| 41 | IM_REVOKE_REASON ?= CACompromise |
| 42 | |
| 43 | # leaf certs |
| 44 | LEAF_EXPIRATION_DAYS ?= 730 |
Zack Williams | ba5c9d3 | 2022-06-05 21:49:18 -0700 | [diff] [blame] | 45 | LEAF_PURPOSE ?= server_cert_ext # alternatively, use client_cert_ext for client certs |
Zack Williams | ec61381 | 2020-11-09 15:49:29 -0700 | [diff] [blame] | 46 | LEAF_SUBJECT_PARTIAL ?= /C=US/ST=California/L=Menlo Park/O=ONF/OU=Infra/CN= |
| 47 | LEAF_KEYPAIR ?= core |
| 48 | LEAF_SAN ?= DNS:core.example.com,DNS:core.example.net |
| 49 | LEAF_REVOKE_REASON ?= keyCompromise |
| 50 | |
| 51 | # utility/validation targets |
| 52 | valid_server: ## Check Server Cert validity (set LEAF_KEYPAIR, DEFAULT_CA) |
| 53 | openssl verify -verbose -x509_strict -show_chain \ |
| 54 | -purpose sslserver \ |
| 55 | -CAfile $(BASE_DIR)/$(DEFAULT_CA)/chain.pem \ |
| 56 | -CRLfile $(BASE_DIR)/$(DEFAULT_CA)/ca.crl -crl_check \ |
| 57 | $(BASE_DIR)/certout/$(LEAF_KEYPAIR).pem |
| 58 | |
| 59 | valid_client: ## Check Client Cert validity (set LEAF_KEYPAIR, DEFAULT_CA) |
| 60 | openssl verify -verbose -x509_strict -show_chain \ |
| 61 | -purpose sslclient \ |
| 62 | -CAfile $(BASE_DIR)/$(DEFAULT_CA)/chain.pem \ |
| 63 | -CRLfile $(BASE_DIR)/$(DEFAULT_CA)/ca.crl -crl_check \ |
| 64 | $(BASE_DIR)/certout/$(LEAF_KEYPAIR).pem |
| 65 | |
| 66 | valid_im: ## Check IM CA validity (set IM_CA_NAME, ROOT_CA_NAME) |
| 67 | openssl verify -verbose -x509_strict -purpose any \ |
| 68 | -CAfile $(BASE_DIR)/$(ROOT_CA_NAME)/ca.pem \ |
| 69 | -CRLfile $(BASE_DIR)/$(ROOT_CA_NAME)/ca.crl -crl_check_all \ |
| 70 | $(BASE_DIR)/$(IM_CA_NAME)/ca.pem |
| 71 | |
| 72 | printca: $(BASE_DIR)/$(DEFAULT_CA)/ca.pem ## Print CA Public Key (PEM) for DEFAULT_CA |
| 73 | openssl x509 -in $< -text -noout |
| 74 | |
| 75 | printcrl: $(BASE_DIR)/$(DEFAULT_CA)/ca.crl ## Print CRL (Revoke List) for DEFAULT_CA |
| 76 | openssl crl -in $< -text -noout |
| 77 | |
| 78 | printkey: ## Print KEY (Private Key) for LEAF_KEYPAIR |
| 79 | openssl rsa -in $(BASE_DIR)/certout/$(LEAF_KEYPAIR).key -text -noout -check |
| 80 | |
| 81 | printcsr: ## Print CSR (Sign Request) for LEAF_KEYPAIR |
| 82 | openssl req -in $(BASE_DIR)/certout/$(LEAF_KEYPAIR).csr -text -noout -verify |
| 83 | |
| 84 | printpem: ## Print PEM (Public Key) for LEAF_KEYPAIR |
| 85 | openssl x509 -in $(BASE_DIR)/certout/$(LEAF_KEYPAIR).pem -text -noout |
| 86 | |
| 87 | revoke_leaf: ## Revoke Leaf Cert (set IM_CA_NAME, LEAF_KEYPAIR, LEAF_REVOKE_REASON) |
| 88 | BASE_DIR=$(BASE_DIR) CA_NAME=$(IM_CA_NAME) openssl ca \ |
| 89 | -config $(OPENSSL_CNF) \ |
| 90 | -passin file:$(BASE_DIR)/$(IM_CA_NAME)/private/ca_passphrase \ |
| 91 | -revoke $(BASE_DIR)/certout/$(LEAF_KEYPAIR).pem \ |
| 92 | -crl_reason $(LEAF_REVOKE_REASON) |
| 93 | BASE_DIR=$(BASE_DIR) CA_NAME=$(IM_CA_NAME) openssl ca -gencrl \ |
| 94 | -config $(OPENSSL_CNF) \ |
| 95 | -passin file:$(BASE_DIR)/$(IM_CA_NAME)/private/ca_passphrase \ |
| 96 | -out $(BASE_DIR)/$(IM_CA_NAME)/ca.crl |
| 97 | |
| 98 | revoke_im: ## Revoke Intermediate CA Cert (set IM_CA_NAME, IM_REVOKE_REASON, ROOT_CA_NAME) |
| 99 | BASE_DIR=$(BASE_DIR) CA_NAME=$(ROOT_CA_NAME) openssl ca \ |
| 100 | -config $(OPENSSL_CNF) \ |
| 101 | -passin file:$(BASE_DIR)/$(ROOT_CA_NAME)/private/ca_passphrase \ |
| 102 | -revoke $(BASE_DIR)/$(IM_CA_NAME)/ca.pem \ |
| 103 | -crl_reason $(IM_REVOKE_REASON) |
| 104 | BASE_DIR=$(BASE_DIR) CA_NAME=$(ROOT_CA_NAME) openssl ca -gencrl \ |
| 105 | -config $(OPENSSL_CNF) \ |
| 106 | -passin file:$(BASE_DIR)/$(ROOT_CA_NAME)/private/ca_passphrase \ |
| 107 | -out $(BASE_DIR)/$(ROOT_CA_NAME)/ca.crl |
| 108 | |
| 109 | destroy: ## Delete all certificates and data |
| 110 | rm -rf $(BASE_DIR) |
| 111 | |
| 112 | # don't delete intermediate files |
| 113 | .PRECIOUS: ca_passphrase $(BASE_DIR)/certout/%.csr $(BASE_DIR)/certout/%.key |
| 114 | |
| 115 | # Generic CA directory creation |
| 116 | $(BASE_DIR)/%_ca: |
| 117 | mkdir -p $@/private $@/db $@/crl/db $@/certs |
| 118 | chmod 700 $@/private |
| 119 | touch $@/db/ca.db |
| 120 | printf "unique_subject = no\ncopy_extensions = copy\n" > $@/db/ca.db.attr |
| 121 | echo 01 > $@/db/ca.srl |
| 122 | echo 01 > $@/crl/db/ca.crl.srl |
| 123 | touch $@/index.txt |
| 124 | |
| 125 | # Root CA creation |
| 126 | $(BASE_DIR)/$(ROOT_CA_NAME)/private/ca_passphrase: | $(BASE_DIR)/$(ROOT_CA_NAME) |
| 127 | @echo $(ROOT_CA_PASSPHRASE) > $@ |
| 128 | |
| 129 | $(BASE_DIR)/$(ROOT_CA_NAME)/private/ca_key.pem: | $(BASE_DIR)/$(ROOT_CA_NAME)/private/ca_passphrase |
| 130 | @echo "## Creating root CA private key, $@" |
| 131 | BASE_DIR=$(BASE_DIR) CA_NAME=$(ROOT_CA_NAME) openssl genrsa -aes256 \ |
| 132 | -passout file:$(BASE_DIR)/$(ROOT_CA_NAME)/private/ca_passphrase \ |
| 133 | -out $@ $(KEY_SIZE) |
| 134 | |
Zack Williams | ba5c9d3 | 2022-06-05 21:49:18 -0700 | [diff] [blame] | 135 | $(BASE_DIR)/$(ROOT_CA_NAME)/ca.pem: | $(BASE_DIR)/$(ROOT_CA_NAME)/private/ca_key.pem |
Zack Williams | ec61381 | 2020-11-09 15:49:29 -0700 | [diff] [blame] | 136 | @echo "## Creating self-signed root CA cert: $@" |
| 137 | BASE_DIR=$(BASE_DIR) CA_NAME=$(ROOT_CA_NAME) openssl req -config $(OPENSSL_CNF) \ |
| 138 | -extensions root_ca_ext \ |
| 139 | -new -x509 -sha256 \ |
Zack Williams | ba5c9d3 | 2022-06-05 21:49:18 -0700 | [diff] [blame] | 140 | -days $(ROOT_EXPIRATION_DAYS) \ |
| 141 | -key $(@D)/private/ca_key.pem \ |
Zack Williams | ec61381 | 2020-11-09 15:49:29 -0700 | [diff] [blame] | 142 | -passin file:$(BASE_DIR)/$(ROOT_CA_NAME)/private/ca_passphrase \ |
| 143 | -subj "$(ROOT_CA_SUBJECT)" \ |
| 144 | -out $@ |
| 145 | @echo "## Creating root CA revocation list: $(@D)/ca.crl" |
| 146 | BASE_DIR=$(BASE_DIR) CA_NAME=$(ROOT_CA_NAME) openssl ca -gencrl \ |
| 147 | -config $(OPENSSL_CNF) \ |
| 148 | -passin file:$(BASE_DIR)/$(ROOT_CA_NAME)/private/ca_passphrase \ |
| 149 | -out $(@D)/ca.crl |
| 150 | |
| 151 | # Intermediate CA creation |
| 152 | $(BASE_DIR)/$(IM_CA_NAME)/private/ca_passphrase: | $(BASE_DIR)/$(IM_CA_NAME) |
| 153 | @echo $(IM_CA_PASSPHRASE) > $@ |
| 154 | |
Zack Williams | ba5c9d3 | 2022-06-05 21:49:18 -0700 | [diff] [blame] | 155 | $(BASE_DIR)/$(IM_CA_NAME)/private/ca_key.pem: | $(BASE_DIR)/$(IM_CA_NAME)/private/ca_passphrase |
Zack Williams | ec61381 | 2020-11-09 15:49:29 -0700 | [diff] [blame] | 156 | @echo "## Creating intermediate CA private key: $@" |
| 157 | BASE_DIR=$(BASE_DIR) CA_NAME=$(IM_CA_NAME) openssl genrsa -aes256 \ |
| 158 | -passout file:$(@D)/ca_passphrase \ |
| 159 | -out $@ $(KEY_SIZE) |
| 160 | |
Zack Williams | ba5c9d3 | 2022-06-05 21:49:18 -0700 | [diff] [blame] | 161 | $(BASE_DIR)/$(IM_CA_NAME)/private/im_ca.csr: | $(BASE_DIR)/$(IM_CA_NAME)/private/ca_key.pem |
Zack Williams | ec61381 | 2020-11-09 15:49:29 -0700 | [diff] [blame] | 162 | @echo "## Creating intermediate CA signing request $@ from $<" |
| 163 | BASE_DIR=$(BASE_DIR) CA_NAME=$(IM_CA_NAME) openssl req -config $(OPENSSL_CNF) \ |
| 164 | -new -sha256 \ |
Zack Williams | ba5c9d3 | 2022-06-05 21:49:18 -0700 | [diff] [blame] | 165 | -key $(@D)/ca_key.pem \ |
Zack Williams | ec61381 | 2020-11-09 15:49:29 -0700 | [diff] [blame] | 166 | -passin file:$(@D)/ca_passphrase \ |
| 167 | -subj "$(IM_CA_SUBJECT)" \ |
| 168 | -out $@ |
| 169 | |
Zack Williams | ba5c9d3 | 2022-06-05 21:49:18 -0700 | [diff] [blame] | 170 | $(BASE_DIR)/$(IM_CA_NAME)/ca.pem: | $(BASE_DIR)/$(IM_CA_NAME)/private/im_ca.csr $(BASE_DIR)/$(ROOT_CA_NAME)/ca.pem |
Zack Williams | ec61381 | 2020-11-09 15:49:29 -0700 | [diff] [blame] | 171 | @echo "## Signing $< with root CA key to create intermediate CA cert: $@" |
| 172 | BASE_DIR=$(BASE_DIR) CA_NAME=$(ROOT_CA_NAME) openssl ca -config $(OPENSSL_CNF) \ |
| 173 | -extensions im_ca_ext \ |
| 174 | -notext -batch -md sha256 \ |
| 175 | -days $(IM_EXPIRATION_DAYS) \ |
| 176 | -passin file:$(BASE_DIR)/$(ROOT_CA_NAME)/private/ca_passphrase \ |
Zack Williams | ba5c9d3 | 2022-06-05 21:49:18 -0700 | [diff] [blame] | 177 | -in $(@D)/private/im_ca.csr \ |
Zack Williams | ec61381 | 2020-11-09 15:49:29 -0700 | [diff] [blame] | 178 | -out $@ |
| 179 | @echo "## Creating chain with Root CA and IM CA: $@" |
| 180 | cat $@ $(BASE_DIR)/$(ROOT_CA_NAME)/ca.pem > $(@D)/chain.pem |
| 181 | openssl crl2pkcs7 -nocrl -certfile $(@D)/chain.pem | openssl pkcs7 -print_certs -noout |
| 182 | @echo "## Creating IM CA revocation list: $(@D)/ca.crl" |
| 183 | BASE_DIR=$(BASE_DIR) CA_NAME=$(IM_CA_NAME) openssl ca -gencrl \ |
| 184 | -config $(OPENSSL_CNF) \ |
| 185 | -passin file:$(BASE_DIR)/$(IM_CA_NAME)/private/ca_passphrase \ |
| 186 | -out $(@D)/ca.crl |
| 187 | |
| 188 | # Leaf cert creation |
| 189 | $(BASE_DIR)/certout: |
| 190 | mkdir -p $@ |
| 191 | |
Zack Williams | ba5c9d3 | 2022-06-05 21:49:18 -0700 | [diff] [blame] | 192 | $(BASE_DIR)/certout/%.key: | $(BASE_DIR)/certout |
Zack Williams | ec61381 | 2020-11-09 15:49:29 -0700 | [diff] [blame] | 193 | @echo "## Creating leaf private key: $@" |
| 194 | openssl genrsa -out $@ $(KEY_SIZE) |
| 195 | |
Zack Williams | ba5c9d3 | 2022-06-05 21:49:18 -0700 | [diff] [blame] | 196 | $(BASE_DIR)/certout/%.csr: | $(BASE_DIR)/certout/%.key |
Zack Williams | ec61381 | 2020-11-09 15:49:29 -0700 | [diff] [blame] | 197 | @echo "## Creating signing request $@ from $<" |
| 198 | BASE_DIR=$(BASE_DIR) CA_NAME=$(IM_CA_NAME) openssl req -config $(OPENSSL_CNF) \ |
| 199 | -new -sha256 \ |
Zack Williams | ba5c9d3 | 2022-06-05 21:49:18 -0700 | [diff] [blame] | 200 | -key $(@D)/$(*F).key \ |
Zack Williams | ec61381 | 2020-11-09 15:49:29 -0700 | [diff] [blame] | 201 | -subj "$(LEAF_SUBJECT_PARTIAL)$*" \ |
| 202 | -addext "subjectAltName = $(LEAF_SAN)" \ |
| 203 | -out $@ |
| 204 | |
Zack Williams | ba5c9d3 | 2022-06-05 21:49:18 -0700 | [diff] [blame] | 205 | $(BASE_DIR)/certout/%.pem: | $(BASE_DIR)/certout/%.csr $(BASE_DIR)/$(IM_CA_NAME)/ca.pem |
Zack Williams | ec61381 | 2020-11-09 15:49:29 -0700 | [diff] [blame] | 206 | @echo "## Signing $< with IM CA key to create signed leaf cert: $@" |
| 207 | BASE_DIR=$(BASE_DIR) CA_NAME=$(IM_CA_NAME) openssl ca -config $(OPENSSL_CNF) \ |
| 208 | -extensions $(LEAF_PURPOSE) \ |
| 209 | -policy any_pol \ |
| 210 | -notext -batch -md sha256 \ |
| 211 | -days $(LEAF_EXPIRATION_DAYS) \ |
| 212 | -passin file:$(BASE_DIR)/$(IM_CA_NAME)/private/ca_passphrase \ |
Zack Williams | ba5c9d3 | 2022-06-05 21:49:18 -0700 | [diff] [blame] | 213 | -in $(@D)/$(*F).csr \ |
Zack Williams | ec61381 | 2020-11-09 15:49:29 -0700 | [diff] [blame] | 214 | -out $@ |
| 215 | @echo "## Creating bundle with IM CA and Leaf: $(basename $@)_bundle.pem" |
| 216 | cat $@ $(BASE_DIR)/$(IM_CA_NAME)/ca.pem > $(basename $@)_bundle.pem |
| 217 | openssl crl2pkcs7 -nocrl -certfile $(basename $@)_bundle.pem | openssl pkcs7 -print_certs -noout |
| 218 | |
| 219 | # testing and license tasks |
| 220 | test: license |
| 221 | |
| 222 | license: $(VENV_NAME) ## Check license with the reuse tool |
| 223 | reuse --version ;\ |
| 224 | reuse --root . lint |
| 225 | |
| 226 | help: ## Print help for each target |
| 227 | @echo onfca make targets |
| 228 | @echo See README.md for more detailed instructions |
| 229 | @echo |
| 230 | @grep '^[[:alnum:]_-]*:.* ##' $(MAKEFILE_LIST) \ |
| 231 | | sort | awk 'BEGIN {FS=":.* ## "}; {printf "%-25s %s\n", $$1, $$2};' |