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