mkcert.sh revision 1.1.1.4 1 1.1 christos #! /bin/bash
2 1.1 christos #
3 1.1.1.4 christos # Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
4 1.1 christos # Copyright (c) 2016 Viktor Dukhovni <openssl-users (at] dukhovni.org>.
5 1.1 christos # All rights reserved.
6 1.1 christos #
7 1.1.1.2 christos # Licensed under the OpenSSL license (the "License"). You may not use
8 1.1.1.2 christos # this file except in compliance with the License. You can obtain a copy
9 1.1.1.2 christos # in the file LICENSE in the source distribution or at
10 1.1.1.2 christos # https://www.openssl.org/source/license.html
11 1.1.1.2 christos
12 1.1.1.2 christos # This file is dual-licensed and is also available under other terms.
13 1.1.1.2 christos # Please contact the author.
14 1.1 christos
15 1.1 christos # 100 years should be enough for now
16 1.1 christos if [ -z "$DAYS" ]; then
17 1.1 christos DAYS=36525
18 1.1 christos fi
19 1.1 christos
20 1.1 christos if [ -z "$OPENSSL_SIGALG" ]; then
21 1.1 christos OPENSSL_SIGALG=sha256
22 1.1 christos fi
23 1.1 christos
24 1.1 christos if [ -z "$REQMASK" ]; then
25 1.1 christos REQMASK=utf8only
26 1.1 christos fi
27 1.1 christos
28 1.1 christos stderr_onerror() {
29 1.1 christos (
30 1.1 christos err=$("$@" >&3 2>&1) || {
31 1.1 christos printf "%s\n" "$err" >&2
32 1.1 christos exit 1
33 1.1 christos }
34 1.1 christos ) 3>&1
35 1.1 christos }
36 1.1 christos
37 1.1 christos key() {
38 1.1 christos local key=$1; shift
39 1.1 christos
40 1.1 christos local alg=rsa
41 1.1 christos if [ -n "$OPENSSL_KEYALG" ]; then
42 1.1 christos alg=$OPENSSL_KEYALG
43 1.1 christos fi
44 1.1 christos
45 1.1 christos local bits=2048
46 1.1 christos if [ -n "$OPENSSL_KEYBITS" ]; then
47 1.1 christos bits=$OPENSSL_KEYBITS
48 1.1 christos fi
49 1.1 christos
50 1.1 christos if [ ! -f "${key}.pem" ]; then
51 1.1 christos args=(-algorithm "$alg")
52 1.1 christos case $alg in
53 1.1 christos rsa) args=("${args[@]}" -pkeyopt rsa_keygen_bits:$bits );;
54 1.1 christos ec) args=("${args[@]}" -pkeyopt "ec_paramgen_curve:$bits")
55 1.1 christos args=("${args[@]}" -pkeyopt ec_param_enc:named_curve);;
56 1.1.1.2 christos dsa) args=(-paramfile "$bits");;
57 1.1.1.2 christos ed25519) ;;
58 1.1.1.2 christos ed448) ;;
59 1.1 christos *) printf "Unsupported key algorithm: %s\n" "$alg" >&2; return 1;;
60 1.1 christos esac
61 1.1 christos stderr_onerror \
62 1.1 christos openssl genpkey "${args[@]}" -out "${key}.pem"
63 1.1 christos fi
64 1.1 christos }
65 1.1 christos
66 1.1 christos # Usage: $0 req keyname dn1 dn2 ...
67 1.1 christos req() {
68 1.1 christos local key=$1; shift
69 1.1 christos
70 1.1 christos key "$key"
71 1.1 christos local errs
72 1.1 christos
73 1.1 christos stderr_onerror \
74 1.1 christos openssl req -new -"${OPENSSL_SIGALG}" -key "${key}.pem" \
75 1.1 christos -config <(printf "string_mask=%s\n[req]\n%s\n%s\n[dn]\n" \
76 1.1 christos "$REQMASK" "prompt = no" "distinguished_name = dn"
77 1.1 christos for dn in "$@"; do echo "$dn"; done)
78 1.1 christos }
79 1.1 christos
80 1.1 christos req_nocn() {
81 1.1 christos local key=$1; shift
82 1.1 christos
83 1.1 christos key "$key"
84 1.1 christos stderr_onerror \
85 1.1 christos openssl req -new -"${OPENSSL_SIGALG}" -subj / -key "${key}.pem" \
86 1.1 christos -config <(printf "[req]\n%s\n[dn]\nCN_default =\n" \
87 1.1 christos "distinguished_name = dn")
88 1.1 christos }
89 1.1 christos
90 1.1 christos cert() {
91 1.1 christos local cert=$1; shift
92 1.1 christos local exts=$1; shift
93 1.1 christos
94 1.1 christos stderr_onerror \
95 1.1 christos openssl x509 -req -"${OPENSSL_SIGALG}" -out "${cert}.pem" \
96 1.1 christos -extfile <(printf "%s\n" "$exts") "$@"
97 1.1 christos }
98 1.1 christos
99 1.1 christos genroot() {
100 1.1 christos local cn=$1; shift
101 1.1 christos local key=$1; shift
102 1.1 christos local cert=$1; shift
103 1.1 christos local skid="subjectKeyIdentifier = hash"
104 1.1 christos local akid="authorityKeyIdentifier = keyid"
105 1.1 christos
106 1.1 christos exts=$(printf "%s\n%s\n%s\n" "$skid" "$akid" "basicConstraints = critical,CA:true")
107 1.1 christos for eku in "$@"
108 1.1 christos do
109 1.1 christos exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$eku")
110 1.1 christos done
111 1.1 christos csr=$(req "$key" "CN = $cn") || return 1
112 1.1 christos echo "$csr" |
113 1.1 christos cert "$cert" "$exts" -signkey "${key}.pem" -set_serial 1 -days "${DAYS}"
114 1.1 christos }
115 1.1 christos
116 1.1 christos genca() {
117 1.1.1.4 christos local OPTIND=1
118 1.1.1.4 christos local purpose=
119 1.1.1.4 christos
120 1.1.1.4 christos while getopts p: o
121 1.1.1.4 christos do
122 1.1.1.4 christos case $o in
123 1.1.1.4 christos p) purpose="$OPTARG";;
124 1.1.1.4 christos *) echo "Usage: $0 genca [-p EKU] cn keyname certname cakeyname cacertname" >&2
125 1.1.1.4 christos return 1;;
126 1.1.1.4 christos esac
127 1.1.1.4 christos done
128 1.1.1.4 christos
129 1.1.1.4 christos shift $((OPTIND - 1))
130 1.1 christos local cn=$1; shift
131 1.1 christos local key=$1; shift
132 1.1 christos local cert=$1; shift
133 1.1 christos local cakey=$1; shift
134 1.1 christos local cacert=$1; shift
135 1.1 christos local skid="subjectKeyIdentifier = hash"
136 1.1 christos local akid="authorityKeyIdentifier = keyid"
137 1.1 christos
138 1.1 christos exts=$(printf "%s\n%s\n%s\n" "$skid" "$akid" "basicConstraints = critical,CA:true")
139 1.1.1.4 christos if [ -n "$purpose" ]; then
140 1.1.1.4 christos exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$purpose")
141 1.1.1.4 christos fi
142 1.1 christos if [ -n "$NC" ]; then
143 1.1 christos exts=$(printf "%s\nnameConstraints = %s\n" "$exts" "$NC")
144 1.1 christos fi
145 1.1 christos csr=$(req "$key" "CN = $cn") || return 1
146 1.1 christos echo "$csr" |
147 1.1 christos cert "$cert" "$exts" -CA "${cacert}.pem" -CAkey "${cakey}.pem" \
148 1.1.1.4 christos -set_serial 2 -days "${DAYS}" "$@"
149 1.1 christos }
150 1.1 christos
151 1.1 christos gen_nonbc_ca() {
152 1.1 christos local cn=$1; shift
153 1.1 christos local key=$1; shift
154 1.1 christos local cert=$1; shift
155 1.1 christos local cakey=$1; shift
156 1.1 christos local cacert=$1; shift
157 1.1 christos local skid="subjectKeyIdentifier = hash"
158 1.1 christos local akid="authorityKeyIdentifier = keyid"
159 1.1 christos
160 1.1 christos exts=$(printf "%s\n%s\n%s\n" "$skid" "$akid")
161 1.1 christos exts=$(printf "%s\nkeyUsage = %s\n" "$exts" "keyCertSign, cRLSign")
162 1.1 christos for eku in "$@"
163 1.1 christos do
164 1.1 christos exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$eku")
165 1.1 christos done
166 1.1 christos csr=$(req "$key" "CN = $cn") || return 1
167 1.1 christos echo "$csr" |
168 1.1 christos cert "$cert" "$exts" -CA "${cacert}.pem" -CAkey "${cakey}.pem" \
169 1.1 christos -set_serial 2 -days "${DAYS}"
170 1.1 christos }
171 1.1 christos
172 1.1 christos # Usage: $0 genpc keyname certname eekeyname eecertname pcext1 pcext2 ...
173 1.1 christos #
174 1.1 christos # Note: takes csr on stdin, so must be used with $0 req like this:
175 1.1 christos #
176 1.1 christos # $0 req keyname dn | $0 genpc keyname certname eekeyname eecertname pcext ...
177 1.1 christos genpc() {
178 1.1 christos local key=$1; shift
179 1.1 christos local cert=$1; shift
180 1.1 christos local cakey=$1; shift
181 1.1 christos local ca=$1; shift
182 1.1 christos
183 1.1 christos exts=$(printf "%s\n%s\n%s\n%s\n" \
184 1.1 christos "subjectKeyIdentifier = hash" \
185 1.1 christos "authorityKeyIdentifier = keyid, issuer:always" \
186 1.1 christos "basicConstraints = CA:false" \
187 1.1 christos "proxyCertInfo = critical, @pcexts";
188 1.1 christos echo "[pcexts]";
189 1.1 christos for x in "$@"; do echo $x; done)
190 1.1 christos cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
191 1.1 christos -set_serial 2 -days "${DAYS}"
192 1.1 christos }
193 1.1 christos
194 1.1.1.2 christos # Usage: $0 geneealt keyname certname eekeyname eecertname alt1 alt2 ...
195 1.1 christos #
196 1.1 christos # Note: takes csr on stdin, so must be used with $0 req like this:
197 1.1 christos #
198 1.1.1.2 christos # $0 req keyname dn | $0 geneealt keyname certname eekeyname eecertname alt ...
199 1.1 christos geneealt() {
200 1.1 christos local key=$1; shift
201 1.1 christos local cert=$1; shift
202 1.1 christos local cakey=$1; shift
203 1.1 christos local ca=$1; shift
204 1.1 christos
205 1.1 christos exts=$(printf "%s\n%s\n%s\n%s\n" \
206 1.1 christos "subjectKeyIdentifier = hash" \
207 1.1 christos "authorityKeyIdentifier = keyid" \
208 1.1 christos "basicConstraints = CA:false" \
209 1.1 christos "subjectAltName = @alts";
210 1.1 christos echo "[alts]";
211 1.1 christos for x in "$@"; do echo $x; done)
212 1.1 christos cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
213 1.1 christos -set_serial 2 -days "${DAYS}"
214 1.1 christos }
215 1.1 christos
216 1.1 christos genee() {
217 1.1 christos local OPTIND=1
218 1.1 christos local purpose=serverAuth
219 1.1 christos
220 1.1 christos while getopts p: o
221 1.1 christos do
222 1.1 christos case $o in
223 1.1 christos p) purpose="$OPTARG";;
224 1.1 christos *) echo "Usage: $0 genee [-p EKU] cn keyname certname cakeyname cacertname" >&2
225 1.1 christos return 1;;
226 1.1 christos esac
227 1.1 christos done
228 1.1 christos
229 1.1 christos shift $((OPTIND - 1))
230 1.1 christos local cn=$1; shift
231 1.1 christos local key=$1; shift
232 1.1 christos local cert=$1; shift
233 1.1 christos local cakey=$1; shift
234 1.1 christos local ca=$1; shift
235 1.1 christos
236 1.1 christos exts=$(printf "%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \
237 1.1 christos "subjectKeyIdentifier = hash" \
238 1.1 christos "authorityKeyIdentifier = keyid, issuer" \
239 1.1 christos "basicConstraints = CA:false" \
240 1.1 christos "extendedKeyUsage = $purpose" \
241 1.1 christos "subjectAltName = @alts" "DNS=${cn}")
242 1.1 christos csr=$(req "$key" "CN = $cn") || return 1
243 1.1 christos echo "$csr" |
244 1.1 christos cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
245 1.1 christos -set_serial 2 -days "${DAYS}" "$@"
246 1.1 christos }
247 1.1 christos
248 1.1.1.3 christos geneenocsr() {
249 1.1.1.3 christos local OPTIND=1
250 1.1.1.3 christos local purpose=serverAuth
251 1.1.1.3 christos
252 1.1.1.3 christos while getopts p: o
253 1.1.1.3 christos do
254 1.1.1.3 christos case $o in
255 1.1.1.3 christos p) purpose="$OPTARG";;
256 1.1.1.3 christos *) echo "Usage: $0 genee [-p EKU] cn certname cakeyname cacertname" >&2
257 1.1.1.3 christos return 1;;
258 1.1.1.3 christos esac
259 1.1.1.3 christos done
260 1.1.1.3 christos
261 1.1.1.3 christos shift $((OPTIND - 1))
262 1.1.1.3 christos local cn=$1; shift
263 1.1.1.3 christos local cert=$1; shift
264 1.1.1.3 christos local cakey=$1; shift
265 1.1.1.3 christos local ca=$1; shift
266 1.1.1.3 christos
267 1.1.1.3 christos exts=$(printf "%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \
268 1.1.1.3 christos "subjectKeyIdentifier = hash" \
269 1.1.1.3 christos "authorityKeyIdentifier = keyid, issuer" \
270 1.1.1.3 christos "basicConstraints = CA:false" \
271 1.1.1.3 christos "extendedKeyUsage = $purpose" \
272 1.1.1.3 christos "subjectAltName = @alts" "DNS=${cn}")
273 1.1.1.3 christos cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
274 1.1.1.3 christos -set_serial 2 -days "${DAYS}" "$@"
275 1.1.1.3 christos }
276 1.1.1.3 christos
277 1.1 christos genss() {
278 1.1 christos local cn=$1; shift
279 1.1 christos local key=$1; shift
280 1.1 christos local cert=$1; shift
281 1.1 christos
282 1.1 christos exts=$(printf "%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \
283 1.1 christos "subjectKeyIdentifier = hash" \
284 1.1 christos "authorityKeyIdentifier = keyid, issuer" \
285 1.1 christos "basicConstraints = CA:false" \
286 1.1 christos "extendedKeyUsage = serverAuth" \
287 1.1 christos "subjectAltName = @alts" "DNS=${cn}")
288 1.1 christos csr=$(req "$key" "CN = $cn") || return 1
289 1.1 christos echo "$csr" |
290 1.1 christos cert "$cert" "$exts" -signkey "${key}.pem" \
291 1.1 christos -set_serial 1 -days "${DAYS}" "$@"
292 1.1 christos }
293 1.1 christos
294 1.1 christos gennocn() {
295 1.1 christos local key=$1; shift
296 1.1 christos local cert=$1; shift
297 1.1 christos
298 1.1 christos csr=$(req_nocn "$key") || return 1
299 1.1 christos echo "$csr" |
300 1.1 christos cert "$cert" "" -signkey "${key}.pem" -set_serial 1 -days -1 "$@"
301 1.1 christos }
302 1.1 christos
303 1.1 christos "$@"
304