forked from cornelinux/yubikey-luks
/
yubikey-luks-enroll
executable file
·113 lines (95 loc) · 3.22 KB
/
yubikey-luks-enroll
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
#!/bin/bash
set -euo pipefail
#Instead of assuming /dev/sda3, this function reads /etc/crypttab for the first non-cryptswap entry and then
#queries cryptsetup to determine the actual device. More reliable, especially for computers using NVMe SSDs.
function getLUKSRootDisk() {
luksDevice=$(grep -v cryptswap /etc/crypttab | awk '{print $1}');
DISK=$(cryptsetup status "$luksDevice" | grep 'device: ' | awk '{print $2}')
}
SLOT=7;
DISK='';
CLEAR_SLOT=0;
DBG=0;
. /etc/ykluks.cfg
getLUKSRootDisk;
if [ "$(id -u)" -ne 0 ]; then
echo "You must be root." 1>&2;
exit 1;
fi
while getopts ":s:d:hcv" opt; do
case $opt in
s)
if [ "$OPTARG" -gt -1 ] && [ "$OPTARG" -lt 8 ]; then
SLOT=$OPTARG
echo "Setting slot to $OPTARG."
else
echo "Invalid slot specified, choose one slot between 0 and 7 or omit this option to choose the default ($SLOT)";
exit 3;
fi;
;;
d)
if [ -b "$OPTARG" ]; then #Check it's a block device
DISK=$OPTARG
echo "Setting disk to $OPTARG."
else
echo "$OPTARG is not a block device!"
exit 4;
fi
;;
c) CLEAR_SLOT=1;
echo "Clearing slot";
;;
v) DBG=1;
echo "Debugging enabled";
;;
h)
echo;
echo " -d <partition>: set the partition";
echo " -s <slot> : set the slot";
echo " -c : clear the slot prior to writing";
echo " -v : show input/output in cleartext";
echo
exit 1;
;;
\?)
echo "Invalid option: -$OPTARG" >&2;
;;
esac
done
echo "This script will utilize slot $SLOT on drive $DISK. If this is not what you intended, exit now!";
if [ $CLEAR_SLOT -eq 1 ]; then
echo "Killing LUKS slot $SLOT";
cryptsetup luksKillSlot "$DISK" "$SLOT";
else
SLOT_STATUS=$(cryptsetup luksDump "$DISK" | grep "Key Slot $SLOT" | awk '{print $4}');
if [ "$SLOT_STATUS" != 'DISABLED' ]; then
echo "Slot $SLOT is occupied and -c is not specified! Clear this slot before attempting to set a new key.";
exit 2;
fi
fi
echo "Adding yubikey to initrd";
P1=$(/lib/cryptsetup/askpass "Please insert a yubikey and enter a new password. This is the password that will only work while your yubikey is installed in your computer.");
if [ $DBG -eq 1 ]; then echo "Password: $P1"; fi
P2=$(/lib/cryptsetup/askpass "Please enter the yubikey password again:");
if [ $DBG -eq 1 ]; then echo "Password: $P2"; fi
if [ "x$P1" != "x$P2" ]; then
echo "Passwords do not match";
exit 1;
fi
if [ "$HASH" -eq 1 ]; then
P1=$(printf %s "$P1" | sha256sum | awk '{print $1}');
if [ $DBG -eq 1 ]; then echo "Password hash: $P1"; fi
fi
#Run the password through the Yubikey. We probably want to know if this fails!
R=$(ykchalresp -2 "$P1");
if [ $DBG -eq 1 ]; then echo "Yubikey response: $R"; fi
OLD=$(/lib/cryptsetup/askpass "Please provide an existing passphrase. This is NOT the passphrase you just entered, this is the passphrase that you currently use to unlock your LUKS encrypted drive:");
if [ $DBG -eq 1 ]; then echo "Old passphrase: $OLD"; fi
if [ "$CONCATENATE" -eq 1 ]; then
printf '%s\n' "$OLD" "$P1$R" "$P1$R" | cryptsetup --key-slot="$SLOT" luksAddKey "$DISK" 2>&1;
if [ $DBG -eq 1 ]; then echo "LUKS key: $P1$R"; fi
else
printf '%s\n' "$OLD" "$R" "$R" | cryptsetup --key-slot="$SLOT" luksAddKey "$DISK" 2>&1;
if [ $DBG -eq 1 ]; then echo "LUKS key: $R"; fi
fi
exit 0;