-
Notifications
You must be signed in to change notification settings - Fork 31
/
pem_create.sh
executable file
·243 lines (190 loc) · 7.42 KB
/
pem_create.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
#!/usr/bin/env bash
# Script to create the test keys used pem_test.cxx
##################################
# prerequisites
CXX="${CXX:-c++}"
MAKEJOBS="${MAKEJOBS:-2}"
if ! command -v "${CXX}" 2>/dev/null; then
echo "Please install a compiler like g++"
exit 1
fi
if ! command -v openssl 2>/dev/null; then
echo "Please install openssl package"
exit 1
fi
if ! command -v curl 2>/dev/null; then
echo "Please install curl package"
exit 1
fi
if ! command -v perl 2>/dev/null; then
echo "Please install perl package"
exit 1
fi
# We need OpenSSL 1.0.2 or above
OPENSSL_102_OR_ABOVE=$(openssl version | grep -c -v -E '(OpenSSL 0.[0-9]|OpenSSL 1.0.0|OpenSSL 1.0.1)')
if [[ "${OPENSSL_102_OR_ABOVE}" -eq 0 ]]; then
echo "Please install OpenSSL 1.0.2 or above"
exit 1
fi
# We need -traditional option for OpenSSL 3.0 or above for private keys
OPENSSL_30_OR_ABOVE=$(openssl version | grep -c -v -E '(OpenSSL 0.[0-9]|OpenSSL 1.[0-9]|OpenSSL 2.[0-9])')
if [[ "${OPENSSL_30_OR_ABOVE}" -ne 0 ]]; then
echo "Using OpenSSL -traditional option"
OPENSSL_TRADITIONAL="-traditional"
fi
##################################
# test program
echo "Compiling test program with ${CXX}"
rm -rf pem_test.exe pem_eol.exe
CXXFLAGS="-DDEBUG -g3 -O0 -Wall"
# Build crypto++ library if out of date.
if ! CXX="${CXX}" CXXFLAGS="${CXXFLAGS}" make -j ${MAKEJOBS}; then
echo "Failed to build libcryptopp.a"
exit 1
fi
# Build the test program
if ! ${CXX} ${CXXFLAGS} pem_test.cxx ./libcryptopp.a -o pem_test.exe; then
echo "Failed to build pem_test.exe"
exit 1
fi
# Build the RFC1421 EOL converter. OpenSSL no longer outputs well formed PEM.
if ! ${CXX} ${CXXFLAGS} pem_eol.cxx -o pem_eol.exe; then
echo "Failed to build pem_test.exe"
exit 1
fi
# Build the reproducer program in case test program crashes
# The reproducer loads badcert.der.
if [[ -e badcert.cxx ]]; then
if ! ${CXX} ${CXXFLAGS} badcert.cxx ./libcryptopp.a -o badcert.exe; then
echo "Failed to build badcert.exe"
exit 1
fi
fi
##################################
# test keys
echo "Generating OpenSSL keys"
# RSA private key, public key, and encrypted private key
openssl genrsa -out rsa-priv.pem 2048
openssl rsa -in rsa-priv.pem -out rsa-pub.pem ${OPENSSL_TRADITIONAL} -pubout
openssl rsa -in rsa-priv.pem -out rsa-enc-priv.pem ${OPENSSL_TRADITIONAL} -aes128 -passout pass:abcdefghijklmnopqrstuvwxyz
# Fix the private key, if needed
if [[ -n "${OPENSSL_TRADITIONAL}" ]]; then
openssl rsa -in rsa-priv.pem -inform PEM -out rsa-priv.pem.fixed -outform PEM ${OPENSSL_TRADITIONAL}
mv rsa-priv.pem.fixed rsa-priv.pem
fi
# DSA private key, public key, and encrypted private key
openssl dsaparam -out dsa-params.pem 2048
openssl gendsa -out dsa-priv.pem dsa-params.pem
openssl dsa -in dsa-priv.pem -out dsa-pub.pem -pubout
openssl dsa -in dsa-priv.pem -out dsa-enc-priv.pem ${OPENSSL_TRADITIONAL} -aes128 -passout pass:abcdefghijklmnopqrstuvwxyz
# Fix the private key, if needed
if [[ -n "${OPENSSL_TRADITIONAL}" ]]; then
openssl dsa -in dsa-priv.pem -inform PEM -out dsa-priv.pem.fixed -outform PEM
mv dsa-priv.pem.fixed dsa-priv.pem
fi
# EC private key, public key, and encrypted private key
openssl ecparam -out ec-params.pem -name secp256k1 -genkey
openssl ec -in ec-params.pem -out ec-priv.pem
openssl ec -in ec-priv.pem -out ec-pub.pem -pubout
openssl ec -in ec-priv.pem -out ec-enc-priv.pem ${OPENSSL_TRADITIONAL} -aes128 -passout pass:abcdefghijklmnopqrstuvwxyz
# Fix the private key, if needed
if [[ -n "${OPENSSL_TRADITIONAL}" ]]; then
openssl ec -in ec-priv.pem -inform PEM -out ec-priv.pem.fixed -outform PEM
mv ec-priv.pem.fixed ec-priv.pem
fi
# Diffie-Hellman parameters
openssl dhparam -out dh-params.pem 2048
# Make line endings CRLF per RFC 1421. OpenSSL no longer outputs well formed PEM.
./pem_eol.exe rsa-priv.pem rsa-pub.pem rsa-enc-priv.pem
./pem_eol.exe dsa-params.pem dsa-priv.pem dsa-pub.pem dsa-enc-priv.pem
./pem_eol.exe ec-params.pem ec-priv.pem ec-pub.pem ec-enc-priv.pem
./pem_eol.exe dh-params.pem
##################################
# malformed
# Only the '-----BEGIN PUBLIC KEY-----'
echo "-----BEGIN PUBLIC KEY-----" > rsa-short.pem
# Remove the last CRLF
perl -pe 'chop' < rsa-pub.pem | perl -pe 'chop' > rsa-trunc-1.pem
# Remove the last dash from encapsulation boundary (should throw)
perl -pe 'chop' < rsa-trunc-1.pem > rsa-trunc-2.pem
# Two keys in one file; missing CRLF between them
cat rsa-trunc-1.pem > rsa-concat.pem
cat rsa-pub.pem >> rsa-concat.pem
# Uses only CR (remove LF)
perl -pe 's/\n//g;' rsa-pub.pem > rsa-eol-cr.pem
# Uses only LF (remove CR)
perl -pe 's/\r//g;' rsa-pub.pem > rsa-eol-lf.pem
# No EOL (remove CR and LF)
perl -pe 's/\r//g;' -pe 's/\n//g;' rsa-pub.pem > rsa-eol-none.pem
echo "-----BEGIN FOO-----" > foobar.pem
head -c 180 /dev/urandom | base64 | fold -w 64 >> foobar.pem
echo "-----END BAR-----" >> foobar.pem
##################################
# Test Certificate
cat << EOF > ./example-com.conf
[ req ]
prompt = no
default_bits = 2048
default_keyfile = server-key.pem
distinguished_name = subject
req_extensions = req_ext
x509_extensions = x509_ext
string_mask = utf8only
# CA/B requires a domain name in the Common Name
[ subject ]
countryName = US
stateOrProvinceName = NY
localityName = New York
organizationName = Example, LLC
commonName = Example Company
emailAddress = [email protected]
# A real server cert usually does not need clientAuth or secureShellServer
[ x509_ext ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
basicConstraints = critical,CA:FALSE
keyUsage = digitalSignature
extendedKeyUsage = serverAuth, clientAuth
subjectAltName = @alternate_names
nsComment = "OpenSSL Generated Certificate"
# A real server cert usually does not need clientAuth or secureShellServer
[ req_ext ]
subjectKeyIdentifier = hash
basicConstraints = critical,CA:FALSE
keyUsage = digitalSignature
extendedKeyUsage = serverAuth, clientAuth
subjectAltName = @alternate_names
nsComment = "OpenSSL Generated Certificate"
# A real server cert should not have email addresses
# The CA/B BR forbids IP addresses
[ alternate_names ]
DNS.1 = example.com
DNS.2 = www.example.com
DNS.3 = mail.example.com
DNS.4 = ftp.example.com
IP.1 = 127.0.0.1
IP.2 = ::1
email.1 = [email protected]
email.2 = [email protected]
email.3 = [email protected]
EOF
# And create the cert
openssl req -config example-com.conf -new -x509 -sha256 -newkey rsa:2048 -nodes \
-keyout example-com.key.pem -days 365 -out example-com.cert.pem
# Convert to ASN.1/DER
openssl x509 -in example-com.cert.pem -inform PEM -out example-com.cert.der -outform DER
# View PEM cert with 'openssl x509 -in example-com.cert.pem -inform PEM -text -noout'
# View DER cert with 'dumpasn1 example-com.cert.der'
##################################
# Mozilla cacert.pem
if [ ! -e "cacert.pem" ]; then
curl -L -s -o cacert.pem https://curl.se/ca/cacert.pem
fi
##################################
# Google roots.pem
if [ ! -e "roots.pem" ]; then
curl -L -s -o roots.pem https://pki.goog/roots.pem
fi
##################################
# Crypto++ website
echo -e "GET / HTTP/1.1\r\nHost: www.cryptopp.com\r\n\r\n" | openssl s_client -showcerts -servername www.cryptopp.com -connect www.cryptopp.com:443 2>/dev/null | openssl x509 > www-cryptopp-com.cert.pem