summaryrefslogtreecommitdiffstats
path: root/usr/bin/cryptosmartcard.sh
blob: ac8c206a3e2a476526f95f8b0cd4994f8e3416bb (plain)
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
#!/bin/sh

# Part of passwordless cryptofs setup in Debian Etch.
# See: http://wejn.org/how-to-make-passwordless-cryptsetup.html
# Author: Wejn <wejn at box dot cz>
#
# Updated by Rodolfo Garcia (kix) <kix at kix dot com>
# For multiple partitions
# http://www.kix.es/
#
# Updated by TJ <[email protected]> 7 July 2008
# For use with Ubuntu Hardy, usplash, automatic detection of USB devices,
# detection and examination of *all* partitions on the device (not just partition #1),
# automatic detection of partition type, refactored, commented, debugging code.
#
# Update by Timothy Pearson <[email protected]> 8/28/2008
# Modified for use with SmartCard script instead of USB key
#
# Updated by Timothy Pearson <[email protected]> 4/19/2010
# Added Plymouth detection and support
#
# Updated by Timothy Pearson <[email protected]> 9/15/2015
# Rewrite to use on-card RSA encryption

# define counter-intuitive shell logic values (based on /bin/true & /bin/false)
TRUE=0
FALSE=1

# set DEBUG=$TRUE to display debug messages, DEBUG=$FALSE to be quiet
DEBUG=$FALSE

# Fix the aggressive usplash timeout
if [ -x /sbin/usplash_write ]; then
	/sbin/usplash_write "TIMEOUT 180" || true
fi

# Find plymouth
PLYDIR=/bin/plymouth

# print message to usplash or stderr
# usage: msg <command> "message" [switch]
# command: TEXT | STATUS | SUCCESS | FAILURE | CLEAR (see 'man usplash_write' for all commands)
# switch : switch used for echo to stderr (ignored for usplash)
# when using usplash the command will cause "message" to be
# printed according to the usplash <command> definition.
# using the switch -n will allow echo to write multiple messages
# to the same line
# msg ()
# {
# 	if [ -p /dev/.initramfs/usplash_outfifo ] && [ -x /sbin/usplash_write ]; then
# 		usplash_write "TEXT-URGENT $@"
# 	else
# 		echo "$@" >&2
# 	fi
# 	return 0
# }

msg ()
{
	HAS_PLYMOUTH=0
	if [ -e $PLYDIR ]; then
		plymouth --ping
		if [ $? -eq 0 ]; then
			HAS_PLYMOUTH=1
		fi
	fi
	if [ $HAS_PLYMOUTH -eq 1 ]; then
		plymouth message --text="$@"
	else
		if [ -p /dev/.initramfs/usplash_outfifo ] && [ -x /sbin/usplash_write ]; then
			usplash_write "TEXT-URGENT $@"
		else
			echo "$@" >&2
		fi
	fi
	return 0
}

[ $DEBUG -eq $TRUE ] && msg "Executing cryptosmartcard.sh ..."
# flag tracking key-file availability
OPENED=$FALSE

# Terminate the PC/SC subsystem
killall -9 pcscd > /dev/null 2>&1 || true

# Is the USB driver loaded?
cat /proc/modules | busybox grep usb_storage >/dev/null 2>&1
USBLOAD=0$?
if [ $USBLOAD -gt 0 ]; then
	[ $DEBUG -eq $TRUE ] && msg "Loading driver 'usb_storage'"
	modprobe usb_storage >/dev/null 2>&1
fi

# Make sure USB device nodes have loaded
udevadm settle

# Relaunch the PC/SC subsystem
pcscd > /dev/null 2>&1

CARD_INSERTED=$FALSE
OPENED=$FALSE
LUKS_KEY_DIR=/tde_luks_keys
LUKS_KEY_COUNT=$(ls -1 $LUKS_KEY_DIR/ 2> /dev/null | wc -l)

DISK_UUID=$(blkid -s UUID -o value $CRYPTTAB_SOURCE)

if [ $LUKS_KEY_COUNT -gt 0 ]; then
	if [ "$DISK_UUID" != "" ]; then
		# Disk UUID found and LUKS keys are present
		# Check for card presence...
		pkcs15-tool --list-certificates > /dev/null 2>&1
		RET=$?
		if [ $RET -eq 0 ]; then
			# Card present
			CARD_INSERTED=$TRUE
			msg "SmartCard inserted, attempting to authenticate"

			if [ -e /dev/kmsg ]; then
				# Linux specific!
				# Wait for nonblocking random driver to start.
				# Without waiting, the pincheck utility can stall
				# for a very long time (forever?) waiting
				# for enough random data to start PKCS11.
				dmesg | grep -q "random: nonblocking pool is initialized" &> /dev/null
				RET=$?
				LOOPS=0
				if [ $RET -ne 0 ]; then
					msg "Waiting for nonblocking random pool to start..."
					sleep 1
					while [ $RET -ne 0 ]; do
						dmesg | grep -q "random: nonblocking pool is initialized" &> /dev/null
						RET=$?
						if [ $RET -ne 0 ]; then
							sleep 1
							LOOPS=$((LOOPS+1))
							if [ $LOOPS -eq 10 ]; then
								msg "Random pool initialization is slow.  Try pressing keys or moving the mouse to speed it up..."
							fi
						fi
					done
					msg "Nonblocking pool started, continuing!"
				fi
				rm -f /tmp/kmsg
			fi

			PIN=$(cardpincheck /usr/lib/opensc-pkcs11.so)
			RET=$?
			if [ $RET -eq 0 ]; then
				# PIN valid
				msg "SmartCard unlocked"
				for KEYFILE in ${LUKS_KEY_DIR}/${DISK_UUID}_slot*; do
					# Try decrypting
					echo "$PIN" | cardpincheck /usr/lib/opensc-pkcs11.so $KEYFILE 2> /dev/null
					RET=$?
					if [ $RET -eq 0 ]; then
						OPENED=$TRUE
						break
					fi
				done
			else
				msg "SmartCard authentication failed"
			fi
		fi
	fi
fi

killall -9 pcscd > /dev/null 2>&1 || true

if [ $OPENED -eq $FALSE ]; then
	if [ $CARD_INSERTED -eq $TRUE ]; then
		msg "SmartCard LUKS keyfile invalid or incorrect SmartCard inserted"
		exit 0
	else
		msg "No SmartCard inserted or no LUKS keyfiles available on this system"
	fi
	if [ $HAS_PLYMOUTH -eq 1 ]; then
		plymouth ask-for-password --prompt="Please enter the LUKS password"
	else
		msg "Please enter the LUKS password: "
		read -s -r A < /dev/console
		echo -n "$A"
		msg "Attempting to authenticate..."
	fi
fi

exit 0