1#!/bin/sh
2
3# Script for generating RSA and ECC Intermediate CA and server/client certs based on it.
4
5# Result is chains that looks like:
6# RSA Server
7#  ROOT: ./certs/ca-cert.pem
8#      C=US, ST=Montana, L=Bozeman, O=Sawtooth, OU=Consulting, CN=www.wolfssl.com/emailAddress=info@wolfssl.com)
9#    INTERMEDIATE: ./certs/intermediate/ca-int-cert.pem
10#        C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Development, CN=wolfSSL Intermediate CA/emailAddress=info@wolfssl.com
11#      INTERMEDIATE2: ./certs/intermediate/ca-int2-cert.pem
12#          C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Development, CN=wolfSSL Intermediate2 CA/emailAddress=info@wolfssl.com
13#        SERVER: ./certs/intermediate/server-int-cert.pem
14#            C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Development, CN=wolfSSL Server Chain/emailAddress=info@wolfssl.com
15
16# RSA Client
17#  ROOT: ./certs/ca-cert.pem
18#      C=US, ST=Montana, L=Bozeman, O=Sawtooth, OU=Consulting, CN=www.wolfssl.com/emailAddress=info@wolfssl.com)
19#    INTERMEDIATE: ./certs/intermediate/ca-int-cert.pem
20#        C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Development, CN=wolfSSL Intermediate CA/emailAddress=info@wolfssl.com
21#      INTERMEDIATE: ./certs/intermediate/ca-int2-cert.pem
22#          C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Development, CN=wolfSSL Intermediate2 CA/emailAddress=info@wolfssl.com
23#        CLIENT: ./certs/intermediate/client-int-cert.pem
24#            C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Development, CN=wolfSSL Client Chain/emailAddress=info@wolfssl.com
25
26# ECC Server
27#  ROOT: ./certs/ca-ecc-cert.pem
28#      C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Development, CN=www.wolfssl.com/emailAddress=info@wolfssl.com
29#    INTERMEDIATE: ./certs/intermediate/ca-int-ecc-cert.pem
30#        C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Development, CN=wolfSSL Intermediate CA ECC/emailAddress=info@wolfssl.com
31#      INTERMEDIATE2: ./certs/intermediate/ca-int-ecc-cert.pem
32#          C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Development, CN=wolfSSL Intermediate2 CA ECC/emailAddress=info@wolfssl.com
33#        SERVER: ./certs/intermediate/server-int-ecc-cert.pem
34#            C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Development, CN=wolfSSL Server Chain ECC/emailAddress=info@wolfssl.com
35
36# ECC Client
37#  ROOT: ./certs/ca-ecc-cert.pem
38#      C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Development, CN=www.wolfssl.com/emailAddress=info@wolfssl.com
39#    INTERMEDIATE: ./certs/intermediate/ca-int-ecc-cert.pem
40#        C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Development, CN=wolfSSL Intermediate CA ECC/emailAddress=info@wolfssl.com
41#      INTERMEDIATE2: ./certs/intermediate/ca-int2-ecc-cert.pem
42#          C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Development, CN=wolfSSL Intermediate2 CA ECC/emailAddress=info@wolfssl.com
43#        CLIENT: ./certs/intermediate/client-int-ecc-cert.pem
44#            C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Development, CN=wolfSSL Client Chain ECC/emailAddress=info@wolfssl.com
45
46
47# Run from wolfssl-root as  `./certs/intermediate/genintcerts.sh`
48# To cleanup temp files use `./certs/intermediate/genintcerts.sh clean`
49# To cleanup all files use  `./certs/intermediate/genintcerts.sh cleanall`
50
51dir="."
52
53cleanup_files(){
54    rm -f ./certs/intermediate/index.*
55    rm -f ./certs/intermediate/*.old
56    rm -f ./certs/intermediate/serial
57    rm -f ./certs/intermediate/crlnumber
58    rm -f ./certs/intermediate/*.cnf
59    rm -rf ./certs/intermediate/new_certs
60    exit 0
61}
62
63check_result() {
64    if [ $1 -ne 0 ]; then
65        echo "Step Failed, Abort"
66        exit 1
67    else
68        echo "Step Succeeded!"
69    fi
70}
71
72# Args: 1=CnfFile, 2=Key, 3=Cert
73create_ca_config() {
74    echo "# Generated openssl conf"                              > "$1"
75    echo "[ ca ]"                                               >> "$1"
76    echo "default_ca = CA_default"                              >> "$1"
77    echo ""                                                     >> "$1"
78    echo "[ CA_default ]"                                       >> "$1"
79    echo "certs             = $dir/certs/intermediate"          >> "$1"
80    echo "new_certs_dir     = $dir/certs/intermediate/new_certs">> "$1"
81    echo "database          = $dir/certs/intermediate/index.txt">> "$1"
82    echo "serial            = $dir/certs/intermediate/serial"   >> "$1"
83    echo "RANDFILE          = $dir/private/.rand"               >> "$1"
84    echo ""                                                     >> "$1"
85    echo "private_key       = $dir/$2"                          >> "$1"
86    echo "certificate       = $dir/$3"                          >> "$1"
87    echo ""                                                     >> "$1"
88    echo "crlnumber         = $dir/certs/intermediate/crlnumber">> "$1"
89    echo "crl_extensions    = crl_ext"                          >> "$1"
90    echo "default_crl_days  = 1000"                             >> "$1"
91    echo "default_md        = sha256"                           >> "$1"
92    echo ""                                                     >> "$1"
93    echo "name_opt          = ca_default"                       >> "$1"
94    echo "cert_opt          = ca_default"                       >> "$1"
95    echo "default_days      = 3650"                             >> "$1"
96    echo "preserve          = no"                               >> "$1"
97    echo "policy            = policy_loose"                     >> "$1"
98    echo ""                                                     >> "$1"
99    echo "[ policy_strict ]"                                    >> "$1"
100    echo "countryName             = match"                      >> "$1"
101    echo "stateOrProvinceName     = match"                      >> "$1"
102    echo "organizationName        = match"                      >> "$1"
103    echo "organizationalUnitName  = optional"                   >> "$1"
104    echo "commonName              = supplied"                   >> "$1"
105    echo "emailAddress            = optional"                   >> "$1"
106    echo ""                                                     >> "$1"
107    echo "[ policy_loose ]"                                     >> "$1"
108    echo "countryName             = optional"                   >> "$1"
109    echo "stateOrProvinceName     = optional"                   >> "$1"
110    echo "localityName            = optional"                   >> "$1"
111    echo "organizationName        = optional"                   >> "$1"
112    echo "organizationalUnitName  = optional"                   >> "$1"
113    echo "commonName              = supplied"                   >> "$1"
114    echo "emailAddress            = optional"                   >> "$1"
115    echo ""                                                     >> "$1"
116    echo "[ req ]"                                              >> "$1"
117    echo "default_bits        = 2048"                           >> "$1"
118    echo "distinguished_name  = req_distinguished_name"         >> "$1"
119    echo "string_mask         = utf8only"                       >> "$1"
120    echo "default_md          = sha256"                         >> "$1"
121    echo "x509_extensions     = v3_ca"                          >> "$1"
122    echo ""                                                     >> "$1"
123    echo "[ req_distinguished_name ]"                           >> "$1"
124    echo "countryName                     = US"                 >> "$1"
125    echo "stateOrProvinceName             = Washington"         >> "$1"
126    echo "localityName                    = Seattle"            >> "$1"
127    echo "organizationName                = wolfSSL"            >> "$1"
128    echo "organizationalUnitName          = Development"        >> "$1"
129    echo "commonName                      = www.wolfssl.com"    >> "$1"
130    echo "emailAddress                    = info@wolfssl.com"   >> "$1"
131    echo ""                                                     >> "$1"
132    echo "[ v3_ca ]"                                            >> "$1"
133    echo "subjectKeyIdentifier = hash"                          >> "$1"
134    echo "authorityKeyIdentifier = keyid:always,issuer"         >> "$1"
135    echo "basicConstraints = critical, CA:true"                 >> "$1"
136    echo "keyUsage = critical, digitalSignature, cRLSign, keyCertSign">> "$1"
137    echo ""                                                     >> "$1"
138    echo "[ v3_intermediate_ca ]"                               >> "$1"
139    echo "subjectKeyIdentifier = hash"                          >> "$1"
140    echo "authorityKeyIdentifier = keyid:always,issuer"         >> "$1"
141    echo "basicConstraints = critical, CA:true, pathlen:1"      >> "$1"
142    echo "keyUsage = critical, digitalSignature, cRLSign, keyCertSign">> "$1"
143    echo ""                                                     >> "$1"
144    echo "[ v3_intermediate2_ca ]"                              >> "$1"
145    echo "subjectKeyIdentifier = hash"                          >> "$1"
146    echo "authorityKeyIdentifier = keyid:always,issuer"         >> "$1"
147    echo "basicConstraints = critical, CA:true, pathlen:1"      >> "$1"
148    echo "keyUsage = critical, digitalSignature, cRLSign, keyCertSign">> "$1"
149    echo ""                                                     >> "$1"
150    echo "[ usr_cert ]"                                         >> "$1"
151    echo "basicConstraints = CA:FALSE"                          >> "$1"
152    echo "nsCertType = client, email"                           >> "$1"
153    echo "subjectKeyIdentifier = hash"                          >> "$1"
154    echo "authorityKeyIdentifier = keyid,issuer"                >> "$1"
155    echo "keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment">> "$1"
156    echo "extendedKeyUsage = clientAuth, emailProtection"       >> "$1"
157    echo ""                                                     >> "$1"
158    echo "[ server_cert ]"                                      >> "$1"
159    echo "basicConstraints = CA:FALSE"                          >> "$1"
160    echo "nsCertType = server"                                  >> "$1"
161    echo "subjectKeyIdentifier = hash"                          >> "$1"
162    echo "authorityKeyIdentifier = keyid,issuer:always"         >> "$1"
163    echo "keyUsage = critical, digitalSignature, keyEncipherment, keyAgreement">> "$1"
164    echo "extendedKeyUsage = serverAuth"                        >> "$1"
165    echo ""                                                     >> "$1"
166    echo "[ crl_ext ]"                                          >> "$1"
167    echo "authorityKeyIdentifier=keyid:always"                  >> "$1"
168}
169
170# Args: 1=reqcnf, 2=signcnf, 3=keyfile, 4=certfile, 5=ext, 6=subj, 7=days
171create_cert() {
172    openssl req -config ./certs/intermediate/$1.cnf -new -sha256 \
173        -key $3 \
174        -out ./certs/intermediate/tmp.csr \
175        -subj "/C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Development/CN=$6/emailAddress=info@wolfssl.com"
176    check_result $?
177    openssl ca -config ./certs/intermediate/$2.cnf -extensions $5 -days $7 -notext -md sha256 \
178        -in ./certs/intermediate/tmp.csr -out ./certs/intermediate/$4.pem -batch
179    check_result $?
180    rm ./certs/intermediate/tmp.csr
181
182    # Convert Cert to DER
183    openssl x509 -in ./certs/intermediate/$4.pem -inform PEM -out ./certs/intermediate/$4.der -outform DER
184    check_result $?
185
186    # Add text to cert PEM file
187    openssl x509 -in ./certs/intermediate/$4.pem -text > ./certs/intermediate/tmp.pem
188    check_result $?
189    mv ./certs/intermediate/tmp.pem ./certs/intermediate/$4.pem
190}
191
192if [ "$1" == "clean" ]; then
193    echo "Cleaning temp files"
194    cleanup_files
195fi
196if [ "$1" == "cleanall" ]; then
197    echo "Cleaning all files"
198    rm -f ./certs/intermediate/*.pem
199    rm -f ./certs/intermediate/*.der
200    rm -f ./certs/intermediate/*.csr
201    cleanup_files
202fi
203
204# Make sure required CA files exist and are populated
205rm -f ./certs/intermediate/index.*
206touch ./certs/intermediate/index.txt
207if [ ! -f ./certs/intermediate/serial ]; then
208    echo 1000 > ./certs/intermediate/serial
209fi
210if [ ! -f ./certs/intermediate/crlnumber ]; then
211    echo 2000 > ./certs/intermediate/crlnumber
212fi
213if [ ! -d ./certs/intermediate/new_certs ]; then
214    mkdir ./certs/intermediate/new_certs
215fi
216
217
218# RSA
219echo "Creating RSA CA configuration cnf files"
220create_ca_config ./certs/intermediate/wolfssl_root.cnf certs/ca-key.pem certs/ca-cert.pem
221create_ca_config ./certs/intermediate/wolfssl_int.cnf certs/intermediate/ca-int-key.pem certs/intermediate/ca-int-cert.pem
222create_ca_config ./certs/intermediate/wolfssl_int2.cnf certs/intermediate/ca-int2-key.pem certs/intermediate/ca-int2-cert.pem
223
224if [ ! -f ./certs/intermediate/ca-int-key.pem ]; then
225    echo "Make Intermediate RSA CA Key"
226    openssl genrsa -out ./certs/intermediate/ca-int-key.pem 2048
227    check_result $?
228    openssl rsa -in ./certs/intermediate/ca-int-key.pem -inform PEM -out ./certs/intermediate/ca-int-key.der -outform DER
229    check_result $?
230fi
231if [ ! -f ./certs/intermediate/ca-int2-key.pem ]; then
232    echo "Make Intermediate2 RSA CA Key"
233    openssl genrsa -out ./certs/intermediate/ca-int2-key.pem 2048
234    check_result $?
235    openssl rsa -in ./certs/intermediate/ca-int2-key.pem -inform PEM -out ./certs/intermediate/ca-int2-key.der -outform DER
236    check_result $?
237fi
238
239echo "Create RSA Intermediate CA signed by root"
240create_cert wolfssl_int wolfssl_root ./certs/intermediate/ca-int-key.pem ca-int-cert v3_intermediate_ca "wolfSSL Intermediate CA" 7300
241
242echo "Create RSA Intermediate2 CA signed by RSA Intermediate"
243create_cert wolfssl_int2 wolfssl_int ./certs/intermediate/ca-int2-key.pem ca-int2-cert v3_intermediate2_ca "wolfSSL Intermediate2 CA" 7300
244
245echo "Create RSA Server Certificate signed by intermediate2"
246create_cert wolfssl_int2 wolfssl_int2 ./certs/server-key.pem server-int-cert server_cert "wolfSSL Server Chain" 3650
247
248echo "Create RSA Client Certificate signed by intermediate2"
249create_cert wolfssl_int2 wolfssl_int2 ./certs/client-key.pem client-int-cert usr_cert "wolfSSL Client Chain" 3650
250
251echo "Generate CRLs for new certificates"
252openssl ca -config ./certs/intermediate/wolfssl_root.cnf -gencrl -crldays 1000 -out ./certs/crl/ca-int.pem -keyfile ./certs/intermediate/ca-int-key.pem -cert ./certs/intermediate/ca-int-cert.pem
253check_result $?
254openssl ca -config ./certs/intermediate/wolfssl_int.cnf  -gencrl -crldays 1000 -out ./certs/crl/ca-int2.pem -keyfile ./certs/intermediate/ca-int2-key.pem -cert ./certs/intermediate/ca-int2-cert.pem
255check_result $?
256openssl ca -config ./certs/intermediate/wolfssl_int2.cnf -gencrl -crldays 1000 -out ./certs/crl/server-int.pem -keyfile ./certs/server-key.pem -cert ./certs/intermediate/server-int-cert.pem
257check_result $?
258openssl ca -config ./certs/intermediate/wolfssl_int2.cnf -gencrl -crldays 1000 -out ./certs/crl/client-int.pem -keyfile ./certs/client-key.pem -cert ./certs/intermediate/client-int-cert.pem
259check_result $?
260
261echo "Assemble test chains - peer first, then intermediate2, then intermediate"
262openssl x509 -in ./certs/intermediate/server-int-cert.pem  > ./certs/intermediate/server-chain.pem
263openssl x509 -in ./certs/intermediate/ca-int2-cert.pem    >> ./certs/intermediate/server-chain.pem
264openssl x509 -in ./certs/intermediate/ca-int-cert.pem     >> ./certs/intermediate/server-chain.pem
265cat ./certs/intermediate/server-int-cert.der ./certs/intermediate/ca-int2-cert.der ./certs/intermediate/ca-int-cert.der > ./certs/intermediate/server-chain.der
266
267openssl x509 -in ./certs/intermediate/client-int-cert.pem  > ./certs/intermediate/client-chain.pem
268openssl x509 -in ./certs/intermediate/ca-int2-cert.pem    >> ./certs/intermediate/client-chain.pem
269openssl x509 -in ./certs/intermediate/ca-int-cert.pem     >> ./certs/intermediate/client-chain.pem
270cat ./certs/intermediate/client-int-cert.der ./certs/intermediate/ca-int2-cert.der ./certs/intermediate/ca-int-cert.der > ./certs/intermediate/client-chain.der
271
272echo "Assemble cert chain with extra cert for testing alternate chains"
273cp ./certs/intermediate/server-chain.pem ./certs/intermediate/server-chain-alt.pem
274cp ./certs/intermediate/client-chain.pem ./certs/intermediate/client-chain-alt.pem
275openssl x509 -in ./certs/external/ca-google-root.pem      >> ./certs/intermediate/server-chain-alt.pem
276openssl x509 -in ./certs/external/ca-google-root.pem      >> ./certs/intermediate/client-chain-alt.pem
277
278
279# ECC
280echo "Creating ECC CA configuration cnf files"
281create_ca_config ./certs/intermediate/wolfssl_root_ecc.cnf certs/ca-ecc-key.pem certs/ca-ecc-cert.pem
282create_ca_config ./certs/intermediate/wolfssl_int_ecc.cnf certs/intermediate/ca-int-ecc-key.pem certs/intermediate/ca-int-ecc-cert.pem
283create_ca_config ./certs/intermediate/wolfssl_int2_ecc.cnf certs/intermediate/ca-int2-ecc-key.pem certs/intermediate/ca-int2-ecc-cert.pem
284
285if [ ! -f ./certs/intermediate/ca-int-ecc-key.pem ]; then
286    echo "Make Intermediate ECC CA Key"
287    openssl ecparam -name prime256v1 -genkey -noout -out ./certs/intermediate/ca-int-ecc-key.pem
288    check_result $?
289    openssl ec -in ./certs/intermediate/ca-int-ecc-key.pem -inform PEM -out ./certs/intermediate/ca-int-ecc-key.der -outform DER
290    check_result $?
291fi
292if [ ! -f ./certs/intermediate/ca-int2-ecc-key.pem ]; then
293    echo "Make Intermediate2 ECC CA Key"
294    openssl ecparam -name prime256v1 -genkey -noout -out ./certs/intermediate/ca-int2-ecc-key.pem
295    check_result $?
296    openssl ec -in ./certs/intermediate/ca-int2-ecc-key.pem -inform PEM -out ./certs/intermediate/ca-int2-ecc-key.der -outform DER
297    check_result $?
298fi
299
300echo "Create ECC Intermediate CA signed by root"
301create_cert wolfssl_int_ecc wolfssl_root_ecc ./certs/intermediate/ca-int-ecc-key.pem ca-int-ecc-cert v3_intermediate_ca "wolfSSL Intermediate CA ECC" 7300
302
303echo "Create ECC Intermediate2 CA signed by Intermediate"
304create_cert wolfssl_int2_ecc wolfssl_int_ecc ./certs/intermediate/ca-int2-ecc-key.pem ca-int2-ecc-cert v3_intermediate2_ca "wolfSSL Intermediate2 CA ECC" 7300
305
306echo "Create ECC Server Certificate signed by intermediate2"
307create_cert wolfssl_int2_ecc wolfssl_int2_ecc ./certs/ecc-key.pem server-int-ecc-cert server_cert "wolfSSL Server Chain ECC" 3650
308
309echo "Create ECC Client Certificate signed by intermediate2"
310create_cert wolfssl_int2_ecc wolfssl_int2_ecc ./certs/ecc-client-key.pem client-int-ecc-cert usr_cert "wolfSSL Client Chain ECC" 3650
311
312echo "Generate CRLs for new certificates"
313openssl ca -config ./certs/intermediate/wolfssl_root_ecc.cnf -gencrl -crldays 1000 -out ./certs/crl/ca-int-ecc.pem -keyfile ./certs/intermediate/ca-int-ecc-key.pem -cert ./certs/intermediate/ca-int-ecc-cert.pem
314check_result $?
315openssl ca -config ./certs/intermediate/wolfssl_int_ecc.cnf -gencrl -crldays 1000 -out ./certs/crl/ca-int2-ecc.pem -keyfile ./certs/intermediate/ca-int2-ecc-key.pem -cert ./certs/intermediate/ca-int2-ecc-cert.pem
316check_result $?
317openssl ca -config ./certs/intermediate/wolfssl_int2_ecc.cnf -gencrl -crldays 1000 -out ./certs/crl/server-int-ecc.pem -keyfile ./certs/ecc-key.pem -cert ./certs/intermediate/server-int-ecc-cert.pem
318check_result $?
319openssl ca -config ./certs/intermediate/wolfssl_int2_ecc.cnf -gencrl -crldays 1000 -out ./certs/crl/client-int-ecc.pem -keyfile ./certs/ecc-client-key.pem -cert ./certs/intermediate/client-int-ecc-cert.pem
320check_result $?
321
322echo "Assemble test chains - peer first, then intermediate2, then intermediate"
323openssl x509 -in ./certs/intermediate/server-int-ecc-cert.pem  > ./certs/intermediate/server-chain-ecc.pem
324openssl x509 -in ./certs/intermediate/ca-int2-ecc-cert.pem    >> ./certs/intermediate/server-chain-ecc.pem
325openssl x509 -in ./certs/intermediate/ca-int-ecc-cert.pem     >> ./certs/intermediate/server-chain-ecc.pem
326cat ./certs/intermediate/server-int-ecc-cert.der ./certs/intermediate/ca-int2-ecc-cert.der ./certs/intermediate/ca-int-ecc-cert.der > ./certs/intermediate/server-chain-ecc.der
327
328openssl x509 -in ./certs/intermediate/client-int-ecc-cert.pem  > ./certs/intermediate/client-chain-ecc.pem
329openssl x509 -in ./certs/intermediate/ca-int2-ecc-cert.pem    >> ./certs/intermediate/client-chain-ecc.pem
330openssl x509 -in ./certs/intermediate/ca-int-ecc-cert.pem     >> ./certs/intermediate/client-chain-ecc.pem
331cat ./certs/intermediate/client-int-ecc-cert.der ./certs/intermediate/ca-int2-ecc-cert.der ./certs/intermediate/ca-int-ecc-cert.der > ./certs/intermediate/client-chain-ecc.der
332
333echo "Assemble cert chain with extra untrusted cert for testing alternate chains"
334cp ./certs/intermediate/server-chain-ecc.pem ./certs/intermediate/server-chain-alt-ecc.pem
335cp ./certs/intermediate/client-chain-ecc.pem ./certs/intermediate/client-chain-alt-ecc.pem
336openssl x509 -in ./certs/external/ca-google-root.pem          >> ./certs/intermediate/server-chain-alt-ecc.pem
337openssl x509 -in ./certs/external/ca-google-root.pem          >> ./certs/intermediate/client-chain-alt-ecc.pem
338