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