Make it possible to generate proxy certs with test/certs/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 DAYS=36525
12
13 if [ -z "$OPENSSL_SIGALG" ]; then
14     OPENSSL_SIGALG=sha256
15 fi
16
17 stderr_onerror() {
18     (
19         err=$("$@" >&3 2>&1) || {
20             printf "%s\n" "$err" >&2
21             exit 1
22         }
23     ) 3>&1
24 }
25
26 key() {
27     local key=$1; shift
28
29     local alg=rsa
30     if [ -n "$OPENSSL_KEYALG" ]; then
31         alg=$OPENSSL_KEYALG
32     fi
33
34     local bits=2048
35     if [ -n "$OPENSSL_KEYBITS" ]; then
36         bits=$OPENSSL_KEYBITS
37     fi
38
39     if [ ! -f "${key}.pem" ]; then
40         args=(-algorithm "$alg")
41         case $alg in
42         rsa) args=("${args[@]}" -pkeyopt rsa_keygen_bits:$bits );;
43         ec)  args=("${args[@]}" -pkeyopt "ec_paramgen_curve:$bits")
44                args=("${args[@]}" -pkeyopt ec_param_enc:named_curve);;
45         *) printf "Unsupported key algorithm: %s\n" "$alg" >&2; return 1;;
46         esac
47         stderr_onerror \
48             openssl genpkey "${args[@]}" -out "${key}.pem"
49     fi
50 }
51
52 # Usage: $0 req keyname dn1 dn2 ...
53 req() {
54     local key=$1; shift
55
56     key "$key"
57     local errs
58
59     stderr_onerror \
60         openssl req -new -"${OPENSSL_SIGALG}" -key "${key}.pem" \
61             -config <(printf "[req]\n%s\n%s\n[dn]\n" \
62                       "prompt = no" "distinguished_name = dn" "${dn}"
63                       for dn in "$@"; do echo "$dn"; done)
64 }
65
66 req_nocn() {
67     local key=$1; shift
68
69     key "$key"
70     stderr_onerror \
71         openssl req -new -"${OPENSSL_SIGALG}" -subj / -key "${key}.pem" \
72             -config <(printf "[req]\n%s\n[dn]\nCN_default =\n" \
73                       "distinguished_name = dn")
74 }
75
76 cert() {
77     local cert=$1; shift
78     local exts=$1; shift
79
80     stderr_onerror \
81         openssl x509 -req -"${OPENSSL_SIGALG}" -out "${cert}.pem" \
82             -extfile <(printf "%s\n" "$exts") "$@"
83 }
84
85 genroot() {
86     local cn=$1; shift
87     local key=$1; shift
88     local cert=$1; shift
89     local skid="subjectKeyIdentifier = hash"
90     local akid="authorityKeyIdentifier = keyid"
91
92     exts=$(printf "%s\n%s\n%s\n" "$skid" "$akid" "basicConstraints = critical,CA:true")
93     for eku in "$@"
94     do
95         exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$eku")
96     done
97     csr=$(req "$key" "CN = $cn") || return 1
98     echo "$csr" |
99        cert "$cert" "$exts" -signkey "${key}.pem" -set_serial 1 -days "${DAYS}"
100 }
101
102 genca() {
103     local cn=$1; shift
104     local key=$1; shift
105     local cert=$1; shift
106     local cakey=$1; shift
107     local cacert=$1; shift
108     local skid="subjectKeyIdentifier = hash"
109     local akid="authorityKeyIdentifier = keyid"
110
111     exts=$(printf "%s\n%s\n%s\n" "$skid" "$akid" "basicConstraints = critical,CA:true")
112     for eku in "$@"
113     do
114         exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$eku")
115     done
116     csr=$(req "$key" "CN = $cn") || return 1
117     echo "$csr" |
118         cert "$cert" "$exts" -CA "${cacert}.pem" -CAkey "${cakey}.pem" \
119             -set_serial 2 -days "${DAYS}"
120 }
121
122 gen_nonbc_ca() {
123     local cn=$1; shift
124     local key=$1; shift
125     local cert=$1; shift
126     local cakey=$1; shift
127     local cacert=$1; shift
128     local skid="subjectKeyIdentifier = hash"
129     local akid="authorityKeyIdentifier = keyid"
130
131     exts=$(printf "%s\n%s\n%s\n" "$skid" "$akid")
132     exts=$(printf "%s\nkeyUsage = %s\n" "$exts" "keyCertSign, cRLSign")
133     for eku in "$@"
134     do
135         exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$eku")
136     done
137     csr=$(req "$key" "CN = $cn") || return 1
138     echo "$csr" |
139         cert "$cert" "$exts" -CA "${cacert}.pem" -CAkey "${cakey}.pem" \
140             -set_serial 2 -days "${DAYS}"
141 }
142
143 # Usage: $0 genpc keyname certname eekeyname eecertname pcext1 pcext2 ...
144 #
145 # Note: takes csr on stdin, so must be used with $0 req like this:
146 #
147 # $0 req keyname dn | $0 genpc keyname certname eekeyname eecertname pcext ...
148 genpc() {
149     local key=$1; shift
150     local cert=$1; shift
151     local cakey=$1; shift
152     local ca=$1; shift
153
154     exts=$(printf "%s\n%s\n%s\n%s\n" \
155             "subjectKeyIdentifier = hash" \
156             "authorityKeyIdentifier = keyid, issuer:always" \
157             "basicConstraints = CA:false" \
158             "proxyCertInfo = critical, @pcexts";
159            echo "[pcexts]";
160            for x in "$@"; do echo $x; done)
161     cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
162          -set_serial 2 -days "${DAYS}"
163 }
164
165 genee() {
166     local OPTIND=1
167     local purpose=serverAuth
168
169     while getopts p: o
170     do
171         case $o in
172         p) purpose="$OPTARG";;
173         *) echo "Usage: $0 genee [-p EKU] cn keyname certname cakeyname cacertname" >&2
174            return 1;;
175         esac
176     done
177
178     shift $((OPTIND - 1))
179     local cn=$1; shift
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%s\n[alts]\n%s\n" \
186             "subjectKeyIdentifier = hash" \
187             "authorityKeyIdentifier = keyid, issuer" \
188             "basicConstraints = CA:false" \
189             "extendedKeyUsage = $purpose" \
190             "subjectAltName = @alts" "DNS=${cn}")
191     csr=$(req "$key" "CN = $cn") || return 1
192     echo "$csr" |
193         cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
194             -set_serial 2 -days "${DAYS}" "$@"
195 }
196
197 genss() {
198     local cn=$1; shift
199     local key=$1; shift
200     local cert=$1; shift
201
202     exts=$(printf "%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \
203             "subjectKeyIdentifier   = hash" \
204             "authorityKeyIdentifier = keyid, issuer" \
205             "basicConstraints = CA:false" \
206             "extendedKeyUsage = serverAuth" \
207             "subjectAltName = @alts" "DNS=${cn}")
208     csr=$(req "$key" "CN = $cn") || return 1
209     echo "$csr" |
210         cert "$cert" "$exts" -signkey "${key}.pem" \
211             -set_serial 1 -days "${DAYS}" "$@"
212 }
213
214 gennocn() {
215     local key=$1; shift
216     local cert=$1; shift
217
218     csr=$(req_nocn "$key") || return 1
219     echo "$csr" |
220         cert "$cert" "" -signkey "${key}.pem" -set_serial 1 -days -1 "$@"
221 }
222
223 "$@"