1 /***************************************************************************
2     begin       : Mon Mar 01 2004
3     copyright   : (C) 2004-2010 by Martin Preuss
4     email       : martin@libchipcard.de
5 
6  ***************************************************************************
7  *          Please see toplevel file COPYING for license details           *
8  ***************************************************************************/
9 
10 
11 #ifdef HAVE_CONFIG_H
12 # include <config.h>
13 #endif
14 
15 #include "ct_card.h"
16 
17 #include <gwenhywfar/misc.h>
18 #include <gwenhywfar/debug.h>
19 #include <gwenhywfar/ct_be.h>
20 #include <gwenhywfar/cryptdefs.h>
21 #include <gwenhywfar/gui.h>
22 
23 
24 
LC_Crypt_Token_ResultToError(LC_CLIENT_RESULT res)25 int LC_Crypt_Token_ResultToError(LC_CLIENT_RESULT res) {
26   int rv;
27 
28   switch(res) {
29   case LC_Client_ResultOk:
30     rv=0;
31     break;
32   case LC_Client_ResultWait:
33     rv=GWEN_ERROR_TIMEOUT;
34     break;
35   case LC_Client_ResultIpcError:
36   case LC_Client_ResultCmdError:
37   case LC_Client_ResultDataError:
38     rv=GWEN_ERROR_IO;
39     break;
40 
41   case LC_Client_ResultAborted:
42     rv=GWEN_ERROR_USER_ABORTED;
43     break;
44 
45   case LC_Client_ResultInvalid:
46     rv=GWEN_ERROR_INVALID;
47     break;
48 
49   case LC_Client_ResultNoData:
50     rv=GWEN_ERROR_NO_DATA;
51     break;
52 
53   case LC_Client_ResultCardRemoved:
54     rv=GWEN_ERROR_REMOVED;
55     break;
56 
57   case LC_Client_ResultNotSupported:
58     rv=GWEN_ERROR_NOT_SUPPORTED;
59     break;
60 
61   case LC_Client_ResultInternal:
62   case LC_Client_ResultGeneric:
63   default:
64     rv=GWEN_ERROR_GENERIC;
65     break;
66   }
67 
68   return rv;
69 }
70 
71 
72 static
LC_Crypt_Token__GetPin(GWEN_CRYPT_TOKEN * ct,LC_CARD * hcard,int pid,GWEN_CRYPT_PINTYPE pt,GWEN_CRYPT_PINENCODING pe,uint32_t flags,unsigned char * buffer,unsigned int minLength,unsigned int maxLength,unsigned int * pinLength,uint32_t guiid)73 int LC_Crypt_Token__GetPin(GWEN_CRYPT_TOKEN *ct,
74 			   LC_CARD *hcard,
75 			   int pid,
76 			   GWEN_CRYPT_PINTYPE pt,
77 			   GWEN_CRYPT_PINENCODING pe,
78 			   uint32_t flags,
79 			   unsigned char *buffer,
80 			   unsigned int minLength,
81 			   unsigned int maxLength,
82 			   unsigned int *pinLength,
83 			   uint32_t guiid) {
84   int rv;
85 
86   rv=GWEN_Crypt_Token_GetPin(ct,
87 			     pt, pe, flags,
88 			     buffer,
89 			     minLength, maxLength,
90 			     pinLength,
91 			     guiid);
92   if (rv==GWEN_ERROR_DEFAULT_VALUE) {
93     LC_CLIENT_RESULT res;
94 
95     res=LC_Card_GetInitialPin(hcard, pid, buffer, maxLength,
96                               pinLength);
97     if (res) {
98       DBG_INFO(LC_LOGDOMAIN, "here (%d)", res);
99       return GWEN_ERROR_IO;
100     }
101 
102     if (pe!=GWEN_Crypt_PinEncoding_Ascii) {
103       rv=GWEN_Crypt_TransformPin(GWEN_Crypt_PinEncoding_Ascii,
104 				 pe,
105 				 buffer,
106 				 maxLength,
107 				 pinLength);
108       if (rv) {
109         DBG_INFO(LC_LOGDOMAIN, "here (%d)", rv);
110         return rv;
111       }
112     }
113   }
114   else if (rv) {
115     DBG_INFO(LC_LOGDOMAIN, "here (%d)", rv);
116     return rv;
117   }
118 
119   return 0;
120 }
121 
122 
123 
124 static
LC_Crypt_Token__ChangePin(GWEN_CRYPT_TOKEN * ct,LC_CARD * hcard,GWEN_CRYPT_PINTYPE pt,int initial,uint32_t guiid)125 int LC_Crypt_Token__ChangePin(GWEN_CRYPT_TOKEN *ct,
126 			      LC_CARD *hcard,
127 			      GWEN_CRYPT_PINTYPE pt,
128 			      int initial,
129 			      uint32_t guiid) {
130   LC_CLIENT_RESULT res;
131   LC_PININFO *pi;
132   int maxErrors;
133   int currentErrors;
134 
135   assert(hcard);
136 
137   if (pt==GWEN_Crypt_PinType_Manage)
138     pi=LC_Card_GetPinInfoByName(hcard, "eg_pin");
139   else
140     pi=LC_Card_GetPinInfoByName(hcard, "ch_pin");
141   assert(pi);
142 
143   if (LC_PinInfo_GetAllowChange(pi)==0) {
144     DBG_ERROR(LC_LOGDOMAIN,
145               "Change of Pin is not allowed for this card");
146     LC_PinInfo_free(pi);
147     return GWEN_ERROR_INVALID;
148   }
149 
150   res=LC_Card_GetPinStatus(hcard,
151                            LC_PinInfo_GetId(pi),
152                            &maxErrors,
153                            &currentErrors);
154   if (res!=LC_Client_ResultNotSupported) {
155     if (res!=LC_Client_ResultOk) {
156       DBG_ERROR(LC_LOGDOMAIN,
157                 "Unable to read status of pin %x (%d)",
158                 LC_PinInfo_GetId(pi),
159                 res);
160       LC_PinInfo_free(pi);
161       return LC_Crypt_Token_ResultToError(res);
162     }
163 
164     if ((currentErrors!=maxErrors) &&
165         (GWEN_Crypt_Token_GetModes(ct) & GWEN_CRYPT_TOKEN_MODE_FORCE_PIN_ENTRY)){
166       DBG_ERROR(LC_LOGDOMAIN,
167                 "Bad pin entered at least once before, aborting");
168       LC_PinInfo_free(pi);
169       return GWEN_ERROR_ABORTED;
170     }
171   }
172 
173   if (!initial && (pt!=GWEN_Crypt_PinType_Manage) &&
174       (LC_Card_GetReaderFlags(hcard) & LC_READER_FLAGS_KEYPAD)) {
175     int mres;
176     int triesLeft=-1;
177 
178     DBG_INFO(LC_LOGDOMAIN,"Terminal has a keypad, will ask for pin.");
179     /* tell the user about pin verification */
180     mres=GWEN_Crypt_Token_BeginEnterPin(ct, pt, guiid);
181     if (mres) {
182       DBG_ERROR(LC_LOGDOMAIN, "Error in user interaction");
183       LC_PinInfo_free(pi);
184       return mres;
185     }
186 
187     res=LC_Card_IsoPerformModification(hcard, 0, pi, &triesLeft);
188 
189     if (res!=LC_Client_ResultOk) {
190       /* tell the user about end of pin verification */
191       GWEN_Crypt_Token_EndEnterPin(ct, pt, 0, guiid);
192       DBG_ERROR(LC_LOGDOMAIN, "sw1=%02x sw2=%02x (%s)",
193                 LC_Card_GetLastSW1(hcard),
194                 LC_Card_GetLastSW2(hcard),
195                 LC_Card_GetLastText(hcard));
196       LC_PinInfo_free(pi);
197 
198       if (LC_Card_GetLastSW1(hcard)==0x63) {
199 	switch (LC_Card_GetLastSW2(hcard)) {
200         case 0xc0: /* no error left */
201           return GWEN_ERROR_BAD_PIN_0_LEFT;
202         case 0xc1: /* one left */
203           return GWEN_ERROR_BAD_PIN_1_LEFT;
204         case 0xc2: /* two left */
205           return GWEN_ERROR_BAD_PIN_2_LEFT;
206         default:   /* unknown error */
207           return GWEN_ERROR_BAD_PIN;
208         } // switch
209       }
210       else if (LC_Card_GetLastSW1(hcard)==0x69 &&
211                LC_Card_GetLastSW2(hcard)==0x83) {
212         DBG_ERROR(LC_LOGDOMAIN, "Card unusable");
213         return GWEN_ERROR_IO;
214       }
215       else if (LC_Card_GetLastSW1(hcard)==0x64 &&
216                LC_Card_GetLastSW2(hcard)==0x01) {
217         DBG_ERROR(LC_LOGDOMAIN, "Aborted by user");
218         return GWEN_ERROR_USER_ABORTED;
219       }
220       else {
221         return GWEN_ERROR_IO;
222       }
223     } /* if not ok */
224     else {
225       /* PIN ok */
226       DBG_INFO(LC_LOGDOMAIN, "Pin ok");
227       GWEN_Crypt_Token_EndEnterPin(ct, pt, 1, guiid);
228     }
229   } /* if hasKeyPad */
230   else {
231     unsigned char pinBuffer1[64];
232     unsigned char pinBuffer2[64];
233     unsigned int pinLength1;
234     unsigned int pinLength2;
235     int mres;
236     int pinMaxLen;
237     uint32_t pflags=0;
238     GWEN_CRYPT_PINENCODING pe;
239     int triesLeft=-1;
240 
241     DBG_INFO(LC_LOGDOMAIN, "No keypad (or disabled), will ask for PIN");
242     memset(pinBuffer1, 0, sizeof(pinBuffer1));
243     memset(pinBuffer2, 0, sizeof(pinBuffer2));
244 
245     pe=LC_PinInfo_GetEncoding(pi);
246     if (pt==GWEN_Crypt_PinType_Manage)
247       pflags|=GWEN_GUI_INPUT_FLAGS_ALLOW_DEFAULT;
248     pflags|=GWEN_GUI_INPUT_FLAGS_NUMERIC;
249     pinLength1=0;
250     pinMaxLen=LC_PinInfo_GetMaxLength(pi);
251     if (!pinMaxLen || pinMaxLen>sizeof(pinBuffer1)-1)
252       pinMaxLen=sizeof(pinBuffer1)-1;
253     if (initial) {
254       LC_CLIENT_RESULT res;
255 
256       res=LC_Card_GetInitialPin(hcard,
257                                 LC_PinInfo_GetId(pi),
258                                 pinBuffer1, pinMaxLen,
259                                 &pinLength1);
260       if (res) {
261         DBG_INFO(LC_LOGDOMAIN, "here (%d)", res);
262         mres=GWEN_ERROR_IO;
263       }
264       else
265         mres=0;
266     }
267     else
268       mres=LC_Crypt_Token__GetPin(ct,
269 				  hcard,
270 				  LC_PinInfo_GetId(pi),
271 				  pt,
272 				  pe,
273 				  pflags,
274 				  pinBuffer1,
275 				  LC_PinInfo_GetMinLength(pi),
276 				  pinMaxLen,
277 				  &pinLength1,
278 				  guiid);
279     if (mres!=0) {
280       DBG_ERROR(LC_LOGDOMAIN, "Error asking for PIN, aborting");
281       memset(pinBuffer1, 0, sizeof(pinBuffer1));
282       memset(pinBuffer2, 0, sizeof(pinBuffer2));
283       LC_PinInfo_free(pi);
284       return mres;
285     }
286 
287     if (pinLength1<pinMaxLen && LC_PinInfo_GetFiller(pi)) {
288       int i;
289       unsigned char c;
290 
291       c=(unsigned char)LC_PinInfo_GetFiller(pi);
292       for (i=pinLength1; i<pinMaxLen; i++)
293         pinBuffer1[i]=c;
294       pinLength1=pinMaxLen;
295     }
296 
297     /* get new pin */
298     if (pt==GWEN_Crypt_PinType_Manage)
299       pflags|=GWEN_GUI_INPUT_FLAGS_ALLOW_DEFAULT;
300     pflags|=GWEN_GUI_INPUT_FLAGS_NUMERIC;
301     pflags|=GWEN_GUI_INPUT_FLAGS_CONFIRM;
302     pinLength2=0;
303     pinMaxLen=LC_PinInfo_GetMaxLength(pi);
304     if (!pinMaxLen || pinMaxLen>sizeof(pinBuffer2)-1)
305       pinMaxLen=sizeof(pinBuffer2)-1;
306     mres=LC_Crypt_Token__GetPin(ct,
307 				hcard,
308 				LC_PinInfo_GetId(pi),
309 				pt,
310 				pe,
311 				pflags,
312 				pinBuffer2,
313 				LC_PinInfo_GetMinLength(pi),
314 				pinMaxLen,
315 				&pinLength2,
316 				guiid);
317     if (mres!=0) {
318       DBG_ERROR(LC_LOGDOMAIN, "Error asking for PIN, aborting");
319       memset(pinBuffer1, 0, sizeof(pinBuffer1));
320       memset(pinBuffer2, 0, sizeof(pinBuffer2));
321       LC_PinInfo_free(pi);
322       return mres;
323     }
324 
325     if (pinLength2<pinMaxLen && LC_PinInfo_GetFiller(pi)) {
326       int i;
327       unsigned char c;
328 
329       c=(unsigned char)LC_PinInfo_GetFiller(pi);
330       for (i=pinLength2; i<pinMaxLen; i++)
331         pinBuffer2[i]=c;
332       pinLength2=pinMaxLen;
333     }
334 
335     DBG_INFO(LC_LOGDOMAIN, "Modifying the PIN");
336     res=LC_Card_IsoModifyPin(hcard,
337                              0, pi,
338                              pinBuffer1,
339                              pinLength1,
340                              pinBuffer2,
341                              pinLength2,
342                              &triesLeft);
343     if (res!=LC_Client_ResultOk) {
344       DBG_ERROR(LC_LOGDOMAIN, "sw1=%02x sw2=%02x (%s)",
345                 LC_Card_GetLastSW1(hcard),
346                 LC_Card_GetLastSW2(hcard),
347                 LC_Card_GetLastText(hcard));
348       LC_PinInfo_free(pi);
349 
350       if (LC_Card_GetLastSW1(hcard)==0x63) {
351         /* TODO: Set Pin status */
352         switch (LC_Card_GetLastSW2(hcard)) {
353         case 0xc0: /* no error left */
354 	  return GWEN_ERROR_BAD_PIN_0_LEFT;
355         case 0xc1: /* one left */
356           return GWEN_ERROR_BAD_PIN_1_LEFT;
357         case 0xc2: /* two left */
358           return GWEN_ERROR_BAD_PIN_2_LEFT;
359         default:
360           return GWEN_ERROR_BAD_PIN;
361         } // switch
362       }
363       else if (LC_Card_GetLastSW1(hcard)==0x69 &&
364                LC_Card_GetLastSW2(hcard)==0x83) {
365         /* TODO: Set Pin status */
366         DBG_ERROR(LC_LOGDOMAIN, "Card unusable");
367         return GWEN_ERROR_IO;
368       }
369       else if (LC_Card_GetLastSW1(hcard)==0x64 &&
370                LC_Card_GetLastSW2(hcard)==0x01) {
371         return GWEN_ERROR_USER_ABORTED;
372       }
373       else {
374         DBG_ERROR(LC_LOGDOMAIN, "Unknown error");
375         return GWEN_ERROR_IO;
376       }
377     } // if not ok
378     else {
379       DBG_INFO(LC_LOGDOMAIN, "PIN ok");
380       /* TODO: Set Pin Status */
381     }
382   } // if no keyPad
383   LC_PinInfo_free(pi);
384 
385   return 0;
386 }
387 
388 
389 
390 static
LC_Crypt_Token__EnterPinWithPinInfo(GWEN_CRYPT_TOKEN * ct,LC_CARD * hcard,GWEN_CRYPT_PINTYPE pt,const LC_PININFO * pi,uint32_t guiid)391 int LC_Crypt_Token__EnterPinWithPinInfo(GWEN_CRYPT_TOKEN *ct,
392 					LC_CARD *hcard,
393 					GWEN_CRYPT_PINTYPE pt,
394 					const LC_PININFO *pi,
395 					uint32_t guiid) {
396   LC_CLIENT_RESULT res;
397   int maxErrors;
398   int currentErrors;
399 
400   assert(hcard);
401   assert(pi);
402 
403 #if 0
404   if (pi) {
405     GWEN_DB_NODE *dbDEBUG;
406 
407     dbDEBUG=GWEN_DB_Group_new("PinInfo");
408     LC_PinInfo_toDb(pi, dbDEBUG);
409     GWEN_DB_Dump(dbDEBUG, stderr, 2);
410     GWEN_DB_Group_free(dbDEBUG);
411   }
412 #endif
413 
414   res=LC_Card_GetPinStatus(hcard,
415                            LC_PinInfo_GetId(pi),
416                            &maxErrors,
417                            &currentErrors);
418   if (res!=LC_Client_ResultNotSupported) {
419     if (res!=LC_Client_ResultOk) {
420       DBG_ERROR(LC_LOGDOMAIN,
421                 "Unable to read status of pin %x (%d)",
422                 LC_PinInfo_GetId(pi),
423                 res);
424       return LC_Crypt_Token_ResultToError(res);
425     }
426 
427     if ((currentErrors!=maxErrors) &&
428         !(GWEN_Crypt_Token_GetModes(ct) &
429 	  GWEN_CRYPT_TOKEN_MODE_FORCE_PIN_ENTRY)
430        ){
431       DBG_ERROR(LC_LOGDOMAIN,
432                 "Bad pin entered at least once before, aborting");
433       return GWEN_ERROR_ABORTED;
434     }
435   }
436   else {
437     DBG_INFO(LC_LOGDOMAIN,
438 	     "Unable to read pin status for pin %02x (not supported)",
439 	     LC_PinInfo_GetId(pi));
440   }
441 
442   if ((pt!=GWEN_Crypt_PinType_Manage) &&
443       (LC_Card_GetReaderFlags(hcard) & LC_READER_FLAGS_KEYPAD) &&
444       !(GWEN_Crypt_Token_GetModes(ct) & GWEN_CRYPT_TOKEN_MODE_FORCE_PIN_ENTRY)) {
445     uint32_t bid;
446     int triesLeft=-1;
447 
448     DBG_INFO(LC_LOGDOMAIN,"Terminal has a keypad, will ask for pin.");
449     /* tell the user about pin verification */
450     bid=GWEN_Crypt_Token_BeginEnterPin(ct, pt, guiid);
451     if (bid==0) {
452       DBG_ERROR(LC_LOGDOMAIN, "Error in user interaction");
453       return GWEN_ERROR_GENERIC;
454     }
455 
456     res=LC_Card_IsoPerformVerification(hcard, 0, pi, &triesLeft);
457 
458     if (res!=LC_Client_ResultOk) {
459       /* tell the user about end of pin verification */
460       GWEN_Crypt_Token_EndEnterPin(ct, pt, 0, bid);
461       DBG_ERROR(LC_LOGDOMAIN, "sw1=%02x sw2=%02x (%s)",
462                 LC_Card_GetLastSW1(hcard),
463                 LC_Card_GetLastSW2(hcard),
464                 LC_Card_GetLastText(hcard));
465 
466       if (LC_Card_GetLastSW1(hcard)==0x63) {
467 	switch (LC_Card_GetLastSW2(hcard)) {
468         case 0xc0: /* no error left */
469 	  return GWEN_ERROR_BAD_PIN_0_LEFT;
470         case 0xc1: /* one left */
471           return GWEN_ERROR_BAD_PIN_1_LEFT;
472         case 0xc2: /* two left */
473           return GWEN_ERROR_BAD_PIN_2_LEFT;
474         default:   /* unknown error */
475           return GWEN_ERROR_BAD_PIN;
476         } // switch
477       }
478       else if (LC_Card_GetLastSW1(hcard)==0x69 &&
479                LC_Card_GetLastSW2(hcard)==0x83) {
480         DBG_ERROR(LC_LOGDOMAIN, "Card unusable");
481         return GWEN_ERROR_IO;
482       }
483       else if (LC_Card_GetLastSW1(hcard)==0x64 &&
484                LC_Card_GetLastSW2(hcard)==0x01) {
485         DBG_ERROR(LC_LOGDOMAIN, "Aborted by user");
486         return GWEN_ERROR_USER_ABORTED;
487       }
488       else {
489         if (triesLeft>=0) {
490           switch (triesLeft) {
491           case 0: /* no error left */
492             return GWEN_ERROR_BAD_PIN_0_LEFT;
493           case 1: /* one left */
494             return GWEN_ERROR_BAD_PIN_1_LEFT;
495           case 2: /* two left */
496             return GWEN_ERROR_BAD_PIN_2_LEFT;
497           default:   /* unknown count */
498             return GWEN_ERROR_BAD_PIN;
499           } // switch
500         }
501 
502         return GWEN_ERROR_IO;
503       }
504     } /* if not ok */
505     else {
506       /* PIN ok */
507       DBG_INFO(LC_LOGDOMAIN, "Pin ok");
508       GWEN_Crypt_Token_EndEnterPin(ct, pt, 1, bid);
509     }
510   } /* if hasKeyPad */
511   else {
512     unsigned char pinBuffer[64];
513     int mres;
514     int pinMaxLen;
515     unsigned int pinLength;
516     unsigned int origPinLength;
517     uint32_t pflags=0;
518     GWEN_CRYPT_PINENCODING pe;
519     int triesLeft=-1;
520 
521     DBG_INFO(LC_LOGDOMAIN, "No keypad (or disabled), will ask for PIN");
522     memset(pinBuffer, 0, sizeof(pinBuffer));
523 
524     pe=LC_PinInfo_GetEncoding(pi);
525     if (pt==GWEN_Crypt_PinType_Manage)
526       pflags|=GWEN_GUI_INPUT_FLAGS_ALLOW_DEFAULT;
527     pflags|=GWEN_GUI_INPUT_FLAGS_NUMERIC;
528     pinLength=0;
529     pinMaxLen=LC_PinInfo_GetMaxLength(pi);
530     if (!pinMaxLen || pinMaxLen>sizeof(pinBuffer)-1)
531       pinMaxLen=sizeof(pinBuffer)-1;
532     mres=LC_Crypt_Token__GetPin(ct,
533 				hcard,
534 				LC_PinInfo_GetId(pi),
535 				pt,
536 				pe,
537 				pflags,
538 				pinBuffer,
539 				LC_PinInfo_GetMinLength(pi),
540 				pinMaxLen,
541 				&pinLength,
542 				guiid);
543     if (mres!=0) {
544       DBG_ERROR(LC_LOGDOMAIN, "Error asking for PIN, aborting");
545       memset(pinBuffer, 0, sizeof(pinBuffer));
546       return mres;
547     }
548     origPinLength=pinLength;
549 
550     if (pinLength<pinMaxLen && LC_PinInfo_GetFiller(pi)) {
551       int i;
552       unsigned char c;
553 
554       c=(unsigned char)LC_PinInfo_GetFiller(pi);
555       for (i=pinLength; i<pinMaxLen; i++)
556         pinBuffer[i]=c;
557       pinLength=pinMaxLen;
558     }
559 
560     DBG_INFO(LC_LOGDOMAIN, "Verifying the PIN");
561     res=LC_Card_IsoVerifyPin(hcard,
562                              0,
563                              pi,
564                              pinBuffer,
565                              pinLength,
566                              &triesLeft);
567     if (res!=LC_Client_ResultOk) {
568       DBG_ERROR(LC_LOGDOMAIN, "sw1=%02x sw2=%02x (%s)",
569                 LC_Card_GetLastSW1(hcard),
570                 LC_Card_GetLastSW2(hcard),
571                 LC_Card_GetLastText(hcard));
572 
573       if (LC_Card_GetLastSW1(hcard)==0x63) {
574         /* set pin status */
575 	GWEN_Crypt_Token_SetPinStatus(ct,
576 				      pt,
577 				      pe,
578 				      pflags,
579 				      pinBuffer,
580 				      origPinLength,
581 				      0,
582 				      guiid);
583 
584         switch (LC_Card_GetLastSW2(hcard)) {
585         case 0xc0: /* no error left */
586           return GWEN_ERROR_BAD_PIN_0_LEFT;
587         case 0xc1: /* one left */
588           return GWEN_ERROR_BAD_PIN_1_LEFT;
589         case 0xc2: /* two left */
590           return GWEN_ERROR_BAD_PIN_2_LEFT;
591         default:
592           return GWEN_ERROR_BAD_PIN;
593         } // switch
594       }
595       else if (LC_Card_GetLastSW1(hcard)==0x69 &&
596                LC_Card_GetLastSW2(hcard)==0x83) {
597         /* set pin status */
598 	GWEN_Crypt_Token_SetPinStatus(ct,
599 				      pt,
600 				      pe,
601 				      pflags,
602 				      pinBuffer,
603 				      origPinLength,
604 				      0,
605 				      guiid);
606         DBG_ERROR(LC_LOGDOMAIN, "Card unusable");
607         return GWEN_ERROR_IO;
608       }
609       else if (LC_Card_GetLastSW1(hcard)==0x64 &&
610                LC_Card_GetLastSW2(hcard)==0x01) {
611         return GWEN_ERROR_USER_ABORTED;
612       }
613       else {
614         if (triesLeft>=0) {
615           /* set pin status */
616 	  GWEN_Crypt_Token_SetPinStatus(ct,
617 					pt,
618 					pe,
619 					pflags,
620 					pinBuffer,
621 					origPinLength,
622 					0,
623 					guiid);
624 	  switch (triesLeft) {
625           case 0: /* no error left */
626             return GWEN_ERROR_BAD_PIN_0_LEFT;
627           case 1: /* one left */
628 	    return GWEN_ERROR_BAD_PIN_1_LEFT;
629           case 2: /* two left */
630             return GWEN_ERROR_BAD_PIN_2_LEFT;
631           default:   /* unknown count */
632             return GWEN_ERROR_BAD_PIN;
633           } // switch
634         }
635         DBG_ERROR(LC_LOGDOMAIN, "Unknown error");
636         return GWEN_ERROR_IO;
637       }
638     } // if not ok
639     else {
640       DBG_INFO(LC_LOGDOMAIN, "PIN ok");
641       /* set pin status */
642       GWEN_Crypt_Token_SetPinStatus(ct,
643 				    pt,
644 				    pe,
645 				    pflags,
646 				    pinBuffer,
647 				    origPinLength,
648 				    1,
649 				    guiid);
650     }
651   } // if no keyPad
652 
653   return 0;
654 }
655 
656 
657 
658 static
LC_Crypt_Token__EnterPin(GWEN_CRYPT_TOKEN * ct,LC_CARD * hcard,GWEN_CRYPT_PINTYPE pt,uint32_t guiid)659 int LC_Crypt_Token__EnterPin(GWEN_CRYPT_TOKEN *ct,
660 			     LC_CARD *hcard,
661 			     GWEN_CRYPT_PINTYPE pt,
662 			     uint32_t guiid) {
663   LC_PININFO *pi;
664   int rv;
665 
666   assert(hcard);
667 
668   if (pt==GWEN_Crypt_PinType_Manage) {
669     pi=LC_Card_GetPinInfoByName(hcard, "eg_pin");
670   }
671   else {
672     pi=LC_Card_GetPinInfoByName(hcard, "ch_pin");
673   }
674   assert(pi);
675 
676   rv=LC_Crypt_Token__EnterPinWithPinInfo(ct, hcard, pt, pi, guiid);
677   LC_PinInfo_free(pi);
678 
679   return rv;
680 }
681 
682 
683 
LC_Crypt_Token_VerifyPin(GWEN_CRYPT_TOKEN * ct,LC_CARD * hcard,GWEN_CRYPT_PINTYPE pt,uint32_t guiid)684 int LC_Crypt_Token_VerifyPin(GWEN_CRYPT_TOKEN *ct,
685                              LC_CARD *hcard,
686                              GWEN_CRYPT_PINTYPE pt,
687                              uint32_t guiid) {
688   int rv;
689 
690   /* enter pin */
691   rv=LC_Crypt_Token__EnterPin(ct, hcard, pt, guiid);
692   if (rv) {
693     DBG_INFO(LC_LOGDOMAIN, "Error in pin input");
694     return rv;
695   }
696 
697   return 0;
698 }
699 
700 
701 
LC_Crypt_Token_VerifyPinWithPinInfo(GWEN_CRYPT_TOKEN * ct,LC_CARD * hcard,GWEN_CRYPT_PINTYPE pt,const LC_PININFO * pi,uint32_t guiid)702 int LC_Crypt_Token_VerifyPinWithPinInfo(GWEN_CRYPT_TOKEN *ct,
703                                         LC_CARD *hcard,
704                                         GWEN_CRYPT_PINTYPE pt,
705                                         const LC_PININFO *pi,
706                                         uint32_t guiid) {
707   int rv;
708 
709   /* enter pin */
710   rv=LC_Crypt_Token__EnterPinWithPinInfo(ct, hcard, pt, pi, guiid);
711   if (rv) {
712     DBG_INFO(LC_LOGDOMAIN, "Error in pin input");
713     return rv;
714   }
715 
716   return 0;
717 }
718 
719 
720 
LC_Crypt_Token_ChangePin(GWEN_CRYPT_TOKEN * ct,LC_CARD * hcard,GWEN_CRYPT_PINTYPE pt,int initial,uint32_t guiid)721 int LC_Crypt_Token_ChangePin(GWEN_CRYPT_TOKEN *ct,
722 			     LC_CARD *hcard,
723 			     GWEN_CRYPT_PINTYPE pt,
724 			     int initial,
725 			     uint32_t guiid) {
726   int rv;
727 
728   if (pt!=GWEN_Crypt_PinType_Access &&
729       pt==GWEN_Crypt_PinType_Manage) {
730     DBG_ERROR(LC_LOGDOMAIN, "Unknown pin type \"%s\"",
731               GWEN_Crypt_PinType_toString(pt));
732     return GWEN_ERROR_INVALID;
733   }
734 
735   /* enter pin */
736   rv=LC_Crypt_Token__ChangePin(ct, hcard, pt, initial, guiid);
737   if (rv) {
738     DBG_INFO(LC_LOGDOMAIN, "Error in pin input");
739     return rv;
740   }
741 
742   return 0;
743 }
744 
745 
746 
747 
748