-
Notifications
You must be signed in to change notification settings - Fork 4
/
cfssl-ca.sh
executable file
·208 lines (167 loc) · 5.73 KB
/
cfssl-ca.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
#!/bin/bash
# Copyright 2015 ISRG. All rights reserved
# 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/.
set -o pipefail
SETTINGS=~/.cfssl-pkcs11-ca
if [ "$(uname)" == "Darwin" ] ; then
# OSX Settings: Use `brew install engine_pkcs11 opensc libp11`
SPYMODULE=/usr/local/Cellar/opensc/0.14.0_1/lib/pkcs11/pkcs11-spy.so
MODULE=/usr/local/Cellar/opensc/0.14.0_1/lib/pkcs11/opensc-pkcs11.so
fi
if [ "$(uname)" == "Linux" ] ; then
# Linux settings, at least for CentOS x64.
SPYMODULE=/usr/lib64/pkcs11/pkcs11-spy.so
MODULE=/usr/lib64/pkcs11/opensc-pkcs11.so
fi
die() {
printf "[!] Stopping.\n%s\n" "$@"
exit 1
}
join() {
local IFS="$1"
shift
echo "$*"
}
debug() {
echo "Enabling PKCS11 Spying"
[ -r "${SPYMODULE}" ] \
|| die "${SPYMODULE} does not exist; it comes from the OpenSC project."
# Let the PKCS11 Spy know where the real module is
export PKCS11SPY="${MODULE}"
# Override the module
MODULE="${SPYMODULE}"
}
install() {
echo "Reinstalling CFSSL tools"
go install -tags pkcs11 github.com/cloudflare/cfssl/cmd/cfssl \
|| die "Could not install"
go install -tags pkcs11 github.com/cloudflare/cfssl/cmd/cfssljson \
|| die "Could not install"
}
info() {
[ -x "$(which pkcs11-tool)" ] \
|| die "Couldn't find pkcs11-tool; you probably need to install it."
cat <<EOF
If things fail, you probably want to try 2-3 times before deciding a
configuration is bad; most consumer HSMs have lots of spurious failure with
the OpenSC library in particular.
EOF
cat <<EOF
********************************************************************************
Determining the SLOT field
********************************************************************************
You need to figure out the slot name that describes this HSM. It's going to
be to the right of the "Slot X (0xY):" part. In this example, it's the entire
string "PIV_II (PIV Card Holder pin)"
Available slots:
Slot 0 (0x1): Yubico Yubikey NEO OTP+CCID
token label : PIV_II (PIV Card Holder pin)
token manufacturer : piv_II
token model : PKCS#15 emulated
token flags : rng, login required, PIN initialized, token initialized
hardware version : 0.0
firmware version : 0.0
serial num : 00000000
********************************************************************************
</example>
********************************************************************************
EOF
pkcs11-tool --module "${MODULE}" --login --pin "${PIN}" --list-slots
cat <<EOF
********************************************************************************
Determining the LABEL field
********************************************************************************
You need to figure out the label for the thing labeled a Private Key Object.
It will look something like this:
Private Key Object; RSA
label: SIGN key
ID: 02
Usage: decrypt, sign, non-repudiation
Access: always authenticate
Public Key Object; RSA 2048 bits
label: SIGN pubkey
ID: 02
Usage: encrypt, verify
Certificate Object, type = X.509 cert
label: Certificate for Digital Signature
ID: 02
********************************************************************************
</example>
********************************************************************************
EOF
pkcs11-tool --module "${MODULE}" --login --pin "${PIN}" --list-objects
}
sign() {
CERT_ID=$(date +%s)
[ -r "${MODULE}" ] || die "Module not found at ${MODULE}"
[ -w "${CERTDIR}" ] || die "You need to make a certs directory at ${CERTDIR}"
[ -r "${CACERT}" ] || die "CA Cert not readable at ${CACERT}"
[ -x "$(which cfssl)" ] || die "Couldn't find cfssl - try $0 install"
[ -x "$(which cfssljson)" ] || die "Couldn't find cfssljson - try $0 install"
OUTFILE=$(mktemp /tmp/signtmpXXXXXX)
SAN_CSV=$(join , ${HOSTNAMES})
if [ -x $(which openssl) ] ; then
echo "CSR details:"
$(which openssl) req -in "${CSR}" -text | grep "Subject:"
$(which openssl) req -in "${CSR}" -text | grep "Subject Alternative" -A 1
fi
if [ "x${HOSTNAMES}" != "x" ] ; then
echo "Producing SAN for:"
for h in ${HOSTNAMES}; do
echo "* ${h}"
done
fi
echo "Profile in use: ${PROFILE}"
echo " "
echo "Sign? [y/N], or press ctrl-c to cancel"
read x
if [ "${x}" != "y" ] && [ "${x}" != "Y" ] ; then
exit 0
fi
cfssl sign -ca="${CACERT}" -pkcs11-module="${MODULE}" \
-pkcs11-label="${LABEL}" -pkcs11-token="${SLOT}" -pkcs11-pin="${PIN}" \
-config="${CONFIG}" -profile="${PROFILE}" -hostname="${SAN_CSV}" \
"${CSR}" > "${OUTFILE}" || die "Signing failure. Likely spurious. Maybe retry?" \
"$(cat ${OUTFILE})"
cfssljson -bare "${CERTDIR}/${CERT_ID}" < "${OUTFILE}" || die "Failed to save"
rm -f "${OUTFILE}"
if [ -x $(which openssl) ] ; then
$(which openssl) x509 -in "${CERTDIR}/${CERT_ID}.pem" -text
fi
echo "Produced: "
ls -la "${CERTDIR}/${CERT_ID}"*
}
help() {
cat <<EOF
$0 [-debug] {command} [CSR] {SAN Name 1..n}
Options:
-debug Enable PKCS11 Debugging with the OpenSC PKCS11 Spy
Commands:
sign Sign a CSR
install Install the CFSSL binaries
info Use PKCS11-Tool to help select the PKCS11 module options
help This message
EOF
}
[ -r "${SETTINGS}" ] || die "Could not load settings from ${SETTINGS}. Start from cfssl-pkcs11-ca.example."
source "${SETTINGS}"
if [ "$1" == "-debug" ] ; then
debug
shift
fi
if [ "$1" == "sign" ] ; then
shift
CSR="$1"
shift
HOSTNAMES="$@"
[ -r "${CSR}" ] || die "Cannot open CSR: ${CSR}"
sign
elif [ "$1" == "install" ] ; then
install
elif [ "$1" == "info" ] ; then
info
else
help
fi