forked from DataDog/yubikey
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mac.sh
executable file
·249 lines (221 loc) · 8.37 KB
/
mac.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
244
245
246
247
248
249
#!/bin/bash
# Stop on error.
set -e
# Use Homebrew formulae.
HOMEBREW=/usr/local/bin
GIT=$HOMEBREW/git
GPG=$HOMEBREW/gpg
GPG_AGENT=$HOMEBREW/gpg-agent
GPGCONF=$HOMEBREW/gpgconf
YKMAN=$HOMEBREW/ykman
echo "Welcome! This program will automatically generate GPG keys on your Yubikey."
echo "If you ever run into problems, just press Ctrl-C, and rerun this program again."
echo ""
# install required tools
echo "Installing required tools, please try a full upgrade with 'brew upgrade --force'"
echo "of the problematic packages if something goes wrong, then try again."
brew install --force expect git gnupg pinentry-mac ykman
echo ""
# Check for ROCA.
DEVICE_TYPE=$($YKMAN info | grep 'Device type:' | cut -f2 -d:)
FIRMWARE_VERSION=$($YKMAN info | grep 'Firmware version:' | cut -f2 -d:)
echo "Checking whether Yubikey suffers from ROCA vulnerability..."
./roca-check.py "$DEVICE_TYPE" "$FIRMWARE_VERSION"
echo ""
# Get some information from the user.
# 1. Real name.
realname=$($GIT config --global --default '' --get user.name)
echo "What is the real name you use on GitHub?"
read -p "Real name (press Enter to accept '$realname'): " input
if [[ -z $realname ]]
then
if [[ -z $input ]]
then
echo "No name found!"
exit 1
else
realname=$input
echo "Using given input: $realname"
echo "Setting your git-config global user.name too..."
$GIT config --global user.name $realname
fi
else
if [[ -z $input ]]
then
echo "Using given user.name: $realname"
else
realname=$input
echo "Using given input: $realname"
fi
fi
echo ""
# 2. Email address.
email=$($GIT config --global --default '' --get user.email)
echo "What is an email address you have registered with GitHub?"
read -p "Email (press Enter to accept '$email'): " input
if [[ -z $email ]]
then
if [[ -z $input ]]
then
echo "No email found!"
exit 1
else
email=$input
echo "Using given input: $email"
echo "Setting your git-config global user.email too..."
$GIT config --global user.email $email
fi
else
if [[ -z $input ]]
then
echo "Using given user.email: $email"
else
email=$input
echo "Using given input: $email"
fi
fi
echo ""
# 3. Comment.
comment="GPG on Yubikey for Datadog"
echo "What is a comment you would like to use to distinguish this key?"
read -p "Comment (press Enter to accept '$comment'): " input
comment=${input:-$comment}
echo ""
# Generate some information for the user.
echo "There are two important random numbers for the Yubikey you MUST keep safely."
echo "See https://developers.yubico.com/yubikey-piv-manager/PIN_and_Management_Key.html"
echo ""
# 1. PIN
PIN=$(python -S -c "import random; print(random.SystemRandom().randrange(10**7,10**8))")
echo "The first number is the PIN."
echo "The PIN is used during normal operation to authorize an action such as creating a digital signature for any of the loaded certificates."
echo ""
echo "***********************************************************"
echo "Default PIN code: 123456"
echo "New PIN code: $PIN"
echo "***********************************************************"
echo ""
echo "Please save this new PIN immediately in your password manager."
read -p "Have you done this? "
echo "Great. Now, remember, the first time you are asked for the PIN, please enter: 123456"
echo "After that, you will be asked to set a new PIN. Enter: $PIN"
echo ""
# 2. PUK
PUK=$(python -S -c "import random; print(random.SystemRandom().randrange(10**7,10**8))")
echo "The second number is the Admin PIN, aka PUK."
echo "The Admin PIN can be used to reset the PIN if it is ever lost or becomes blocked after the maximum number of incorrect attempts."
echo ""
echo "***********************************************************"
echo "Default Admin PIN code: 12345678"
echo "New Admin PIN code: $PUK"
echo "***********************************************************"
echo ""
echo "Please save this new Admin PIN immediately in your password manager."
read -p "Have you done this? "
echo "Great. Now, remember, the first time you are asked for the Admin PIN, please enter: 12345678"
echo "After that, you will be asked to set a new Admin PIN. Enter: $PUK"
echo ""
# setup pinentry-mac
mkdir -p ~/.gnupg
cat << EOF > ~/.gnupg/gpg-agent.conf
# https://www.gnupg.org/documentation/manuals/gnupg/Agent-Options.html
pinentry-program /usr/local/bin/pinentry-mac
enable-ssh-support
# For usability while balancing security, cache PIN for at most a day.
default-cache-ttl 86400
max-cache-ttl 86400
EOF
# enable SSH
read -p "Would you like to SSH using your Yubikey? [y/n] "
if [[ $REPLY =~ ^[Yy]$ ]]; then
if [[ $(cat ~/.bash_profile) =~ "gpg-agent.ssh" ]]; then
echo 'export "SSH_AUTH_SOCK=${HOME}/.gnupg/S.gpg-agent.ssh"' >> ~/.bash_profile
fi
if [[ $(cat ~/.zshrc) =~ "gpg-agent.ssh" ]]; then
echo 'export "SSH_AUTH_SOCK=${HOME}/.gnupg/S.gpg-agent.ssh"' >> ~/.zshrc
fi
fi
echo ""
# restart GPG daemons to pick up pinentry-mac
$GPGCONF --kill all
# show card information to user so they can be sure they are wiping right key
echo "Yubikey status:"
$GPG --card-status
echo ""
# reset yubikey openPGP applet
echo "RESETTING THE OPENGPG APPLET ON YOUR YUBIKEY!!!"
$YKMAN openpgp reset
echo ""
# drive yubikey setup
# but right before, kill all GPG daemons to make sure things work reliably
$GPGCONF --kill all
./expect.sh "$realname" "$email" "$comment"
# NOTE: After we are done setting up Yubikey, kill existing SSH and GPG agents,
# and start GPG agent manually (with SSH support added above) to maximize odds
# of picking up SSH key.
killall ssh-agent || echo "ssh-agent was not running."
$GPGCONF --kill all
$GPG_AGENT --daemon
echo ""
# Ask user whether all git commits and tags should be signed.
keyid=$($GPG --card-status | grep 'sec>' | awk '{print $2}' | cut -f2 -d/)
read -p "Do you want to set up git so that all commits and tags will be signed with this key (STRONGLY recommended)? [y/n] "
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]
then
echo "Setting git to use this GPG key globally."
echo "Also, turning on signing of all commits and tags by default."
# Tell git to use this GPG key.
$GIT config --global user.signingkey $keyid
# Also, turn on signing commits and tags by default.
$GIT config --global commit.gpgsign true
$GIT config --global tag.forceSignAnnotated true
echo ""
fi
# Export GPG public key.
echo "Exporting your GPG public key to $keyid.gpg.pub."
$GPG --armor --export $keyid > $keyid.gpg.pub
$GPG --armor --export $keyid | pbcopy
echo "It has also been copied to your clipboard."
echo "You may now add it to GitHub: https://github.com/settings/gpg/new"
echo "Opening GitHub..."
open "https://github.com/settings/gpg/new"
echo "Please save a copy in your password manager."
read -p "Have you done this? "
echo "There is NO off-card backup of your private / secret keys."
echo "So if your Yubikey is damaged, lost, or stolen, then you must rotate your GPG keys out-of-band."
echo ""
# Export SSH key derived from GPG authentication subkey.
echo "Exporting your SSH public key to $keyid.ssh.pub."
ssh-add -L | grep -iF 'cardno' > $keyid.ssh.pub
ssh-add -L | grep -iF 'cardno' | pbcopy
echo "It has also been copied to your clipboard."
echo "You may now add it to GitHub: https://github.com/settings/ssh/new"
echo "Opening GitHub..."
open "https://github.com/settings/ssh/new"
echo "Please save a copy in your password manager."
read -p "Have you done this? "
echo "Great."
echo ""
# Ask user to save revocation certificate before deleting it.
fingerprint=$($GPG --card-status | grep 'Signature key' | cut -f2 -d: | tr -d ' ')
cat ~/.gnupg/openpgp-revocs.d/$fingerprint.rev | pbcopy
echo "Your revocation certificate is at ~/.gnupg/openpgp-revocs.d/$fingerprint.rev"
echo "It has been copied to your clipboard."
echo "Please save a copy in your password manager before we delete it off disk."
read -p "Have you done this? "
rm ~/.gnupg/openpgp-revocs.d/$fingerprint.rev
echo "Great. Deleted this revocation certificate from disk."
# NOTE: EMPTY clipboard after this.
pbcopy < /dev/null
echo ""
# Final reminders.
echo "Finally, remember that your keys will not expire until 10 years from now."
echo "You will need to enter your PIN (once a day), and touch your Yubikey everytime in order to sign any message with this GPG key."
echo ""
echo "************************************************************"
echo "Your PIN is: $PIN"
echo "Your Admin PIN, aka PUK is: $PUK"
echo "************************************************************"
echo ""
echo "Enjoy using your Yubikey at Datadog!"