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