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