Require intermediate CAs to have basicConstraints CA:true.
[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 stderr_onerror() {
14     (
15         err=$("$@" >&3 2>&1) || {
16             printf "%s\n" "$err" >&2
17             exit 1
18         }
19     ) 3>&1
20 }
21
22 key() {
23     local key=$1; shift
24
25     local alg=rsa
26     if [ -n "$OPENSSL_KEYALG" ]; then
27         alg=$OPENSSL_KEYALG
28     fi
29
30     local bits=2048
31     if [ -n "$OPENSSL_KEYBITS" ]; then
32         bits=$OPENSSL_KEYBITS
33     fi
34
35     if [ ! -f "${key}.pem" ]; then
36         args=(-algorithm "$alg")
37         case $alg in
38         rsa) args=("${args[@]}" -pkeyopt rsa_keygen_bits:$bits );;
39         ec)  args=("${args[@]}" -pkeyopt "ec_paramgen_curve:$bits")
40                args=("${args[@]}" -pkeyopt ec_param_enc:named_curve);;
41         *) printf "Unsupported key algorithm: %s\n" "$alg" >&2; return 1;;
42         esac
43         stderr_onerror \
44             openssl genpkey "${args[@]}" -out "${key}.pem"
45     fi
46 }
47
48 req() {
49     local key=$1; shift
50     local cn=$1; shift
51
52     key "$key"
53     local errs
54
55     stderr_onerror \
56         openssl req -new -sha256 -key "${key}.pem" \
57             -config <(printf "[req]\n%s\n%s\n[dn]\nCN=%s\n" \
58                       "prompt = no" "distinguished_name = dn" "${cn}")
59 }
60
61 req_nocn() {
62     local key=$1; shift
63
64     key "$key"
65     stderr_onerror \
66         openssl req -new -sha256 -subj / -key "${key}.pem" \
67             -config <(printf "[req]\n%s\n[dn]\nCN_default =\n" \
68                       "distinguished_name = dn")
69 }
70
71 cert() {
72     local cert=$1; shift
73     local exts=$1; shift
74
75     stderr_onerror \
76         openssl x509 -req -sha256 -out "${cert}.pem" \
77             -extfile <(printf "%s\n" "$exts") "$@"
78 }
79
80 genroot() {
81     local cn=$1; shift
82     local key=$1; shift
83     local cert=$1; shift
84     local skid="subjectKeyIdentifier = hash"
85     local akid="authorityKeyIdentifier = keyid"
86
87     exts=$(printf "%s\n%s\n%s\n" "$skid" "$akid" "basicConstraints = CA:true")
88     for eku in "$@"
89     do
90         exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$eku")
91     done
92     csr=$(req "$key" "$cn") || return 1
93     echo "$csr" |
94        cert "$cert" "$exts" -signkey "${key}.pem" -set_serial 1 -days "${DAYS}"
95 }
96
97 genca() {
98     local cn=$1; shift
99     local key=$1; shift
100     local cert=$1; shift
101     local cakey=$1; shift
102     local cacert=$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 = CA:true")
107     for eku in "$@"
108     do
109         exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$eku")
110     done
111     csr=$(req "$key" "$cn") || return 1
112     echo "$csr" |
113         cert "$cert" "$exts" -CA "${cacert}.pem" -CAkey "${cakey}.pem" \
114             -set_serial 2 -days "${DAYS}"
115 }
116
117 gen_nonbc_ca() {
118     local cn=$1; shift
119     local key=$1; shift
120     local cert=$1; shift
121     local cakey=$1; shift
122     local cacert=$1; shift
123     local skid="subjectKeyIdentifier = hash"
124     local akid="authorityKeyIdentifier = keyid"
125
126     exts=$(printf "%s\n%s\n%s\n" "$skid" "$akid")
127     exts=$(printf "%s\nkeyUsage = %s\n" "$exts" "keyCertSign, cRLSign")
128     for eku in "$@"
129     do
130         exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$eku")
131     done
132     csr=$(req "$key" "$cn") || return 1
133     echo "$csr" |
134         cert "$cert" "$exts" -CA "${cacert}.pem" -CAkey "${cakey}.pem" \
135             -set_serial 2 -days "${DAYS}"
136 }
137
138 genee() {
139     local OPTIND=1
140     local purpose=serverAuth
141
142     while getopts p: o
143     do
144         case $o in
145         p) purpose="$OPTARG";;
146         *) echo "Usage: $0 genee [-p EKU] cn keyname certname cakeyname cacertname" >&2
147            return 1;;
148         esac
149     done
150
151     shift $((OPTIND - 1))
152     local cn=$1; shift
153     local key=$1; shift
154     local cert=$1; shift
155     local cakey=$1; shift
156     local ca=$1; shift
157
158     exts=$(printf "%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \
159             "subjectKeyIdentifier = hash" \
160             "authorityKeyIdentifier = keyid, issuer" \
161             "basicConstraints = CA:false" \
162             "extendedKeyUsage = $purpose" \
163             "subjectAltName = @alts" "DNS=${cn}")
164     csr=$(req "$key" "$cn") || return 1
165     echo "$csr" |
166         cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
167             -set_serial 2 -days "${DAYS}" "$@"
168 }
169
170 genss() {
171     local cn=$1; shift
172     local key=$1; shift
173     local cert=$1; shift
174
175     exts=$(printf "%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \
176             "subjectKeyIdentifier   = hash" \
177             "authorityKeyIdentifier = keyid, issuer" \
178             "basicConstraints = CA:false" \
179             "extendedKeyUsage = serverAuth" \
180             "subjectAltName = @alts" "DNS=${cn}")
181     csr=$(req "$key" "$cn") || return 1
182     echo "$csr" |
183         cert "$cert" "$exts" -signkey "${key}.pem" \
184             -set_serial 1 -days "${DAYS}" "$@"
185 }
186
187 gennocn() {
188     local key=$1; shift
189     local cert=$1; shift
190
191     csr=$(req_nocn "$key") || return 1
192     echo "$csr" |
193         cert "$cert" "" -signkey "${key}.pem" -set_serial 1 -days -1 "$@"
194 }
195
196 "$@"