forked from tomberek/easy-ca
-
Notifications
You must be signed in to change notification settings - Fork 0
/
create-codesign
193 lines (154 loc) · 5.55 KB
/
create-codesign
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
#!/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 <[email protected]>
# Christian Göttsche <[email protected]>
# Tom Bereknyei <[email protected]>
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 -c CERT_NAME"
echo "Issues a code signing certificate named CERT_NAME"
echo
echo "Options:"
echo " -c CERT_NAME Certificate name (commonName) for the new cert"
echo
}
if [ ! -f ca/ca.crt ]; then
echo -e "$ERR Must be run inside a CA directory!"
exit 2
fi
CERT_NAME=
while getopts c:h FLAG; do
case $FLAG in
c) CERT_NAME=${OPTARG} ;;
h) echo -e -n "$SUCC " && usage && exit 0 ;;
*) echo -e -n "$ERR " && usage && exit 2 ;;
esac
done
if [ $OPTIND -le $# ]; then
echo -e -n "$ERR " && usage && exit 2
elif [ "${CERT_NAME}" = "" ]; then
echo -e -n "$ERR " && usage && exit 1
fi
SAFE_NAME=$(echo "${CERT_NAME}" | sed 's/\*/star/g' | sed 's/[^A-Za-z0-9-]/-/g')
echo -e "$NOTE Creating new code signing certificate named '$CERT_NAME'" >&2
pushd "${BIN_DIR}/.." > /dev/null
if [ -d "certs/codesign/$SAFE_NAME" ]; then
echo -e "$ERR Configuration already exists for '$CERT_NAME' ($SAFE_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/codesign/$SAFE_NAME"' 0
mkdir -p "certs/codesign/$SAFE_NAME"
# Generate the code signing cert openssl config
export CA_USERNAME="${CERT_NAME}"
export CA_CERT_MAIL=""
ask_client_cert_questions
export SAN="email:$CA_CERT_MAIL"
template "${BIN_DIR}/templates/codesign.tpl" "certs/codesign/$SAFE_NAME/$SAFE_NAME.conf"
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
echo -e -n "$INPUT Enter PIN for PIV key: " >&2
read -r -s PASS
echo >&2
export PIV_PASS="${PASS}"
ENABLE_ENGINE=1
CA_PASS=$PIV_PASS init_slot 9a "certs/codesign/$SAFE_NAME/$SAFE_NAME.pub" "pkcs11:object=PIV%20AUTH%20key"
fi
echo -e "$NOTE Creating the code signing key and csr" >&2
# Create the code signing key and csr
openssl_engine_cmd='
-engine pkcs11
-keyform engine
-key pkcs11:object=PIV%20AUTH%20key
-passin env:PIV_PASS'
openssl req -new -batch \
${ENABLE_ENGINE:+$openssl_engine_cmd} \
-config "certs/codesign/$SAFE_NAME/$SAFE_NAME.conf" \
-out "certs/codesign/$SAFE_NAME/$SAFE_NAME.csr" \
$( [ -z $ENABLE_ENGINE ] && echo "
-nodes
-keyout certs/codesign/$SAFE_NAME/$SAFE_NAME.key")
openssl_engine_cmd='
-engine pkcs11
-inform engine
-in pkcs11:object=PIV%20AUTH%20key
-passin env:PIV_PASS'
openssl rsa \
${ENABLE_ENGINE:+$openssl_engine_cmd} \
$( [ -z $ENABLE_ENGINE ] && echo "-check -in certs/codesign/$SAFE_NAME/$SAFE_NAME.key") \
-noout
if [ -z "$ENABLE_ENGINE" ]; then
chmod 0400 "certs/codesign/$SAFE_NAME/$SAFE_NAME.key"
openssl rsa -in "certs/codesign/$SAFE_NAME/$SAFE_NAME.key" \
-pubout -out "certs/codesign/$SAFE_NAME/$SAFE_NAME.pub"
fi
echo -e "$NOTE Creating the code signing certificate" >&2
# Create the code signing 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/codesign/$SAFE_NAME/$SAFE_NAME.csr" \
-out "certs/codesign/$SAFE_NAME/$SAFE_NAME.crt" \
-extensions codesign_ext \
-passin env:CA_PASS
if [[ -n "$ENABLE_ENGINE" ]]; then
replace_crt 9a certs/codesign/"$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 \
-passin env:PIV_PASS"
key_mod=$(openssl rsa \
${ENABLE_ENGINE:+$openssl_engine_cmd} -noout -modulus \
$( [ -z $ENABLE_ENGINE ] && echo "-in certs/codesign/$SAFE_NAME/$SAFE_NAME.key")
)
cert_mod=$(openssl x509 -noout -modulus -in "certs/codesign/$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" >&2
openssl verify -CAfile ca/chain.pem "certs/codesign/$SAFE_NAME/$SAFE_NAME.crt"
echo -e "$NOTE Exporting to a p12 file" >&2
openssl pkcs12 -export \
-in certs/codesign/$SAFE_NAME/$SAFE_NAME.crt \
-inkey certs/codesign/$SAFE_NAME/$SAFE_NAME.key \
-certfile ca/ca.crt \
-out certs/codesign/$SAFE_NAME/$SAFE_NAME.p12
popd > /dev/null
unset CA_PASS
trap 0
echo -e "$SUCC Code Signing certificate named '${CERT_NAME}' created."