Changes On Branch ad6536ceb0480aa1

Changes In Branch protected-auth-path Through [ad6536ceb0] Excluding Merge-Ins

This is equivalent to a diff from 6ba1dff55a to ad6536ceb0

2015-07-15
20:10
Merged divergent PIV branches Closed-Leaf check-in: 466549fe92 user: rkeene tags: piv
20:08
Merged in trunk Closed-Leaf check-in: bab332232a user: rkeene tags: protected-auth-path
2014-03-14
14:30
Merged in changes from PIV check-in: 8ba93699b4 user: rkeene tags: trunk
14:25
Updated to reset the card if a retry is required check-in: ad6536ceb0 user: rkeene tags: protected-auth-path
2014-01-17
13:42
Merged in trunk check-in: b5af3ab373 user: rkeene tags: protected-auth-path
2013-10-17
20:29
Merged in PIV support check-in: 3e5963d5d9 user: rkeene tags: trunk
20:29
Updated to deal with 6E00 and added support for win32 build options check-in: 6ba1dff55a user: rkeene tags: piv
2013-09-14
02:50
Updated to treat a return code of 0x6E00 (wrong instruction class) the same as 0x6982 (security status not satisified) check-in: 2e1e0bfc20 user: rkeene tags: piv

Modified build/cackey_osx_build/Template_pmbuild/index.xml.in from [7d02eca4b2] to [6bfcbad535].

30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44







-
+







{\fonttbl\f0\fnil\fcharset0 LucidaGrande;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural

\f0\fs26 \cf0 Release information:\
    pkg: CACKey\
 author: US Army Corps of Engineers\
Mac build contact: Kenneth Van Alstyne <DC1SAN_SUPPORT@hq.dhs.gov>\
Mac build contact: Kenneth Van Alstyne <Kenneth.VanAlstyne@associates.hq.dhs.gov>\
                   US Department of Homeland Security\
contact: Roy Keene <DC1-UNIX@hq.dhs.gov>\
------------------------------------------------\
\
The PKCS11.tokend connector module included in this package is licensed under\
the APSL. See: http://devel.kvanals.org/PKCS11_Tokend\
\
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
75
76
77
78
79
80
81



82
83
84
85
86
87
88







-
-
-







To use, be sure to import the certificate authorities into Keychain Access.\
\
A debug version, /Library/CACKey/libcackey_g.dylib is provided if debug output is necessary.}]]>
			</resource>
		</locale>
	</resources>
	<requirements>
		<requirement id="tosv" operator="lt" value="'@@NEXTOSXVER@@'">
			<message>This CACKey release requires Mac OS X @@CUROSXVER@@.</message>
		</requirement>
		<requirement id="tosv" operator="ge" value="'@@CUROSXVER@@'">
			<message>This CACKey release requires Mac OS X @@CUROSXVER@@.</message>
		</requirement>
	</requirements>
	<flags/>
	<item type="file">01libcackey.xml</item>
	<item type="file">02libcackey.xml</item>

Modified build/cackey_osx_build/build_osx.sh from [c66d1aadeb] to [361c9900ba].

12
13
14
15
16
17
18
19

20
21
22
23
24
25
26
12
13
14
15
16
17
18

19
20
21
22
23
24
25
26







-
+







# Usage function
usage() {
	echo "Usage: build_osx.sh <target>"
	echo Where target is one of:
	echo "    leopard  - (Builds Universal 10.5 Library for PPCG4/i386)"
	echo "    snowleopard  - (Builds Universal 10.6 Library for i386/x86_64)"
	echo "    lion  - (Builds Universal 10.7 Library for i386/x86_64)"
	echo "    sltoml - (Builds Universal 10.6/10.7/10.8 Library for i386/x86_64)"
	echo "    sltomav - (Builds Universal 10.6/10.7/10.8/10.9 Library for i386/x86_64)"
	echo "    all - (Builds for all supported targets)"
	echo "    clean - (Cleans up)"
	echo "Run from CACKey Build Root."
	exit $?
}

# Clean up function
41
42
43
44
45
46
47
48

49
50
51
52
53
54
55
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55







-
+







		LIBTOOLDIR=/Developer/usr/share/libtool/config
	fi
	if [ ! -d macbuild ]; then
		mkdir macbuild
		mkdir macbuild/Leopard
		mkdir macbuild/Snowleopard
		mkdir macbuild/Lion
		mkdir macbuild/Sltoml
		mkdir macbuild/Sltomav
		mkdir macbuild/pkg
	fi
	if [ ! -f config.guess ]; then
		cp ${LIBTOOLDIR}/config.guess .
	fi
	if [ ! -f config.sub ]; then
		cp ${LIBTOOLDIR}/config.sub .
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
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







-



















-



















-









-
+







-
+

-









-
+







-
+

-







	LIBRARY=/Developer/SDKs/MacOSX10.5.sdk/System/Library/Frameworks/PCSC.framework/PCSC
	LIB=""
	ARCHLIST=""
	DLIB=""
	DARCHLIST=""
	OSX=Leopard
	PKTARGETOS=3
	NEXTOSXVER=10.6
	CUROSXVER=10.5
	for HOST in powerpc-apple-darwin9 i386-apple-darwin9; do
		genbuild
	done
	libbuild
	pkgbuild
}

# Build function for Snow Leopard
snowleopard() {
	makedir
	HEADERS=/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/PCSC.framework/Versions/A/Headers/
	LIBRARY=/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/PCSC.framework/PCSC
	LIB=""
	ARCHLIST=""
	DLIB=""
	DARCHLIST=""
	OSX=Snowleopard
	PKTARGETOS=3
	NEXTOSXVER=10.7
	CUROSXVER=10.6
	for HOST in i386-apple-darwin10 x86_64-apple-darwin10; do
		genbuild
	done
	libbuild
	pkgbuild
}

# Build function for Lion
lion() {
	makedir
	HEADERS=/Developer/SDKs/MacOSX10.7.sdk/System/Library/Frameworks/PCSC.framework/Versions/A/Headers/
	LIBRARY=/Developer/SDKs/MacOSX10.7.sdk/System/Library/Frameworks/PCSC.framework/PCSC
	LIB=""
	ARCHLIST=""
	DLIB=""
	DARCHLIST=""
	OSX=Lion
	PKTARGETOS=3
	NEXTOSXVER=10.8
	CUROSXVER=10.7
	for HOST in i386-apple-darwin11 x86_64-apple-darwin11; do
		genbuild
	done
	libbuild
	pkgbuild
}

# Build function for Snow Leopard/Lion/Mountain Lion
sltoml() {
sltomav() {
	makedir
	HEADERS=/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/PCSC.framework/Versions/A/Headers/
	LIBRARY=/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/PCSC.framework/PCSC
	LIB=""
	ARCHLIST=""
	DLIB=""
	DARCHLIST=""
	OSX=Sltoml
	OSX=Sltomav
	PKTARGETOS=3
	NEXTOSXVER=10.9
	CUROSXVER=10.6
	for HOST in i386-apple-darwin10 x86_64-apple-darwin10; do
		genbuild
	done
	libbuild
	pkgbuild
}

# Build function for Snow Leopard/Lion/Mountain Lion
sltoml() {
sltomav() {
	makedir
	HEADERS=/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/PCSC.framework/Versions/A/Headers/
	LIBRARY=/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/PCSC.framework/PCSC
	LIB=""
	ARCHLIST=""
	DLIB=""
	DARCHLIST=""
	OSX=Sltoml
	OSX=Sltomav
	PKTARGETOS=3
	NEXTOSXVER=10.9
	CUROSXVER=10.6
	for HOST in i386-apple-darwin10 x86_64-apple-darwin10; do
		genbuild
	done
	libbuild
	pkgbuild
}
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
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







-










-
-
+
+







		PMDOC="`echo "${PMDOC}" | sed 's|l.in|l|g' | sed 's|build/cackey_osx_build/Template_pmbuild/||g'`"
		UUID="`python -c 'import uuid; print uuid.uuid1()' | dd conv=ucase 2>/dev/null`"
		mkdir -p build/cackey_osx_build/${OSX}_pmbuild.pmdoc
		sed "s|@@BUILDROOTDIR@@|$(pwd)|g" build/cackey_osx_build/Template_pmbuild/${PMDOC}.in > build/cackey_osx_build/${OSX}_pmbuild.pmdoc/${PMDOC}
		sed "s|@@OSXVERSION@@|${OSX}|g" build/cackey_osx_build/${OSX}_pmbuild.pmdoc/${PMDOC} > build/cackey_osx_build/${OSX}_pmbuild.pmdoc/${PMDOC}.1
		sed "s|@@UUID@@|${UUID}|g" build/cackey_osx_build/${OSX}_pmbuild.pmdoc/${PMDOC}.1 > build/cackey_osx_build/${OSX}_pmbuild.pmdoc/${PMDOC}
		sed "s|@@TARGETOS@@|${PKTARGETOS}|g" build/cackey_osx_build/${OSX}_pmbuild.pmdoc/${PMDOC} > build/cackey_osx_build/${OSX}_pmbuild.pmdoc/${PMDOC}.1
		sed "s|@@NEXTOSXVER@@|${NEXTOSXVER}|g" build/cackey_osx_build/${OSX}_pmbuild.pmdoc/${PMDOC}.1 > build/cackey_osx_build/${OSX}_pmbuild.pmdoc/${PMDOC}
		sed "s|@@CUROSXVER@@|${CUROSXVER}|g" build/cackey_osx_build/${OSX}_pmbuild.pmdoc/${PMDOC} > build/cackey_osx_build/${OSX}_pmbuild.pmdoc/${PMDOC}.1
		sed "s|@@LIBCACKEYG@@|${LIBCACKEYG}|g" build/cackey_osx_build/${OSX}_pmbuild.pmdoc/${PMDOC}.1 > build/cackey_osx_build/${OSX}_pmbuild.pmdoc/${PMDOC}
		cp build/cackey_osx_build/${OSX}_pmbuild.pmdoc/${PMDOC} build/cackey_osx_build/${OSX}_pmbuild.pmdoc/${PMDOC}.1
		mv build/cackey_osx_build/${OSX}_pmbuild.pmdoc/${PMDOC}.1 build/cackey_osx_build/${OSX}_pmbuild.pmdoc/${PMDOC}
	done
	EXT=pkg
	if [ ${OSX} == "Snowleopard" ]; then
		cat build/cackey_osx_build/${OSX}_pmbuild.pmdoc/index.xml | sed 's|for Mac OS X Snowleopard|for Mac OS X SnowLeopard|g' > build/cackey_osx_build/${OSX}_pmbuild.pmdoc/index.xml.new
		mv build/cackey_osx_build/${OSX}_pmbuild.pmdoc/index.xml.new build/cackey_osx_build/${OSX}_pmbuild.pmdoc/index.xml
	fi
	if [ ${OSX} == "Sltoml" ]; then
		cat build/cackey_osx_build/${OSX}_pmbuild.pmdoc/index.xml | sed 's|for Mac OS X Sltoml|for Mac OS X SLtoML|g' > build/cackey_osx_build/${OSX}_pmbuild.pmdoc/index.xml.new
	if [ ${OSX} == "Sltomav" ]; then
		cat build/cackey_osx_build/${OSX}_pmbuild.pmdoc/index.xml | sed 's|for Mac OS X Sltomav|for Mac OS X SLtoMav|g' > build/cackey_osx_build/${OSX}_pmbuild.pmdoc/index.xml.new
		mv build/cackey_osx_build/${OSX}_pmbuild.pmdoc/index.xml.new build/cackey_osx_build/${OSX}_pmbuild.pmdoc/index.xml
	fi
	/Developer/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker -d build/cackey_osx_build/${OSX}_pmbuild.pmdoc -o macbuild/pkg/CACKey_${CACKEY_VERSION}_${OSX}.${EXT}
	tar --create --directory macbuild/pkg/ --file macbuild/pkg/CACKey_${CACKEY_VERSION}_${OSX}.${EXT}.tar CACKey_${CACKEY_VERSION}_${OSX}.${EXT}
	gzip -9 macbuild/pkg/CACKey_${CACKEY_VERSION}_${OSX}.${EXT}.tar
	rm -rf macbuild/pkg/CACKey_${CACKEY_VERSION}_${OSX}.${EXT}
	rm -f build/cackey_osx_build/cackey.dylib
272
273
274
275
276
277
278
279

280
281

282
283
284
285
286
287
288

289
290
291
292
293
294
295
266
267
268
269
270
271
272

273
274

275
276
277
278
279
280
281

282
283
284
285
286
287
288
289







-
+

-
+






-
+







	
	"lion")
		./autogen.sh
		lion
		exit $?
	;;
	
	"sltoml")
	"sltomav")
		./autogen.sh
		sltoml
		sltomav
		exit $?
	;;

	"all")
		./autogen.sh
		leopard
		sltoml
		sltomav
		echo ""
		echo "All builds complete."
		exit $?
	;;

	"clean")
		clean

Modified cackey.c from [e6fa629162] to [318588635a].

1113
1114
1115
1116
1117
1118
1119

1120




1121
1122
1123
1124
1125
1126
1127
1128
1129

1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153


1154
1155


1156

1157
1158
1159
1160

1161
1162
1163
1164

1165
1166




1167
1168
1169
1170
1171
1172
1173
1113
1114
1115
1116
1117
1118
1119
1120

1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132

1133
1134
1135
1136
1137
1138
1139
1140
1141



1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153

1154
1155
1156
1157
1158
1159

1160
1161
1162
1163

1164
1165
1166
1167

1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181







+
-
+
+
+
+








-
+








-
-
-












-
+
+


+
+
-
+



-
+



-
+


+
+
+
+








	if (slot->pcsc_card_connected) {
		SCardDisconnect(slot->pcsc_card, SCARD_LEAVE_CARD);
	}

	slot->slot_reset = 1;
	slot->pcsc_card_connected = 0;
	if (cackey_pin_command == NULL) {
	slot->token_flags = CKF_LOGIN_REQUIRED;
		slot->token_flags = CKF_LOGIN_REQUIRED;
	} else {
		slot->token_flags = 0;
	}

	CACKEY_DEBUG_PRINTF("Returning.");

	return;
}

/*
 * SYNPOSIS
 *     LONG cackey_reconnect_card(struct cackey_slot *slot, DWORD default_protocol, LPDWORD selected_protocol);
 *     LONG cackey_reconnect_card(struct cackey_slot *slot, DWORD default_protocol);
 *
 * ARGUMENTS
 *     cackey_slot *slot
 *         Slot to send commands to
 *
 *     DWORD default_protocol
 *         Protocol to attempt first
 *
 *     LPDWORD selected_protocol
 *         [OUT] Protocol selected
 *
 * RETURN VALUE
 *     The return value from SCardReconnect()
 *
 * NOTES
 *     This function is a wrapper around SCardReconnect()
 *
 *     The SCardReconnect() function call will be called first with the
 *     dwPreferredProtocols of "default_protocol".  If that call returns
 *     SCARD_E_PROTO_MISMATCH try again with a protocol of T=0, and failing
 *     that T=1.
 *
 */
static LONG cackey_reconnect_card(struct cackey_slot *slot, DWORD default_protocol, LPDWORD selected_protocol) {
static LONG cackey_reconnect_card(struct cackey_slot *slot, DWORD default_protocol) {
	DWORD selected_protocol;
	LONG scard_conn_ret;

	selected_protocol = 0;

	scard_conn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, default_protocol, SCARD_RESET_CARD, selected_protocol);
	scard_conn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, default_protocol, SCARD_RESET_CARD, &selected_protocol);

	if (scard_conn_ret == SCARD_E_PROTO_MISMATCH) {
		CACKEY_DEBUG_PRINTF("SCardReconnect() returned SCARD_E_PROTO_MISMATCH, trying with just T=0")
		scard_conn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, SCARD_RESET_CARD, selected_protocol);
		scard_conn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, SCARD_RESET_CARD, &selected_protocol);

		if (scard_conn_ret == SCARD_E_PROTO_MISMATCH) {
			CACKEY_DEBUG_PRINTF("SCardReconnect() returned SCARD_E_PROTO_MISMATCH, trying with just T=1")
			scard_conn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1, SCARD_RESET_CARD, selected_protocol);
			scard_conn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1, SCARD_RESET_CARD, &selected_protocol);
		}
	}

	if (scard_conn_ret == SCARD_S_SUCCESS) {
		slot->protocol = selected_protocol;
	}

	return(scard_conn_ret);
}

/*
 * SYNPOSIS
 *     cackey_ret cackey_connect_card(struct cackey_slot *slot);
1230
1231
1232
1233
1234
1235
1236
1237

1238
1239
1240
1241
1242
1243
1244
1238
1239
1240
1241
1242
1243
1244

1245
1246
1247
1248
1249
1250
1251
1252







-
+








				if (scard_conn_ret == SCARD_E_PROTO_MISMATCH) {
					CACKEY_DEBUG_PRINTF("SCardConnect() returned SCARD_E_PROTO_MISMATCH, trying with just T=1")
					scard_conn_ret = SCardConnect(*cackey_pcsc_handle, slot->pcsc_reader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1, &slot->pcsc_card, &protocol);
				}
			}

			scard_conn_ret = cackey_reconnect_card(slot, protocol, &protocol);
			scard_conn_ret = cackey_reconnect_card(slot, protocol);
		}

		if (scard_conn_ret != SCARD_S_SUCCESS) {
			CACKEY_DEBUG_PRINTF("Connection to card failed, returning in failure (SCardConnect() = %s/%li)", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_conn_ret), (long) scard_conn_ret);

			return(CACKEY_PCSC_E_GENERIC);
		}
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1445
1446
1447
1448
1449
1450
1451

1452
1453
1454
1455
1456
1457
1458







-







 *     goes away.
 *
 */
static cackey_ret cackey_send_apdu(struct cackey_slot *slot, unsigned char class, unsigned char instruction, unsigned char p1, unsigned char p2, unsigned int lc, unsigned char *data, unsigned int le, uint16_t *respcode, unsigned char *respdata, size_t *respdata_len) {
	uint8_t major_rc, minor_rc;
	size_t bytes_to_copy, tmp_respdata_len;
	LPCSCARD_IO_REQUEST pioSendPci;
	DWORD protocol;
	DWORD xmit_len, recv_len;
	LONG scard_xmit_ret, scard_reconn_ret;
	BYTE xmit_buf[1024], recv_buf[1024];
	int pcsc_connect_ret, pcsc_getresp_ret;
	int idx;

	CACKEY_DEBUG_PRINTF("Called.");
1532
1533
1534
1535
1536
1537
1538


1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551

1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559

1560
1561
1562


1563
1564
1565
1566
1567
1568
1569







+
+












-
+


-
-








	if (scard_xmit_ret == SCARD_E_NOT_TRANSACTED) {
		CACKEY_DEBUG_PRINTF("Failed to send APDU to card (SCardTransmit() = %s/%lx), will ask calling function to retry (not resetting card)...", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_xmit_ret), (unsigned long) scard_xmit_ret);

		/* Begin Smartcard Transaction */
		cackey_end_transaction(slot);

		cackey_reconnect_card(slot, slot->protocol);

		return(CACKEY_PCSC_E_RETRY);
	}

	if (scard_xmit_ret != SCARD_S_SUCCESS) {
		CACKEY_DEBUG_PRINTF("Failed to send APDU to card (SCardTransmit() = %s/%lx)", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_xmit_ret), (unsigned long) scard_xmit_ret);

		CACKEY_DEBUG_PRINTF("Marking slot as having been reset");
		cackey_mark_slot_reset(slot);

		if (scard_xmit_ret == SCARD_W_RESET_CARD) {
			CACKEY_DEBUG_PRINTF("Reset required, please hold...");

			scard_reconn_ret = cackey_reconnect_card(slot, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &protocol);
			scard_reconn_ret = cackey_reconnect_card(slot, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1);

			if (scard_reconn_ret == SCARD_S_SUCCESS) {
				/* Update protocol */
				slot->protocol = protocol;
				switch (slot->protocol) {
					case SCARD_PROTOCOL_T0:
						pioSendPci = SCARD_PCI_T0;

						break;
					case SCARD_PROTOCOL_T1:
						pioSendPci = SCARD_PCI_T1;
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872


2873
2874

2875
2876

2877
2878


2879

2880
2881
2882






2883
2884
2885
2886
2887
2888
2889
2890
2891
2860
2861
2862
2863
2864
2865
2866


2867
2868
2869
2870
2871
2872
2873
2874
2875


2876
2877
2878

2879


2880


2881
2882
2883
2884



2885
2886
2887
2888
2889
2890
2891

2892
2893
2894
2895
2896
2897
2898







-
-









-
-
+
+

-
+
-
-
+
-
-
+
+

+
-
-
-
+
+
+
+
+
+

-







				send_ret = cackey_send_apdu(slot, class, NISTSP800_73_3_INSTR_GENAUTH, NISTSP800_78_3_ALGO_RSA2048, identity->pcsc_identity->card.piv.key_id, bytes_to_send, tmpbuf, le, &respcode, outbuf, &tmpoutbuflen);
				break;
			case CACKEY_ID_TYPE_CERT_ONLY:
				break;
		}

		if (send_ret != CACKEY_PCSC_S_OK) {
			CACKEY_DEBUG_PRINTF("ADPU Sending Failed -- returning in error.");

			if (free_tmpbuf) {
				if (tmpbuf_s) {
					free(tmpbuf_s);
				}
			}

			/* End transaction */
			cackey_end_transaction(slot);

			if (respcode == 0x6982 || respcode == 0x6e00) {
				CACKEY_DEBUG_PRINTF("Security status not satisified (respcode = 0x%04x).  Returning NEEDLOGIN", (int) respcode);
			if (send_ret == CACKEY_PCSC_E_RETRY) {
				CACKEY_DEBUG_PRINTF("ADPU Sending Failed -- retrying.");

				cackey_mark_slot_reset(slot);
				return(cackey_signdecrypt(slot, identity, buf, buflen, outbuf, outbuflen, padInput, unpadOutput));
				slot->token_flags = CKF_LOGIN_REQUIRED;

			}
				return(CACKEY_PCSC_E_NEEDLOGIN);
			}

			CACKEY_DEBUG_PRINTF("ADPU Sending Failed -- returning in error.");

			if (respcode == 0x6982 || respcode == 0x6e00) {
			if (respcode == 0x6E00) {
				CACKEY_DEBUG_PRINTF("Got \"WRONG CLASS\", this means we are talking to the wrong object (likely because the card went away) -- resetting");

				if (respcode == 0x6E00) {
					CACKEY_DEBUG_PRINTF("Got \"WRONG CLASS\", this means we are talking to the wrong object (likely because the card went away) -- resetting");
				} else {
					CACKEY_DEBUG_PRINTF("Security status not satisified (respcode = 0x%04x).  Returning NEEDLOGIN", (int) respcode);
				}

				cackey_mark_slot_reset(slot);
				slot->token_flags = CKF_LOGIN_REQUIRED;

				return(CACKEY_PCSC_E_NEEDLOGIN);
			}

			if (send_ret == CACKEY_PCSC_E_TOKENABSENT) {
				CACKEY_DEBUG_PRINTF("Token absent.  Returning TOKENABSENT");

3182
3183
3184
3185
3186
3187
3188
3189

3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3189
3190
3191
3192
3193
3194
3195

3196
3197



3198
3199
3200
3201
3202
3203
3204







-
+

-
-
-








	if (status_ret != SCARD_S_SUCCESS) {
		cackey_mark_slot_reset(slot);

		if (status_ret == SCARD_W_RESET_CARD) {
			CACKEY_DEBUG_PRINTF("Reset required, please hold...");

			scard_reconn_ret = cackey_reconnect_card(slot, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &protocol);
			scard_reconn_ret = cackey_reconnect_card(slot, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1);
			if (scard_reconn_ret == SCARD_S_SUCCESS) {
				/* Update protocol */
				slot->protocol = protocol;

				/* Re-establish transaction, if it was present */
				if (slot->transaction_depth > 0) {
					slot->transaction_depth--;
					slot->transaction_need_hw_lock = 1;
					cackey_begin_transaction(slot);
				}

4430
4431
4432
4433
4434
4435
4436
4437

4438
4439
4440
4441
4442
4443
4444
4445
4446
4447

4448




4449
4450
4451
4452
4453

4454
4455





4456
4457
4458
4459
4460
4461
4462
4463
4464

4465
4466
4467
4468
4469
4470
4471
4434
4435
4436
4437
4438
4439
4440

4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452

4453
4454
4455
4456
4457
4458
4459
4460
4461
4462


4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475

4476
4477
4478
4479
4480
4481
4482
4483







-
+










+
-
+
+
+
+





+
-
-
+
+
+
+
+








-
+








					if (currslot >= (sizeof(cackey_slots) / sizeof(cackey_slots[0]))) {
						CACKEY_DEBUG_PRINTF("Found more readers than slots are available!");

						break;
					}

					CACKEY_DEBUG_PRINTF("Found reader: %s", pcsc_readers);
					CACKEY_DEBUG_PRINTF("Found reader: %s (currslot = %lu)", pcsc_readers, (unsigned long) currslot);

					/* Only update the list of slots if we are actually being asked supply the slot information */
					if (pSlotList) {
						if (slot_reset) {
							cackey_slots[currslot].active = 1;
							cackey_slots[currslot].internal = 0;
							cackey_slots[currslot].pcsc_reader = strdup(pcsc_readers);
							cackey_slots[currslot].pcsc_card_connected = 0;
							cackey_slots[currslot].transaction_depth = 0;
							cackey_slots[currslot].transaction_need_hw_lock = 0;
							if (cackey_pin_command == NULL) {
							cackey_slots[currslot].token_flags = CKF_LOGIN_REQUIRED;
								cackey_slots[currslot].token_flags = CKF_LOGIN_REQUIRED;
							} else {
								cackey_slots[currslot].token_flags = 0;
							}
							cackey_slots[currslot].label = NULL;

							cackey_mark_slot_reset(&cackey_slots[currslot]);
						}
					} else {
						if (!cackey_slots[currslot].active) {
						/* Artificially increase the number of active slots by what will become active */
						slot_count++;
							/* Artificially increase the number of active slots by what will become active */
							CACKEY_DEBUG_PRINTF("Found in-active slot %lu, but it will be active after a reset -- marking as active for accounting purposes", (unsigned long) currslot);

							slot_count++;
						}
					}
					currslot++;

					pcsc_readers += curr_reader_len + 1;
				}

				for (currslot = 0; currslot < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); currslot++) {
					if (cackey_slots[currslot].active) {
						CACKEY_DEBUG_PRINTF("Found active slot %lu", (unsigned long) currslot);
						CACKEY_DEBUG_PRINTF("Found active slot %lu, reader = %s", (unsigned long) currslot, cackey_slots[currslot].pcsc_reader);

						slot_count++;
					}
				}
			} else {
				CACKEY_DEBUG_PRINTF("Second call to SCardListReaders failed, return %s/%li", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_listreaders_ret), (long) scard_listreaders_ret);
			}
5186
5187
5188
5189
5190
5191
5192
5193

5194
5195
5196
5197
5198
5199
5200
5198
5199
5200
5201
5202
5203
5204

5205
5206
5207
5208
5209
5210
5211
5212







-
+







	}

	CACKEY_DEBUG_PRINTF("Returning CKR_FUNCTION_NOT_SUPPORTED (%i)", CKR_FUNCTION_NOT_SUPPORTED);

	return(CKR_FUNCTION_NOT_SUPPORTED);
}

CK_DEFINE_FUNCTION(CK_RV, C_Login)(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen) {
CK_DEFINE_FUNCTION(CK_RV, _C_LoginMutexArg)(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen, int lock_mutex) {
	CK_SLOT_ID slotID;
	FILE *pinfd;
	char *pincmd, pinbuf[64], *fgets_ret;
	int mutex_retval;
	int tries_remaining;
	int login_ret;
	int pclose_ret;
5215
5216
5217
5218
5219
5220
5221

5222
5223
5224



5225
5226


5227
5228
5229

5230


5231
5232
5233
5234
5235
5236
5237
5238
5239
5240




5241
5242
5243
5244
5245
5246
5247

5248


5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264

5265


5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280

5281


5282
5283
5284
5285
5286
5287
5288
5289
5290

5291


5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307

5308


5309
5310
5311
5312
5313
5314
5315
5227
5228
5229
5230
5231
5232
5233
5234



5235
5236
5237
5238

5239
5240
5241
5242
5243
5244

5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268

5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287

5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305

5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317

5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336

5337
5338
5339
5340
5341
5342
5343
5344
5345







+
-
-
-
+
+
+

-
+
+



+
-
+
+










+
+
+
+







+
-
+
+
















+
-
+
+















+
-
+
+









+
-
+
+
















+
-
+
+








	if (userType != CKU_USER) {
		CACKEY_DEBUG_PRINTF("Error.  We only support USER mode, asked for %lu mode.", (unsigned long) userType)

		return(CKR_USER_TYPE_INVALID);
	}

	if (lock_mutex) {
	mutex_retval = cackey_mutex_lock(cackey_biglock);
	if (mutex_retval != 0) {
		CACKEY_DEBUG_PRINTF("Error.  Locking failed.");
		mutex_retval = cackey_mutex_lock(cackey_biglock);
		if (mutex_retval != 0) {
			CACKEY_DEBUG_PRINTF("Error.  Locking failed.");

		return(CKR_GENERAL_ERROR);
			return(CKR_GENERAL_ERROR);
		}
	}

	if (!cackey_sessions[hSession].active) {
		if (lock_mutex) {
		cackey_mutex_unlock(cackey_biglock);
			cackey_mutex_unlock(cackey_biglock);
		}

		CACKEY_DEBUG_PRINTF("Error.  Session not active.");
		
		return(CKR_SESSION_HANDLE_INVALID);
	}

	slotID = cackey_sessions[hSession].slotID;

	if (slotID < 0 || slotID >= (sizeof(cackey_slots) / sizeof(cackey_slots[0]))) {
		CACKEY_DEBUG_PRINTF("Error. Invalid slot requested (%lu), outside of valid range", slotID);

		if (lock_mutex) {
			cackey_mutex_unlock(cackey_biglock);
		}

		return(CKR_GENERAL_ERROR);
	}

	if (cackey_slots[slotID].active == 0) {
		CACKEY_DEBUG_PRINTF("Error. Invalid slot requested (%lu), slot not currently active", slotID);

		if (lock_mutex) {
		cackey_mutex_unlock(cackey_biglock);
			cackey_mutex_unlock(cackey_biglock);
		}

		return(CKR_GENERAL_ERROR);
	}

	pincmd = cackey_pin_command;
	if (pincmd != NULL) {
		CACKEY_DEBUG_PRINTF("CACKEY_PIN_COMMAND = %s", pincmd);

		if (pPin != NULL) {
			CACKEY_DEBUG_PRINTF("Protected authentication path in effect and PIN provided !?");
		}

		pinfd = popen(pincmd, "r");
		if (pinfd == NULL) {
			CACKEY_DEBUG_PRINTF("Error.  %s: Unable to run", pincmd);

			if (lock_mutex) {
			cackey_mutex_unlock(cackey_biglock);
				cackey_mutex_unlock(cackey_biglock);
			}

			CACKEY_DEBUG_PRINTF("Returning CKR_PIN_INCORRECT (%i)", (int) CKR_PIN_INCORRECT);

			return(CKR_PIN_INCORRECT);
		}

		fgets_ret = fgets(pinbuf, sizeof(pinbuf), pinfd);
		if (fgets_ret == NULL) {
			pinbuf[0] = '\0';
		}

		pclose_ret = pclose(pinfd);
		if (pclose_ret != 0) {
			CACKEY_DEBUG_PRINTF("Error.  %s: exited with non-zero status of %i", pincmd, pclose_ret);

			if (lock_mutex) {
			cackey_mutex_unlock(cackey_biglock);
				cackey_mutex_unlock(cackey_biglock);
			}

			CACKEY_DEBUG_PRINTF("Returning CKR_PIN_INCORRECT (%i)", (int) CKR_PIN_INCORRECT);

			return(CKR_PIN_INCORRECT);
		}

		if (strlen(pinbuf) < 1) {
			CACKEY_DEBUG_PRINTF("Error.  %s: returned no data", pincmd);

			if (lock_mutex) {
			cackey_mutex_unlock(cackey_biglock);
				cackey_mutex_unlock(cackey_biglock);
			}

			CACKEY_DEBUG_PRINTF("Returning CKR_PIN_INCORRECT (%i)", (int) CKR_PIN_INCORRECT);

			return(CKR_PIN_INCORRECT);
		}

		if (pinbuf[strlen(pinbuf) - 1] == '\n') {
			pinbuf[strlen(pinbuf) - 1] = '\0';
		}

		pPin = (CK_UTF8CHAR_PTR) pinbuf;
		ulPinLen = strlen(pinbuf);
	}

	login_ret = cackey_login(&cackey_slots[slotID], pPin, ulPinLen, &tries_remaining);
	if (login_ret != CACKEY_PCSC_S_OK) {
		if (lock_mutex) {
		cackey_mutex_unlock(cackey_biglock);
			cackey_mutex_unlock(cackey_biglock);
		}

		if (login_ret == CACKEY_PCSC_E_LOCKED) {
			CACKEY_DEBUG_PRINTF("Error.  Token is locked.");

			cackey_slots[slotID].token_flags |= CKF_USER_PIN_LOCKED;

			CACKEY_DEBUG_PRINTF("Returning CKR_PIN_LOCKED (%i)", (int) CKR_PIN_LOCKED);
5334
5335
5336
5337
5338
5339
5340

5341
5342
5343



5344
5345


5346
5347
5348
5349
5350
5351




5352
5353
5354
5355
5356
5357
5358
5364
5365
5366
5367
5368
5369
5370
5371



5372
5373
5374
5375

5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394







+
-
-
-
+
+
+

-
+
+






+
+
+
+







		return(CKR_GENERAL_ERROR);
	}

	cackey_slots[slotID].token_flags &= ~(CKF_USER_PIN_LOCKED | CKF_USER_PIN_COUNT_LOW | CKF_LOGIN_REQUIRED | CKF_USER_PIN_FINAL_TRY);

	cackey_sessions[hSession].state = CKS_RO_USER_FUNCTIONS;

	if (lock_mutex) {
	mutex_retval = cackey_mutex_unlock(cackey_biglock);
	if (mutex_retval != 0) {
		CACKEY_DEBUG_PRINTF("Error.  Unlocking failed.");
		mutex_retval = cackey_mutex_unlock(cackey_biglock);
		if (mutex_retval != 0) {
			CACKEY_DEBUG_PRINTF("Error.  Unlocking failed.");

		return(CKR_GENERAL_ERROR);
			return(CKR_GENERAL_ERROR);
		}
	}

	CACKEY_DEBUG_PRINTF("Returning CKR_OK (%i)", CKR_OK);

	return(CKR_OK);
}

CK_DEFINE_FUNCTION(CK_RV, C_Login)(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen) {
	return(_C_LoginMutexArg(hSession, userType, pPin, ulPinLen, 1));
}

CK_DEFINE_FUNCTION(CK_RV, C_Logout)(CK_SESSION_HANDLE hSession) {
	CK_SLOT_ID slotID;
	int mutex_retval;

	CACKEY_DEBUG_PRINTF("Called.");

5396
5397
5398
5399
5400
5401
5402


5403




5404
5405
5406
5407
5408
5409
5410
5432
5433
5434
5435
5436
5437
5438
5439
5440

5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451







+
+
-
+
+
+
+








		cackey_mutex_unlock(cackey_biglock);

		return(CKR_GENERAL_ERROR);
	}

	cackey_sessions[hSession].state = CKS_RO_PUBLIC_SESSION;

	if (cackey_pin_command == NULL) {
	cackey_slots[slotID].token_flags = CKF_LOGIN_REQUIRED;
		cackey_slots[slotID].token_flags = CKF_LOGIN_REQUIRED;
	} else {
		cackey_slots[slotID].token_flags = 0;
	}

	mutex_retval = cackey_mutex_unlock(cackey_biglock);
	if (mutex_retval != 0) {
		CACKEY_DEBUG_PRINTF("Error.  Unlocking failed.");

		return(CKR_GENERAL_ERROR);
	}
6320
6321
6322
6323
6324
6325
6326






6327
6328
6329
6330
6331
6332
6333
6334


6335
6336
6337
6338
6339
6340
6341
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390







+
+
+
+
+
+








+
+







		return(CKR_GENERAL_ERROR);
	}

	switch (cackey_sessions[hSession].decrypt_mechanism) {
		case CKM_RSA_PKCS:
			/* Ask card to decrypt */
			buflen = cackey_signdecrypt(&cackey_slots[slotID], cackey_sessions[hSession].decrypt_identity, pEncryptedPart, ulEncryptedPartLen, buf, sizeof(buf), 0, 1);

			if (buflen == CACKEY_PCSC_E_NEEDLOGIN && cackey_pin_command != NULL) {
				if (_C_LoginMutexArg(hSession, CKU_USER, NULL, 0, 0) == CKR_OK) {
					buflen = cackey_signdecrypt(&cackey_slots[slotID], cackey_sessions[hSession].decrypt_identity, pEncryptedPart, ulEncryptedPartLen, buf, sizeof(buf), 0, 1);
				}
			}

			if (buflen < 0) {
				/* Decryption failed. */
				if (buflen == CACKEY_PCSC_E_NEEDLOGIN) {
					retval = CKR_USER_NOT_LOGGED_IN;
				} else if (buflen == CACKEY_PCSC_E_TOKENABSENT) {
					retval = CKR_DEVICE_REMOVED;
				} else {
					CACKEY_DEBUG_PRINTF("Failed to send APDU, error = %li", (long int) buflen);

					retval = CKR_GENERAL_ERROR;
				}
			} else if (((unsigned long) buflen) > *pulPartLen && pPart) {
				/* Decrypted data too large */
				retval = CKR_BUFFER_TOO_SMALL;
			} else {
				if (pPart) {
6831
6832
6833
6834
6835
6836
6837






6838
6839
6840
6841
6842
6843
6844
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899







+
+
+
+
+
+







	}

	switch (cackey_sessions[hSession].sign_mechanism) {
		case CKM_RSA_PKCS:
			/* Ask card to sign */
			CACKEY_DEBUG_PRINTF("Asking to sign from identity %p in session %lu", (void *) cackey_sessions[hSession].sign_identity, (unsigned long) hSession);
			sigbuflen = cackey_signdecrypt(&cackey_slots[slotID], cackey_sessions[hSession].sign_identity, cackey_sessions[hSession].sign_buf, cackey_sessions[hSession].sign_bufused, sigbuf, sizeof(sigbuf), 1, 0);

			if (sigbuflen == CACKEY_PCSC_E_NEEDLOGIN && cackey_pin_command != NULL) {
				if (_C_LoginMutexArg(hSession, CKU_USER, NULL, 0, 0) == CKR_OK) {
					sigbuflen = cackey_signdecrypt(&cackey_slots[slotID], cackey_sessions[hSession].sign_identity, cackey_sessions[hSession].sign_buf, cackey_sessions[hSession].sign_bufused, sigbuf, sizeof(sigbuf), 1, 0);
				}
			}

			if (sigbuflen < 0) {
				/* Signing failed. */
				if (sigbuflen == CACKEY_PCSC_E_NEEDLOGIN) {
					retval = CKR_USER_NOT_LOGGED_IN;
				} else if (sigbuflen == CACKEY_PCSC_E_TOKENABSENT) {
					retval = CKR_DEVICE_REMOVED;

Modified configure.ac from [8333de68f9] to [b130174bba].

1

2
3
4
5
6
7
8

1
2
3
4
5
6
7
8
-
+







AC_INIT(cackey, 0.6.8) 
AC_INIT(cackey, 0.7.0) 
AC_CONFIG_HEADERS(config.h)

dnl Locate standard tools
AC_PROG_CC
AC_PROG_MAKE_SET
AC_PROG_INSTALL
AC_AIX