Add DSA support to mkcert.sh
[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         dsa)  args=(-paramfile "$bits");;
52         *) printf "Unsupported key algorithm: %s\n" "$alg" >&2; return 1;;
53         esac
54         stderr_onerror \
55             openssl genpkey "${args[@]}" -out "${key}.pem"
56     fi
57 }
58
59 # Usage: $0 req keyname dn1 dn2 ...
60 req() {
61     local key=$1; shift
62
63     key "$key"
64     local errs
65
66     stderr_onerror \
67         openssl req -new -"${OPENSSL_SIGALG}" -key "${key}.pem" \
68             -config <(printf "string_mask=%s\n[req]\n%s\n%s\n[dn]\n" \
69               "$REQMASK" "prompt = no" "distinguished_name = dn"
70                       for dn in "$@"; do echo "$dn"; done)
71 }
72
73 req_nocn() {
74     local key=$1; shift
75
76     key "$key"
77     stderr_onerror \
78         openssl req -new -"${OPENSSL_SIGALG}" -subj / -key "${key}.pem" \
79             -config <(printf "[req]\n%s\n[dn]\nCN_default =\n" \
80                       "distinguished_name = dn")
81 }
82
83 cert() {
84     local cert=$1; shift
85     local exts=$1; shift
86
87     stderr_onerror \
88         openssl x509 -req -"${OPENSSL_SIGALG}" -out "${cert}.pem" \
89             -extfile <(printf "%s\n" "$exts") "$@"
90 }
91
92 genroot() {
93     local cn=$1; shift
94     local key=$1; shift
95     local cert=$1; shift
96     local skid="subjectKeyIdentifier = hash"
97     local akid="authorityKeyIdentifier = keyid"
98
99     exts=$(printf "%s\n%s\n%s\n" "$skid" "$akid" "basicConstraints = critical,CA:true")
100     for eku in "$@"
101     do
102         exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$eku")
103     done
104     csr=$(req "$key" "CN = $cn") || return 1
105     echo "$csr" |
106        cert "$cert" "$exts" -signkey "${key}.pem" -set_serial 1 -days "${DAYS}"
107 }
108
109 genca() {
110     local cn=$1; shift
111     local key=$1; shift
112     local cert=$1; shift
113     local cakey=$1; shift
114     local cacert=$1; shift
115     local skid="subjectKeyIdentifier = hash"
116     local akid="authorityKeyIdentifier = keyid"
117
118     exts=$(printf "%s\n%s\n%s\n" "$skid" "$akid" "basicConstraints = critical,CA:true")
119     for eku in "$@"
120     do
121         exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$eku")
122     done
123     if [ -n "$NC" ]; then
124         exts=$(printf "%s\nnameConstraints = %s\n" "$exts" "$NC")
125     fi
126     csr=$(req "$key" "CN = $cn") || return 1
127     echo "$csr" |
128         cert "$cert" "$exts" -CA "${cacert}.pem" -CAkey "${cakey}.pem" \
129             -set_serial 2 -days "${DAYS}"
130 }
131
132 gen_nonbc_ca() {
133     local cn=$1; shift
134     local key=$1; shift
135     local cert=$1; shift
136     local cakey=$1; shift
137     local cacert=$1; shift
138     local skid="subjectKeyIdentifier = hash"
139     local akid="authorityKeyIdentifier = keyid"
140
141     exts=$(printf "%s\n%s\n%s\n" "$skid" "$akid")
142     exts=$(printf "%s\nkeyUsage = %s\n" "$exts" "keyCertSign, cRLSign")
143     for eku in "$@"
144     do
145         exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$eku")
146     done
147     csr=$(req "$key" "CN = $cn") || return 1
148     echo "$csr" |
149         cert "$cert" "$exts" -CA "${cacert}.pem" -CAkey "${cakey}.pem" \
150             -set_serial 2 -days "${DAYS}"
151 }
152
153 # Usage: $0 genpc keyname certname eekeyname eecertname pcext1 pcext2 ...
154 #
155 # Note: takes csr on stdin, so must be used with $0 req like this:
156 #
157 # $0 req keyname dn | $0 genpc keyname certname eekeyname eecertname pcext ...
158 genpc() {
159     local key=$1; shift
160     local cert=$1; shift
161     local cakey=$1; shift
162     local ca=$1; shift
163
164     exts=$(printf "%s\n%s\n%s\n%s\n" \
165             "subjectKeyIdentifier = hash" \
166             "authorityKeyIdentifier = keyid, issuer:always" \
167             "basicConstraints = CA:false" \
168             "proxyCertInfo = critical, @pcexts";
169            echo "[pcexts]";
170            for x in "$@"; do echo $x; done)
171     cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
172          -set_serial 2 -days "${DAYS}"
173 }
174
175 # Usage: $0 genalt keyname certname eekeyname eecertname alt1 alt2 ...
176 #
177 # Note: takes csr on stdin, so must be used with $0 req like this:
178 #
179 # $0 req keyname dn | $0 genalt keyname certname eekeyname eecertname alt ...
180 geneealt() {
181     local key=$1; shift
182     local cert=$1; shift
183     local cakey=$1; shift
184     local ca=$1; shift
185
186     exts=$(printf "%s\n%s\n%s\n%s\n" \
187             "subjectKeyIdentifier = hash" \
188             "authorityKeyIdentifier = keyid" \
189             "basicConstraints = CA:false" \
190             "subjectAltName = @alts";
191            echo "[alts]";
192            for x in "$@"; do echo $x; done)
193     cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
194          -set_serial 2 -days "${DAYS}"
195 }
196
197 genee() {
198     local OPTIND=1
199     local purpose=serverAuth
200
201     while getopts p: o
202     do
203         case $o in
204         p) purpose="$OPTARG";;
205         *) echo "Usage: $0 genee [-p EKU] cn keyname certname cakeyname cacertname" >&2
206            return 1;;
207         esac
208     done
209
210     shift $((OPTIND - 1))
211     local cn=$1; shift
212     local key=$1; shift
213     local cert=$1; shift
214     local cakey=$1; shift
215     local ca=$1; shift
216
217     exts=$(printf "%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \
218             "subjectKeyIdentifier = hash" \
219             "authorityKeyIdentifier = keyid, issuer" \
220             "basicConstraints = CA:false" \
221             "extendedKeyUsage = $purpose" \
222             "subjectAltName = @alts" "DNS=${cn}")
223     csr=$(req "$key" "CN = $cn") || return 1
224     echo "$csr" |
225         cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
226             -set_serial 2 -days "${DAYS}" "$@"
227 }
228
229 genss() {
230     local cn=$1; shift
231     local key=$1; shift
232     local cert=$1; shift
233
234     exts=$(printf "%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \
235             "subjectKeyIdentifier   = hash" \
236             "authorityKeyIdentifier = keyid, issuer" \
237             "basicConstraints = CA:false" \
238             "extendedKeyUsage = serverAuth" \
239             "subjectAltName = @alts" "DNS=${cn}")
240     csr=$(req "$key" "CN = $cn") || return 1
241     echo "$csr" |
242         cert "$cert" "$exts" -signkey "${key}.pem" \
243             -set_serial 1 -days "${DAYS}" "$@"
244 }
245
246 gennocn() {
247     local key=$1; shift
248     local cert=$1; shift
249
250     csr=$(req_nocn "$key") || return 1
251     echo "$csr" |
252         cert "$cert" "" -signkey "${key}.pem" -set_serial 1 -days -1 "$@"
253 }
254
255 "$@"