b546ed569b4413ec1c4b8f5ba2db1ca61ac7926a
[gnupg.git] / scd / app-openpgp.c
1 /* app-openpgp.c - The OpenPGP card application.
2  *      Copyright (C) 2003 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG 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
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <errno.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <assert.h>
27
28 #include "scdaemon.h"
29 #include "app-common.h"
30 #include "iso7816.h"
31
32
33
34 static struct {
35   int tag;
36   int constructed;
37   int get_from;  /* Constructed DO with this DO or 0 for direct access. */
38   int binary;
39   char *desc;
40 } data_objects[] = {
41   { 0x005E, 0,    0, 1, "Login Data" },
42   { 0x5F50, 0,    0, 0, "URL" },
43   { 0x0065, 1,    0, 1, "Cardholder Related Data"},
44   { 0x005B, 0, 0x65, 0, "Name" },
45   { 0x5F2D, 0, 0x65, 0, "Language preferences" },
46   { 0x5F35, 0, 0x65, 0, "Sex" },
47   { 0x006E, 1,    0, 1, "Application Related Data" },
48   { 0x004F, 0, 0x6E, 1, "AID" },
49   { 0x0073, 1,    0, 1, "Discretionary Data Objects" },
50   { 0x0047, 0, 0x6E, 1, "Card Capabilities" },
51   { 0x00C0, 0, 0x6E, 1, "Extended Card Capabilities" },
52   { 0x00C1, 0, 0x6E, 1, "Algorithm Attributes Signature" },
53   { 0x00C2, 0, 0x6E, 1, "Algorithm Attributes Decryption" },
54   { 0x00C3, 0, 0x6E, 1, "Algorithm Attributes Authentication" },
55   { 0x00C4, 0, 0x6E, 1, "CHV Status Bytes" },
56   { 0x00C5, 0, 0x6E, 1, "Fingerprints" },
57   { 0x00C6, 0, 0x6E, 1, "CA Fingerprints" },
58   { 0x007A, 1,    0, 1, "Security Support Template" },
59   { 0x0093, 0, 0x7A, 1, "Digital Signature Counter" },
60   { 0 }
61 };
62
63
64 /* Locate a TLV encoded data object in BUFFER of LENGTH and
65    return a pointer to value as well as its length in NBYTES.  Return
66    NULL if it was not found.  Note, that the function does not check
67    whether the value fits into the provided buffer. 
68
69    FIXME: Move this to an extra file, it is mostly duplicated from card.c.
70 */
71 static const unsigned char *
72 find_tlv (const unsigned char *buffer, size_t length,
73           int tag, size_t *nbytes, int nestlevel)
74 {
75   const unsigned char *s = buffer;
76   size_t n = length;
77   size_t len;
78   int this_tag;
79   int composite;
80     
81   for (;;)
82     {
83       buffer = s;
84       if (n < 2)
85         return NULL; /* buffer definitely too short for tag and length. */
86       if (!*s || *s == 0xff)
87         { /* Skip optional filler between TLV objects. */
88           s++;
89           n--;
90           continue;
91         }
92       composite = !!(*s & 0x20);
93       if ((*s & 0x1f) == 0x1f)
94         { /* more tag bytes to follow */
95           s++;
96           n--;
97           if (n < 2)
98             return NULL; /* buffer definitely too short for tag and length. */
99           if ((*s & 0x1f) == 0x1f)
100             return NULL; /* We support only up to 2 bytes. */
101           this_tag = (s[-1] << 8) | (s[0] & 0x7f);
102         }
103       else
104         this_tag = s[0];
105       len = s[1];
106       s += 2; n -= 2;
107       if (len < 0x80)
108         ;
109       else if (len == 0x81)
110         { /* One byte length follows. */
111           if (!n)
112             return NULL; /* we expected 1 more bytes with the length. */
113           len = s[0];
114           s++; n--;
115         }
116       else if (len == 0x82)
117         { /* Two byte length follows. */
118           if (n < 2)
119             return NULL; /* we expected 2 more bytes with the length. */
120           len = (s[0] << 8) | s[1];
121           s += 2; n -= 2;
122         }
123       else
124         return NULL; /* APDU limit is 65535, thus it does not make
125                         sense to assume longer length fields. */
126
127       if (composite && nestlevel < 100)
128         { /* Dive into this composite DO after checking for too deep
129              nesting. */
130           const unsigned char *tmp_s;
131           size_t tmp_len;
132           
133           tmp_s = find_tlv (s, len, tag, &tmp_len, nestlevel+1);
134           if (tmp_s)
135             {
136               *nbytes = tmp_len;
137               return tmp_s;
138             }
139         }
140
141       if (this_tag == tag)
142         {
143           *nbytes = len;
144           return s;
145         }
146       if (len > n)
147         return NULL; /* buffer too short to skip to the next tag. */
148       s += len; n -= len;
149     }
150 }
151
152
153 /* Get the DO identified by TAG from the card in SLOT and return a
154    buffer with its content in RESULT and NBYTES.  The return value is
155    NULL if not found or a pointer which must be used to release the
156    buffer holding value. */
157 static void *
158 get_one_do (int slot, int tag, unsigned char **result, size_t *nbytes)
159 {
160   int rc, i;
161   unsigned char *buffer;
162   size_t buflen;
163   unsigned char *value;
164   size_t valuelen;
165
166   *result = NULL;
167   *nbytes = 0;
168   for (i=0; data_objects[i].tag && data_objects[i].tag != tag; i++)
169     ;
170
171   value = NULL;
172   rc = -1;
173   if (data_objects[i].tag && data_objects[i].get_from)
174     {
175       rc = iso7816_get_data (slot, data_objects[i].get_from,
176                              &buffer, &buflen);
177       if (!rc)
178         {
179           const unsigned char *s;
180
181           s = find_tlv (buffer, buflen, tag, &valuelen, 0);
182           if (!s)
183             value = NULL; /* not found */
184           else if (valuelen > buflen - (s - buffer))
185             {
186               log_error ("warning: constructed DO too short\n");
187               value = NULL;
188               xfree (buffer); buffer = NULL;
189             }
190           else
191             value = buffer + (s - buffer);
192         }
193     }
194
195   if (!value) /* Not in a constructed DO, try simple. */
196     {
197       rc = iso7816_get_data (slot, tag, &buffer, &buflen);
198       if (!rc)
199         {
200           value = buffer;
201           valuelen = buflen;
202         }
203     }
204
205   if (!rc)
206     {
207       *nbytes = valuelen;
208       *result = value;
209       return buffer;
210     }
211   return NULL;
212 }
213
214 #if 0 /* not used */
215 static void
216 dump_one_do (int slot, int tag)
217 {
218   int rc, i;
219   unsigned char *buffer;
220   size_t buflen;
221   const char *desc;
222   int binary;
223   const unsigned char *value;
224   size_t valuelen;
225
226   for (i=0; data_objects[i].tag && data_objects[i].tag != tag; i++)
227     ;
228   desc = data_objects[i].tag? data_objects[i].desc : "?";
229   binary = data_objects[i].tag? data_objects[i].binary : 1;
230
231   value = NULL;
232   rc = -1;
233   if (data_objects[i].tag && data_objects[i].get_from)
234     {
235       rc = iso7816_get_data (slot, data_objects[i].get_from,
236                              &buffer, &buflen);
237       if (!rc)
238         {
239           value = find_tlv (buffer, buflen, tag, &valuelen, 0);
240           if (!value)
241             ; /* not found */
242           else if (valuelen > buflen - (value - buffer))
243             {
244               log_error ("warning: constructed DO too short\n");
245               value = NULL;
246               xfree (buffer); buffer = NULL;
247             }
248         }
249     }
250
251   if (!value) /* Not in a constructed DO, try simple. */
252     {
253       rc = iso7816_get_data (slot, tag, &buffer, &buflen);
254       if (!rc)
255         {
256           value = buffer;
257           valuelen = buflen;
258         }
259     }
260   if (rc == 0x6a88)
261     log_info ("DO `%s' not available\n", desc);
262   else if (rc) 
263     log_info ("DO `%s' not available (rc=%04X)\n", desc, rc);
264   else
265     {
266       if (binary)
267         {
268           log_info ("DO `%s': ", desc);
269           log_printhex ("", value, valuelen);
270         }
271       else
272         log_info ("DO `%s': `%.*s'\n",
273                   desc, (int)valuelen, value); /* FIXME: sanitize */
274       xfree (buffer);
275     }
276 }
277 #endif /*not used*/
278
279
280 static void
281 dump_all_do (int slot)
282 {
283   int rc, i, j;
284   unsigned char *buffer;
285   size_t buflen;
286   
287   for (i=0; data_objects[i].tag; i++)
288     {
289       if (data_objects[i].get_from)
290         continue;
291
292       rc = iso7816_get_data (slot, data_objects[i].tag, &buffer, &buflen);
293       if (rc == 0x6a88)
294         ;
295       else if (rc) 
296         log_info ("DO `%s' not available (rc=%04X)\n",
297                   data_objects[i].desc, rc);
298       else
299         {
300           if (data_objects[i].binary)
301             {
302               log_info ("DO `%s': ", data_objects[i].desc);
303               log_printhex ("", buffer, buflen);
304             }
305           else
306             log_info ("DO `%s': `%.*s'\n",
307                       data_objects[i].desc,
308                       (int)buflen, buffer); /* FIXME: sanitize */
309         }
310
311       if (data_objects[i].constructed)
312         {
313           for (j=0; data_objects[j].tag; j++)
314             {
315               const unsigned char *value;
316               size_t valuelen;
317
318               if (j==i || data_objects[i].tag != data_objects[j].get_from)
319                 continue;
320               value = find_tlv (buffer, buflen,
321                                 data_objects[j].tag, &valuelen, 0);
322               if (!value)
323                 ; /* not found */
324               else if (valuelen > buflen - (value - buffer))
325                 log_error ("warning: constructed DO too short\n");
326               else
327                 {
328                   if (data_objects[j].binary)
329                     {
330                       log_info ("DO `%s': ", data_objects[j].desc);
331                       log_printhex ("", value, valuelen);
332                     }
333                   else
334                     log_info ("DO `%s': `%.*s'\n",
335                               data_objects[j].desc,
336                               (int)valuelen, value); /* FIXME: sanitize */
337                 }
338             }
339         }
340       xfree (buffer); buffer = NULL;
341     }
342 }
343
344 /* Note, that FPR must be at least 20 bytes. */
345 static int 
346 store_fpr (int slot, int keynumber, u32 timestamp,
347            const unsigned char *m, size_t mlen,
348            const unsigned char *e, size_t elen, 
349            unsigned char *fpr)
350 {
351   unsigned int n;
352   unsigned char *buffer, *p;
353   int rc;
354   
355   n = 6 + 2 + mlen + 2 + elen;
356   p = buffer = xtrymalloc (3 + n);
357   if (!buffer)
358     return out_of_core ();
359   
360   *p++ = 0x99;     /* ctb */
361   *p++ = n >> 8;   /* 2 byte length header */
362   *p++ = n;
363   *p++ = 4;        /* key packet version */
364   *p++ = timestamp >> 24;
365   *p++ = timestamp >> 16;
366   *p++ = timestamp >>  8;
367   *p++ = timestamp;
368   *p++ = 1; /* RSA */
369   *p++ = (mlen*8) >> 8; /* (we want number of bits here) */
370   *p++ = (mlen*8);
371   memcpy (p, m, mlen); p += mlen;
372   *p++ = (elen*8) >> 8;
373   *p++ = (elen*8);
374   memcpy (p, e, elen); p += elen;
375     
376   gcry_md_hash_buffer (GCRY_MD_SHA1, fpr, buffer, n+3);
377
378   xfree (buffer);
379
380   rc = iso7816_put_data (slot, 0xC6 + keynumber, fpr, 20);
381   if (rc)
382     log_error ("failed to store the fingerprint: rc=%04X\n", rc);
383
384   return rc;
385 }
386
387        
388 static void
389 send_fpr_if_not_null (CTRL ctrl, const char *keyword,
390                       int number, const unsigned char *fpr)
391 {                      
392   int i;
393   char buf[41];
394   char numbuf[25];
395
396   for (i=0; i < 20 && !fpr[i]; i++)
397     ;
398   if (i==20)
399     return; /* All zero. */
400   for (i=0; i< 20; i++)
401     sprintf (buf+2*i, "%02X", fpr[i]);
402   if (number == -1)
403     *numbuf = 0; /* Don't print the key number */
404   else
405     sprintf (numbuf, "%d", number);
406   send_status_info (ctrl, keyword,
407                     numbuf, (size_t)strlen(numbuf),
408                     buf, (size_t)strlen (buf), NULL, 0);
409 }
410
411 static void
412 send_key_data (CTRL ctrl, const char *name, 
413                const unsigned char *a, size_t alen)
414 {
415   char *p, *buf = xmalloc (alen*2+1);
416   
417   for (p=buf; alen; a++, alen--, p += 2)
418     sprintf (p, "%02X", *a);
419
420   send_status_info (ctrl, "KEY-DATA",
421                     name, (size_t)strlen(name), 
422                     buf, (size_t)strlen (buf),
423                     NULL, 0);
424   xfree (buf);
425 }
426
427
428
429 static int
430 do_learn_status (APP app, CTRL ctrl)
431 {
432   void *relptr;
433   unsigned char *value;
434   size_t valuelen;
435   int i;
436
437   relptr = get_one_do (app->slot, 0x005B, &value, &valuelen);
438   if (relptr)
439     {
440       send_status_info (ctrl, "DISP-NAME", value, valuelen, NULL, 0);
441       xfree (relptr);
442     }
443   relptr = get_one_do (app->slot, 0x5F50, &value, &valuelen);
444   if (relptr)
445     {
446       send_status_info (ctrl, "PUBKEY-URL", value, valuelen, NULL, 0);
447       xfree (relptr);
448     }
449
450   relptr = get_one_do (app->slot, 0x00C5, &value, &valuelen);
451   if (relptr && valuelen >= 60)
452     {
453       for (i=0; i < 3; i++)
454         send_fpr_if_not_null (ctrl, "KEY-FPR", i+1, value+i*20);
455     }
456   xfree (relptr);
457   relptr = get_one_do (app->slot, 0x00C6, &value, &valuelen);
458   if (relptr && valuelen >= 60)
459     {
460       for (i=0; i < 3; i++)
461         send_fpr_if_not_null (ctrl, "CA-FPR", i+1, value+i*20);
462     }
463   xfree (relptr);
464   return 0;
465 }
466
467
468 /* Handle the SETATTR operation. All arguments are already basically
469    checked. */
470 static int 
471 do_setattr (APP app, const char *name,
472             int (*pincb)(void*, const char *, char **),
473             void *pincb_arg,
474             const unsigned char *value, size_t valuelen)
475 {
476   gpg_error_t rc;
477
478   log_debug ("app_openpgp#setattr `%s' value of length %u\n",
479              name, (unsigned int)valuelen); /* fixme: name should be
480                                                sanitized. */
481
482   if (!app->did_chv3)
483     {
484       char *pinvalue;
485
486       rc = pincb (pincb_arg, "Admin PIN (CHV3)",
487                   &pinvalue);
488       pinvalue = xstrdup ("12345678");
489       rc = 0;
490       if (rc)
491         {
492           log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
493           return rc;
494         }
495
496       rc = iso7816_verify (app->slot, 0x83, pinvalue, strlen (pinvalue));
497       xfree (pinvalue);
498       if (rc)
499         {
500           log_error ("verify CHV3 failed\n");
501           rc = gpg_error (GPG_ERR_GENERAL);
502           return rc;
503         }
504       app->did_chv3 = 1;
505     }
506
507   log_debug ("setting `%s' to `%.*s'\n", name, (int)valuelen, value);
508   if (!strcmp (name, "DISP-NAME"))
509     {
510       rc = iso7816_put_data (app->slot, 0x005B, value, valuelen);
511       if (rc)
512         {
513           /* FIXME: If this fails we should *once* try again after
514           doing a verify command, so that in case of a problem with
515           tracking the verify operation we have a fallback. */
516           /* FIXME: change this when iso7816 returns correct error
517           codes. */
518           log_error ("failed to set `Name'\n");
519           rc = gpg_error (GPG_ERR_GENERAL);
520         }
521     }
522   else if (!strcmp (name, "PUBKEY-URL"))
523     {
524       rc = iso7816_put_data (app->slot, 0x5F50, value, valuelen);
525       if (rc)
526         {
527           log_error ("failed to set `Pubkey-URL'\n");
528           rc = gpg_error (GPG_ERR_GENERAL);
529         }
530     }
531   else
532     rc = gpg_error (GPG_ERR_INV_NAME); 
533
534   return rc;
535 }
536
537
538 /* Handle the GENKEY command. */
539 static int 
540 do_genkey (APP app, CTRL ctrl,  const char *keynostr, unsigned int flags,
541           int (*pincb)(void*, const char *, char **),
542           void *pincb_arg)
543 {
544   int rc;
545   int i;
546   char numbuf[30];
547   unsigned char fprbuf[20];
548   const unsigned char *fpr;
549   const unsigned char *keydata, *m, *e;
550   unsigned char *buffer;
551   size_t buflen, keydatalen, n, mlen, elen;
552   time_t created_at;
553   int keyno = atoi (keynostr);
554   int force = (flags & 1);
555   time_t start_at;
556
557   if (keyno < 1 || keyno > 3)
558     return gpg_error (GPG_ERR_INV_ID);
559   keyno--;
560
561   rc = iso7816_get_data (app->slot, 0x006E, &buffer, &buflen);
562   if (rc)
563     {
564       log_error ("error reading application data\n");
565       return gpg_error (GPG_ERR_GENERAL);
566     }
567   fpr = find_tlv (buffer, buflen, 0x00C5, &n, 0);
568   if (!fpr || n != 60)
569     {
570       rc = gpg_error (GPG_ERR_GENERAL);
571       log_error ("error reading fingerprint DO\n");
572       goto leave;
573     }
574   fpr += 20*keyno;
575   for (i=0; i < 20 && !fpr[i]; i++)
576     ;
577   if (i!=20 && !force)
578     {
579       rc = gpg_error (GPG_ERR_EEXIST);
580       log_error ("key already exists\n");
581       goto leave;
582     }
583   else if (i!=20)
584     log_info ("existing key will be replaced\n");
585   else
586     log_info ("generating new key\n");
587
588   {
589     char *pinvalue;
590     rc = pincb (pincb_arg, "Admin PIN", &pinvalue); 
591     if (rc)
592       {
593         log_error ("error getting PIN: %s\n", gpg_strerror (rc));
594         return rc;
595       }
596     rc = iso7816_verify (app->slot, 0x83, pinvalue, strlen (pinvalue));
597     xfree (pinvalue);
598   }
599   if (rc)
600     {
601       log_error ("verify CHV3 failed: rc=%04X\n", rc);
602       goto leave;
603     }
604
605   xfree (buffer); buffer = NULL;
606 #if 1
607   log_info ("please wait while key is being generated ...\n");
608   start_at = time (NULL);
609   rc = iso7816_generate_keypair 
610 #else
611 #warning key generation temporary replaced by reading an existing key.
612   rc = iso7816_read_public_key
613 #endif
614                               (app->slot, 
615                                  keyno == 0? "\xB6" :
616                                  keyno == 1? "\xB8" : "\xA4",
617                                  2,
618                                  &buffer, &buflen);
619   if (rc)
620     {
621       rc = gpg_error (GPG_ERR_CARD);
622       log_error ("generating key failed\n");
623       goto leave;
624     }
625   log_info ("key generation completed (%d seconds)\n",
626             (int)(time (NULL) - start_at));
627   keydata = find_tlv (buffer, buflen, 0x7F49, &keydatalen, 0);
628   if (!keydata)
629     {
630       log_error ("response does not contain the public key data\n");
631       goto leave;
632     }
633  
634   m = find_tlv (keydata, keydatalen, 0x0081, &mlen, 0);
635   if (!m)
636     {
637       log_error ("response does not contain the RSA modulus\n");
638       goto leave;
639     }
640 /*    log_printhex ("RSA n:", m, mlen); */
641   send_key_data (ctrl, "n", m, mlen);
642
643   e = find_tlv (keydata, keydatalen, 0x0082, &elen, 0);
644   if (!e)
645     {
646       log_error ("response does not contain the RSA public exponent\n");
647       goto leave;
648     }
649 /*    log_printhex ("RSA e:", e, elen); */
650   send_key_data (ctrl, "e", e, elen);
651
652   created_at = gnupg_get_time ();
653   sprintf (numbuf, "%lu", (unsigned long)created_at);
654   send_status_info (ctrl, "KEY-CREATED-AT",
655                     numbuf, (size_t)strlen(numbuf), NULL, 0);
656
657   rc = store_fpr (app->slot, keyno, (u32)created_at,
658                   m, mlen, e, elen, fprbuf);
659   if (rc)
660     goto leave;
661   send_fpr_if_not_null (ctrl, "KEY-FPR", -1, fprbuf);
662
663
664  leave:
665   xfree (buffer);
666   return rc;
667 }
668
669
670 static unsigned long
671 get_sig_counter (APP app)
672 {
673   void *relptr;
674   unsigned char *value;
675   size_t valuelen;
676   unsigned long ul;
677
678   relptr = get_one_do (app->slot, 0x0093, &value, &valuelen);
679   if (!relptr)
680     return 0;
681   if (valuelen == 3 )
682     ul = (value[0] << 16) | (value[1] << 8) | value[2];
683   else
684     {
685       log_error ("invalid structure of OpenPGP card (DO 0x93)\n");
686       ul = 0;
687     }
688   xfree (relptr);
689   return ul;
690 }
691
692 static int
693 compare_fingerprint (APP app, int keyno, unsigned char *sha1fpr)
694 {
695   const unsigned char *fpr;
696   unsigned char *buffer;
697   size_t buflen, n;
698   int rc, i;
699   
700   assert (keyno >= 1 && keyno <= 3);
701
702   rc = iso7816_get_data (app->slot, 0x006E, &buffer, &buflen);
703   if (rc)
704     {
705       log_error ("error reading application data\n");
706       return gpg_error (GPG_ERR_GENERAL);
707     }
708   fpr = find_tlv (buffer, buflen, 0x00C5, &n, 0);
709   if (!fpr || n != 60)
710     {
711       xfree (buffer);
712       log_error ("error reading fingerprint DO\n");
713       return gpg_error (GPG_ERR_GENERAL);
714     }
715   fpr += (keyno-1)*20;
716   for (i=0; i < 20; i++)
717     if (sha1fpr[i] != fpr[i])
718       {
719         xfree (buffer);
720         return gpg_error (GPG_ERR_WRONG_SECKEY);
721       }
722   xfree (buffer);
723   return 0;
724 }
725
726
727
728 /* Compute a digital signature on INDATA which is expected to be the
729    raw message digest. For this application the KEYIDSTR consists of
730    the serialnumber and the fingerprint delimited by a slash.
731
732    Note that this fucntion may return the error code
733    GPG_ERR_WRONG_CARD to indicate that the card currently present does
734    not match the one required for the requested action (e.g. the
735    serial number does not match). */
736 static int 
737 do_sign (APP app, const char *keyidstr, int hashalgo,
738          int (*pincb)(void*, const char *, char **),
739          void *pincb_arg,
740          const void *indata, size_t indatalen,
741          unsigned char **outdata, size_t *outdatalen )
742 {
743   static unsigned char sha1_prefix[15] = /* Object ID is 1.3.14.3.2.26 */
744   { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
745     0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
746   static unsigned char rmd160_prefix[15] = /* Object ID is 1.3.36.3.2.1 */
747   { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
748     0x02, 0x01, 0x05, 0x00, 0x04, 0x14 };
749   int rc;
750   unsigned char data[35];
751   unsigned char tmp_sn[20]; /* actually 16 but we use it also for the fpr. */
752   const char *s;
753   int n;
754   const char *fpr = NULL;
755   unsigned long sigcount;
756
757   if (!keyidstr || !*keyidstr)
758     return gpg_error (GPG_ERR_INV_VALUE);
759   if (indatalen != 20)
760     return gpg_error (GPG_ERR_INV_VALUE);
761
762   /* Check whether an OpenPGP card of any version has been requested. */
763   if (strlen (keyidstr) < 32 || strncmp (keyidstr, "D27600012401", 12))
764     return gpg_error (GPG_ERR_INV_ID);
765   
766   for (s=keyidstr, n=0; hexdigitp (s); s++, n++)
767     ;
768   if (n != 32)
769     return gpg_error (GPG_ERR_INV_ID);
770   else if (!*s)
771     ; /* no fingerprint given: we allow this for now. */
772   else if (*s == '/')
773     fpr = s + 1; 
774   else
775     return gpg_error (GPG_ERR_INV_ID);
776
777   for (s=keyidstr, n=0; n < 16; s += 2, n++)
778     tmp_sn[n] = xtoi_2 (s);
779
780   if (app->serialnolen != 16)
781     return gpg_error (GPG_ERR_INV_CARD);
782   if (memcmp (app->serialno, tmp_sn, 16))
783     return gpg_error (GPG_ERR_WRONG_CARD);
784
785   /* If a fingerprint has been specified check it against the one on
786      the card.  This is allows for a meaningful error message in case
787      the key on the card has been replaced but the shadow information
788      known to gpg was not updated.  If there is no fingerprint, gpg
789      will detect the bodus signature anyway die to the
790      verify-after-signing feature. */
791   if (fpr)
792     {
793       for (s=fpr, n=0; hexdigitp (s); s++, n++)
794         ;
795       if (n != 40)
796         return gpg_error (GPG_ERR_INV_ID);
797       else if (!*s)
798         ; /* okay */
799       else
800         return gpg_error (GPG_ERR_INV_ID);
801
802       for (s=fpr, n=0; n < 20; s += 2, n++)
803         tmp_sn[n] = xtoi_2 (s);
804       rc = compare_fingerprint (app, 1, tmp_sn);
805       if (rc)
806         return rc;
807     }
808
809   if (hashalgo == GCRY_MD_SHA1)
810     memcpy (data, sha1_prefix, 15);
811   else if (hashalgo == GCRY_MD_RMD160)
812     memcpy (data, rmd160_prefix, 15);
813   else 
814     return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
815   memcpy (data+15, indata, indatalen);
816
817   sigcount = get_sig_counter (app);
818   log_info ("signatures created so far: %lu\n", sigcount);
819
820   /* FIXME: Check whether we are really required to enter the PIN for
821      each signature. There is a DO for this. */
822   if (!app->did_chv1 || 1) 
823     {
824       char *pinvalue;
825
826       {
827         char *prompt;
828         if (asprintf (&prompt, "Signature PIN [sigs done: %lu]", sigcount) < 0)
829           return gpg_error_from_errno (errno);
830         rc = pincb (pincb_arg, prompt, &pinvalue); 
831         free (prompt);
832       }
833 /*        pinvalue = xstrdup ("123456"); */
834 /*        rc = 0; */
835       if (rc)
836         {
837           log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
838           return rc;
839         }
840
841       rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue));
842       xfree (pinvalue);
843       if (rc)
844         {
845           log_error ("verify CHV1 failed\n");
846           rc = gpg_error (GPG_ERR_GENERAL);
847           return rc;
848         }
849       app->did_chv1 = 1;
850     }
851
852   rc = iso7816_compute_ds (app->slot, data, 35, outdata, outdatalen);
853   return rc;
854 }
855
856
857 static int 
858 do_decipher (APP app, const char *keyidstr,
859              int (pincb)(void*, const char *, char **),
860              void *pincb_arg,
861              const void *indata, size_t indatalen,
862              unsigned char **outdata, size_t *outdatalen )
863 {
864   int rc;
865   unsigned char tmp_sn[20]; /* actually 16 but we use it also for the fpr. */
866   const char *s;
867   int n;
868   const char *fpr = NULL;
869
870   if (!keyidstr || !*keyidstr || !indatalen)
871     return gpg_error (GPG_ERR_INV_VALUE);
872
873   /* Check whether an OpenPGP card of any version has been requested. */
874   if (strlen (keyidstr) < 32 || strncmp (keyidstr, "D27600012401", 12))
875     return gpg_error (GPG_ERR_INV_ID);
876   
877   for (s=keyidstr, n=0; hexdigitp (s); s++, n++)
878     ;
879   if (n != 32)
880     return gpg_error (GPG_ERR_INV_ID);
881   else if (!*s)
882     ; /* no fingerprint given: we allow this for now. */
883   else if (*s == '/')
884     fpr = s + 1; 
885   else
886     return gpg_error (GPG_ERR_INV_ID);
887
888   for (s=keyidstr, n=0; n < 16; s += 2, n++)
889     tmp_sn[n] = xtoi_2 (s);
890
891   if (app->serialnolen != 16)
892     return gpg_error (GPG_ERR_INV_CARD);
893   if (memcmp (app->serialno, tmp_sn, 16))
894     return gpg_error (GPG_ERR_WRONG_CARD);
895
896   /* If a fingerprint has been specified check it against the one on
897      the card.  This is allows for a meaningful error message in case
898      the key on the card has been replaced but the shadow information
899      known to gpg was not updated.  If there is no fingerprint, the
900      decryption will won't produce the right plaintext anyway. */
901   if (fpr)
902     {
903       for (s=fpr, n=0; hexdigitp (s); s++, n++)
904         ;
905       if (n != 40)
906         return gpg_error (GPG_ERR_INV_ID);
907       else if (!*s)
908         ; /* okay */
909       else
910         return gpg_error (GPG_ERR_INV_ID);
911
912       for (s=fpr, n=0; n < 20; s += 2, n++)
913         tmp_sn[n] = xtoi_2 (s);
914       rc = compare_fingerprint (app, 2, tmp_sn);
915       if (rc)
916         return rc;
917     }
918
919   if (!app->did_chv2) 
920     {
921       char *pinvalue;
922
923       rc = pincb (pincb_arg, "Decryption PIN", &pinvalue); 
924 /*        pinvalue = xstrdup ("123456"); */
925 /*        rc = 0; */
926       if (rc)
927         {
928           log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
929           return rc;
930         }
931
932       rc = iso7816_verify (app->slot, 0x82, pinvalue, strlen (pinvalue));
933       xfree (pinvalue);
934       if (rc)
935         {
936           log_error ("verify CHV2 failed\n");
937           rc = gpg_error (GPG_ERR_GENERAL);
938           return rc;
939         }
940       app->did_chv2 = 1;
941     }
942   
943   rc = iso7816_decipher (app->slot, indata, indatalen, outdata, outdatalen);
944   return rc;
945 }
946
947
948
949
950 /* Select the OpenPGP application on the card in SLOT.  This function
951    must be used before any other OpenPGP application functions. */
952 int
953 app_select_openpgp (APP app, unsigned char **sn, size_t *snlen)
954 {
955   static char const aid[] = { 0xD2, 0x76, 0x00, 0x01, 0x24, 0x01 };
956   int slot = app->slot;
957   int rc;
958   unsigned char *buffer;
959   size_t buflen;
960   
961   rc = iso7816_select_application (slot, aid, sizeof aid);
962   if (!rc)
963     {
964       /* fixme: get the full AID and check that the version is okay
965          with us. */
966       rc = iso7816_get_data (slot, 0x004F, &buffer, &buflen);
967       if (rc)
968         goto leave;
969       if (opt.verbose)
970         {
971           log_info ("got AID: ");
972           log_printhex ("", buffer, buflen);
973         }
974
975       if (sn)
976         {
977           *sn = buffer;
978           *snlen = buflen;
979         }
980       else
981         xfree (buffer);
982
983       if (opt.verbose > 1)
984         dump_all_do (slot);
985
986       app->fnc.learn_status = do_learn_status;
987       app->fnc.setattr = do_setattr;
988       app->fnc.genkey = do_genkey;
989       app->fnc.sign = do_sign;
990       app->fnc.decipher = do_decipher;
991    }
992
993 leave:
994   return rc;
995 }
996
997
998
999