3 # Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
4 # Copyright (c) 2016 Viktor Dukhovni <openssl-users@dukhovni.org>.
7 # Licensed under the Apache License 2.0 (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
12 # This file is dual-licensed and is also available under other terms.
13 # Please contact the author.
15 # 100 years should be enough for now
16 if [ -z "$DAYS" ]; then
20 if [ -z "$OPENSSL_SIGALG" ]; then
24 if [ -z "$REQMASK" ]; then
30 err=$("$@" >&3 2>&1) || {
31 printf "%s\n" "$err" >&2
41 if [ -n "$OPENSSL_KEYALG" ]; then
46 if [ -n "$OPENSSL_KEYBITS" ]; then
50 if [ ! -f "${key}.pem" ]; then
51 args=(-algorithm "$alg")
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");;
59 *) printf "Unsupported key algorithm: %s\n" "$alg" >&2; return 1;;
62 openssl genpkey "${args[@]}" -out "${key}.pem"
66 # Usage: $0 req keyname dn1 dn2 ...
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)
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")
95 openssl x509 -req -"${OPENSSL_SIGALG}" -out "${cert}.pem" \
96 -extfile <(printf "%s\n" "$exts") "$@"
103 local bcon="basicConstraints = critical,CA:true"
104 local ku="keyUsage = keyCertSign,cRLSign"
105 local skid="subjectKeyIdentifier = hash"
106 local akid="authorityKeyIdentifier = keyid"
108 exts=$(printf "%s\n%s\n%s\n" "$bcon" "$ku" "$skid" "$akid")
111 exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$eku")
113 csr=$(req "$key" "CN = $cn") || return 1
115 cert "$cert" "$exts" -signkey "${key}.pem" -set_serial 1 -days "${DAYS}"
122 local cakey=$1; shift
123 local cacert=$1; shift
124 local bcon="basicConstraints = critical,CA:true"
125 local ku="keyUsage = keyCertSign,cRLSign"
126 local skid="subjectKeyIdentifier = hash"
127 local akid="authorityKeyIdentifier = keyid"
129 exts=$(printf "%s\n%s\n%s\n" "$bcon" "$ku" "$skid" "$akid")
132 exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$eku")
134 if [ -n "$NC" ]; then
135 exts=$(printf "%s\nnameConstraints = %s\n" "$exts" "$NC")
137 csr=$(req "$key" "CN = $cn") || return 1
139 cert "$cert" "$exts" -CA "${cacert}.pem" -CAkey "${cakey}.pem" \
140 -set_serial 2 -days "${DAYS}"
147 local cakey=$1; shift
148 local cacert=$1; shift
149 local skid="subjectKeyIdentifier = hash"
150 local akid="authorityKeyIdentifier = keyid"
152 exts=$(printf "%s\n%s\n%s\n" "$skid" "$akid")
153 exts=$(printf "%s\nkeyUsage = %s\n" "$exts" "keyCertSign, cRLSign")
156 exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$eku")
158 csr=$(req "$key" "CN = $cn") || return 1
160 cert "$cert" "$exts" -CA "${cacert}.pem" -CAkey "${cakey}.pem" \
161 -set_serial 2 -days "${DAYS}"
164 # Usage: $0 genpc keyname certname eekeyname eecertname pcext1 pcext2 ...
166 # Note: takes csr on stdin, so must be used with $0 req like this:
168 # $0 req keyname dn | $0 genpc keyname certname eekeyname eecertname pcext ...
172 local cakey=$1; shift
175 exts=$(printf "%s\n%s\n%s\n%s\n" \
176 "subjectKeyIdentifier = hash" \
177 "authorityKeyIdentifier = keyid, issuer:always" \
178 "basicConstraints = CA:false" \
179 "proxyCertInfo = critical, @pcexts";
181 for x in "$@"; do echo $x; done)
182 cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
183 -set_serial 2 -days "${DAYS}"
186 # Usage: $0 geneealt keyname certname eekeyname eecertname alt1 alt2 ...
188 # Note: takes csr on stdin, so must be used with $0 req like this:
190 # $0 req keyname dn | $0 geneealt keyname certname eekeyname eecertname alt ...
194 local cakey=$1; shift
197 exts=$(printf "%s\n%s\n%s\n%s\n" \
198 "subjectKeyIdentifier = hash" \
199 "authorityKeyIdentifier = keyid" \
200 "basicConstraints = CA:false" \
201 "subjectAltName = @alts";
203 for x in "$@"; do echo $x; done)
204 cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
205 -set_serial 2 -days "${DAYS}"
210 local purpose=serverAuth
215 p) purpose="$OPTARG";;
216 *) echo "Usage: $0 genee [-p EKU] cn keyname certname cakeyname cacertname" >&2
221 shift $((OPTIND - 1))
225 local cakey=$1; shift
228 exts=$(printf "%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \
229 "subjectKeyIdentifier = hash" \
230 "authorityKeyIdentifier = keyid, issuer" \
231 "basicConstraints = CA:false" \
232 "extendedKeyUsage = $purpose" \
233 "subjectAltName = @alts" "DNS=${cn}")
234 csr=$(req "$key" "CN = $cn") || return 1
236 cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
237 -set_serial 2 -days "${DAYS}" "$@"
242 local purpose=serverAuth
247 p) purpose="$OPTARG";;
248 *) echo "Usage: $0 geneeextra [-p EKU] cn keyname certname cakeyname cacertname extraext" >&2
253 shift $((OPTIND - 1))
257 local cakey=$1; shift
259 local extraext=$1; shift
261 exts=$(printf "%s\n%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \
262 "subjectKeyIdentifier = hash" \
263 "authorityKeyIdentifier = keyid, issuer" \
264 "basicConstraints = CA:false" \
265 "extendedKeyUsage = $purpose" \
266 "subjectAltName = @alts"\
267 "$extraext" "DNS=${cn}")
268 csr=$(req "$key" "CN = $cn") || return 1
270 cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
271 -set_serial 2 -days "${DAYS}" "$@"
276 local purpose=serverAuth
281 p) purpose="$OPTARG";;
282 *) echo "Usage: $0 geneenocsr [-p EKU] cn certname cakeyname cacertname" >&2
287 shift $((OPTIND - 1))
290 local cakey=$1; shift
293 exts=$(printf "%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \
294 "subjectKeyIdentifier = hash" \
295 "authorityKeyIdentifier = keyid, issuer" \
296 "basicConstraints = CA:false" \
297 "extendedKeyUsage = $purpose" \
298 "subjectAltName = @alts" "DNS=${cn}")
299 cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
300 -set_serial 2 -days "${DAYS}" "$@"
308 exts=$(printf "%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \
309 "subjectKeyIdentifier = hash" \
310 "authorityKeyIdentifier = keyid, issuer" \
311 "basicConstraints = CA:false" \
312 "extendedKeyUsage = serverAuth" \
313 "subjectAltName = @alts" "DNS=${cn}")
314 csr=$(req "$key" "CN = $cn") || return 1
316 cert "$cert" "$exts" -signkey "${key}.pem" \
317 -set_serial 1 -days "${DAYS}" "$@"
324 csr=$(req_nocn "$key") || return 1
326 cert "$cert" "" -signkey "${key}.pem" -set_serial 1 -days -1 "$@"
331 local purpose=serverAuth
336 p) purpose="$OPTARG";;
337 *) echo "Usage: $0 genct [-p EKU] cn keyname certname cakeyname cacertname ctlogkey" >&2
342 shift $((OPTIND - 1))
346 local cakey=$1; shift
348 local logkey=$1; shift
350 exts=$(printf "%s\n%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \
351 "subjectKeyIdentifier = hash" \
352 "authorityKeyIdentifier = keyid, issuer" \
353 "basicConstraints = CA:false" \
354 "extendedKeyUsage = $purpose" \
355 "1.3.6.1.4.1.11129.2.4.3 = critical,ASN1:NULL"\
356 "subjectAltName = @alts" "DNS=${cn}")
357 csr=$(req "$key" "CN = $cn") || return 1
359 cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
360 -set_serial 2 -days "${DAYS}" "$@"
361 cat ${cert}.pem ${ca}.pem > ${cert}-chain.pem
362 go run github.com/google/certificate-transparency-go/ctutil/sctgen \
363 --log_private_key ${logkey}.pem \
364 --timestamp="2020-01-01T00:00:00Z" \
365 --cert_chain ${cert}-chain.pem \
366 --tls_out ${cert}.tlssct
368 filesize=$(wc -c <${cert}.tlssct)
369 exts=$(printf "%s\n%s\n%s\n%s\n%s%04X%04X%s\n%s\n[alts]\n%s\n" \
370 "subjectKeyIdentifier = hash" \
371 "authorityKeyIdentifier = keyid, issuer" \
372 "basicConstraints = CA:false" \
373 "extendedKeyUsage = $purpose" \
374 "1.3.6.1.4.1.11129.2.4.2 = ASN1:FORMAT:HEX,OCT:" $((filesize+2)) $filesize `xxd -p ${cert}.tlssct | tr -d '\n'` \
375 "subjectAltName = @alts" "DNS=${cn}")
377 cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
378 -set_serial 2 -days "${DAYS}" "$@"