1#!/bin/sh
2# Helper script to create CA and server certificates.
3
4srcdir=${1-.}
5
6OPENSSL=@OPENSSL@
7CONF=${srcdir}/openssl.conf
8REQ="${OPENSSL} req -config ${CONF}"
9CA="${OPENSSL} ca -config ${CONF} -batch"
10# MKCERT makes a self-signed cert
11MKCERT="${REQ} -x509 -new -days 900"
12
13REQDN=reqDN
14STRMASK=default
15CADIR=./ca
16export REQDN STRMASK CADIR
17
18asn1date() {
19	date -d "$1" "+%y%m%d%H%M%SZ"
20}
21
22openssl version 1>&2
23
24set -ex
25
26for i in ca ca1 ca2 ca3; do
27    rm -rf $i
28    mkdir $i
29    touch $i/index.txt
30    echo 01 > $i/serial
31    ${OPENSSL} genrsa -rand ${srcdir}/../configure > $i/key.pem
32done
33
34${OPENSSL} genrsa -rand ${srcdir}/../configure > client.key
35
36${OPENSSL} dsaparam -genkey -rand ${srcdir}/../configure 1024 > client.dsap
37${OPENSSL} gendsa client.dsap > clientdsa.key
38
39${MKCERT} -key ca/key.pem -out ca/cert.pem <<EOF
40US
41California
42Oakland
43Neosign
44Random Dept
45nowhere.example.com
46neon@webdav.org
47EOF
48
49# Function to generate appropriate output for `openssl req'.
50csr_fields() {
51CN=${2-"localhost"}
52OU=${1-"Neon QA Dept"}
53Org=${3-"Neon Hackers Ltd"}
54Locality=${4-"Cambridge"}
55State=${5-"Cambridgeshire"}
56cat <<EOF
57GB
58${State}
59${Locality}
60${Org}
61${OU}
62${CN}
63neon@webdav.org
64.
65.
66EOF
67}
68
69# Create intermediary CA
70csr_fields IntermediaryCA | ${REQ} -new -key ca2/key.pem -out ca2.csr
71${CA} -extensions caExt -days 3560 -in ca2.csr -out ca2/cert.pem
72
73csr_fields ExpiredCA | ${REQ} -new -key ca1/key.pem -out ca1/cert.csr
74
75csr_fields NotYetValidCA | ${REQ} -new -key ca3/key.pem -out ca3/cert.csr
76
77CADIR=./ca1 ${CA} -name neoncainit -extensions caExt -startdate `asn1date "2 days ago"` -enddate `asn1date "yesterday"` \
78  -in ca1/cert.csr -keyfile ca1/key.pem -out ca1/cert.pem -selfsign
79
80CADIR=./ca3 ${CA} -name neoncainit -extensions caExt -startdate `asn1date "1 year"` -enddate `asn1date "2 years"` \
81  -in ca3/cert.csr -keyfile ca3/key.pem -out ca3/cert.pem -selfsign
82
83csr_fields | ${REQ} -new -key ${srcdir}/server.key -out server.csr
84
85csr_fields | ${REQ} -new -key ${srcdir}/server.key -out expired.csr
86csr_fields | ${REQ} -new -key ${srcdir}/server.key -out notyet.csr
87
88csr_fields "Upper Case Dept" lOcALhost | \
89${REQ} -new -key ${srcdir}/server.key -out caseless.csr
90
91csr_fields "Use AltName Dept" nowhere.example.com | \
92${REQ} -new -key ${srcdir}/server.key -out altname1.csr
93
94csr_fields "Two AltName Dept" nowhere.example.com | \
95${REQ} -new -key ${srcdir}/server.key -out altname2.csr
96
97csr_fields "Third AltName Dept" nowhere.example.com | \
98${REQ} -new -key ${srcdir}/server.key -out altname3.csr
99
100csr_fields "Fourth AltName Dept" localhost | \
101${REQ} -new -key ${srcdir}/server.key -out altname4.csr
102
103csr_fields "Good ipAddress altname Dept" nowhere.example.com | \
104${REQ} -new -key ${srcdir}/server.key -out altname5.csr
105
106csr_fields "Bad ipAddress altname 1 Dept" nowhere.example.com | \
107${REQ} -new -key ${srcdir}/server.key -out altname6.csr
108
109csr_fields "Bad ipAddress altname 2 Dept" nowhere.example.com | \
110${REQ} -new -key ${srcdir}/server.key -out altname7.csr
111
112csr_fields "Bad ipAddress altname 3 Dept" nowhere.example.com | \
113${REQ} -new -key ${srcdir}/server.key -out altname8.csr
114
115csr_fields "Wildcard Altname Dept 1" | \
116${REQ} -new -key ${srcdir}/server.key -out altname9.csr
117
118csr_fields "Bad Hostname Department" nohost.example.com | \
119${REQ} -new -key ${srcdir}/server.key -out wrongcn.csr
120
121csr_fields "Self-Signed" | \
122${MKCERT} -key ${srcdir}/server.key -out ssigned.pem
123
124# default => T61String
125csr_fields "`echo -e 'H\0350llo World'`" localhost |
126${REQ} -new -key ${srcdir}/server.key -out t61subj.csr
127
128STRMASK=pkix # => BMPString
129csr_fields "`echo -e 'H\0350llo World'`" localhost |
130${REQ} -new -key ${srcdir}/server.key -out bmpsubj.csr
131
132STRMASK=utf8only # => UTF8String
133csr_fields "`echo -e 'H\0350llo World'`" localhost |
134${REQ} -new -key ${srcdir}/server.key -out utf8subj.csr
135
136STRMASK=default
137
138### produce a set of CA certs
139
140csr_fields "First Random CA" "first.example.com" "CAs Ltd." Lincoln Lincolnshire | \
141${MKCERT} -key ${srcdir}/server.key -out ca1.pem
142
143csr_fields "Second Random CA" "second.example.com" "CAs Ltd." Falmouth Cornwall | \
144${MKCERT} -key ${srcdir}/server.key -out ca2.pem
145
146csr_fields "Third Random CA" "third.example.com" "CAs Ltd." Ipswich Suffolk | \
147${MKCERT} -key ${srcdir}/server.key -out ca3.pem
148
149csr_fields "Fourth Random CA" "fourth.example.com" "CAs Ltd." Norwich Norfolk | \
150${MKCERT} -key ${srcdir}/server.key -out ca4.pem
151
152cat ca/cert.pem ca[1234].pem > calist.pem
153
154csr_fields "Wildcard Cert Dept" "*.example.com" | \
155${REQ} -new -key ${srcdir}/server.key -out wildcard.csr
156
157csr_fields "Wildcard IP Cert" "*.0.0.1" | \
158${REQ} -new -key ${srcdir}/server.key -out wildip.csr
159
160csr_fields "Neon Client Cert" ignored.example.com | \
161${REQ} -new -key client.key -out client.csr
162
163csr_fields "Neon Client Cert" ignored.example.com | \
164${REQ} -new -key clientdsa.key -out clientdsa.csr
165
166### requests using special DN.
167
168REQDN=reqDN.doubleCN
169csr_fields "Double CN Dept" "nohost.example.com
170localhost" | ${REQ} -new -key ${srcdir}/server.key -out twocn.csr
171
172REQDN=reqDN.CNfirst
173echo localhost | ${REQ} -new -key ${srcdir}/server.key -out cnfirst.csr
174
175REQDN=reqDN.missingCN
176echo GB | ${REQ} -new -key ${srcdir}/server.key -out missingcn.csr
177
178REQDN=reqDN.justEmail
179echo blah@example.com | ${REQ} -new -key ${srcdir}/server.key -out justmail.csr
180
181# presume AVAs will come out in least->most specific order still...
182REQDN=reqDN.twoOU
183csr_fields "Second OU Dept
184First OU Dept" | ${REQ} -new -key ${srcdir}/server.key -out twoou.csr
185
186### don't put ${REQ} invocations after here
187
188for f in server client clientdsa twocn caseless cnfirst \
189    t61subj bmpsubj utf8subj \
190    missingcn justmail twoou wildcard wildip wrongcn; do
191  ${CA} -days 900 -in ${f}.csr -out ${f}.cert
192done
193
194${CA} -startdate `asn1date "2 days ago"` -enddate `asn1date "yesterday"` -in expired.csr -out expired.cert
195
196${CA} -startdate `asn1date "tomorrow"` -enddate `asn1date "2 days"` -in notyet.csr -out notyet.cert
197
198for n in 1 2 3 4 5 6 7 8 9; do
199 ${CA} -extensions altExt${n} -days 900 \
200     -in altname${n}.csr -out altname${n}.cert
201done
202
203# Sign this CSR using the intermediary CA
204CADIR=./ca2 ${CA} -days 900 -in server.csr -out ca2server.cert
205# And create a file with the concatenation of both EE and intermediary
206# cert.
207cat ca2server.cert ca2/cert.pem > ca2server.pem
208 
209# sign with expired CA
210CADIR=./ca1 ${CA} -days 3 -in server.csr -out ca1server.cert
211
212# sign with not yet valid CA
213CADIR=./ca3 ${CA} -days 3 -in server.csr -out ca3server.cert
214
215MKPKCS12="${OPENSSL} pkcs12 -export -passout stdin -in client.cert -inkey client.key"
216
217# generate a PKCS12 cert from the client cert: -passOUT because it's the
218# passphrase on the OUTPUT cert, confusing...
219echo foobar | ${MKPKCS12} -name "Just A Neon Client Cert" -out client.p12
220
221# generate a PKCS#12 cert with no password and a friendly name
222echo | ${MKPKCS12} -name "An Unencrypted Neon Client Cert" -out unclient.p12
223
224# PKCS#12 cert with DSA key
225echo | ${OPENSSL} pkcs12 -name "An Unencrypted Neon DSA Client Cert" \
226    -export -passout stdin \
227    -in clientdsa.cert -inkey clientdsa.key \
228    -out dsaclient.p12
229
230# generate a PKCS#12 cert with no friendly name
231echo | ${MKPKCS12} -out noclient.p12
232
233# generate a PKCS#12 cert with no private keys
234echo | ${MKPKCS12} -nokeys -out nkclient.p12
235
236# generate a PKCS#12 cert without the cert
237echo | ${MKPKCS12} -nokeys -out ncclient.p12
238
239# generate an encoded PKCS#12 cert with no private keys
240echo foobar | ${MKPKCS12} -nokeys -out enkclient.p12
241
242# a PKCS#12 cert including a bundled CA cert
243echo foobar | ${MKPKCS12} -certfile ca/cert.pem -name "A Neon Client Cert With CA" -out clientca.p12
244
245### a file containing a complete chain
246
247cat ca/cert.pem server.cert > chain.pem
248
249### NSS database initialization, for testing PKCS#11.
250CERTUTIL=@CERTUTIL@
251PK12UTIL=@PK12UTIL@
252
253if [ ${CERTUTIL} != "notfound" -a ${PK12UTIL} != "notfound" ]; then
254  rm -rf nssdb nssdb-dsa
255  mkdir nssdb nssdb-dsa
256
257  echo foobar > nssdb.pw
258
259  ${CERTUTIL} -d nssdb -N -f nssdb.pw
260  ${PK12UTIL} -d nssdb -K foobar -W '' -i unclient.p12
261
262  ${CERTUTIL} -d nssdb-dsa -N -f nssdb.pw
263  ${PK12UTIL} -d nssdb-dsa -K foobar -W '' -i dsaclient.p12
264
265  rm -f nssdb.pw
266fi
267