ee31bf0097007f779b69a154ae1a17fcfd882a48
[openssl.git] / test / certs / mkcert.sh
1 #! /bin/bash
2 #
3 # Copyright (c) 2016 Viktor Dukhovni <openssl-users@dukhovni.org>.
4 # All rights reserved.
5 #
6 # Contributed to the OpenSSL project under the terms of the OpenSSL license
7 # included with the version of the OpenSSL software that includes this module.
8
9 # 100 years should be enough for now
10 #
11 if [ -z "$DAYS" ]; then
12     DAYS=36525
13 fi
14
15 if [ -z "$OPENSSL_SIGALG" ]; then
16     OPENSSL_SIGALG=sha256
17 fi
18
19 if [ -z "$REQMASK" ]; then
20     REQMASK=utf8only
21 fi
22
23 stderr_onerror() {
24     (
25         err=$("$@" >&3 2>&1) || {
26             printf "%s\n" "$err" >&2
27             exit 1
28         }
29     ) 3>&1
30 }
31
32 key() {
33     local key=$1; shift
34
35     local alg=rsa
36     if [ -n "$OPENSSL_KEYALG" ]; then
37         alg=$OPENSSL_KEYALG
38     fi
39
40     local bits=2048
41     if [ -n "$OPENSSL_KEYBITS" ]; then
42         bits=$OPENSSL_KEYBITS
43     fi
44
45     if [ ! -f "${key}.pem" ]; then
46         args=(-algorithm "$alg")
47         case $alg in
48         rsa) args=("${args[@]}" -pkeyopt rsa_keygen_bits:$bits );;
49         ec)  args=("${args[@]}" -pkeyopt "ec_paramgen_curve:$bits")
50                args=("${args[@]}" -pkeyopt ec_param_enc:named_curve);;
51         *) printf "Unsupported key algorithm: %s\n" "$alg" >&2; return 1;;
52         esac
53         stderr_onerror \
54             openssl genpkey "${args[@]}" -out "${key}.pem"
55     fi
56 }
57
58 # Usage: $0 req keyname dn1 dn2 ...
59 req() {
60     local key=$1; shift
61
62     key "$key"
63     local errs
64
65     stderr_onerror \
66         openssl req -new -"${OPENSSL_SIGALG}" -key "${key}.pem" \
67             -config <(printf "string_mask=%s\n[req]\n%s\n%s\n[dn]\n" \
68               "$REQMASK" "prompt = no" "distinguished_name = dn"
69                       for dn in "$@"; do echo "$dn"; done)
70 }
71
72 req_nocn() {
73     local key=$1; shift
74
75     key "$key"
76     stderr_onerror \
77         openssl req -new -"${OPENSSL_SIGALG}" -subj / -key "${key}.pem" \
78             -config <(printf "[req]\n%s\n[dn]\nCN_default =\n" \
79                       "distinguished_name = dn")
80 }
81
82 cert() {
83     local cert=$1; shift
84     local exts=$1; shift
85
86     stderr_onerror \
87         openssl x509 -req -"${OPENSSL_SIGALG}" -out "${cert}.pem" \
88             -extfile <(printf "%s\n" "$exts") "$@"
89 }
90
91 genroot() {
92     local cn=$1; shift
93     local key=$1; shift
94     local cert=$1; shift
95     local skid="subjectKeyIdentifier = hash"
96     local akid="authorityKeyIdentifier = keyid"
97
98     exts=$(printf "%s\n%s\n%s\n" "$skid" "$akid" "basicConstraints = critical,CA:true")
99     for eku in "$@"
100     do
101         exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$eku")
102     done
103     csr=$(req "$key" "CN = $cn") || return 1
104     echo "$csr" |
105        cert "$cert" "$exts" -signkey "${key}.pem" -set_serial 1 -days "${DAYS}"
106 }
107
108 genca() {
109     local cn=$1; shift
110     local key=$1; shift
111     local cert=$1; shift
112     local cakey=$1; shift
113     local cacert=$1; shift
114     local skid="subjectKeyIdentifier = hash"
115     local akid="authorityKeyIdentifier = keyid"
116
117     exts=$(printf "%s\n%s\n%s\n" "$skid" "$akid" "basicConstraints = critical,CA:true")
118     for eku in "$@"
119     do
120         exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$eku")
121     done
122     if [ -n "$NC" ]; then
123         exts=$(printf "%s\nnameConstraints = %s\n" "$exts" "$NC")
124     fi
125     csr=$(req "$key" "CN = $cn") || return 1
126     echo "$csr" |
127         cert "$cert" "$exts" -CA "${cacert}.pem" -CAkey "${cakey}.pem" \
128             -set_serial 2 -days "${DAYS}"
129 }
130
131 gen_nonbc_ca() {
132     local cn=$1; shift
133     local key=$1; shift
134     local cert=$1; shift
135     local cakey=$1; shift
136     local cacert=$1; shift
137     local skid="subjectKeyIdentifier = hash"
138     local akid="authorityKeyIdentifier = keyid"
139
140     exts=$(printf "%s\n%s\n%s\n" "$skid" "$akid")
141     exts=$(printf "%s\nkeyUsage = %s\n" "$exts" "keyCertSign, cRLSign")
142     for eku in "$@"
143     do
144         exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$eku")
145     done
146     csr=$(req "$key" "CN = $cn") || return 1
147     echo "$csr" |
148         cert "$cert" "$exts" -CA "${cacert}.pem" -CAkey "${cakey}.pem" \
149             -set_serial 2 -days "${DAYS}"
150 }
151
152 # Usage: $0 genpc keyname certname eekeyname eecertname pcext1 pcext2 ...
153 #
154 # Note: takes csr on stdin, so must be used with $0 req like this:
155 #
156 # $0 req keyname dn | $0 genpc keyname certname eekeyname eecertname pcext ...
157 genpc() {
158     local key=$1; shift
159     local cert=$1; shift
160     local cakey=$1; shift
161     local ca=$1; shift
162
163     exts=$(printf "%s\n%s\n%s\n%s\n" \
164             "subjectKeyIdentifier = hash" \
165             "authorityKeyIdentifier = keyid, issuer:always" \
166             "basicConstraints = CA:false" \
167             "proxyCertInfo = critical, @pcexts";
168            echo "[pcexts]";
169            for x in "$@"; do echo $x; done)
170     cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
171          -set_serial 2 -days "${DAYS}"
172 }
173
174 # Usage: $0 genalt keyname certname eekeyname eecertname alt1 alt2 ...
175 #
176 # Note: takes csr on stdin, so must be used with $0 req like this:
177 #
178 # $0 req keyname dn | $0 genalt keyname certname eekeyname eecertname alt ...
179 geneealt() {
180     local key=$1; shift
181     local cert=$1; shift
182     local cakey=$1; shift
183     local ca=$1; shift
184
185     exts=$(printf "%s\n%s\n%s\n%s\n" \
186             "subjectKeyIdentifier = hash" \
187             "authorityKeyIdentifier = keyid" \
188             "basicConstraints = CA:false" \
189             "subjectAltName = @alts";
190            echo "[alts]";
191            for x in "$@"; do echo $x; done)
192     cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
193          -set_serial 2 -days "${DAYS}"
194 }
195
196 genee() {
197     local OPTIND=1
198     local purpose=serverAuth
199
200     while getopts p: o
201     do
202         case $o in
203         p) purpose="$OPTARG";;
204         *) echo "Usage: $0 genee [-p EKU] cn keyname certname cakeyname cacertname" >&2
205            return 1;;
206         esac
207     done
208
209     shift $((OPTIND - 1))
210     local cn=$1; shift
211     local key=$1; shift
212     local cert=$1; shift
213     local cakey=$1; shift
214     local ca=$1; shift
215
216     exts=$(printf "%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \
217             "subjectKeyIdentifier = hash" \
218             "authorityKeyIdentifier = keyid, issuer" \
219             "basicConstraints = CA:false" \
220             "extendedKeyUsage = $purpose" \
221             "subjectAltName = @alts" "DNS=${cn}")
222     csr=$(req "$key" "CN = $cn") || return 1
223     echo "$csr" |
224         cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
225             -set_serial 2 -days "${DAYS}" "$@"
226 }
227
228 genss() {
229     local cn=$1; shift
230     local key=$1; shift
231     local cert=$1; shift
232
233     exts=$(printf "%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \
234             "subjectKeyIdentifier   = hash" \
235             "authorityKeyIdentifier = keyid, issuer" \
236             "basicConstraints = CA:false" \
237             "extendedKeyUsage = serverAuth" \
238             "subjectAltName = @alts" "DNS=${cn}")
239     csr=$(req "$key" "CN = $cn") || return 1
240     echo "$csr" |
241         cert "$cert" "$exts" -signkey "${key}.pem" \
242             -set_serial 1 -days "${DAYS}" "$@"
243 }
244
245 gennocn() {
246     local key=$1; shift
247     local cert=$1; shift
248
249     csr=$(req_nocn "$key") || return 1
250     echo "$csr" |
251         cert "$cert" "" -signkey "${key}.pem" -set_serial 1 -days -1 "$@"
252 }
253
254 "$@"