forked from cgzones/easy-ca
-
Notifications
You must be signed in to change notification settings - Fork 11
/
create-server
executable file
·207 lines (170 loc) · 6.36 KB
/
create-server
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
#!/usr/bin/env bash
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# Derek Moore <derek.moore@gmail.com>
# Christian Göttsche <cgzones@googlemail.com>
set -eu
set -o pipefail
umask 0077
BIN_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source "${BIN_DIR}/functions"
source "${BIN_DIR}/defaults.conf"
usage() {
echo "Usage: $0 -s SHORT_NAME -a ALT_NAME [-a ALT_NAME2]... [-i ALT_IP1]..."
echo "Issues a server certificate for SHORT_NAME"
echo
echo "Options:"
echo " -s SHORT_NAME Server hostname (commonName) for the new cert"
echo " -a ALT_NAME One (or more) subjectAltNames for the new cert"
echo " -i ALT_IP One (or more) IP addresses as SANs for the new cert"
echo
}
if [ ! -f ca/ca.crt ]; then
echo -e "$ERR Must be run inside a CA directory!"
exit 2
fi
SERVER_NAME=
ALT_NAME=
while getopts s:a:i:h FLAG; do
case $FLAG in
h) echo -e -n "$SUCC " && usage && exit 0
;;
s) SERVER_NAME="${OPTARG}"
;;
a) if [ -z "${ALT_NAME}" ]; then
ALT_NAME="DNS:${OPTARG}"
else
ALT_NAME="${ALT_NAME}, DNS:${OPTARG}"
fi
;;
i) if [ -z "${ALT_NAME}" ]; then
ALT_NAME="IP:${OPTARG}"
else
ALT_NAME="${ALT_NAME}, IP:${OPTARG}"
fi
;;
*) echo -e -n "$ERR " && usage && exit 2
;;
esac
done
if [ $OPTIND -le $# ]; then
echo -e -n "$ERR " && usage && exit 2
elif [ "$SERVER_NAME" = "" ]; then
echo -e -n "$ERR " && usage && exit 2
elif [ "$ALT_NAME" = "" ]; then
echo -e -n "$ERR " && usage && exit 2
fi
# Sanitize the commonName to make it suitable for use in filenames
SAFE_NAME=$(echo "$SERVER_NAME" | sed 's/\*/star/g' | sed 's/[^A-Za-z0-9-]/-/g')
echo -e "$NOTE Creating new SSL server certificate for:" >&2
echo -e "$NOTE commonName $SERVER_NAME" >&2
echo -e "$NOTE subjectAltName $ALT_NAME" >&2
pushd "$BIN_DIR/.." > /dev/null
if [ -d "certs/server/$SAFE_NAME" ]; then
echo -e "$ERR Configuration already exists for '$SERVER_NAME', exiting." >&2
exit 1
fi
echo
if [ -n "$CA_ENABLE_ENGINE" ]; then
echo -e "$NOTE Your CA key is on PKCS11 device, enter PIN." >&2
fi
PASS=`ask -s "$INPUT Enter passphrase for signing CA key: " CA_SIGN_PASS_DEFAULT "${SIGN_PASS:-""}"`
echo >&2
export CA_PASS="${PASS}"
openssl_engine_cmd='
-engine pkcs11
-inform engine
-in pkcs11:object=SIGN%20key'
openssl rsa \
${CA_ENABLE_ENGINE:+$openssl_engine_cmd} \
$( [ -z $CA_ENABLE_ENGINE ] && echo "-check -in ca/private/ca.key") \
-noout \
-passin env:CA_PASS
trap 'rm -Rf "certs/server/$SAFE_NAME"' 0
mkdir -p "certs/server/$SAFE_NAME/ssh"
# Generate the server openssl config
export CA_HOSTNAME="${SERVER_NAME}"
export SAN="${ALT_NAME}"
ask_server_cert_questions
template "${BIN_DIR}/templates/server.tpl" "certs/server/$SAFE_NAME/$SAFE_NAME.conf"
echo -e "$NOTE Usually a server key will not be on a pkcs11 device." >&2
SURE=`ask "$INPUT Create csr on pkcs11 device? (key must be in \"PIV AUTH key\" or 9a) [y/N]: " CA_USE_PKCS11 "N"`
if [ "${SURE}" != "y" ] && [ "${SURE}" != "Y" ]; then
ENABLE_ENGINE=
else
ENABLE_ENGINE=1
init_slot 9a "certs/server/$SAFE_NAME/$SAFE_NAME.pub" "pkcs11:object=PIV%20AUTH%20key"
fi
echo -e "$NOTE Creating the server key and csr" >&2
# Create the sever key and csr
openssl_engine_cmd='
-engine pkcs11
-keyform engine
-key pkcs11:object=PIV%20AUTH%20key'
openssl req -new -batch \
${ENABLE_ENGINE:+$openssl_engine_cmd} \
-config "certs/server/$SAFE_NAME/$SAFE_NAME.conf" \
-out "certs/server/$SAFE_NAME/$SAFE_NAME.csr" \
$( [ -z $ENABLE_ENGINE ] && echo "
-nodes
-keyout certs/server/$SAFE_NAME/$SAFE_NAME.key")
openssl_engine_cmd='
-engine pkcs11
-inform engine
-in pkcs11:object=PIV%20AUTH%20key'
openssl rsa \
${ENABLE_ENGINE:+$openssl_engine_cmd} \
$( [ -z $ENABLE_ENGINE ] && echo "-check -in certs/server/$SAFE_NAME/$SAFE_NAME.key") \
-noout
echo -e "$NOTE Example known_hosts: @cert-authority *.example.com ca.ssh-cert.pub" >&2
echo -e "$NOTE Example sshd_config: HostCertificate $SAFE_NAME.ssh-cert.pub" >&2
echo -e "$NOTE Example sshd_config: TrustedUserCAKeys ca.ssh.pub" >&2
echo -e "$NOTE Example sshd_config: RevokedKeys revoked-keys" >&2
if [ -z "$ENABLE_ENGINE" ]; then
chmod 0400 "certs/server/$SAFE_NAME/$SAFE_NAME.key"
ln -s ../"$SAFE_NAME".key "certs/server/$SAFE_NAME/ssh/$SAFE_NAME.ssh"
openssl rsa -in "certs/server/$SAFE_NAME/$SAFE_NAME.key" \
-pubout -out "certs/server/$SAFE_NAME/$SAFE_NAME.pub"
fi
ssh-keygen -f "certs/server/$SAFE_NAME/$SAFE_NAME.pub" -i -mPKCS8 \
| awk "{printf \$0;print \" ${SAFE_NAME}\"}" > "certs/server/$SAFE_NAME/ssh/$SAFE_NAME.ssh.pub"
echo -e "$NOTE Creating the server certificate" >&2
# Create the server certificate
openssl_engine_cmd="\
-engine pkcs11 \
-keyform engine \
-keyfile pkcs11:object=SIGN%20key"
openssl ca -batch -notext \
${CA_ENABLE_ENGINE:+$openssl_engine_cmd} \
-config ca/ca.conf \
-in "certs/server/$SAFE_NAME/$SAFE_NAME.csr" \
-out "certs/server/$SAFE_NAME/$SAFE_NAME.crt" \
-extensions server_ext \
-passin env:CA_PASS
if [[ -n "$ENABLE_ENGINE" ]]; then
replace_crt 9a certs/server/"$SAFE_NAME"/"$SAFE_NAME".crt
fi
echo -e "$NOTE Verifying certificate/key pair" >&2
openssl_engine_cmd="\
-engine pkcs11 \
-inform engine \
-in pkcs11:object=PIV%20AUTH%20key"
key_mod=$(openssl rsa \
${ENABLE_ENGINE:+$openssl_engine_cmd} -noout -modulus \
$( [ -z $ENABLE_ENGINE ] && echo "-in certs/server/$SAFE_NAME/$SAFE_NAME.key")
)
cert_mod=$(openssl x509 -noout -modulus -in "certs/server/$SAFE_NAME/$SAFE_NAME.crt")
if [ ! "$key_mod" = "$cert_mod" ];then
echo -e "$ERR Certificate/Key pair invalid:"
echo -e "$ERR <>$cert_mod<>"
echo -e "$ERR <>$key_mod<>"
echo
exit 2
fi
echo -e "$NOTE Verifying trusted chain"
openssl verify -CAfile ca/chain.pem "certs/server/$SAFE_NAME/$SAFE_NAME.crt"
popd > /dev/null
unset CA_PASS
trap 0
echo -e "$SUCC Server certificate for '${SERVER_NAME}' created."