Generate some certificates with the certificatePolicies extension
[openssl.git] / test / certs / mkcert.sh
1 #! /bin/bash
2 #
3 # Copyright 2016-2021 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 OpenSSL license (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 OPTIND=1
118     local purpose=
119
120     while getopts p:c: o
121     do
122         case $o in
123         p) purpose="$OPTARG";;
124         c) certpol="$OPTARG";;
125         *) echo "Usage: $0 genca [-p EKU][-c policyoid] cn keyname certname cakeyname cacertname" >&2
126            return 1;;
127         esac
128     done
129
130     shift $((OPTIND - 1))
131     local cn=$1; shift
132     local key=$1; shift
133     local cert=$1; shift
134     local cakey=$1; shift
135     local cacert=$1; shift
136     local skid="subjectKeyIdentifier = hash"
137     local akid="authorityKeyIdentifier = keyid"
138
139     exts=$(printf "%s\n%s\n%s\n" "$skid" "$akid" "basicConstraints = critical,CA:true")
140     if [ -n "$purpose" ]; then
141         exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$purpose")
142     fi
143     if [ -n "$NC" ]; then
144         exts=$(printf "%s\nnameConstraints = %s\n" "$exts" "$NC")
145     fi
146     if [ -n "$certpol" ]; then
147         exts=$(printf "%s\ncertificatePolicies = %s\n" "$exts" "$certpol")
148     fi
149
150     csr=$(req "$key" "CN = $cn") || return 1
151     echo "$csr" |
152         cert "$cert" "$exts" -CA "${cacert}.pem" -CAkey "${cakey}.pem" \
153             -set_serial 2 -days "${DAYS}" "$@"
154 }
155
156 gen_nonbc_ca() {
157     local cn=$1; shift
158     local key=$1; shift
159     local cert=$1; shift
160     local cakey=$1; shift
161     local cacert=$1; shift
162     local skid="subjectKeyIdentifier = hash"
163     local akid="authorityKeyIdentifier = keyid"
164
165     exts=$(printf "%s\n%s\n%s\n" "$skid" "$akid")
166     exts=$(printf "%s\nkeyUsage = %s\n" "$exts" "keyCertSign, cRLSign")
167     for eku in "$@"
168     do
169         exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$eku")
170     done
171     csr=$(req "$key" "CN = $cn") || return 1
172     echo "$csr" |
173         cert "$cert" "$exts" -CA "${cacert}.pem" -CAkey "${cakey}.pem" \
174             -set_serial 2 -days "${DAYS}"
175 }
176
177 # Usage: $0 genpc keyname certname eekeyname eecertname pcext1 pcext2 ...
178 #
179 # Note: takes csr on stdin, so must be used with $0 req like this:
180 #
181 # $0 req keyname dn | $0 genpc keyname certname eekeyname eecertname pcext ...
182 genpc() {
183     local key=$1; shift
184     local cert=$1; shift
185     local cakey=$1; shift
186     local ca=$1; shift
187
188     exts=$(printf "%s\n%s\n%s\n%s\n" \
189             "subjectKeyIdentifier = hash" \
190             "authorityKeyIdentifier = keyid, issuer:always" \
191             "basicConstraints = CA:false" \
192             "proxyCertInfo = critical, @pcexts";
193            echo "[pcexts]";
194            for x in "$@"; do echo $x; done)
195     cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
196          -set_serial 2 -days "${DAYS}"
197 }
198
199 # Usage: $0 geneealt keyname certname eekeyname eecertname alt1 alt2 ...
200 #
201 # Note: takes csr on stdin, so must be used with $0 req like this:
202 #
203 # $0 req keyname dn | $0 geneealt keyname certname eekeyname eecertname alt ...
204 geneealt() {
205     local key=$1; shift
206     local cert=$1; shift
207     local cakey=$1; shift
208     local ca=$1; shift
209
210     exts=$(printf "%s\n%s\n%s\n%s\n" \
211             "subjectKeyIdentifier = hash" \
212             "authorityKeyIdentifier = keyid" \
213             "basicConstraints = CA:false" \
214             "subjectAltName = @alts";
215            echo "[alts]";
216            for x in "$@"; do echo $x; done)
217     cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
218          -set_serial 2 -days "${DAYS}"
219 }
220
221 genee() {
222     local OPTIND=1
223     local purpose=serverAuth
224
225     while getopts p: o
226     do
227         case $o in
228         p) purpose="$OPTARG";;
229         *) echo "Usage: $0 genee [-p EKU] cn keyname certname cakeyname cacertname" >&2
230            return 1;;
231         esac
232     done
233
234     shift $((OPTIND - 1))
235     local cn=$1; shift
236     local key=$1; shift
237     local cert=$1; shift
238     local cakey=$1; shift
239     local ca=$1; shift
240
241     exts=$(printf "%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \
242             "subjectKeyIdentifier = hash" \
243             "authorityKeyIdentifier = keyid, issuer" \
244             "basicConstraints = CA:false" \
245             "extendedKeyUsage = $purpose" \
246             "subjectAltName = @alts" "DNS=${cn}")
247     csr=$(req "$key" "CN = $cn") || return 1
248     echo "$csr" |
249         cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
250             -set_serial 2 -days "${DAYS}" "$@"
251 }
252
253 geneenocsr() {
254     local OPTIND=1
255     local purpose=serverAuth
256
257     while getopts p: o
258     do
259         case $o in
260         p) purpose="$OPTARG";;
261         *) echo "Usage: $0 genee [-p EKU] cn certname cakeyname cacertname" >&2
262            return 1;;
263         esac
264     done
265
266     shift $((OPTIND - 1))
267     local cn=$1; shift
268     local cert=$1; shift
269     local cakey=$1; shift
270     local ca=$1; shift
271
272     exts=$(printf "%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \
273             "subjectKeyIdentifier = hash" \
274             "authorityKeyIdentifier = keyid, issuer" \
275             "basicConstraints = CA:false" \
276             "extendedKeyUsage = $purpose" \
277             "subjectAltName = @alts" "DNS=${cn}")
278         cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
279             -set_serial 2 -days "${DAYS}" "$@"
280 }
281
282 genss() {
283     local cn=$1; shift
284     local key=$1; shift
285     local cert=$1; shift
286
287     exts=$(printf "%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \
288             "subjectKeyIdentifier   = hash" \
289             "authorityKeyIdentifier = keyid, issuer" \
290             "basicConstraints = CA:false" \
291             "extendedKeyUsage = serverAuth" \
292             "subjectAltName = @alts" "DNS=${cn}")
293     csr=$(req "$key" "CN = $cn") || return 1
294     echo "$csr" |
295         cert "$cert" "$exts" -signkey "${key}.pem" \
296             -set_serial 1 -days "${DAYS}" "$@"
297 }
298
299 gennocn() {
300     local key=$1; shift
301     local cert=$1; shift
302
303     csr=$(req_nocn "$key") || return 1
304     echo "$csr" |
305         cert "$cert" "" -signkey "${key}.pem" -set_serial 1 -days -1 "$@"
306 }
307
308 "$@"