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