1 
2 /* ****************************************************************************
3 
4 * eID Middleware Project.
5 * Copyright (C) 2008-2014 FedICT.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License version
9 * 3.0 as published by the Free Software Foundation.
10 *
11 * This software is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this software; if not, see
18 * http://www.gnu.org/licenses/.
19 
20 **************************************************************************** */
21 #include "bytearray.h"
22 #include "eiderrors.h"
23 #include "beid_p11.h"
24 #include "cardlayer.h"
25 #include "readersinfo.h"
26 #include "p11.h"
27 #include "util.h"
28 #include "cal.h"
29 #include "pkcs11log.h"
30 #include "cert.h"
31 #include "mw_util.h"
32 #include "tlvbuffer.h"
33 #include "thread.h"
34 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
35 #include "beid_fuzz.h"
36 #endif
37 #ifndef WIN32
38 #define strcpy_s(a,b,c)         strcpy((a),(c))
39 #define sprintf_s(a,b,c,d)    sprintf((a),(c),(d))
40 
41 //linux config file
42 #ifdef HAVE_CONFIG_H
43 #include "config.h"
44 #endif
45 #endif
46 
47 
48 using namespace eIDMW;
49 
50 CCardLayer *oCardLayer;
51 CReadersInfo *oReadersInfo;
52 
53 extern "C"
54 {
55 	extern unsigned int gRefCount;
56 	extern unsigned int nReaders;
57 	extern bool gSlotsChanged;
58 	extern P11_SLOT gpSlot[MAX_SLOTS];
59 	//local functions
60 	CK_RV cal_translate_error(const char *WHERE, long err);
61 	int cal_map_status(tCardStatus calstatus);
62 }
63 
64 #ifdef PKCS11_FF
65 /*
66 static int gnFFReaders;
67 int cal_getgnFFReaders(void)
68 {
69 	return gnFFReaders;
70 }
71 
72 void cal_setgnFFReaders(int newgnFFReaders)
73 {
74 	gnFFReaders = newgnFFReaders;
75 }
76 
77 void cal_incgnFFReaders(void)
78 {
79 	gnFFReaders++;
80 }
81 
82 void cal_re_establish_context(void)
83 {
84 	oCardLayer->PCSCReEstablishContext();
85 }*/
86 
87 #endif
88 
89 void cal_free_reader_states(SCARD_READERSTATEA * txReaderStates,
90 			    unsigned long ulnReaders);
91 
92 /*
93 long cal_check_pcsc(CK_BBOOL* pRunning)
94 {
95 	//allthough both CK_BBOOL and bool are 1 byte at the moment
96 	bool pbRunning = false;
97 	long error = 0;
98 	error = oCardLayer->PCSCServiceRunning(&pbRunning);
99 	if (pbRunning == true)
100 		*pRunning = CK_TRUE;
101 	else
102 		*pRunning = CK_FALSE;
103 	return error;
104 }*/
105 
cal_wait(int millisecs)106 void cal_wait(int millisecs)
107 {
108 	CThread::SleepMillisecs(millisecs);
109 }
110 
111 /*#define WHERE "cal_init_pcsc()"
112 void cal_init_pcsc()
113 {
114 	oCardLayer->StartPCSCService();
115 }
116 #undef WHERE*/
117 
118 #define WHERE "cal_init()"
cal_init()119 CK_RV cal_init()
120 {
121 	CK_RV ret = CKR_OK;
122 
123 	if (gRefCount > 0)
124 		return 0;
125 
126 	try
127 	{
128 		oCardLayer = new CCardLayer();
129 		oReadersInfo = new CReadersInfo(oCardLayer->ListReaders());
130 	}
131 	catch(CMWException &e)
132 	{
133 		return (cal_translate_error(WHERE, e.GetError()));
134 	}
135 	catch( ...)
136 	{
137 		log_trace(WHERE, "E: unkown exception thrown");
138 		return (CKR_FUNCTION_FAILED);
139 	}
140 
141 	//init slots and token in slots
142 #ifdef PKCS11_FF
143 //	gnFFReaders = 0;
144 #endif
145 	memset(gpSlot, 0, sizeof(gpSlot));
146 	ret = cal_init_slots();
147 	if (ret)
148 		log_trace(WHERE, "E: p11_init_slots() returns %lu", ret);
149 
150 	return (ret);
151 }
152 
153 #undef WHERE
154 
155 
156 #define WHERE "cal_close()"
cal_close()157 void cal_close()
158 {
159 	//Reference count countdown, clean if 0
160 	//if (--gRefCount > 0)
161 	//   return (0);
162 
163 	if (oCardLayer)
164 		delete(oCardLayer);
165 	if (oReadersInfo)
166 		delete(oReadersInfo);
167 
168 	oCardLayer = NULL;
169 	oReadersInfo = NULL;
170 
171 	cal_clean_slots();
172 
173 	return;
174 }
175 
176 #undef WHERE
177 
178 #define WHERE "cal_clean_slots()"
cal_clean_slots()179 void cal_clean_slots()
180 {
181 	unsigned int i;
182 	CK_SLOT_ID hSlot = 0;
183 	P11_SLOT *pSlot = NULL;
184 	P11_OBJECT *pObject = NULL;
185 
186 	for (; hSlot < MAX_SLOTS; hSlot++)
187 	{
188 		pSlot = p11_get_slot(hSlot);
189 		if (pSlot == NULL)
190 		{
191 			//slot not in use
192 			break;
193 		}
194 		//clean objects
195 		for (i = 1; i <= pSlot->nobjects; i++)
196 		{
197 			pObject = p11_get_slot_object(pSlot, i);
198 			p11_clean_object(pObject);
199 			//if (pObject != NULL)
200 			// pObject->state = 0;
201 		}
202 		if (pSlot->pobjects != NULL)
203 		{
204 			free(pSlot->pobjects);
205 			pSlot->pobjects = NULL;
206 			pSlot->ulCardDataCached = 0;
207 		}
208 	}
209 	return;
210 }
211 
212 #undef WHERE
213 
214 
215 
216 #define WHERE "cal_init_slots()"
cal_init_slots(void)217 CK_RV cal_init_slots(void)
218 {
219 	CK_RV ret = CKR_OK;
220 	unsigned int i;
221 
222 	try
223 	{
224 		nReaders = (unsigned int)(oReadersInfo->ReaderCount());
225 		//get readernames
226 		for (i = 0; i < nReaders; i++)
227 		{
228 			//initialize login state to not logged in by SO nor user
229 			gpSlot[i].logged_in = CK_FALSE;
230 			std::string reader = oReadersInfo->ReaderName(i);
231 			strcpy_n((unsigned char *) gpSlot[i].name,
232 				 (const char *) reader.c_str(),
233 				 (unsigned int) reader.size(), (char) '\x00');
234 		}
235 	}
236 	catch(CMWException &e)
237 	{
238 		return (cal_translate_error(WHERE, e.GetError()));
239 	}
240 	catch( ...)
241 	{
242 		log_trace(WHERE, "E: unkown exception thrown");
243 		return (CKR_FUNCTION_FAILED);
244 	}
245 
246 	return (ret);
247 }
248 
249 #undef WHERE
250 
251 
252 #define WHERE "cal_token_present()"
cal_token_present(CK_SLOT_ID hSlot,int * pPresent)253 CK_RV cal_token_present(CK_SLOT_ID hSlot, int *pPresent)
254 {
255 	CK_RV ret = CKR_OK;
256 	int status = P11_CARD_NOT_PRESENT;
257 
258 	ret = cal_update_token(hSlot, &status, 0);
259 
260 	switch (status)
261 	{
262 		case P11_CARD_INSERTED:
263 		case P11_CARD_STILL_PRESENT:
264 		case P11_CARD_OTHER:
265 			*pPresent = 1;
266 			break;
267 		case P11_CARD_NOT_PRESENT:
268 		case P11_CARD_REMOVED:
269 		case P11_CARD_UNKNOWN_STATE:
270 		default:
271 			*pPresent = 0;
272 	}
273 
274 	return (ret);
275 }
276 
277 #undef WHERE
278 
279 
280 
281 
282 #define WHERE "cal_get_token_info()"
cal_get_token_info(CK_SLOT_ID hSlot,CK_TOKEN_INFO_PTR pInfo)283 CK_RV cal_get_token_info(CK_SLOT_ID hSlot, CK_TOKEN_INFO_PTR pInfo)
284 {
285 	CK_RV ret = CKR_OK;
286 	int status;
287 	P11_SLOT *pSlot = NULL;
288 
289 	pInfo->flags = 0;
290 
291 	pSlot = p11_get_slot(hSlot);
292 	if (pSlot == NULL)
293 	{
294 		log_trace(WHERE, "E: Invalid slot (%lu)", hSlot);
295 		return (CKR_SLOT_ID_INVALID);
296 	}
297 
298 	std::string reader = pSlot->name;
299 
300 	ret = cal_update_token(hSlot, &status, 0);
301 	if (ret != CKR_OK)
302 		goto cleanup;
303 
304 	if ((status == P11_CARD_REMOVED) || (status == P11_CARD_NOT_PRESENT))
305 	{
306 		ret = CKR_TOKEN_NOT_PRESENT;
307 		goto cleanup;
308 	}
309 
310 	pInfo->firmwareVersion.major = 1;
311 	pInfo->firmwareVersion.minor = 0;
312 
313 	try
314 	{
315 		// Take the last 16 hex chars of the serialnr.
316 		// For BE eID cards, the serial nr. is 32 hex chars long,
317 		// and the first one are the same for all cards
318 		CReader & oReader = oCardLayer->getReader(reader);
319 		CCard* poCard = oReader.GetCard();
320 
321 		std::string oSerialNr = poCard->GetSerialNr();
322 		size_t serialNrLen = oSerialNr.size();
323 		size_t snoffset = serialNrLen > 16 ? serialNrLen - 16 : 0;
324 		size_t snlen = serialNrLen - snoffset > 16 ? 16 : serialNrLen - snoffset;
325 		//printf("off = %d, len = %d\n", snoffset, snlen);
326 		strcpy_n(pInfo->serialNumber, oSerialNr.c_str() + snoffset, snlen, ' ');
327 		strcpy_n(pInfo->label, poCard->GetCardLabel().c_str(), 32,  ' ');
328 		if (poCard->IsPinpadReader())
329 			pInfo->flags = CKF_PROTECTED_AUTHENTICATION_PATH;
330 		pInfo->firmwareVersion.major = poCard->GetAppletVersion();
331 	}
332 	catch(CMWException &e)
333 	{
334 		return (cal_translate_error(WHERE, e.GetError()));
335 	}
336 	catch( ...)
337 	{
338 		log_trace(WHERE, "E: unkown exception thrown");
339 		return (CKR_FUNCTION_FAILED);
340 	}
341 
342 	strcpy_n(pInfo->manufacturerID, "Belgium Government", 32, ' ');
343 	strcpy_n(pInfo->model, "Belgium eID", 16, ' ');
344 	// strcpy_n(pInfo->label, "Belgian eID", 16, ' '); // FRANK TEST
345 
346 	/* Take the last 16 chars of the serial number (if the are more then 16).
347 	   _Assuming_ that the serial number is a Big Endian counter, this will
348 	   assure that the serial within each type of card will be unique in pkcs11
349 	   (at least for the first 16^16 cards :-) */
350 	//if (sn_start < 0)
351 	//   sn_start = 0;
352 
353 	pInfo->ulMaxSessionCount = MAX_SESSIONS;	//CK_EFFECTIVELY_INFINITE;
354 	pInfo->ulSessionCount = pSlot->nsessions;
355 	pInfo->ulMaxRwSessionCount = MAX_RW_SESSIONS;
356 	pInfo->ulRwSessionCount = 0;	/* FIXME */
357 	pInfo->ulTotalPublicMemory = CK_UNAVAILABLE_INFORMATION;
358 	pInfo->ulFreePublicMemory = CK_UNAVAILABLE_INFORMATION;
359 	pInfo->ulTotalPrivateMemory = CK_UNAVAILABLE_INFORMATION;
360 	pInfo->ulFreePrivateMemory = CK_UNAVAILABLE_INFORMATION;
361 	pInfo->hardwareVersion.major = 1;
362 	pInfo->hardwareVersion.minor = 0;
363 
364 	pInfo->ulMaxPinLen = 12;
365 	pInfo->ulMinPinLen = 4;
366 	strcpy_s((char *) pInfo->utcTime, sizeof(pInfo->utcTime),
367 		 "20080101000000");
368 
369 	pInfo->flags |= CKF_WRITE_PROTECTED | CKF_TOKEN_INITIALIZED | CKF_USER_PIN_INITIALIZED;	// check for pin change capabilitypInfo->flags |= /*CKF_LOGIN_REQUIRED |  CKF_USER_PIN_INITIALIZED |*/; //CAL does logon, so no CKF_LOGIN_REQUIRED nor CKF_USER_PIN_INITIALIZED
370 #ifdef NO_DIALOGS
371 	pInfo->flags |= CKF_LOGIN_REQUIRED;	// no dialogs, so we ask the calling program to ask for PIN
372 #endif
373       cleanup:
374 
375 	return (ret);
376 }
377 
378 #undef WHERE
379 
380 
381 
382 
383 #define WHERE "cal_get_mechanism_list()"
cal_get_mechanism_list(CK_SLOT_ID hSlot,CK_MECHANISM_TYPE_PTR pMechanismList,CK_ULONG_PTR pulCount)384 CK_RV cal_get_mechanism_list(CK_SLOT_ID hSlot,
385 			     CK_MECHANISM_TYPE_PTR pMechanismList,
386 			     CK_ULONG_PTR pulCount)
387 {
388 	CK_RV ret = CKR_OK;
389 	int status;
390 	P11_SLOT *pSlot = NULL;
391 
392 	pSlot = p11_get_slot(hSlot);
393 	if (pSlot == NULL)
394 	{
395 		log_trace(WHERE, "E: Invalid slot (%lu)", hSlot);
396 		return (CKR_SLOT_ID_INVALID);
397 	}
398 
399 	std::string szReader = pSlot->name;
400 	unsigned long algos = 0;
401 	unsigned int n = 0;
402 
403 	ret = cal_update_token(hSlot, &status, 0);
404 	if (ret != CKR_OK)
405 	{
406 		return (ret);
407 	}
408 
409 	if ((status == P11_CARD_REMOVED) || (status == P11_CARD_NOT_PRESENT))
410 	{
411 		return (CKR_TOKEN_NOT_PRESENT);
412 	}
413 
414 	try
415 	{
416 		CReader & oReader = oCardLayer->getReader(szReader);
417 		CCard* poCard = oReader.GetCard();
418 		algos = poCard->GetCardSupportedAlgorithms();
419 	}
420 	catch(CMWException &e)
421 	{
422 		return (cal_translate_error(WHERE, e.GetError()));
423 	}
424 	catch( ...)
425 	{
426 		log_trace(WHERE, "E: unkown exception thrown");
427 		return (CKR_FUNCTION_FAILED);
428 	}
429 
430 	if (pMechanismList == NULL)
431 	{
432 		*pulCount = 6;	//for 6 hash algos
433 
434 		if (algos & SIGN_ALGO_RSA_PKCS)
435 			*pulCount += 1;
436 		if (algos & SIGN_ALGO_MD5_RSA_PKCS)
437 			*pulCount += 1;
438 		if (algos & SIGN_ALGO_SHA1_RSA_PKCS)
439 			*pulCount += 1;
440 		if (algos & SIGN_ALGO_SHA256_RSA_PKCS)
441 			*pulCount += 1;
442 		if (algos & SIGN_ALGO_SHA384_RSA_PKCS)
443 			*pulCount += 1;
444 		if (algos & SIGN_ALGO_SHA512_RSA_PKCS)
445 			*pulCount += 1;
446 		if (algos & SIGN_ALGO_RIPEMD160_RSA_PKCS)
447 			*pulCount += 1;
448 		if (algos & SIGN_ALGO_SHA1_RSA_PSS)
449 			*pulCount += 1;
450 		if (algos & SIGN_ALGO_SHA256_RSA_PSS)
451 			*pulCount += 1;
452 		if (algos & SIGN_ALGO_SHA256_ECDSA)
453 			*pulCount += 1;
454 		if (algos & SIGN_ALGO_SHA384_ECDSA)
455 			*pulCount += 1;
456 		if (algos & SIGN_ALGO_SHA512_ECDSA)
457 			*pulCount += 1;
458 		if (algos & SIGN_ALGO_ECDSA_RAW)
459 			*pulCount += 1;
460 		// TODO: also add SHA3 mechanisms -- PKCS#11 v2.40 does not yet support those, though; PKCS#11 v3 will, but is not released yet.
461 		return (CKR_OK);
462 	}
463 
464 	/* hash algos */
465 	if (n++ < *pulCount)
466 		pMechanismList[n - 1] = CKM_MD5;
467 	else
468 		return (CKR_BUFFER_TOO_SMALL);
469 
470 	if (n++ < *pulCount)
471 		pMechanismList[n - 1] = CKM_SHA_1;
472 	else
473 		return (CKR_BUFFER_TOO_SMALL);
474 
475 	if (n++ < *pulCount)
476 		pMechanismList[n - 1] = CKM_SHA256;
477 	else
478 		return (CKR_BUFFER_TOO_SMALL);
479 
480 	if (n++ < *pulCount)
481 		pMechanismList[n - 1] = CKM_SHA384;
482 	else
483 		return (CKR_BUFFER_TOO_SMALL);
484 
485 	if (n++ < *pulCount)
486 		pMechanismList[n - 1] = CKM_SHA512;
487 	else
488 		return (CKR_BUFFER_TOO_SMALL);
489 
490 	if (n++ < *pulCount)
491 		pMechanismList[n - 1] = CKM_RIPEMD160;
492 	else
493 		return (CKR_BUFFER_TOO_SMALL);
494 
495 	/* sign algos */
496 	if (algos & SIGN_ALGO_RSA_PKCS)
497 	{
498 		if (n++ < *pulCount)
499 			pMechanismList[n - 1] = CKM_RSA_PKCS;
500 		else
501 			return (CKR_BUFFER_TOO_SMALL);
502 	}
503 	if (algos & SIGN_ALGO_MD5_RSA_PKCS)
504 	{
505 		if (n++ < *pulCount)
506 			pMechanismList[n - 1] = CKM_MD5_RSA_PKCS;
507 		else
508 			return (CKR_BUFFER_TOO_SMALL);
509 	}
510 	if (algos & SIGN_ALGO_SHA1_RSA_PKCS)
511 	{
512 		if (n++ < *pulCount)
513 			pMechanismList[n - 1] = CKM_SHA1_RSA_PKCS;
514 		else
515 			return (CKR_BUFFER_TOO_SMALL);
516 	}
517 	if (algos & SIGN_ALGO_SHA256_RSA_PKCS)
518 	{
519 		if (n++ < *pulCount)
520 			pMechanismList[n - 1] = CKM_SHA256_RSA_PKCS;
521 		else
522 			return (CKR_BUFFER_TOO_SMALL);
523 	}
524 	if (algos & SIGN_ALGO_SHA384_RSA_PKCS)
525 	{
526 		if (n++ < *pulCount)
527 			pMechanismList[n - 1] = CKM_SHA384_RSA_PKCS;
528 		else
529 			return (CKR_BUFFER_TOO_SMALL);
530 	}
531 	if (algos & SIGN_ALGO_SHA512_RSA_PKCS)
532 	{
533 		if (n++ < *pulCount)
534 			pMechanismList[n - 1] = CKM_SHA512_RSA_PKCS;
535 		else
536 			return (CKR_BUFFER_TOO_SMALL);
537 	}
538 	if (algos & SIGN_ALGO_RIPEMD160_RSA_PKCS)
539 	{
540 		if (n++ < *pulCount)
541 			pMechanismList[n - 1] = CKM_RIPEMD160_RSA_PKCS;
542 		else
543 			return (CKR_BUFFER_TOO_SMALL);
544 	}
545 	if (algos & SIGN_ALGO_SHA1_RSA_PSS)
546 	{
547 		if (n++ < *pulCount)
548 			pMechanismList[n - 1] = CKM_SHA1_RSA_PKCS_PSS;
549 		else
550 			return (CKR_BUFFER_TOO_SMALL);
551 	}
552 	if (algos & SIGN_ALGO_SHA256_RSA_PSS)
553 	{
554 		if (n++ < *pulCount)
555 			pMechanismList[n - 1] = CKM_SHA256_RSA_PKCS_PSS;
556 		else
557 			return (CKR_BUFFER_TOO_SMALL);
558 	}
559 	if (algos & SIGN_ALGO_SHA256_ECDSA)
560 	{
561 		if (n++ < *pulCount)
562 			pMechanismList[n - 1] = CKM_ECDSA_SHA256;
563 		else
564 			return (CKR_BUFFER_TOO_SMALL);
565 	}
566 	if (algos & SIGN_ALGO_SHA384_ECDSA)
567 	{
568 		if (n++ < *pulCount)
569 			pMechanismList[n - 1] = CKM_ECDSA_SHA384;
570 		else
571 			return (CKR_BUFFER_TOO_SMALL);
572 	}
573 	if (algos & SIGN_ALGO_SHA512_ECDSA)
574 	{
575 		if (n++ < *pulCount)
576 			pMechanismList[n - 1] = CKM_ECDSA_SHA512;
577 		else
578 			return (CKR_BUFFER_TOO_SMALL);
579 	}
580 	if (algos & SIGN_ALGO_ECDSA_RAW)
581 	{
582 		if (n++ < *pulCount)
583 			pMechanismList[n - 1] = CKM_ECDSA;
584 		else
585 			return (CKR_BUFFER_TOO_SMALL);
586 	}
587 	return (ret);
588 }
589 
590 #undef WHERE
591 
592 
593 
594 #define WHERE "cal_get_mechanism_info()"
cal_get_mechanism_info(CK_SLOT_ID hSlot,CK_MECHANISM_TYPE type,CK_MECHANISM_INFO_PTR pInfo)595 CK_RV cal_get_mechanism_info(CK_SLOT_ID hSlot, CK_MECHANISM_TYPE type,
596 			     CK_MECHANISM_INFO_PTR pInfo)
597 {
598 	CK_RV ret = CKR_OK;
599 	P11_MECHANISM_INFO table[] = CAL_MECHANISM_TABLE;
600 	P11_MECHANISM_INFO *info = NULL;
601 	int status;
602 	int i;
603 
604 	if (pInfo == NULL_PTR)
605 	{
606 		ret = CKR_ARGUMENTS_BAD;
607 		goto cleanup;
608 	}
609 	//look for type in table
610 	for (i = 0; i < (int)(sizeof(table) / sizeof(table[0])); i++)
611 	{
612 		if (table[i].type == type)
613 		{
614 			info = &table[i];
615 			break;
616 		}
617 	}
618 
619 	if ((info) && (info->type))
620 	{
621 		if (info->flags & CKF_SIGN)
622 		{
623 			ret = cal_update_token(hSlot, &status, 0);
624 			if (ret != CKR_OK)
625 			{
626 				return (ret);
627 			}
628 
629 			if ((status == P11_CARD_REMOVED) || (status == P11_CARD_NOT_PRESENT))
630 			{
631 				return (CKR_TOKEN_NOT_PRESENT);
632 			}
633 
634 			try
635 			{
636 				P11_SLOT *pSlot = p11_get_slot(hSlot);
637 
638 				if (pSlot == NULL)
639 				{
640 					log_trace(WHERE, "E: Invalid slot(%lu)", hSlot);
641 					return (CKR_SLOT_ID_INVALID);
642 				}
643 				std::string szReader = pSlot->name;
644 
645 				CReader & oReader = oCardLayer->getReader(szReader);
646 				CCard* poCard = oReader.GetCard();
647 				pInfo->ulMinKeySize = pInfo->ulMaxKeySize = (CK_ULONG)poCard->GetPrivKeySize();
648 			}
649 			catch(CMWException &e)
650 			{
651 				return (cal_translate_error
652 					(WHERE, e.GetError()));
653 			}
654 			catch( ...)
655 			{
656 				log_trace(WHERE, "E: unknown exception thrown");
657 				return (CKR_FUNCTION_FAILED);
658 			}
659 		} else
660 		{
661 			pInfo->ulMinKeySize = info->ulMinKeySize;
662 			pInfo->ulMaxKeySize = info->ulMaxKeySize;
663 		}
664 		pInfo->flags = info->flags;
665 	} else
666 		ret = CKR_MECHANISM_INVALID;
667 
668       cleanup:
669 
670 	return (ret);
671 }
672 
673 #undef WHERE
674 
675 
676 
677 
678 #define WHERE "cal_connect()"
cal_connect(CK_SLOT_ID hSlot)679 CK_RV cal_connect(CK_SLOT_ID hSlot)
680 {
681 	CK_RV ret = CKR_OK;
682 	int status;
683 	P11_SLOT *pSlot = NULL;
684 
685 	//connect to token
686 	ret = cal_update_token(hSlot, &status, 0);
687 	if (ret != CKR_OK)
688 		goto cleanup;
689 
690 	if ((status == P11_CARD_REMOVED) || (status == P11_CARD_NOT_PRESENT))
691 	{
692 		ret = CKR_TOKEN_NOT_PRESENT;
693 		goto cleanup;
694 	}
695 
696 	pSlot = p11_get_slot(hSlot);
697 	if (pSlot == NULL)
698 	{
699 		log_trace(WHERE, "E: Invalid slot (%lu)", hSlot);
700 		return (CKR_SLOT_ID_INVALID);
701 	}
702 
703 	pSlot->connect++;
704 
705       cleanup:
706 
707 	return (ret);
708 }
709 
710 #undef WHERE
711 
712 
713 
714 #define WHERE "cal_disconnect()"
cal_disconnect(CK_SLOT_ID hSlot)715 CK_RV cal_disconnect(CK_SLOT_ID hSlot)
716 {
717 	CK_RV ret = 0;
718 	P11_SLOT *pSlot = NULL;
719 
720 	pSlot = p11_get_slot(hSlot);
721 	if (pSlot == NULL)
722 	{
723 		log_trace(WHERE, "E: Invalid slot (%lu)", hSlot);
724 		return (CKR_SLOT_ID_INVALID);
725 	}
726 
727 	if (pSlot->connect > 0)
728 		pSlot->connect--;
729 
730 	if (pSlot->connect < 1)
731 	{
732 		pSlot->connect = 0;
733 		std::string szreader = pSlot->name;
734 		try
735 		{
736 			CReader & oReader = oCardLayer->getReader(szreader);
737 			oReader.Disconnect();
738 		}
739 		catch(CMWException &e)
740 		{
741 			return (cal_translate_error(WHERE, e.GetError()));
742 		}
743 		catch( ...)
744 		{
745 			log_trace(WHERE, "E: unkown exception thrown");
746 			return (CKR_FUNCTION_FAILED);
747 		}
748 	}
749 	return ret;
750 }
751 
752 #undef WHERE
753 
754 
755 #define WHERE "cal_init_objects()"
cal_init_objects(P11_SLOT * pSlot)756 CK_RV cal_init_objects(P11_SLOT * pSlot)
757 {
758 	CK_RV ret = CKR_OK;
759 	CK_ATTRIBUTE PRV_KEY_RSA[] = BEID_TEMPLATE_PRV_KEY_RSA;
760 	CK_ATTRIBUTE PUB_KEY_RSA[] = BEID_TEMPLATE_PUB_KEY_RSA;
761 	CK_ATTRIBUTE PRV_KEY_EC[] = BEID_TEMPLATE_PRV_KEY_EC;
762 	CK_ATTRIBUTE PUB_KEY_EC[] = BEID_TEMPLATE_PUB_KEY_EC;
763 	CK_ATTRIBUTE CERTIFICATE[] = BEID_TEMPLATE_CERTIFICATE;
764 	CK_ULONG hObject = 0;
765 	P11_OBJECT *pObject = NULL;
766 	CK_KEY_TYPE keytype = CKK_RSA;
767 	CK_BBOOL btrue = CK_TRUE;
768 	CK_BBOOL bfalse = CK_FALSE;
769 	CK_ULONG modsize = 0;	/* TODO read from pkcs15 */
770 	CK_ULONG CertId = 0;
771 	CK_ULONG KeyId = 0;
772 	unsigned int certCounter = 0;
773 	unsigned int keyCounter = 0;
774 	char clabel[128];
775 	CK_CERTIFICATE_TYPE certType = CKC_X_509;
776 
777 	//check if the object list is initialized, and if so, return with OK
778 	if (pSlot->ulCardDataCached & CACHED_DATA_TYPE_CDF)
779 		return CKR_OK;
780 
781 	//this function will initialize objects as they are valid for the token
782 	//this function does not read the actual values but enables an application to
783 	//search for an attribute
784 	//attributes are only read from the token as needed and thereafter they are cached
785 	//they remain valid as long as the connection with the smartcard remains valid
786 	//an application might check the PCKS#15 on the card to initialize the PKCS#11 objects here
787 	//or can decide to do this statically
788 
789 	//mapping between these PKCS11 objects and "real" beid objects is done through CLASS type and ID
790 	// e.g. CKA_CLASS=CKO_PRIVATE_KEY and CK_ID=0   => this object is representative for the authentication key on the card.
791 	//      CKA_CLASS=CKO_PUBKEY and CK_ID=0        => this object is represents the public key found in the authentication certificate
792 	//                                                 to read this public key, we read the certificate and extract the public key components
793 
794 	//set attribute template, CKA_TOKEN to true, fill CKA_CLASS type, ID value and CKA_PRIVATE flag
795 
796 	std::string szReader = pSlot->name;
797 	try
798 	{
799 		CReader & oReader = oCardLayer->getReader(szReader);
800 		CCard* poCard = oReader.GetCard();
801 
802 		/* add all certificate objects from card */
803 		for (certCounter = 0; certCounter < poCard->CertCount(); certCounter++)
804 		{
805 			CertId = (CK_ULONG)poCard->GetCert(certCounter).ulID;
806 
807 			sprintf_s(clabel, sizeof(clabel), "%s", poCard->GetCert(certCounter).csLabel.c_str());
808 
809 			ret = p11_add_slot_object(pSlot, CERTIFICATE, sizeof(CERTIFICATE) / sizeof(CK_ATTRIBUTE), CK_TRUE, CKO_CERTIFICATE, CertId, CK_FALSE, &hObject);
810 			if (ret != CKR_OK)
811 				goto cleanup;
812 			pObject = p11_get_slot_object(pSlot, hObject);
813 
814 			ret = p11_set_attribute_value(pObject->pAttr, pObject->count, CKA_CERTIFICATE_TYPE, (CK_VOID_PTR) & certType, sizeof(CK_ULONG));
815 			if (ret != CKR_OK)
816 				goto cleanup;
817 			ret = p11_set_attribute_value(pObject->pAttr, pObject->count, CKA_LABEL, (CK_VOID_PTR) clabel, (CK_ULONG)strlen(clabel));
818 			if (ret != CKR_OK)
819 				goto cleanup;
820 
821 			//only add keys that have a matching cert
822 			for (keyCounter = 0; keyCounter < poCard->PrivKeyCount(); keyCounter++)
823 			{
824 				/***************/
825 				/* Private key */
826 
827 				/***************/
828 				tPrivKey key = poCard->GetPrivKey(keyCounter);
829 				keytype = (key.keyType == RSA ? CKK_RSA : CKK_EC);
830 
831 				KeyId = (CK_ULONG) key.ulID;
832 
833 				if (KeyId == CertId)
834 				{
835 
836 					sprintf_s(clabel, sizeof(clabel), "%s", key.csLabel.c_str());
837 
838 					if (key.keyType == RSA) {
839 						ret = p11_add_slot_object(pSlot, PRV_KEY_RSA, sizeof(PRV_KEY_RSA) / sizeof(CK_ATTRIBUTE), CK_TRUE, CKO_PRIVATE_KEY, KeyId, CK_TRUE, &hObject);
840 						if (ret != CKR_OK)
841 							goto cleanup;
842 					}
843 					else { //if (key.keyType == EC)
844 						ret = p11_add_slot_object(pSlot, PRV_KEY_EC, sizeof(PRV_KEY_EC) / sizeof(CK_ATTRIBUTE), CK_TRUE, CKO_PRIVATE_KEY, KeyId, CK_TRUE, &hObject);
845 						if (ret != CKR_OK)
846 							goto cleanup;
847 					}
848 
849 					//put some other attribute items allready so the key can be used for signing
850 					pObject = p11_get_slot_object(pSlot, hObject);
851 
852 					ret = p11_set_attribute_value(pObject->pAttr, pObject->count, CKA_LABEL, (CK_VOID_PTR) clabel, (CK_ULONG) strlen(clabel));
853 					if (ret != CKR_OK)
854 						goto cleanup;
855 
856 					ret = p11_set_attribute_value(pObject->pAttr, pObject->count, CKA_KEY_TYPE, (CK_VOID_PTR) & keytype, sizeof(CK_KEY_TYPE));
857 					if (ret != CKR_OK)
858 						goto cleanup;
859 
860 					//TODO if (ulKeyUsage & SIGN)
861 					{
862 						ret = p11_set_attribute_value(pObject->pAttr, pObject->count, CKA_SIGN, (CK_VOID_PTR) & btrue, sizeof(btrue));
863 						if (ret != CKR_OK)
864 							goto cleanup;
865 					}
866 
867 					//TODO error in cal, size is in bits allready
868 					if(key.keyType == RSA) {
869 						modsize = key.ulKeyLenBytes * 8;
870 						ret = p11_set_attribute_value(pObject->pAttr, pObject->count, CKA_MODULUS_BITS, (CK_VOID_PTR) & modsize, sizeof(CK_ULONG));
871 						if (ret != CKR_OK)
872 							goto cleanup;
873 					}
874 					//in case keyType == EC, do not pre-fill the CKA_EC_PARAMS with { 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22 }
875 					//we'll read the EC curve from the matching certificate later
876 					/*else { // if (key.keyType == EC)
877 						unsigned char ECCurve[] = { 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22 };
878 						ret = p11_set_attribute_value(pObject->pAttr, pObject->count, CKA_EC_PARAMS, (CK_VOID_PTR)& ECCurve, sizeof(ECCurve));
879 						if (ret != CKR_OK)
880 							goto cleanup;
881 					}*/
882 					ret = p11_set_attribute_value(pObject->pAttr, pObject->count, CKA_EXTRACTABLE, (CK_VOID_PTR) & bfalse, sizeof(bfalse));
883 					if (ret != CKR_OK)
884 						goto cleanup;
885 					ret = p11_set_attribute_value(pObject->pAttr, pObject->count, CKA_DERIVE, (CK_VOID_PTR) & bfalse, sizeof(bfalse));
886 					if (ret != CKR_OK)
887 						goto cleanup;
888 
889 					/**************************************************/
890 					/* Public key corresponding to private key object */
891 
892 					/**************************************************/
893 
894 					if (key.keyType == RSA) {
895 						ret = p11_add_slot_object(pSlot, PUB_KEY_RSA, sizeof(PUB_KEY_RSA) / sizeof(CK_ATTRIBUTE), CK_TRUE, CKO_PUBLIC_KEY, KeyId, CK_FALSE, &hObject);
896 						if (ret != CKR_OK)
897 							goto cleanup;
898 					}
899 					else { //if (key.keyType == EC)
900 						ret = p11_add_slot_object(pSlot, PUB_KEY_EC, sizeof(PUB_KEY_EC) / sizeof(CK_ATTRIBUTE), CK_TRUE, CKO_PUBLIC_KEY, KeyId, CK_FALSE, &hObject);
901 						if (ret != CKR_OK)
902 							goto cleanup;
903 					}
904 
905 					pObject = p11_get_slot_object(pSlot, hObject);
906 
907 					sprintf_s(clabel, sizeof(clabel), "%s", key.csLabel.c_str());
908 					ret = p11_set_attribute_value(pObject->pAttr, pObject->count, CKA_LABEL, (CK_VOID_PTR) clabel, (CK_ULONG) strlen(clabel));
909 					if (ret != CKR_OK)
910 						goto cleanup;
911 					ret = p11_set_attribute_value(pObject->pAttr, pObject->count, CKA_KEY_TYPE, (CK_VOID_PTR) & keytype, sizeof(CK_KEY_TYPE));
912 					if (ret != CKR_OK)
913 						goto cleanup;
914 					if(key.keyType == RSA) {
915 						ret = p11_set_attribute_value(pObject->pAttr, pObject->count, CKA_MODULUS_BITS, (CK_VOID_PTR) & modsize, sizeof(CK_ULONG));
916 						if (ret != CKR_OK)
917 							goto cleanup;
918 					}
919 					//in case keyType == EC, do not pre-fill the CKA_EC_PARAMS with { 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22 }
920 					//we'll read the EC curve from the matching certificate later
921 					/*else {// if (key.keyType == EC)
922 						unsigned char ECCurve[] = { 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22 };
923 						ret = p11_set_attribute_value(pObject->pAttr, pObject->count, CKA_EC_PARAMS, (CK_VOID_PTR)& ECCurve, sizeof(ECCurve));
924 						if (ret != CKR_OK)
925 							goto cleanup;
926 					}*/
927 					ret = p11_set_attribute_value(pObject->pAttr, pObject->count, CKA_DERIVE, (CK_VOID_PTR) & bfalse, sizeof(bfalse));
928 					if (ret != CKR_OK)
929 						goto cleanup;
930 				}
931 			}
932 		}
933 	}
934 	catch(CMWException &e)
935 	{
936 		return (cal_translate_error(WHERE, e.GetError()));
937 	}
938 	catch( ...)
939 	{
940 		log_trace(WHERE, "E: unkown exception thrown");
941 		return (CKR_FUNCTION_FAILED);
942 	}
943 
944       cleanup:
945 	pSlot->ulCardDataCached |= CACHED_DATA_TYPE_CDF;
946 	return (ret);
947 }
948 
949 #undef WHERE
950 
951 
952 
953 #define WHERE "cal_logon()"
cal_logon(CK_SLOT_ID hSlot,size_t l_pin,CK_CHAR_PTR pin,int sec_messaging)954 CK_RV cal_logon(CK_SLOT_ID hSlot, size_t l_pin, CK_CHAR_PTR pin,
955 		int sec_messaging)
956 {
957 	CK_RV ret = CKR_OK;
958 	char cpin[20];
959 	P11_SLOT *pSlot = NULL;
960 
961 	pSlot = p11_get_slot(hSlot);
962 	if (pSlot == NULL)
963 	{
964 		log_trace(WHERE, "E: Invalid slot (%lu)", hSlot);
965 		return (CKR_SLOT_ID_INVALID);
966 	}
967 
968 	std::string szReader = pSlot->name;
969 
970 	memset(cpin, 0, sizeof(cpin));
971 	if (pin && (l_pin < sizeof(cpin)))
972 		memcpy(cpin, pin, l_pin);
973 
974 	std::string csPin = cpin;
975 	unsigned long ulRemaining = 0;
976 
977 	try
978 	{
979 		CReader& oReader = oCardLayer->getReader(szReader);
980 		CCard* poCard = oReader.GetCard();
981 
982 		if (!poCard->PinCmd(PIN_OP_VERIFY, PinBeid, csPin, "", ulRemaining))
983 		{
984 			if (ulRemaining == 0)
985 				ret = CKR_PIN_LOCKED;
986 			else
987 				ret = CKR_PIN_INCORRECT;
988 		}
989 	}
990 	catch(CMWException &e)
991 	{
992 		return (cal_translate_error(WHERE, e.GetError()));
993 	}
994 	catch( ...)
995 	{
996 		log_trace(WHERE, "E: unkown exception thrown");
997 		return (CKR_FUNCTION_FAILED);
998 	}
999 
1000 	return (ret);
1001 }
1002 
1003 #undef WHERE
1004 
1005 
1006 #define WHERE "cal_logout()"
cal_logout(CK_SLOT_ID hSlot)1007 CK_RV cal_logout(CK_SLOT_ID hSlot)
1008 {
1009 	CK_RV ret = CKR_OK;
1010 	P11_SLOT *pSlot = NULL;
1011 
1012 	pSlot = p11_get_slot(hSlot);
1013 	if (pSlot == NULL)
1014 	{
1015 		log_trace(WHERE, "E: Invalid slot (%lu)", hSlot);
1016 		return (CKR_SLOT_ID_INVALID);
1017 	}
1018 
1019 	try
1020 	{
1021 		std::string szReader = pSlot->name;
1022 		CReader &oReader = oCardLayer->getReader(szReader);
1023 		CCard* poCard = oReader.GetCard();
1024 
1025 		if (!poCard->LogOff())
1026 		{
1027 			//can only get here if we're not a BEID card
1028 			log_trace(WHERE, "E: PIN_OP_LOGOFF failed");
1029 			ret = CKR_FUNCTION_FAILED;
1030 		}
1031 	}
1032 	catch (CMWException &e)
1033 	{
1034 		return (cal_translate_error(WHERE, e.GetError()));
1035 	}
1036 	catch (...)
1037 	{
1038 		log_trace(WHERE, "E: unkown exception thrown");
1039 		return (CKR_FUNCTION_FAILED);
1040 	}
1041 	return (ret);
1042 }
1043 
1044 #undef WHERE
1045 
1046 
1047 
1048 
1049 #define WHERE "cal_change_pin()"
cal_change_pin(CK_SLOT_ID hSlot,CK_ULONG pinref,CK_ULONG l_oldpin,CK_CHAR_PTR oldpin,CK_ULONG l_newpin,CK_CHAR_PTR newpin)1050 CK_RV cal_change_pin(CK_SLOT_ID hSlot, CK_ULONG pinref, CK_ULONG l_oldpin, CK_CHAR_PTR oldpin,
1051 		     CK_ULONG l_newpin, CK_CHAR_PTR newpin)
1052 {
1053 	CK_RV ret = CKR_OK;
1054 	P11_SLOT *pSlot = NULL;
1055 
1056 	pSlot = p11_get_slot(hSlot);
1057 	if (pSlot == NULL)
1058 	{
1059 		log_trace(WHERE, "E: Invalid slot (%lu)", hSlot);
1060 		return (CKR_SLOT_ID_INVALID);
1061 	}
1062 
1063 	try
1064 	{
1065 		std::string csPin = "";
1066 		std::string csNewPin = "";
1067 		std::string szReader = pSlot->name;
1068 
1069 		CReader & oReader = oCardLayer->getReader(szReader);
1070 		CCard* poCard = oReader.GetCard();
1071 
1072 		if (oldpin != NULL)
1073 		{
1074 			csPin = (char *) oldpin;
1075 		}
1076 		if (newpin != NULL)
1077 		{
1078 			csNewPin = (char *) newpin;
1079 		}
1080 		unsigned long ulRemaining = 0;
1081 
1082 		if (!(poCard->PinCmd(PIN_OP_CHANGE, PinBeid, csPin, csNewPin, ulRemaining)))
1083 		{
1084 			if (ulRemaining == 0)
1085 				ret = CKR_PIN_LOCKED;
1086 			else
1087 				ret = CKR_PIN_INCORRECT;
1088 		}
1089 	}
1090 	catch(CMWException &e)
1091 	{
1092 		return (cal_translate_error(WHERE, e.GetError()));
1093 	}
1094 	catch( ...)
1095 	{
1096 		log_trace(WHERE, "E: unkown exception thrown");
1097 		return (CKR_FUNCTION_FAILED);
1098 	}
1099 
1100 	return (ret);
1101 }
1102 
1103 #undef WHERE
1104 
1105 
1106 
1107 
1108 #define WHERE "cal_get_card_data()"
1109 //we already know the unsigned data
cal_get_card_data(CK_SLOT_ID hSlot)1110 CK_RV cal_get_card_data(CK_SLOT_ID hSlot)
1111 {
1112 	CK_RV ret = 0;
1113 	CByteArray oATR;
1114 	CByteArray oAPDU(5);
1115 	unsigned char oByte;
1116 	CByteArray oCardData;
1117 
1118 	std::string szReader;
1119 	//      char cBuffer[250];
1120 	//      unsigned char ucBuffer[250];
1121 	const char *plabel = NULL;
1122 	CTLVBuffer oTLVBuffer;
1123 	P11_SLOT *pSlot = NULL;
1124 	CK_ATTRIBUTE ID_DATA[] = BEID_TEMPLATE_ID_DATA;
1125 
1126 	CK_ULONG hObject = 0;
1127 
1128 	pSlot = p11_get_slot(hSlot);
1129 	if (pSlot == NULL)
1130 	{
1131 		log_trace(WHERE, "E: Invalid slot (%lu)", hSlot);
1132 		return (CKR_SLOT_ID_INVALID);
1133 	}
1134 
1135 	szReader = pSlot->name;
1136 	try
1137 	{
1138 		CReader& oReader = oCardLayer->getReader(szReader);
1139 		CCard* poCard = oReader.GetCard();
1140 
1141 		oATR = poCard->GetATR();
1142 		oCardData = poCard->GetInfo();
1143 
1144 		plabel = BEID_LABEL_ATR;
1145 		ret = p11_add_slot_ID_object(pSlot, ID_DATA,
1146 					     sizeof(ID_DATA) /
1147 					     sizeof(CK_ATTRIBUTE), CK_TRUE,
1148 					     CKO_DATA, CK_FALSE, &hObject,
1149 					     (CK_VOID_PTR) plabel,
1150 					     (CK_ULONG) strlen(plabel),
1151 					     (CK_VOID_PTR) oATR.GetBytes(),
1152 					     (CK_ULONG) oATR.Size(),
1153 					     (CK_VOID_PTR)
1154 					     BEID_OBJECTID_CARDDATA,
1155 					     (CK_ULONG)
1156 					     strlen(BEID_OBJECTID_CARDDATA),
1157 						 CK_FALSE);
1158 		if (ret != CKR_OK)
1159 			goto cleanup;
1160 
1161 		plabel = BEID_LABEL_CARD_DATA;
1162 		ret = p11_add_slot_ID_object(pSlot, ID_DATA,
1163 					     sizeof(ID_DATA) /
1164 					     sizeof(CK_ATTRIBUTE), CK_TRUE,
1165 					     CKO_DATA, CK_FALSE, &hObject,
1166 					     (CK_VOID_PTR) plabel,
1167 					     (CK_ULONG) strlen(plabel),
1168 					     (CK_VOID_PTR) oCardData.
1169 					     GetBytes(),
1170 					     (CK_ULONG) oCardData.Size(),
1171 					     (CK_VOID_PTR)
1172 					     BEID_OBJECTID_CARDDATA,
1173 					     (CK_ULONG)
1174 					     strlen(BEID_OBJECTID_CARDDATA),
1175 						 CK_FALSE);
1176 		if (ret != CKR_OK)
1177 			goto cleanup;
1178 
1179 		CByteArray data = CByteArray(oCardData.GetBytes(), 16);
1180 
1181 		plabel = BEID_LABEL_DATA_SerialNr;
1182 		ret = p11_add_slot_ID_object(pSlot, ID_DATA,
1183 					     sizeof(ID_DATA) /
1184 					     sizeof(CK_ATTRIBUTE), CK_TRUE,
1185 					     CKO_DATA, CK_FALSE, &hObject,
1186 					     (CK_VOID_PTR) plabel,
1187 					     (CK_ULONG) strlen(plabel),
1188 					     (CK_VOID_PTR) data.GetBytes(),
1189 					     (CK_ULONG) data.Size(),
1190 					     (CK_VOID_PTR)
1191 					     BEID_OBJECTID_CARDDATA,
1192 					     (CK_ULONG)
1193 					     strlen(BEID_OBJECTID_CARDDATA),
1194 						 CK_FALSE);
1195 		if (ret != CKR_OK)
1196 			goto cleanup;
1197 
1198 		oByte = oCardData.GetByte(16);
1199 		plabel = BEID_LABEL_DATA_CompCode;
1200 		ret = p11_add_slot_ID_object(pSlot, ID_DATA,
1201 					     sizeof(ID_DATA) /
1202 					     sizeof(CK_ATTRIBUTE), CK_TRUE,
1203 					     CKO_DATA, CK_FALSE, &hObject,
1204 					     (CK_VOID_PTR) plabel,
1205 					     (CK_ULONG) strlen(plabel),
1206 					     (CK_VOID_PTR) & oByte,
1207 					     (CK_ULONG) 1,
1208 					     (CK_VOID_PTR)
1209 					     BEID_OBJECTID_CARDDATA,
1210 					     (CK_ULONG)
1211 					     strlen(BEID_OBJECTID_CARDDATA),
1212 						 CK_FALSE);
1213 		if (ret != CKR_OK)
1214 			goto cleanup;
1215 
1216 		oByte = oCardData.GetByte(17);
1217 		plabel = BEID_LABEL_DATA_OSNr;
1218 		ret = p11_add_slot_ID_object(pSlot, ID_DATA,
1219 					     sizeof(ID_DATA) /
1220 					     sizeof(CK_ATTRIBUTE), CK_TRUE,
1221 					     CKO_DATA, CK_FALSE, &hObject,
1222 					     (CK_VOID_PTR) plabel,
1223 					     (CK_ULONG) strlen(plabel),
1224 					     (CK_VOID_PTR) & oByte,
1225 					     (CK_ULONG) 1,
1226 					     (CK_VOID_PTR)
1227 					     BEID_OBJECTID_CARDDATA,
1228 					     (CK_ULONG)
1229 					     strlen(BEID_OBJECTID_CARDDATA),
1230 						 CK_FALSE);
1231 		if (ret != CKR_OK)
1232 			goto cleanup;
1233 
1234 		oByte = oCardData.GetByte(18);
1235 		plabel = BEID_LABEL_DATA_OSVersion;
1236 		ret = p11_add_slot_ID_object(pSlot, ID_DATA,
1237 					     sizeof(ID_DATA) /
1238 					     sizeof(CK_ATTRIBUTE), CK_TRUE,
1239 					     CKO_DATA, CK_FALSE, &hObject,
1240 					     (CK_VOID_PTR) plabel,
1241 					     (CK_ULONG) strlen(plabel),
1242 					     (CK_VOID_PTR) & oByte,
1243 					     (CK_ULONG) 1,
1244 					     (CK_VOID_PTR)
1245 					     BEID_OBJECTID_CARDDATA,
1246 					     (CK_ULONG)
1247 					     strlen(BEID_OBJECTID_CARDDATA),
1248 						 CK_FALSE);
1249 		if (ret != CKR_OK)
1250 			goto cleanup;
1251 
1252 		oByte = oCardData.GetByte(19);
1253 		plabel = BEID_LABEL_DATA_SoftMaskNumber;
1254 		ret = p11_add_slot_ID_object(pSlot, ID_DATA,
1255 					     sizeof(ID_DATA) /
1256 					     sizeof(CK_ATTRIBUTE), CK_TRUE,
1257 					     CKO_DATA, CK_FALSE, &hObject,
1258 					     (CK_VOID_PTR) plabel,
1259 					     (CK_ULONG) strlen(plabel),
1260 					     (CK_VOID_PTR) & oByte,
1261 					     (CK_ULONG) 1,
1262 					     (CK_VOID_PTR)
1263 					     BEID_OBJECTID_CARDDATA,
1264 					     (CK_ULONG)
1265 					     strlen(BEID_OBJECTID_CARDDATA),
1266 						 CK_FALSE);
1267 		if (ret != CKR_OK)
1268 			goto cleanup;
1269 
1270 		oByte = oCardData.GetByte(20);
1271 		plabel = BEID_LABEL_DATA_SoftMaskVersion;
1272 		ret = p11_add_slot_ID_object(pSlot, ID_DATA,
1273 					     sizeof(ID_DATA) /
1274 					     sizeof(CK_ATTRIBUTE), CK_TRUE,
1275 					     CKO_DATA, CK_FALSE, &hObject,
1276 					     (CK_VOID_PTR) plabel,
1277 					     (CK_ULONG) strlen(plabel),
1278 					     (CK_VOID_PTR) & oByte,
1279 					     (CK_ULONG) 1,
1280 					     (CK_VOID_PTR)
1281 					     BEID_OBJECTID_CARDDATA,
1282 					     (CK_ULONG)
1283 					     strlen(BEID_OBJECTID_CARDDATA),
1284 						 CK_FALSE);
1285 		if (ret != CKR_OK)
1286 			goto cleanup;
1287 
1288 		//spec of applet 1.7 is not compatible with that of applet 1.1,
1289 		//so we check the appletversion here, and fill in the remaining fields according to it
1290 		oByte = oCardData.GetByte(21);
1291 
1292 		if (oByte == 0x11)
1293 		{
1294 			data.ClearContents();
1295 			data.Append(oCardData.GetByte(21));
1296 			data.Append(oCardData.GetByte(22));
1297 			plabel = BEID_LABEL_DATA_ApplVersion;
1298 			ret = p11_add_slot_ID_object(pSlot, ID_DATA,
1299 						     sizeof(ID_DATA) / sizeof(CK_ATTRIBUTE),
1300 						     CK_TRUE, CKO_DATA,
1301 						     CK_FALSE, &hObject,
1302 						     (CK_VOID_PTR) plabel,
1303 						     (CK_ULONG) strlen(plabel),
1304 						     (CK_VOID_PTR) data.GetBytes(),
1305 						     (CK_ULONG) data.Size(),
1306 						     (CK_VOID_PTR) BEID_OBJECTID_CARDDATA,
1307 						     (CK_ULONG) strlen(BEID_OBJECTID_CARDDATA),
1308 							 CK_FALSE);
1309 			if (ret != CKR_OK)
1310 				goto cleanup;
1311 
1312 			data.ClearContents();
1313 			data.Append(oCardData.GetByte(23));
1314 			data.Append(oCardData.GetByte(24));
1315 			plabel = BEID_LABEL_DATA_ApplIntVersion;
1316 			ret = p11_add_slot_ID_object(pSlot, ID_DATA,
1317 						     sizeof(ID_DATA) / sizeof(CK_ATTRIBUTE),
1318 						     CK_TRUE, CKO_DATA,
1319 						     CK_FALSE, &hObject,
1320 						     (CK_VOID_PTR) plabel,
1321 						     (CK_ULONG) strlen(plabel),
1322 						     (CK_VOID_PTR) data.GetBytes(),
1323 						     (CK_ULONG) data.Size(),
1324 						     (CK_VOID_PTR) BEID_OBJECTID_CARDDATA,
1325 						     (CK_ULONG) strlen(BEID_OBJECTID_CARDDATA),
1326 							 CK_FALSE);
1327 			if (ret != CKR_OK)
1328 				goto cleanup;
1329 
1330 			data.ClearContents();
1331 			data.Append(oCardData.GetByte(25));
1332 			data.Append(oCardData.GetByte(26));
1333 			plabel = BEID_LABEL_DATA_PKCS15Version;
1334 			ret = p11_add_slot_ID_object(pSlot, ID_DATA,
1335 						     sizeof(ID_DATA) / sizeof(CK_ATTRIBUTE),
1336 						     CK_TRUE, CKO_DATA,
1337 						     CK_FALSE, &hObject,
1338 						     (CK_VOID_PTR) plabel,
1339 						     (CK_ULONG) strlen(plabel),
1340 						     (CK_VOID_PTR) data.GetBytes(),
1341 						     (CK_ULONG) data.Size(),
1342 						     (CK_VOID_PTR) BEID_OBJECTID_CARDDATA,
1343 						     (CK_ULONG) strlen(BEID_OBJECTID_CARDDATA),
1344 							 CK_FALSE);
1345 			if (ret != CKR_OK)
1346 				goto cleanup;
1347 		} else
1348 		{
1349 			plabel = BEID_LABEL_DATA_ApplVersion;
1350 			ret = p11_add_slot_ID_object(pSlot, ID_DATA,
1351 						     sizeof(ID_DATA) / sizeof(CK_ATTRIBUTE),
1352 						     CK_TRUE, CKO_DATA,
1353 						     CK_FALSE, &hObject,
1354 						     (CK_VOID_PTR) plabel,
1355 						     (CK_ULONG) strlen(plabel),
1356 						     (CK_VOID_PTR) & oByte,
1357 						     (CK_ULONG) 1,
1358 						     (CK_VOID_PTR) BEID_OBJECTID_CARDDATA,
1359 						     (CK_ULONG) strlen(BEID_OBJECTID_CARDDATA),
1360 							 CK_FALSE);
1361 			if (ret != CKR_OK)
1362 				goto cleanup;
1363 
1364 			data.ClearContents();
1365 			data.Append(oCardData.GetByte(22));
1366 			data.Append(oCardData.GetByte(23));
1367 			plabel = BEID_LABEL_DATA_GlobOSVersion;
1368 			ret = p11_add_slot_ID_object(pSlot, ID_DATA,
1369 						     sizeof(ID_DATA) / sizeof(CK_ATTRIBUTE),
1370 						     CK_TRUE, CKO_DATA,
1371 						     CK_FALSE, &hObject,
1372 						     (CK_VOID_PTR) plabel,
1373 						     (CK_ULONG) strlen(plabel),
1374 						     (CK_VOID_PTR) data.GetBytes(),
1375 						     (CK_ULONG) data.Size(),
1376 						     (CK_VOID_PTR) BEID_OBJECTID_CARDDATA,
1377 						     (CK_ULONG) strlen(BEID_OBJECTID_CARDDATA),
1378 							 CK_FALSE);
1379 			if (ret != CKR_OK)
1380 				goto cleanup;
1381 
1382 			oByte = oCardData.GetByte(24);
1383 			plabel = BEID_LABEL_DATA_ApplIntVersion;
1384 			ret = p11_add_slot_ID_object(pSlot, ID_DATA,
1385 						     sizeof(ID_DATA) / sizeof(CK_ATTRIBUTE),
1386 						     CK_TRUE, CKO_DATA,
1387 						     CK_FALSE, &hObject,
1388 						     (CK_VOID_PTR) plabel,
1389 						     (CK_ULONG) strlen(plabel),
1390 						     (CK_VOID_PTR) & oByte,
1391 						     (CK_ULONG) 1,
1392 						     (CK_VOID_PTR) BEID_OBJECTID_CARDDATA,
1393 						     (CK_ULONG) strlen(BEID_OBJECTID_CARDDATA),
1394 							 CK_FALSE);
1395 			if (ret != CKR_OK)
1396 				goto cleanup;
1397 
1398 			oByte = oCardData.GetByte(25);
1399 			plabel = BEID_LABEL_DATA_PKCS1Support;
1400 			ret = p11_add_slot_ID_object(pSlot, ID_DATA,
1401 						     sizeof(ID_DATA) / sizeof(CK_ATTRIBUTE),
1402 						     CK_TRUE, CKO_DATA,
1403 						     CK_FALSE, &hObject,
1404 						     (CK_VOID_PTR) plabel,
1405 						     (CK_ULONG) strlen(plabel),
1406 						     (CK_VOID_PTR) & oByte,
1407 						     (CK_ULONG) 1,
1408 						     (CK_VOID_PTR) BEID_OBJECTID_CARDDATA,
1409 						     (CK_ULONG) strlen(BEID_OBJECTID_CARDDATA),
1410 							 CK_FALSE);
1411 			if (ret != CKR_OK)
1412 				goto cleanup;
1413 
1414 			oByte = oCardData.GetByte(26);
1415 			plabel = BEID_LABEL_DATA_KeyExchangeVersion;
1416 			ret = p11_add_slot_ID_object(pSlot, ID_DATA,
1417 						     sizeof(ID_DATA) / sizeof(CK_ATTRIBUTE),
1418 						     CK_TRUE, CKO_DATA,
1419 						     CK_FALSE, &hObject,
1420 						     (CK_VOID_PTR) plabel,
1421 						     (CK_ULONG) strlen(plabel),
1422 						     (CK_VOID_PTR) & oByte,
1423 						     (CK_ULONG) 1,
1424 						     (CK_VOID_PTR) BEID_OBJECTID_CARDDATA,
1425 						     (CK_ULONG) strlen(BEID_OBJECTID_CARDDATA),
1426 							 CK_FALSE);
1427 			if (ret != CKR_OK)
1428 				goto cleanup;
1429 		}
1430 
1431 
1432 		oByte = oCardData.GetByte(27);
1433 		plabel = BEID_LABEL_DATA_ApplLifeCycle;
1434 		ret = p11_add_slot_ID_object(pSlot, ID_DATA,
1435 					     sizeof(ID_DATA) / sizeof(CK_ATTRIBUTE),
1436 					     CK_TRUE, CKO_DATA,
1437 					     CK_FALSE, &hObject,
1438 					     (CK_VOID_PTR) plabel,
1439 					     (CK_ULONG) strlen(plabel),
1440 					     (CK_VOID_PTR) & oByte,
1441 					     (CK_ULONG) 1,
1442 					     (CK_VOID_PTR) BEID_OBJECTID_CARDDATA,
1443 					     (CK_ULONG) strlen(BEID_OBJECTID_CARDDATA),
1444 						 CK_FALSE);
1445 		if (ret != CKR_OK)
1446 			goto cleanup;
1447 
1448 		if(oCardData.Size() > 30) {
1449 			oByte = oCardData.GetByte(28);
1450 			plabel = BEID_LABEL_DATA_PinAuth;
1451 			ret = p11_add_slot_ID_object(pSlot, ID_DATA,
1452 						     sizeof(ID_DATA) / sizeof(CK_ATTRIBUTE),
1453 						     CK_TRUE, CKO_DATA,
1454 						     CK_FALSE, &hObject,
1455 						     (CK_VOID_PTR) plabel,
1456 						     (CK_ULONG) strlen(plabel),
1457 						     (CK_VOID_PTR) & oByte,
1458 						     (CK_ULONG) 1,
1459 						     (CK_VOID_PTR) BEID_OBJECTID_CARDDATA,
1460 						     (CK_ULONG) strlen(BEID_OBJECTID_CARDDATA),
1461 							 CK_FALSE);
1462 			if (ret != CKR_OK)
1463 				goto cleanup;
1464 		}
1465 		//              data.ClearContents();
1466 		//              data = oCardData.GetBytes(28);
1467 		//              plabel = BEID_LABEL_DATA_FILE;
1468 		//              ret = p11_add_slot_ID_object(pSlot, ID_DATA, sizeof(ID_DATA)/sizeof(CK_ATTRIBUTE), CK_TRUE, CKO_DATA, 0, CK_FALSE, &hObject,
1469 		//              (CK_VOID_PTR)plabel, (CK_ULONG)strlen(plabel),(CK_VOID_PTR) data.GetBytes(),(CK_ULONG)data.Size());
1470 		//              if (ret) goto cleanup;
1471 		//
1472 	}
1473 	catch(CMWException &e)
1474 	{
1475 		return (cal_translate_error(WHERE, e.GetError()));
1476 	}
1477 	catch( ...)
1478 	{
1479 		log_trace(WHERE, "E: unkown exception thrown");
1480 		return (CKR_FUNCTION_FAILED);
1481 	}
1482 
1483 	if (ret != 0)
1484 	{
1485 		return (CKR_DEVICE_ERROR);
1486 	}
1487 
1488       cleanup:
1489 	return (ret);
1490 }
1491 
1492 #undef WHERE
1493 
1494 
1495 #define WHERE "cal_read_and_store_file_records()"
cal_read_and_store_record(P11_SLOT * pSlot,CK_ULONG ulDataType,CK_BYTE bRecordID,CK_UTF8CHAR * plabel,CK_ULONG ulLabelLen)1496 CK_RV cal_read_and_store_record(P11_SLOT *pSlot, CK_ULONG ulDataType, CK_BYTE bRecordID, CK_UTF8CHAR* plabel, CK_ULONG ulLabelLen)
1497 {
1498 	CK_RV ret = CKR_OK;
1499 
1500 	std::string szReader;
1501 	CByteArray oRecordData;
1502 	CK_ATTRIBUTE ID_DATA[] = BEID_TEMPLATE_ID_DATA;
1503 
1504 	const char *pobjectID = BEID_OBJECTID_RECORD;
1505 	CK_ULONG hObject = 0;
1506 	unsigned char* pucBuffer = NULL;
1507 	CK_ULONG ulBufferLen = 0;
1508 
1509 	if (pSlot == NULL)
1510 	{
1511 		log_trace(WHERE, "E: Invalid slot pSlot == NULL");
1512 		return (CKR_SLOT_ID_INVALID);
1513 	}
1514 	szReader = pSlot->name;
1515 	try
1516 	{
1517 		CReader & oReader = oCardLayer->getReader(szReader);
1518 		CCard* poCard = oReader.GetCard();
1519 		switch (ulDataType)
1520 		{
1521 		case CACHED_DATA_TYPE_ID:
1522 			oRecordData = poCard->ReadRecordFromFile(BEID_FILE_ID, bRecordID);
1523 			break;
1524 		case CACHED_DATA_TYPE_ADDRESS:
1525 			oRecordData = poCard->ReadRecordFromFile(BEID_FILE_ADDRESS, bRecordID);
1526 			break;
1527 		default:
1528 			//unsupported ulDataType given, not fatal, but also not useable
1529 			log_trace(WHERE, "E: wrong ulDataType given (%lu), recordID = %x", ulDataType, bRecordID);
1530 			return CKR_OK;
1531 		}
1532 
1533 		pucBuffer = oRecordData.GetBytes();
1534 		ulBufferLen = oRecordData.Size();
1535 		//parse TLV (one record, so i.e. just skip first 2 bytes (Type and Length are always 1 byte))
1536 		//and store it into an object
1537 		if (ulBufferLen > 2)
1538 		{
1539 			pucBuffer += 2;
1540 			ulBufferLen -= 2;
1541 		}
1542 		else
1543 		{
1544 			//no data returned (at most the status words), so do not add a slot object
1545 			ret = CKR_OK;
1546 			goto cleanup;
1547 		}
1548 
1549 		ret = p11_add_slot_ID_object(pSlot, //the slot where to object belongs to
1550 			ID_DATA, sizeof(ID_DATA) / sizeof(CK_ATTRIBUTE), //the object attribute template
1551 			CK_TRUE,	//is this a token object?
1552 			CKO_DATA,	//the object class
1553 			CK_FALSE,	//is this a private object?
1554 			&hObject,	//pointer to store the object's handle
1555 			(CK_VOID_PTR)plabel, ulLabelLen,	//the CKA_LABEL attribute (e.g. "surname")
1556 			(CK_VOID_PTR)pucBuffer, ulBufferLen,		//the value of the CKA_LABEL attribute (e.g. your surname as it is found on the token)
1557 			(CK_VOID_PTR)pobjectID, (CK_ULONG)strlen(pobjectID), //the CKA_OBJECT_ID attribute
1558 			CK_TRUE); //the hidden flag (hidden objects are only returned when searching for their Label)
1559 
1560 		if (ret)
1561 		{
1562 			goto cleanup;
1563 		}
1564 
1565 		if (ret != 0)
1566 		{
1567 			return (CKR_DEVICE_ERROR);
1568 		}
1569 
1570 	cleanup:
1571 		return (ret);
1572 
1573 
1574 	}
1575 	catch (CMWException &e)
1576 	{
1577 		return (cal_translate_error(WHERE, e.GetError()));
1578 	}
1579 	catch (...)
1580 	{
1581 		//ret = -1;
1582 		log_trace(WHERE, "E: unknown exception thrown");
1583 		return (CKR_FUNCTION_FAILED);
1584 	}
1585 
1586 }
1587 #undef WHERE
1588 
1589 #define WHERE "cal_read_ID_files()"
cal_read_ID_files(CK_SLOT_ID hSlot,CK_ULONG dataType)1590 CK_RV cal_read_ID_files(CK_SLOT_ID hSlot, CK_ULONG dataType)
1591 {
1592 	CK_RV ret = CKR_OK;
1593 	CByteArray oFileData;
1594 
1595 	std::string szReader;
1596 	char cBuffer[256];
1597 
1598 	//      unsigned char ucBuffer[250];
1599 	const char *plabel = NULL;
1600 	const char *pobjectID = NULL;
1601 	unsigned long ulLen = 0;
1602 	CTLVBuffer oTLVBuffer;
1603 	CTLVBuffer oTLVBufferAddress;	//need second buffer object, as memory is only freed when this object is destructed
1604 	P11_SLOT *pSlot = NULL;
1605 	CK_ATTRIBUTE ID_DATA[] = BEID_TEMPLATE_ID_DATA;
1606 	BEID_DATA_LABELS_NAME ID_LABELS[] = BEID_ID_DATA_LABELS;
1607 	BEID_DATA_LABELS_NAME ADDRESS_LABELS[] = BEID_ADDRESS_DATA_LABELS;
1608 	int i = 0;
1609 	int nrOfItems = 0;
1610 	unsigned char ucAppletVersion = 0;
1611 
1612 	CK_ULONG hObject = 0;
1613 
1614 //	FILE* BEIDfile = fopen("F:\\idFile.dat", "rb");
1615 //	BYTE buffer[4096];
1616 //	int dataSize = 0;
1617 
1618 	pSlot = p11_get_slot(hSlot);
1619 	if (pSlot == NULL)
1620 	{
1621 		log_trace(WHERE, "E: Invalid slot (%lu)", hSlot);
1622 		return (CKR_SLOT_ID_INVALID);
1623 	}
1624 
1625 	szReader = pSlot->name;
1626 	try
1627 	{
1628 		CReader & oReader = oCardLayer->getReader(szReader);
1629 		CCard* poCard = oReader.GetCard();
1630 		switch (dataType)
1631 		{
1632 		case CACHED_DATA_TYPE_ALL_DATA:
1633 		case CACHED_DATA_TYPE_ID:
1634 			oFileData = poCard->ReadCardFile(BEID_FILE_ID);
1635 
1636 			//				dataSize = fread((void *)buffer,1,4096, BEIDfile);
1637 			//				fclose(BEIDfile);
1638 			//				oFileData.Append(buffer, dataSize);
1639 
1640 			plabel = BEID_LABEL_DATA_FILE;
1641 			pobjectID = (char *)BEID_OBJECTID_ID;
1642 			/* XXX the const-ness of pobjectID and plabel should
1643 			 * ideally not be cast away, but it goes pretty deep.
1644 			 * Not Now(TM). */
1645 			ret = p11_add_slot_ID_object(pSlot, ID_DATA,
1646 				sizeof(ID_DATA) / sizeof(CK_ATTRIBUTE),
1647 				CK_TRUE,
1648 				CKO_DATA,
1649 				CK_FALSE,
1650 				&hObject,
1651 				(CK_VOID_PTR)plabel, (CK_ULONG)strlen(plabel),
1652 				(CK_VOID_PTR)oFileData.GetBytes(), (CK_ULONG)oFileData.Size(),
1653 				(CK_VOID_PTR)pobjectID, (CK_ULONG)strlen(pobjectID),
1654 				CK_FALSE);
1655 			if (ret)
1656 				goto cleanup;
1657 
1658 			oTLVBuffer.ParseTLV(oFileData.GetBytes(), oFileData.Size());
1659 
1660 			nrOfItems = sizeof(ID_LABELS) / sizeof(BEID_DATA_LABELS_NAME);
1661 
1662 			for (i = 0; i < nrOfItems; i++)
1663 			{
1664 				ulLen = sizeof(cBuffer);
1665 				memset(cBuffer, 0, ulLen);
1666 				if (oTLVBuffer.FillUTF8Data(ID_LABELS[i].tag, cBuffer, &ulLen)) {
1667 					plabel = ID_LABELS[i].name;
1668 					ret = p11_add_slot_ID_object(pSlot, ID_DATA, sizeof(ID_DATA) / sizeof(CK_ATTRIBUTE),
1669 						CK_TRUE, CKO_DATA, CK_FALSE, &hObject, (CK_VOID_PTR)plabel,
1670 						(CK_ULONG)strlen(plabel), (CK_VOID_PTR)cBuffer, ulLen,
1671 						(CK_VOID_PTR)pobjectID, (CK_ULONG)strlen(pobjectID), CK_FALSE);
1672 					if (ret)
1673 						goto cleanup;
1674 				}
1675 			}
1676 			if (dataType != CACHED_DATA_TYPE_ALL_DATA)
1677 			{
1678 				break;
1679 			}
1680 			/* Falls through */
1681 		case CACHED_DATA_TYPE_ADDRESS:
1682 			oFileData = poCard->ReadCardFile(BEID_FILE_ADDRESS);
1683 			plabel = BEID_LABEL_ADDRESS_FILE;
1684 			pobjectID = BEID_OBJECTID_ADDRESS;
1685 			ret = p11_add_slot_ID_object(pSlot, ID_DATA, sizeof(ID_DATA) / sizeof(CK_ATTRIBUTE), CK_TRUE, CKO_DATA,
1686 				CK_FALSE, &hObject, (CK_VOID_PTR)plabel, (CK_ULONG)strlen(plabel),
1687 				(CK_VOID_PTR)oFileData.GetBytes(), (CK_ULONG)oFileData.Size(),
1688 				(CK_VOID_PTR)pobjectID, (CK_ULONG)strlen(pobjectID), CK_FALSE);
1689 			if (ret)
1690 				goto cleanup;
1691 			oTLVBufferAddress.ParseTLV(oFileData.GetBytes(),
1692 				oFileData.Size());
1693 			nrOfItems = sizeof(ADDRESS_LABELS) / sizeof(BEID_DATA_LABELS_NAME);
1694 			for (i = 0; i < nrOfItems; i++)
1695 			{
1696 				ulLen = sizeof(cBuffer);
1697 				memset(cBuffer, 0, ulLen);
1698 				if (oTLVBufferAddress.FillUTF8Data(ADDRESS_LABELS[i].tag, cBuffer, &ulLen)) {
1699 					plabel = ADDRESS_LABELS[i].name;
1700 					ret = p11_add_slot_ID_object(pSlot, ID_DATA, sizeof(ID_DATA) / sizeof(CK_ATTRIBUTE), CK_TRUE,
1701 						CKO_DATA, CK_FALSE, &hObject, (CK_VOID_PTR)plabel,
1702 						(CK_ULONG)strlen(plabel), (CK_VOID_PTR)cBuffer, ulLen,
1703 						(CK_VOID_PTR)pobjectID, (CK_ULONG)strlen(pobjectID), CK_FALSE);
1704 					if (ret)
1705 						goto cleanup;
1706 				}
1707 			}
1708 			if (dataType != CACHED_DATA_TYPE_ALL_DATA)
1709 			{
1710 				break;
1711 			}
1712 			/* Falls through */
1713 		case CACHED_DATA_TYPE_PHOTO:
1714 			plabel = BEID_LABEL_PHOTO;
1715 			pobjectID = BEID_OBJECTID_PHOTO;
1716 			oFileData = poCard->ReadCardFile(BEID_FILE_PHOTO);
1717 			ret = p11_add_slot_ID_object(pSlot, ID_DATA,
1718 				sizeof(ID_DATA) / sizeof(CK_ATTRIBUTE),
1719 				CK_TRUE,
1720 				CKO_DATA,
1721 				CK_FALSE,
1722 				&hObject,
1723 				(CK_VOID_PTR)plabel, (CK_ULONG)strlen(plabel),
1724 				(CK_VOID_PTR)oFileData.GetBytes(), (CK_ULONG)oFileData.Size(),
1725 				(CK_VOID_PTR)pobjectID, (CK_ULONG)strlen(BEID_OBJECTID_PHOTO),
1726 				CK_FALSE);
1727 			if (ret)
1728 				goto cleanup;
1729 			if (dataType != CACHED_DATA_TYPE_ALL_DATA)
1730 			{
1731 				break;
1732 			}
1733 			/* Falls through */
1734 		case CACHED_DATA_TYPE_RNCERT:
1735 			oFileData = poCard->ReadCardFile(BEID_FILE_CERT_RRN);
1736 			plabel = BEID_LABEL_CERT_RN;
1737 			pobjectID = BEID_OBJECTID_RNCERT;
1738 			ret = p11_add_slot_ID_object(pSlot, ID_DATA,
1739 				sizeof(ID_DATA) / sizeof(CK_ATTRIBUTE),
1740 				CK_TRUE,
1741 				CKO_DATA,
1742 				CK_FALSE,
1743 				&hObject,
1744 				(CK_VOID_PTR)plabel, (CK_ULONG)strlen(plabel),
1745 				(CK_VOID_PTR)oFileData.GetBytes(), (CK_ULONG)oFileData.Size(),
1746 				(CK_VOID_PTR)pobjectID, (CK_ULONG)strlen(BEID_OBJECTID_RNCERT),
1747 				CK_FALSE);
1748 			if (ret)
1749 				goto cleanup;
1750 			if (dataType != CACHED_DATA_TYPE_ALL_DATA)
1751 			{
1752 				break;
1753 			}
1754 			/* Falls through */
1755 		case CACHED_DATA_TYPE_SIGN_DATA_FILE:
1756 			plabel = BEID_LABEL_SGN_RN;
1757 			oFileData = poCard->ReadCardFile(BEID_FILE_ID_SIGN);
1758 			ret = p11_add_slot_ID_object(pSlot, ID_DATA,
1759 				sizeof(ID_DATA) / sizeof(CK_ATTRIBUTE),
1760 				CK_TRUE,
1761 				CKO_DATA,
1762 				CK_FALSE,
1763 				&hObject,
1764 				(CK_VOID_PTR)plabel, (CK_ULONG)strlen(plabel),
1765 				(CK_VOID_PTR)oFileData.GetBytes(), (CK_ULONG)oFileData.Size(),
1766 				(CK_VOID_PTR)BEID_OBJECTID_SIGN_DATA_FILE,
1767 				(CK_ULONG)strlen(BEID_OBJECTID_SIGN_DATA_FILE),
1768 				CK_FALSE);
1769 			if (ret)
1770 				goto cleanup;
1771 			if (dataType != CACHED_DATA_TYPE_ALL_DATA)
1772 			{
1773 				break;
1774 			}
1775 			/* Falls through */
1776 		case CACHED_DATA_TYPE_SIGN_ADDRESS_FILE:
1777 			plabel = BEID_LABEL_SGN_ADDRESS;
1778 			oFileData = poCard->ReadCardFile(BEID_FILE_ADDRESS_SIGN);
1779 			ret = p11_add_slot_ID_object(pSlot, ID_DATA,
1780 				sizeof(ID_DATA) / sizeof(CK_ATTRIBUTE),
1781 				CK_TRUE,
1782 				CKO_DATA,
1783 				CK_FALSE,
1784 				&hObject,
1785 				(CK_VOID_PTR)plabel, (CK_ULONG)strlen(plabel),
1786 				(CK_VOID_PTR)oFileData.GetBytes(),
1787 				(CK_ULONG)oFileData.Size(),
1788 				(CK_VOID_PTR)BEID_OBJECTID_SIGN_ADDRESS_FILE, (CK_ULONG)strlen(BEID_OBJECTID_SIGN_ADDRESS_FILE),
1789 				CK_FALSE);
1790 			if (ret)
1791 				goto cleanup;
1792 			if (dataType != CACHED_DATA_TYPE_ALL_DATA)
1793 			{
1794 				break;
1795 			}
1796 			/* Falls through */
1797 		case CACHED_DATA_TYPE_BASIC_KEY_FILE:
1798 			ucAppletVersion = poCard->GetAppletVersion();
1799 
1800 			if (ucAppletVersion >= 0x18)
1801 			{
1802 				plabel = BEID_LABEL_BASIC_KEY;
1803 				pobjectID = BEID_OBJECTID_BASIC_KEY_FILE;
1804 				oFileData = poCard->ReadCardFile(BEID_FILE_BASIC_KEY);
1805 				ret = p11_add_slot_ID_object(pSlot, ID_DATA,
1806 					sizeof(ID_DATA) / sizeof(CK_ATTRIBUTE),
1807 					CK_TRUE,
1808 					CKO_DATA,
1809 					CK_FALSE,
1810 					&hObject,
1811 					(CK_VOID_PTR)plabel, (CK_ULONG)strlen(plabel),
1812 					(CK_VOID_PTR)oFileData.GetBytes(), (CK_ULONG)oFileData.Size(),
1813 					(CK_VOID_PTR)pobjectID, (CK_ULONG)strlen(BEID_OBJECTID_BASIC_KEY_FILE),
1814 					CK_FALSE);
1815 				if (ret)
1816 					goto cleanup;
1817 			}
1818 			if (dataType != CACHED_DATA_TYPE_ALL_DATA)
1819 			{
1820 				break;
1821 			}
1822 			/* Falls through */
1823 		default:
1824 			break;
1825 		}
1826 	}
1827 	catch (CMWException &e)
1828 	{
1829 		return (cal_translate_error(WHERE, e.GetError()));
1830 	}
1831 	catch (...)
1832 	{
1833 		//ret = -1;
1834 		log_trace(WHERE, "E: unknown exception thrown");
1835 		return (CKR_FUNCTION_FAILED);
1836 	}
1837 
1838 	if (ret != 0)
1839 	{
1840 		return (CKR_DEVICE_ERROR);
1841 	}
1842 
1843 	cleanup:
1844 	return (ret);
1845 }
1846 
1847 #undef WHERE
1848 
1849 
1850 
1851 #define WHERE "cal_read_object()"
cal_read_object(CK_SLOT_ID hSlot,P11_OBJECT * pObject)1852 CK_RV cal_read_object(CK_SLOT_ID hSlot, P11_OBJECT * pObject)
1853 {
1854 	CK_RV ret = CKR_OK;
1855 	int status;
1856 	CK_ULONG *pID = NULL;
1857 	CK_ULONG *pClass = NULL;
1858 	CK_ULONG len = 0;
1859 	CK_BBOOL btrue = CK_TRUE;
1860 	CK_BBOOL bfalse = CK_FALSE;
1861 	P11_OBJECT *pCertObject = NULL;
1862 	P11_OBJECT *pPubKeyObject = NULL;
1863 	P11_OBJECT *pPrivKeyObject = NULL;
1864 	T_CERT_INFO certinfo;
1865 	CByteArray oCertData;
1866 	tCert cert;
1867 	tPrivKey key;
1868 
1869 	std::string szReader;
1870 	P11_SLOT *pSlot = NULL;
1871 
1872 	memset(&certinfo, 0, sizeof(T_CERT_INFO));
1873 	pSlot = p11_get_slot(hSlot);
1874 	if (pSlot == NULL)
1875 	{
1876 		log_trace(WHERE, "E: Invalid slot (%lu)", hSlot);
1877 		return (CKR_SLOT_ID_INVALID);
1878 	}
1879 
1880 	szReader = pSlot->name;
1881 
1882 	ret = cal_update_token(hSlot, &status, 0);
1883 	if (ret != CKR_OK)
1884 		goto cleanup;
1885 
1886 	if ((status == P11_CARD_REMOVED) || (status == P11_CARD_NOT_PRESENT))
1887 	{
1888 		ret = CKR_TOKEN_NOT_PRESENT;
1889 		goto cleanup;
1890 	}
1891 
1892 	ret = p11_get_attribute_value(pObject->pAttr, pObject->count,
1893 				      CKA_CLASS, (CK_VOID_PTR *) & pClass,
1894 				      &len);
1895 	if (ret != CKR_OK)
1896 		goto cleanup;
1897 
1898 	//do not refresh the ID files here
1899 	if (*pClass == CKO_DATA)
1900 		goto cleanup;
1901 
1902 	//read ID of object we want to read from token
1903 	ret = p11_get_attribute_value(pObject->pAttr, pObject->count, CKA_ID,
1904 				      (CK_VOID_PTR *) & pID, &len);
1905 	if (ret != CKR_OK)
1906 		goto cleanup;
1907 
1908 	//get the object related to this ID
1909 
1910 	p11_find_slot_object(pSlot, CKO_PRIVATE_KEY, *pID, &pPrivKeyObject);
1911 
1912 	p11_find_slot_object(pSlot, CKO_PUBLIC_KEY, *pID, &pPubKeyObject);
1913 
1914 	p11_find_slot_object(pSlot, CKO_CERTIFICATE, *pID, &pCertObject);
1915 
1916 
1917 
1918 	if (pCertObject != NULL)
1919 	{
1920 		try
1921 		{
1922 			CReader & oReader = oCardLayer->getReader(szReader);
1923 			CCard* poCard = oReader.GetCard();
1924 
1925 			cert = poCard->GetCertByID(*pID);
1926 
1927 			//bValid duidt aan if cert met deze ID
1928 			if (cert.bValid)
1929 				oCertData = poCard->ReadCardFile(cert.csPath);
1930 			else
1931 			{
1932 				log_trace(WHERE, "E: cert.bValid is false");
1933 				return (CKR_DEVICE_ERROR);
1934 			}
1935 
1936             //at least 64K Bytes as size (unsigned int) will suffice for cert length
1937 			if (cert_get_info(oCertData.GetBytes(), (unsigned int)(oCertData.Size()), &certinfo) < 0)
1938 			{
1939 				// ASN.1 parser failed. Assume hardware failure.
1940 				log_trace(WHERE, "E: cert_get_info failed");
1941 				ret = CKR_DEVICE_ERROR;
1942 				goto cleanup;
1943 			}
1944 
1945 			ret = p11_set_attribute_value(pCertObject->pAttr, pCertObject->count, CKA_SUBJECT, (CK_VOID_PTR) certinfo.subject, (CK_ULONG) certinfo.l_subject);
1946 			if (ret != CKR_OK)
1947 				goto cleanup;
1948 
1949 			ret = p11_set_attribute_value(pCertObject->pAttr, pCertObject->count, CKA_ISSUER, (CK_VOID_PTR) certinfo.issuer, (CK_ULONG) certinfo.l_issuer);
1950 			if (ret != CKR_OK)
1951 				goto cleanup;
1952 
1953 			ret = p11_set_attribute_value(pCertObject->pAttr, pCertObject->count, CKA_SERIAL_NUMBER, (CK_VOID_PTR) certinfo.serial, (CK_ULONG) certinfo.l_serial);
1954 			if (ret != CKR_OK)
1955 				goto cleanup;
1956 			//use real length from decoder here instead of lg from cal
1957 			ret = p11_set_attribute_value(pCertObject->pAttr, pCertObject->count, CKA_VALUE, (CK_VOID_PTR) oCertData.GetBytes(), (CK_ULONG) certinfo.lcert);
1958 			if (ret != CKR_OK)
1959 				goto cleanup;
1960 			//TODO Check this in the cal if we can be sure that the certificate can be trusted and not be modified on the card
1961 			ret = p11_set_attribute_value(pCertObject->pAttr, pCertObject->count, CKA_TRUSTED, (CK_VOID_PTR) & btrue, sizeof(btrue));
1962 			if (ret != CKR_OK)
1963 				goto cleanup;
1964 
1965 			pCertObject->state = P11_CACHED;
1966 
1967 			key = poCard->GetPrivKeyByID(*pID);
1968 
1969 			if (pPrivKeyObject != NULL)
1970 			{
1971 				ret = p11_set_attribute_value(pPrivKeyObject->pAttr, pPrivKeyObject->count, CKA_SENSITIVE, (CK_VOID_PTR)& btrue, sizeof(btrue));
1972 				if (ret != CKR_OK)
1973 					goto cleanup;
1974 
1975 				ret = p11_set_attribute_value(pPrivKeyObject->pAttr, pPrivKeyObject->count, CKA_DECRYPT, (CK_VOID_PTR)& bfalse, sizeof(bfalse));
1976 				if (ret != CKR_OK)
1977 					goto cleanup;
1978 
1979 				ret = p11_set_attribute_value(pPrivKeyObject->pAttr, pPrivKeyObject->count, CKA_SIGN_RECOVER, (CK_VOID_PTR)& bfalse, sizeof(CK_BBOOL));
1980 				if (ret != CKR_OK)
1981 					goto cleanup;
1982 
1983 				ret = p11_set_attribute_value(pPrivKeyObject->pAttr, pPrivKeyObject->count, CKA_UNWRAP, (CK_VOID_PTR)& bfalse, sizeof(CK_BBOOL));
1984 				if (ret != CKR_OK)
1985 					goto cleanup;
1986 
1987 				ret = p11_set_attribute_value(pPrivKeyObject->pAttr, pPrivKeyObject->count, CKA_SUBJECT, (CK_VOID_PTR)certinfo.subject, (CK_ULONG)certinfo.l_subject);
1988 				if (ret != CKR_OK)
1989 					goto cleanup;
1990 
1991 				if (key.keyType == RSA)
1992 				{
1993 					if (certinfo.l_mod > 0)
1994 						ret = p11_set_attribute_value(pPrivKeyObject->pAttr, pPrivKeyObject->count, CKA_MODULUS, (CK_VOID_PTR)certinfo.mod, (CK_ULONG)certinfo.l_mod);
1995 					if (ret != CKR_OK)
1996 						goto cleanup;
1997 
1998 					if (certinfo.l_exp > 0)
1999 						ret = p11_set_attribute_value(pPrivKeyObject->pAttr, pPrivKeyObject->count, CKA_PUBLIC_EXPONENT, (CK_VOID_PTR)certinfo.exp, (CK_ULONG)certinfo.l_exp);
2000 					if (ret != CKR_OK)
2001 						goto cleanup;
2002 				}
2003 				else
2004 				{
2005 					if (certinfo.l_curve > 0)
2006 						ret = p11_set_attribute_value(pPrivKeyObject->pAttr, pPrivKeyObject->count, CKA_EC_PARAMS, (CK_VOID_PTR)certinfo.curve, (CK_ULONG)certinfo.l_curve);
2007 					if (ret != CKR_OK)
2008 						goto cleanup;
2009 				}
2010 				pPrivKeyObject->state = P11_CACHED;
2011 			}
2012 			if (pPubKeyObject != NULL)
2013 			{
2014 				ret = p11_set_attribute_value(pPubKeyObject->pAttr, pPubKeyObject->count, CKA_SENSITIVE, (CK_VOID_PTR) & btrue, sizeof(btrue));
2015 				if (ret != CKR_OK)
2016 					goto cleanup;
2017 
2018 				ret = p11_set_attribute_value(pPubKeyObject->pAttr, pPubKeyObject->count, CKA_VERIFY, (CK_VOID_PTR) & btrue, sizeof(btrue));
2019 				if (ret != CKR_OK)
2020 					goto cleanup;
2021 
2022 				ret = p11_set_attribute_value(pPubKeyObject->pAttr, pPubKeyObject->count, CKA_ENCRYPT, (CK_VOID_PTR) & bfalse, sizeof(bfalse));
2023 				if (ret != CKR_OK)
2024 					goto cleanup;
2025 
2026 				ret = p11_set_attribute_value(pPubKeyObject->pAttr, pPubKeyObject->count, CKA_WRAP, (CK_VOID_PTR) & bfalse, sizeof(CK_BBOOL));
2027 				if (ret != CKR_OK)
2028 					goto cleanup;
2029 
2030 				ret = p11_set_attribute_value(pPubKeyObject->pAttr, pPubKeyObject->count, CKA_SUBJECT, (CK_VOID_PTR)certinfo.subject, (CK_ULONG)certinfo.l_subject);
2031 				if (ret != CKR_OK)
2032 					goto cleanup;
2033 
2034 				if (key.keyType == RSA)
2035 				{
2036 					if (certinfo.l_mod > 0)
2037 						ret = p11_set_attribute_value(pPubKeyObject->pAttr, pPubKeyObject->count, CKA_MODULUS, (CK_VOID_PTR)certinfo.mod, certinfo.l_mod);
2038 					if (ret != CKR_OK)
2039 						goto cleanup;
2040 
2041 					if (certinfo.l_exp > 0)
2042 						ret = p11_set_attribute_value(pPubKeyObject->pAttr, pPubKeyObject->count, CKA_PUBLIC_EXPONENT, (CK_VOID_PTR)certinfo.exp, certinfo.l_exp);
2043 					if (ret != CKR_OK)
2044 						goto cleanup;
2045 
2046 					if (certinfo.l_pkinfo > 0)
2047 						ret = p11_set_attribute_value(pPubKeyObject->pAttr, pPubKeyObject->count, CKA_VALUE, (CK_VOID_PTR)certinfo.pkinfo, certinfo.l_pkinfo);
2048 					if (ret != CKR_OK)
2049 						goto cleanup;
2050 				}
2051 				else
2052 				{
2053 					if (certinfo.l_curve > 0)
2054 						ret = p11_set_attribute_value(pPubKeyObject->pAttr, pPubKeyObject->count, CKA_EC_PARAMS, (CK_VOID_PTR)certinfo.curve, (CK_ULONG)certinfo.l_curve);
2055 					if (ret != CKR_OK)
2056 						goto cleanup;
2057 
2058 					if (certinfo.l_pkinfo > 0)
2059 						ret = p11_set_attribute_value(pPubKeyObject->pAttr, pPubKeyObject->count, CKA_EC_POINT, (CK_VOID_PTR)certinfo.pkinfo, certinfo.l_pkinfo);
2060 					if (ret != CKR_OK)
2061 						goto cleanup;
2062 				}
2063 
2064 				//TODO test if we can set the trusted flag...
2065 				ret = p11_set_attribute_value(pPubKeyObject->pAttr, pPubKeyObject->count, CKA_TRUSTED, (CK_VOID_PTR) & btrue, sizeof(btrue));
2066 				if (ret != CKR_OK)
2067 					goto cleanup;
2068 
2069 				pPubKeyObject->state = P11_CACHED;
2070 			}
2071 		}
2072 		catch(CMWException &e)
2073 		{
2074 			cert_free_info(&certinfo);
2075 			return (cal_translate_error(WHERE, e.GetError()));
2076 		}
2077 		catch( ...)
2078 		{
2079 			log_trace(WHERE, "E: unkown exception thrown");
2080 			cert_free_info(&certinfo);
2081 			return (CKR_FUNCTION_FAILED);
2082 		}
2083 	}
2084 	if (ret != 0)
2085 	{
2086 		log_trace(WHERE, "E: ret is 0x%0lx", ret);
2087 		cert_free_info(&certinfo);
2088 		return (CKR_DEVICE_ERROR);
2089 	}
2090 
2091       cleanup:
2092 	cert_free_info(&certinfo);
2093 	return (ret);
2094 }
2095 
2096 #undef WHERE
2097 
2098 
2099 
2100 
2101 
2102 #define WHERE "cal_sign()"
cal_sign(CK_SLOT_ID hSlot,P11_SIGN_DATA * pSignData,unsigned char * in,unsigned long l_in,unsigned char * out,unsigned long * l_out)2103 CK_RV cal_sign(CK_SLOT_ID hSlot, P11_SIGN_DATA * pSignData, unsigned char *in,
2104 	       unsigned long l_in, unsigned char *out, unsigned long *l_out)
2105 {
2106 	CK_RV ret = 0;
2107 	CByteArray oData(in, l_in);
2108 	CByteArray oDataOut;
2109 	unsigned long algo;
2110 	P11_SLOT *pSlot = NULL;
2111 
2112 	pSlot = p11_get_slot(hSlot);
2113 	if (pSlot == NULL)
2114 	{
2115 		log_trace(WHERE, "E: Invalid slot (%lu)", hSlot);
2116 		return (CKR_SLOT_ID_INVALID);
2117 	}
2118 	std::string szReader = pSlot->name;
2119 
2120 	//the caller is responsible for filling in/ checking the length
2121 	/*
2122 	   if (out == NULL)
2123 	   {
2124 	   //get length of signature
2125 	   *l_out = 128;
2126 	   return(CKR_OK);
2127 	   }
2128 	   if (*l_out < 128)
2129 	   return(CKR_BUFFER_TOO_SMALL);
2130 	 */
2131 	try
2132 	{
2133 		CReader & oReader = oCardLayer->getReader(szReader);
2134 		CCard* poCard = oReader.GetCard();
2135 		tPrivKey key = poCard->GetPrivKeyByID(pSignData->id);
2136 
2137 		switch (pSignData->mechanism)
2138 		{
2139 			case CKM_RSA_PKCS:
2140 				algo = SIGN_ALGO_RSA_PKCS;
2141 				break;
2142 			case CKM_MD5:
2143 			case CKM_MD5_RSA_PKCS:
2144 				algo = SIGN_ALGO_MD5_RSA_PKCS;
2145 				break;
2146 			case CKM_SHA_1:
2147 			case CKM_SHA1_RSA_PKCS:
2148 				algo = SIGN_ALGO_SHA1_RSA_PKCS;
2149 				break;
2150 			case CKM_SHA256:
2151 			case CKM_SHA256_RSA_PKCS:
2152 				algo = SIGN_ALGO_SHA256_RSA_PKCS;
2153 				break;
2154 			case CKM_SHA384:
2155 			case CKM_SHA384_RSA_PKCS:
2156 				algo = SIGN_ALGO_SHA384_RSA_PKCS;
2157 				break;
2158 			case CKM_SHA512:
2159 			case CKM_SHA512_RSA_PKCS:
2160 				algo = SIGN_ALGO_SHA512_RSA_PKCS;
2161 				break;
2162 			case CKM_RIPEMD160:
2163 			case CKM_RIPEMD160_RSA_PKCS:
2164 				algo = SIGN_ALGO_RIPEMD160_RSA_PKCS;
2165 				break;
2166 			case CKM_SHA1_RSA_PKCS_PSS:
2167 				algo = SIGN_ALGO_SHA1_RSA_PSS;
2168 				break;
2169 			case CKM_SHA256_RSA_PKCS_PSS:
2170 				algo = SIGN_ALGO_SHA256_RSA_PSS;
2171 				break;
2172 			case CKM_ECDSA_SHA256:
2173 				algo = SIGN_ALGO_SHA256_ECDSA;
2174 				break;
2175 			case CKM_ECDSA_SHA384:
2176 				algo = SIGN_ALGO_SHA384_ECDSA;
2177 				break;
2178 			case CKM_ECDSA_SHA512:
2179 				algo = SIGN_ALGO_SHA512_ECDSA;
2180 				break;
2181 			case CKM_ECDSA:
2182 				algo = SIGN_ALGO_ECDSA_RAW;
2183 				break;
2184 			default:
2185 				ret = CKR_MECHANISM_INVALID;
2186 				goto cleanup;
2187 		}
2188 
2189 		oDataOut = poCard->CardSign(key, algo, oData);
2190 	}
2191 	catch(CMWException & e)
2192 	{
2193 		return (cal_translate_error(WHERE, e.GetError()));
2194 	}
2195 	catch( ...)
2196 	{
2197 		log_trace(WHERE, "E: unkown exception thrown");
2198 		return (CKR_FUNCTION_FAILED);
2199 	}
2200 
2201 	*l_out = oDataOut.Size();
2202 	memcpy(out, oDataOut.GetBytes(), *l_out);
2203 
2204       cleanup:
2205 
2206 	return (ret);
2207 }
2208 
2209 #undef WHERE
2210 
2211 
2212 
2213 #define WHERE "cal_validate_session()"
cal_validate_session(P11_SESSION * pSession)2214 CK_RV cal_validate_session(P11_SESSION * pSession)
2215 {
2216 	CK_RV ret = CKR_OK;
2217 	int status;
2218 
2219 	if (pSession->inuse == 0)
2220 	{
2221 		return (CKR_SESSION_HANDLE_INVALID);
2222 	}
2223 	//check status flag in session first
2224 	if (pSession->state != P11_CARD_STILL_PRESENT)
2225 	{
2226 		//state allready invalid for this session so we can return here
2227 		switch (pSession->state)
2228 		{
2229 			case P11_CARD_INSERTED:	//card is inserted (Opensession allready called connect(update) so state PRESENT is not expected anymore)
2230 			case P11_CARD_NOT_PRESENT:	//card is not present
2231 			case P11_CARD_REMOVED:	//card is removed
2232 			case P11_CARD_OTHER:	//another card has been inserted, replacing the previous one
2233 			default:
2234 				//        return (CKR_TOKEN_NOT_PRESENT);
2235 				return (CKR_DEVICE_REMOVED);
2236 				//        return (CKR_SESSION_HANDLE_INVALID);
2237 		}
2238 	}
2239 
2240 	try
2241 	{
2242 		//previous state is STILL_PRESENT so get new state to see if this has changed
2243 		ret = cal_update_token(pSession->hslot, &status, 0);
2244 		if (ret != CKR_OK)
2245 		{
2246 			return (ret);
2247 		}
2248 
2249 		if (status == P11_CARD_STILL_PRESENT)
2250 			ret = 0;
2251 		else
2252 		{
2253 			//      if ( (status == P11_CARD_REMOVED) || (status == P11_CARD_NOT_PRESENT) )
2254 			ret = CKR_DEVICE_REMOVED;
2255 			//      else
2256 			////         ret = CKR_SESSION_HANDLE_INVALID;
2257 			//         ret = CKR_OK;
2258 		}
2259 	}
2260 	catch(CMWException &e)
2261 	{
2262 		return (cal_translate_error(WHERE, e.GetError()));
2263 	}
2264 	catch( ...)
2265 	{
2266 		log_trace(WHERE, "E: unkown exception thrown");
2267 		return (CKR_GENERAL_ERROR);
2268 	}
2269 	return (ret);
2270 }
2271 
2272 #undef WHERE
2273 
2274 
2275 
2276 
2277 #define WHERE "cal_update_token()"
cal_update_token(CK_SLOT_ID hSlot,int * pStatus,int bPresenceOnly)2278 CK_RV cal_update_token(CK_SLOT_ID hSlot, int *pStatus, int bPresenceOnly)
2279 {
2280 	P11_OBJECT *pObject = NULL;
2281 	CK_RV ret = CKR_OK;
2282 
2283 	//int status;
2284 	unsigned int i = 0;
2285 	P11_SLOT *pSlot = NULL;
2286 
2287 	pSlot = p11_get_slot(hSlot);
2288 	if (pSlot == NULL)
2289 	{
2290 		log_trace(WHERE, "E: Invalid slot (%lu)", hSlot);
2291 		return (CKR_SLOT_ID_INVALID);
2292 	}
2293 
2294 	try
2295 	{
2296 		std::string reader = pSlot->name;
2297 		CReader & oReader = oCardLayer->getReader(reader);
2298 		CCard* poCard = NULL;
2299 		//we get an error thrown here when the cardobject has not been created yet
2300 
2301 		*pStatus = cal_map_status(oReader.Status(true, bPresenceOnly ? true : false));
2302 
2303 		poCard = oReader.GetCard();
2304 
2305 		if ( (*pStatus == P11_CARD_INSERTED) || (*pStatus == P11_CARD_STILL_PRESENT)  || (*pStatus == P11_CARD_OTHER) )
2306 		{
2307 			if (!bPresenceOnly && (poCard->GetType() == CARD_UNKNOWN))
2308 			{
2309 				log_trace(WHERE, "oReader.GetCardType() == CARD_UNKNOWN");
2310 				return (CKR_TOKEN_NOT_RECOGNIZED);
2311 			}
2312 		}
2313 
2314 		if (*pStatus != P11_CARD_STILL_PRESENT)
2315 		{
2316 			//clean objects
2317 			for (i = 1; i <= pSlot->nobjects; i++)
2318 			{
2319 				pObject = p11_get_slot_object(pSlot, i);
2320 				p11_clean_object(pObject);
2321 				//if (pObject != NULL)
2322 				// pObject->state = 0;
2323 			}
2324 			pSlot->ulCardDataCached = 0;
2325 
2326 			//invalidate sessions
2327 			p11_invalidate_sessions(hSlot, *pStatus);
2328 
2329 			//if Present, other => init objects
2330 			if ((*pStatus == P11_CARD_OTHER) || (*pStatus == P11_CARD_INSERTED))
2331 			{
2332 				//(re)initialize objects
2333 #ifdef PKCS11_FF
2334 				ret = cal_init_objects(pSlot);
2335 				if (ret != CKR_OK)
2336 				{
2337 					log_trace(WHERE, "E: cal_init_objects() returned %s", log_map_error(ret));
2338 				}
2339 #endif
2340 			}
2341 
2342 		}
2343 	}
2344 	catch(CMWException &e)
2345 	{
2346 		if (e.GetError() == EIDMW_ERR_NO_CARD)
2347 		{
2348 			//token not present is a status, not an error
2349 			*pStatus = P11_CARD_NOT_PRESENT;
2350 			ret = CKR_OK;
2351 			log_trace(WHERE, "I: No card present");
2352 		}
2353 		else
2354 		{
2355 			ret = cal_translate_error(WHERE, e.GetError());
2356 		}
2357 		return ret;
2358 	}
2359 	catch( ...)
2360 	{
2361 		log_trace(WHERE, "E: unkown exception thrown");
2362 		return (CKR_SESSION_HANDLE_INVALID);
2363 	}
2364 	return ret;
2365 }
2366 
2367 #undef WHERE
2368 
2369 
2370 #define WHERE "cal_get_slot_changes()"
cal_get_slot_changes(int * ph)2371 CK_RV cal_get_slot_changes(int *ph)
2372 {
2373 	int first = 1;
2374 	P11_SLOT *pSlot = NULL;
2375 	CK_RV ret = CKR_NO_EVENT;
2376 
2377 	*ph = -1;
2378 
2379 	try
2380 	{
2381 		for (int i = 0; i < p11_get_nreaders(); i++)
2382 		{
2383 			if (oReadersInfo->ReaderStateChanged(i))
2384 			{
2385 				//return first reader that changed state
2386 				//there could be more than one reader that changed state,
2387 				//keep these events in the slotlist
2388 #ifdef PKCS11_FF
2389 				//in case the upnp reader detected a reader event, we report it with a slotID that is above the highest slotID in the current slotList
2390 				if (i == (p11_get_nreaders() - 1))
2391 				{
2392 					if(first)
2393 					{
2394 						*ph = p11_get_nreaders();
2395 						ret = CKR_OK;
2396 					}
2397 					else {
2398 						pSlot = p11_get_slot(i);
2399 						if (pSlot)
2400 						{
2401 							pSlot->ievent = 2;
2402 						}
2403 					}
2404 				} else
2405 #endif
2406 				{
2407 					if (first)
2408 					{
2409 						*ph = i;
2410 						first = 0;
2411 						ret = CKR_OK;
2412 					} else
2413 					{
2414 						pSlot = p11_get_slot(i);
2415 						if (pSlot)
2416 						{
2417 							if (oReadersInfo->CardPresent(i))
2418 								pSlot->ievent = 1;
2419 							else
2420 								pSlot->ievent = 2;
2421 						}
2422 					}
2423 				}
2424 			}
2425 		}
2426 	}
2427 	catch(CMWException &e)
2428 	{
2429 		return (cal_translate_error(WHERE, e.GetError()));
2430 	}
2431 	catch( ...)
2432 	{
2433 		log_trace(WHERE, "E: unkown exception thrown");
2434 		return (CKR_FUNCTION_FAILED);
2435 	}
2436 	return ret;
2437 }
2438 
2439 #undef WHERE
2440 
2441 #define WHERE "cal_map_status()"
cal_map_status(tCardStatus calstatus)2442 int cal_map_status(tCardStatus calstatus)
2443 {
2444 	switch (calstatus)
2445 	{
2446 		case CARD_INSERTED:
2447 			return (P11_CARD_INSERTED);
2448 		case CARD_NOT_PRESENT:
2449 			return (P11_CARD_NOT_PRESENT);
2450 		case CARD_STILL_PRESENT:
2451 			return (P11_CARD_STILL_PRESENT);
2452 		case CARD_REMOVED:
2453 			return (P11_CARD_REMOVED);
2454 		case CARD_OTHER:
2455 			return (P11_CARD_OTHER);
2456 		case CARD_UNKNOWN_STATE:
2457 			return (P11_CARD_UNKNOWN_STATE);
2458 		default:
2459 			return (-1);
2460 	}
2461 }
2462 
2463 #undef WHERE
2464 
2465 #define WHERE "cal_refresh_readers()"
cal_refresh_readers()2466 CK_RV cal_refresh_readers()
2467 {
2468 	CK_RV ret = CKR_OK;
2469 
2470 	try
2471 	{
2472 		if (oReadersInfo)
2473 		{
2474 			//check if readerlist changed?
2475 			CReadersInfo *pNewReadersInfo = new CReadersInfo(oCardLayer->ListReaders());
2476 			if (pNewReadersInfo->SameList(oReadersInfo) == TRUE)
2477 			{
2478 				//same reader list as before, so we keep the readers' status
2479 				delete(pNewReadersInfo);
2480 				return CKR_OK;
2481 			} else
2482 			{
2483 				delete(oReadersInfo);
2484 				oReadersInfo = pNewReadersInfo;
2485 			}
2486 		} else
2487 		{
2488 			oReadersInfo = new CReadersInfo(oCardLayer->ListReaders());
2489 		}
2490 		//new _reader list, so please stop the scardgetstatuschange that is waiting on the old list
2491 		log_trace(WHERE, "I: stopping the scardgetstatuschange that is waiting on the old list");
2492 		oCardLayer->CancelActions();
2493 		log_trace(WHERE, "I: called oCardLayer->CancelActions()");
2494 	}
2495 	catch(CMWException &e)
2496 	{
2497 		log_trace(WHERE, "E: CMWException exception thrown: 0x%8lx", e.GetError());
2498 		return (cal_translate_error(WHERE, e.GetError()));
2499 	}
2500 	catch( ...)
2501 	{
2502 		log_trace(WHERE, "E: unknown exception thrown");
2503 		return (CKR_FUNCTION_FAILED);
2504 	}
2505 
2506 	//init slots and token in slots
2507 	memset(gpSlot, 0, sizeof(gpSlot));
2508 	ret = cal_init_slots();
2509 	if (ret)
2510 		log_trace(WHERE, "E: p11_init_slots() returns %lu", ret);
2511 
2512 	return (ret);
2513 }
2514 
2515 #undef WHERE
2516 
cal_translate_error(const char * WHERE,long err)2517 CK_RV cal_translate_error(const char *WHERE, long err)
2518 {
2519 	log_trace(WHERE, "E: MiddlewareException thrown: 0x%0lx", err);
2520 
2521 	switch (err)
2522 	{
2523 		case EIDMW_OK:
2524 			return (CKR_OK);
2525 			break;
2526 
2527 		/** A function parameter has an unexpected value (general) */
2528 		case EIDMW_ERR_PARAM_BAD:
2529 			return (CKR_FUNCTION_FAILED);
2530 			break;	//return(CKR_ARGUMENTS_BAD);
2531 
2532 		/** A function parameter exceeded the allowed range */
2533 		case EIDMW_ERR_PARAM_RANGE:
2534 			return (CKR_FUNCTION_FAILED);
2535 			break;	//return(CKR_ARGUMENTS_BAD);
2536 
2537 		/** Bad file path (invalid characters, length no multiple of 4) */
2538 		case EIDMW_ERR_BAD_PATH:
2539 			return (CKR_FUNCTION_FAILED);
2540 			break;
2541 
2542 		/** Unknown/unsupported algorithm */
2543 		case EIDMW_ERR_ALGO_BAD:
2544 			return (CKR_MECHANISM_INVALID);
2545 			break;
2546 
2547 		/** Invalid/unsupported PIN operation */
2548 		case EIDMW_ERR_PIN_OPERATION:
2549 			return (CKR_FUNCTION_FAILED);
2550 			break;
2551 
2552 		/** PIN not allowed for this card (invalid characters, too short/long) */
2553 		case EIDMW_ERR_PIN_FORMAT:
2554 			return (CKR_FUNCTION_FAILED);
2555 			break;
2556 			/* the action was cancelled */
2557 		case EIDMW_ERR_CANCELLED:
2558 			return (CKR_FUNCTION_CANCELED);
2559 			break;
2560 			// Card errors
2561 
2562 		/** Generic card error */
2563 		case EIDMW_ERR_CARD:
2564 			return (CKR_DEVICE_ERROR);
2565 			break;
2566 
2567 		/** Not Authenticated (no PIN specified) */
2568 		case EIDMW_ERR_NOT_AUTHENTICATED:
2569 			return (CKR_USER_NOT_LOGGED_IN);
2570 			break;
2571 
2572 		/** This command is not supported by this card */
2573 		case EIDMW_ERR_NOT_SUPPORTED:
2574 			return (CKR_DEVICE_ERROR);
2575 			break;
2576 
2577 		/** Bad PIN */
2578 		case EIDMW_ERR_PIN_BAD:
2579 			return (CKR_PIN_INCORRECT);
2580 			break;
2581 
2582 		/** PIN blocked */
2583 		case EIDMW_ERR_PIN_BLOCKED:
2584 			return (CKR_PIN_LOCKED);
2585 			break;
2586 
2587 		/** No card present or card has been removed */
2588 		case EIDMW_ERR_NO_CARD:
2589 			return (CKR_TOKEN_NOT_PRESENT);
2590 			break;
2591 
2592 		/** Bad parameter P1 or P2 */
2593 		case EIDMW_ERR_BAD_P1P2:
2594 			return (CKR_DEVICE_ERROR);
2595 			break;
2596 
2597 		/** Command not allowed */
2598 		case EIDMW_ERR_CMD_NOT_ALLOWED:
2599 			return (CKR_DEVICE_ERROR);
2600 			break;
2601 
2602 		/** File not found */
2603 		case EIDMW_ERR_FILE_NOT_FOUND:
2604 			return (CKR_DEVICE_ERROR);
2605 			break;
2606 
2607 		/** Unable to read applet version from the card */
2608 		case EIDMW_ERR_APPLET_VERSION_NOT_FOUND:
2609 			return (CKR_DEVICE_ERROR);
2610 			break;
2611 
2612 		/** Card not activated */
2613 		case EIDMW_ERR_NOT_ACTIVATED:
2614 			return (CKR_DEVICE_ERROR);
2615 			break;
2616 
2617 			// Reader errors
2618 
2619 		/** Error communicating with the card */
2620 		case EIDMW_ERR_CARD_COMM:
2621 			return (CKR_DEVICE_ERROR);
2622 			break;
2623 
2624 		/** No reader has been found */
2625 		case EIDMW_ERR_NO_READER:
2626 			return (CKR_DEVICE_ERROR);
2627 			break;
2628 
2629 		/** The pinpad reader returned an error */
2630 		case EIDMW_ERR_PINPAD:
2631 			return (CKR_DEVICE_ERROR);
2632 			break;
2633 
2634 		/** A card is present but we can't connect in a normal way*/
2635 		case EIDMW_ERR_CANT_CONNECT:
2636 			return (CKR_DEVICE_ERROR);
2637 			break;
2638 
2639 			// Internal errors (caused by the middleware)
2640 
2641 		/** An internal limit has been reached */
2642 		case EIDMW_ERR_LIMIT:
2643 			return (CKR_DEVICE_ERROR);
2644 			break;
2645 
2646 		/** An internal check failed */
2647 		case EIDMW_ERR_CHECK:
2648 			return (CKR_DEVICE_ERROR);
2649 			break;
2650 
2651 		/** The PCSC library could not be located */
2652 		case EIDMW_ERR_PCSC_LIB:
2653 			return (CKR_DEVICE_ERROR);
2654 			break;
2655 
2656 		/** An attempt to resolve a Z-lib address failed */
2657 		case EIDMW_ERR_ZLIB_RESOLVE:
2658 			return (CKR_GENERAL_ERROR);
2659 			break;
2660 
2661 		/** And unknown error occurred */
2662 		case EIDMW_ERR_UNKNOWN:
2663 			return (CKR_GENERAL_ERROR);
2664 			break;
2665 
2666 		/** The pinpad reader received a wrong/unknown value */
2667 		case EIDMW_PINPAD_ERR:
2668 			return (CKR_DEVICE_ERROR);
2669 			break;
2670 
2671 		/** Dynamic library couldn't be loaded (found found at the specified location) */
2672 		case EIDMW_CANT_LOAD_LIB:
2673 			return (CKR_GENERAL_ERROR);
2674 			break;
2675 
2676 		/** Memory error */
2677 		case EIDMW_ERR_MEMORY:
2678 			return (CKR_HOST_MEMORY);
2679 			break;
2680 
2681 		/** Couldn't delete cache file(s) */
2682 		case EIDMW_ERR_DELETE_CACHE:
2683 			return (CKR_GENERAL_ERROR);
2684 			break;
2685 
2686 		/** Error getting or writing config data */
2687 		case EIDMW_CONF:
2688 			return (CKR_GENERAL_ERROR);
2689 			break;
2690 
2691 
2692 			// User errors/events
2693 
2694 		/** User pressed Cancel in PIN dialog */
2695 		case EIDMW_ERR_PIN_CANCEL:
2696 			return (CKR_FUNCTION_CANCELED);
2697 			break;
2698 
2699 		/** Pinpad timeout */
2700 		case EIDMW_ERR_TIMEOUT:
2701 			return (CKR_FUNCTION_CANCELED);
2702 			break;
2703 
2704 		/** The new PINs that were entered differ */
2705 		case EIDMW_NEW_PINS_DIFFER:
2706 
2707 		/** A PIN with invalid length or format was entered */
2708 		case EIDMW_WRONG_PIN_FORMAT:
2709 			return (CKR_FUNCTION_FAILED);
2710 			break;
2711 
2712 			// Parser errors
2713 
2714 		/** Could not find expected elements in parsed ASN.1 vector */
2715 		case EIDMW_WRONG_ASN1_FORMAT:
2716 			return (CKR_FUNCTION_FAILED);
2717 			break;
2718 
2719 			// I/O errors
2720 			// errors modelled on the definitions in errno.h
2721 
2722 		/** File could not be opened */
2723 		case EIDMW_FILE_NOT_OPENED:
2724 			return (CKR_FUNCTION_FAILED);
2725 			break;
2726 
2727 		/** Search permission is denied for a component of the path prefix of path. */
2728 		case EIDMW_PERMISSION_DENIED:
2729 			return (CKR_FUNCTION_FAILED);
2730 			break;
2731 
2732 		/** A loop exists in symbolic links encountered during resolution of the path argument. */
2733 
2734 		/** A component of path does not name an existing file or path is an empty string.*/
2735 
2736 		/** A component of the path prefix is not a directory. */
2737 
2738 		/** The length of the path argument exceeds {PATH_MAX} or a pathname component is longer than {NAME_MAX}. */
2739 		case EIDMW_INVALID_PATH:
2740 			return (CKR_FUNCTION_FAILED);
2741 			break;
2742 
2743 		/** {OPEN_MAX} file descriptors are currently open in the calling process. */
2744 
2745 		/** Too many files are currently open in the system.*/
2746 		case EIDMW_TOO_MANY_OPENED_FILES:
2747 			return (CKR_FUNCTION_FAILED);
2748 			break;
2749 
2750 		/** The argument of closedir or readdir does not refer to an open directory stream. */
2751 		case EIDMW_DIR_NOT_OPENED:
2752 			return (CKR_FUNCTION_FAILED);
2753 			break;
2754 
2755 		/** Interrupted by a signal */
2756 		case EIDMW_INTERRUPTION:
2757 			return (CKR_FUNCTION_FAILED);
2758 			break;
2759 
2760 		/** One of the values in the structure to be returned cannot be represented correctly. */
2761 		case EIDMW_OVERFLOW:
2762 			return (CKR_FUNCTION_FAILED);
2763 			break;
2764 
2765 		/** An I/O error occurred while reading from the file system.*/
2766 		case EIDMW_ERROR_IO:
2767 			return (CKR_FUNCTION_FAILED);
2768 			break;
2769 
2770 		/** Call of the Logger after destruct time */
2771 		case EIDMW_ERR_LOGGER_APPLEAVING:
2772 			return (CKR_FUNCTION_FAILED);
2773 			break;
2774 
2775 			// SDK error
2776 
2777 		/** The document type is unknown for this card */
2778 		case EIDMW_ERR_DOCTYPE_UNKNOWN:
2779 			return (CKR_FUNCTION_FAILED);
2780 			break;
2781 
2782 		/** The card type asked doesn't correspond with the real card type */
2783 		case EIDMW_ERR_CARDTYPE_BAD:
2784 			return (CKR_FUNCTION_FAILED);
2785 			break;
2786 
2787 		/** This card type is unknown */
2788 		case EIDMW_ERR_CARDTYPE_UNKNOWN:
2789 			return (CKR_TOKEN_NOT_RECOGNIZED);
2790 			break;
2791 
2792 		/** This Certificate has no issuer (=root) */
2793 		case EIDMW_ERR_CERT_NOISSUER:
2794 			return (CKR_FUNCTION_FAILED);
2795 			break;
2796 
2797 		/** No release of SDK object has been done before closing the application */
2798 		case EIDMW_ERR_RELEASE_NEEDED:
2799 			return (CKR_FUNCTION_FAILED);
2800 			break;
2801 
2802 			// Errors in system calls
2803 
2804 		/** a system call returned an error */
2805 		case EIDMW_ERR_SYSTEM:
2806 			return (CKR_GENERAL_ERROR);
2807 			break;
2808 
2809 		/** a signal function returned an error */
2810 		case EIDMW_ERR_SIGNAL:
2811 			return (CKR_FUNCTION_FAILED);
2812 			break;
2813 
2814 		default:
2815 			return (CKR_GENERAL_ERROR);
2816 	}
2817 }
2818 
2819 #define WHERE "cal_wait_for_slot_event()"
cal_wait_for_slot_event(int block)2820 CK_RV cal_wait_for_slot_event(int block)
2821 {
2822 	CK_RV ret = CKR_OK;
2823 
2824 	if (oReadersInfo->IsFirstTime())
2825 	{
2826 		ret = cal_wait_for_the_slot_event(0);
2827 		if (ret != CKR_OK)
2828 			return ret;
2829 		oReadersInfo->SetFirstTime(FALSE);
2830 	}
2831 	ret = cal_wait_for_the_slot_event(block);
2832 	return ret;
2833 }
2834 
2835 #undef WHERE
2836 
2837 #define WHERE "cal_wait_for_the_slot_event()"
cal_wait_for_the_slot_event(int block)2838 CK_RV cal_wait_for_the_slot_event(int block)
2839 {
2840 	SCARD_READERSTATEA txReaderStates[MAX_READERS];
2841 	CK_RV ret = CKR_OK;
2842 
2843 #ifdef PKCS11_FF
2844 	long lret = SCARD_E_TIMEOUT;
2845 #endif
2846 	unsigned long ulnReaders = 0;
2847 
2848 	memset(txReaderStates, 0, sizeof(txReaderStates));
2849 	oReadersInfo->GetReaderStates(txReaderStates, MAX_READERS, &ulnReaders);
2850 
2851 	try
2852 	{
2853 		if (block)
2854 		{
2855 			p11_unlock();
2856 
2857 			oCardLayer->GetStatusChange(TIMEOUT_INFINITE, txReaderStates, ulnReaders);
2858 
2859 			log_trace(WHERE, "I: status change received");
2860 			p11_lock();
2861 			if (p11_get_init() != BEIDP11_INITIALIZED)
2862 			{
2863 				log_trace(WHERE,
2864 					  "I: leave, p11_get_init returned false");
2865 				CLEANUP(CKR_CRYPTOKI_NOT_INITIALIZED);
2866 			}
2867 			if (oReadersInfo->IsFirstTime())
2868 			{
2869 				//we never call GetStatusChange with blocked flag when its the first time,
2870 				//if we get here, C_getslotlist must have reset oReadersInfo, in which case
2871 				//all reader states we have here are obsolete
2872 				CLEANUP(CKR_NO_EVENT);
2873 			}
2874 		} else
2875 		{
2876 			oCardLayer->GetStatusChange(0, txReaderStates, ulnReaders);
2877 		}
2878 	}
2879 	catch(CMWException &e)
2880 	{
2881 		if (block)
2882 		{
2883 			p11_lock();
2884 		}
2885 		log_trace(WHERE, "E: CMWException exception thrown 0x%0lx", e.GetError());
2886 		CLEANUP(cal_translate_error(WHERE, e.GetError()));
2887 	}
2888 	catch( ...)
2889 	{
2890 		if (block)
2891 		{
2892 			p11_lock();
2893 		}
2894 		log_trace(WHERE, "E: unkown exception thrown");
2895 		CLEANUP(CKR_FUNCTION_FAILED);
2896 	}
2897 
2898 	oReadersInfo->UpdateReaderStates(txReaderStates, ulnReaders);
2899 
2900       cleanup:
2901 	cal_free_reader_states(txReaderStates, ulnReaders);
2902 	return (ret);
2903 }
2904 
2905 #undef WHERE
2906 
cal_free_reader_states(SCARD_READERSTATEA * txReaderStates,unsigned long ulnReaders)2907 void cal_free_reader_states(SCARD_READERSTATEA * txReaderStates, unsigned long ulnReaders)
2908 {
2909 	// Free the memory allocated for the reader names
2910 	for (DWORD i = 0; i < ulnReaders; i++)
2911 	{
2912 		if (txReaderStates[i].szReader != NULL)
2913 		{
2914 			free((void *) (txReaderStates[i].szReader));
2915 			txReaderStates[i].szReader = NULL;
2916 		}
2917 	}
2918 	return;
2919 }
2920