* app-openpgp.c (store_fpr): Fixed fingerprint calculation.
[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           value = find_tlv (buffer, buflen, tag, &valuelen, 0);
180           if (!value)
181             ; /* not found */
182           else if (valuelen > buflen - (value - buffer))
183             {
184               log_error ("warning: constructed DO too short\n");
185               value = NULL;
186               xfree (buffer); buffer = NULL;
187             }
188         }
189     }
190
191   if (!value) /* Not in a constructed DO, try simple. */
192     {
193       rc = iso7816_get_data (slot, tag, &buffer, &buflen);
194       if (!rc)
195         {
196           value = buffer;
197           valuelen = buflen;
198         }
199     }
200
201   if (!rc)
202     {
203       *nbytes = valuelen;
204       *result = value;
205       return buffer;
206     }
207   return NULL;
208 }
209
210 #if 0 /* not used */
211 static void
212 dump_one_do (int slot, int tag)
213 {
214   int rc, i;
215   unsigned char *buffer;
216   size_t buflen;
217   const char *desc;
218   int binary;
219   const unsigned char *value;
220   size_t valuelen;
221
222   for (i=0; data_objects[i].tag && data_objects[i].tag != tag; i++)
223     ;
224   desc = data_objects[i].tag? data_objects[i].desc : "?";
225   binary = data_objects[i].tag? data_objects[i].binary : 1;
226
227   value = NULL;
228   rc = -1;
229   if (data_objects[i].tag && data_objects[i].get_from)
230     {
231       rc = iso7816_get_data (slot, data_objects[i].get_from,
232                              &buffer, &buflen);
233       if (!rc)
234         {
235           value = find_tlv (buffer, buflen, tag, &valuelen, 0);
236           if (!value)
237             ; /* not found */
238           else if (valuelen > buflen - (value - buffer))
239             {
240               log_error ("warning: constructed DO too short\n");
241               value = NULL;
242               xfree (buffer); buffer = NULL;
243             }
244         }
245     }
246
247   if (!value) /* Not in a constructed DO, try simple. */
248     {
249       rc = iso7816_get_data (slot, tag, &buffer, &buflen);
250       if (!rc)
251         {
252           value = buffer;
253           valuelen = buflen;
254         }
255     }
256   if (rc == 0x6a88)
257     log_info ("DO `%s' not available\n", desc);
258   else if (rc) 
259     log_info ("DO `%s' not available (rc=%04X)\n", desc, rc);
260   else
261     {
262       if (binary)
263         {
264           log_info ("DO `%s': ", desc);
265           log_printhex ("", value, valuelen);
266         }
267       else
268         log_info ("DO `%s': `%.*s'\n",
269                   desc, (int)valuelen, value); /* FIXME: sanitize */
270       xfree (buffer);
271     }
272 }
273 #endif /*not used*/
274
275
276 static void
277 dump_all_do (int slot)
278 {
279   int rc, i, j;
280   unsigned char *buffer;
281   size_t buflen;
282   
283   for (i=0; data_objects[i].tag; i++)
284     {
285       if (data_objects[i].get_from)
286         continue;
287
288       rc = iso7816_get_data (slot, data_objects[i].tag, &buffer, &buflen);
289       if (rc == 0x6a88)
290         ;
291       else if (rc) 
292         log_info ("DO `%s' not available (rc=%04X)\n",
293                   data_objects[i].desc, rc);
294       else
295         {
296           if (data_objects[i].binary)
297             {
298               log_info ("DO `%s': ", data_objects[i].desc);
299               log_printhex ("", buffer, buflen);
300             }
301           else
302             log_info ("DO `%s': `%.*s'\n",
303                       data_objects[i].desc,
304                       (int)buflen, buffer); /* FIXME: sanitize */
305         }
306
307       if (data_objects[i].constructed)
308         {
309           for (j=0; data_objects[j].tag; j++)
310             {
311               const unsigned char *value;
312               size_t valuelen;
313
314               if (j==i || data_objects[i].tag != data_objects[j].get_from)
315                 continue;
316               value = find_tlv (buffer, buflen,
317                                 data_objects[j].tag, &valuelen, 0);
318               if (!value)
319                 ; /* not found */
320               else if (valuelen > buflen - (value - buffer))
321                 log_error ("warning: constructed DO too short\n");
322               else
323                 {
324                   if (data_objects[j].binary)
325                     {
326                       log_info ("DO `%s': ", data_objects[j].desc);
327                       log_printhex ("", value, valuelen);
328                     }
329                   else
330                     log_info ("DO `%s': `%.*s'\n",
331                               data_objects[j].desc,
332                               (int)valuelen, value); /* FIXME: sanitize */
333                 }
334             }
335         }
336       xfree (buffer); buffer = NULL;
337     }
338 }
339
340 /* Note, that FPR must be at least 20 bytes. */
341 static int 
342 store_fpr (int slot, int keynumber, u32 timestamp,
343            const unsigned char *m, size_t mlen,
344            const unsigned char *e, size_t elen, 
345            unsigned char *fpr)
346 {
347   unsigned int n;
348   unsigned char *buffer, *p;
349   int rc;
350   
351   n = 6 + 2 + mlen + 2 + elen;
352   p = buffer = xtrymalloc (3 + n);
353   if (!buffer)
354     return out_of_core ();
355   
356   *p++ = 0x99;     /* ctb */
357   *p++ = n >> 8;   /* 2 byte length header */
358   *p++ = n;
359   *p++ = 4;        /* key packet version */
360   *p++ = timestamp >> 24;
361   *p++ = timestamp >> 16;
362   *p++ = timestamp >>  8;
363   *p++ = timestamp;
364   *p++ = 1; /* RSA */
365   *p++ = (mlen*8) >> 8; /* (we want number of bits here) */
366   *p++ = (mlen*8);
367   memcpy (p, m, mlen); p += mlen;
368   *p++ = (elen*8) >> 8;
369   *p++ = (elen*8);
370   memcpy (p, e, elen); p += elen;
371     
372   gcry_md_hash_buffer (GCRY_MD_SHA1, fpr, buffer, n+3);
373
374   xfree (buffer);
375
376   rc = iso7816_put_data (slot, 0xC6 + keynumber, fpr, 20);
377   if (rc)
378     log_error ("failed to store the fingerprint: rc=%04X\n", rc);
379
380   return rc;
381 }
382
383        
384 static void
385 send_fpr_if_not_null (CTRL ctrl, const char *keyword,
386                       int number, const unsigned char *fpr)
387 {                      
388   int i;
389   char buf[41];
390   char numbuf[25];
391
392   for (i=0; i < 20 && !fpr[i]; i++)
393     ;
394   if (i==20)
395     return; /* All zero. */
396   for (i=0; i< 20; i++)
397     sprintf (buf+2*i, "%02X", fpr[i]);
398   if (number == -1)
399     *numbuf = 0; /* Don't print the key number */
400   else
401     sprintf (numbuf, "%d", number);
402   send_status_info (ctrl, keyword,
403                     numbuf, (size_t)strlen(numbuf),
404                     buf, (size_t)strlen (buf), NULL, 0);
405 }
406
407 static void
408 send_key_data (CTRL ctrl, const char *name, 
409                const unsigned char *a, size_t alen)
410 {
411   char *p, *buf = xmalloc (alen*2+1);
412   
413   for (p=buf; alen; a++, alen--, p += 2)
414     sprintf (p, "%02X", *a);
415
416   send_status_info (ctrl, "KEY-DATA",
417                     name, (size_t)strlen(name), 
418                     buf, (size_t)strlen (buf),
419                     NULL, 0);
420   xfree (buf);
421 }
422
423
424
425 static int
426 do_learn_status (APP app, CTRL ctrl)
427 {
428   void *relptr;
429   unsigned char *value;
430   size_t valuelen;
431   int i;
432
433   relptr = get_one_do (app->slot, 0x005B, &value, &valuelen);
434   if (relptr)
435     {
436       send_status_info (ctrl, "DISP-NAME", value, valuelen, NULL, 0);
437       xfree (relptr);
438     }
439   relptr = get_one_do (app->slot, 0x5FF0, &value, &valuelen);
440   if (relptr)
441     {
442       send_status_info (ctrl, "PUBKEY-URL", value, valuelen, NULL, 0);
443       xfree (relptr);
444     }
445
446   relptr = get_one_do (app->slot, 0x00C5, &value, &valuelen);
447   if (relptr && valuelen >= 60)
448     {
449       for (i=0; i < 3; i++)
450         send_fpr_if_not_null (ctrl, "KEY-FPR", i+1, value+i*20);
451     }
452   xfree (relptr);
453   relptr = get_one_do (app->slot, 0x00C6, &value, &valuelen);
454   if (relptr && valuelen >= 60)
455     {
456       for (i=0; i < 3; i++)
457         send_fpr_if_not_null (ctrl, "CA-FPR", i+1, value+i*20);
458     }
459   xfree (relptr);
460   return 0;
461 }
462
463
464 /* Handle the SETATTR operation. All arguments are already basically
465    checked. */
466 static int 
467 do_setattr (APP app, const char *name,
468             int (*pincb)(void*, const char *, char **),
469             void *pincb_arg,
470             const unsigned char *value, size_t valuelen)
471 {
472   gpg_error_t rc;
473
474   log_debug ("app_openpgp#setattr `%s' value of length %u\n",
475              name, (unsigned int)valuelen); /* fixme: name should be
476                                                sanitized. */
477
478   if (!app->did_chv3)
479     {
480       char *pinvalue;
481
482 /*        rc = pincb (pincb_arg, "Please enter the card's admin PIN (CHV3)", */
483 /*                    &pinvalue); */
484       pinvalue = xstrdup ("12345678");
485       rc = 0;
486       if (rc)
487         {
488           log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
489           return rc;
490         }
491
492       rc = iso7816_verify (app->slot, 0x83, pinvalue, strlen (pinvalue));
493       xfree (pinvalue);
494       if (rc)
495         {
496           log_error ("verify CHV3 failed\n");
497           rc = gpg_error (GPG_ERR_GENERAL);
498           return rc;
499         }
500       app->did_chv3 = 1;
501     }
502
503   log_debug ("setting `%s' to `%.*s'\n", name, (int)valuelen, value);
504   if (!strcmp (name, "DISP-NAME"))
505     {
506       rc = iso7816_put_data (app->slot, 0x005B, value, valuelen);
507       if (rc)
508         {
509           /* FIXME: If this fails we should *once* try again after
510           doing a verify command, so that in case of a problem with
511           tracking the verify operation we have a fallback. */
512           /* FIXME: change this when iso7816 returns correct error
513           codes. */
514           log_error ("failed to set `Name'\n");
515           rc = gpg_error (GPG_ERR_GENERAL);
516         }
517     }
518   else
519     rc = gpg_error (GPG_ERR_INV_NAME); 
520
521   return rc;
522 }
523
524
525 /* Handle the GENKEY command. */
526 static int 
527 do_genkey (APP app, CTRL ctrl,  const char *keynostr, unsigned int flags,
528           int (*pincb)(void*, const char *, char **),
529           void *pincb_arg)
530 {
531   int rc;
532   int i;
533   char numbuf[30];
534   unsigned char fprbuf[20];
535   const unsigned char *fpr;
536   const unsigned char *keydata, *m, *e;
537   unsigned char *buffer;
538   size_t buflen, keydatalen, n, mlen, elen;
539   time_t created_at;
540   int keyno = atoi (keynostr);
541   int force = (flags & 1);
542
543   if (keyno < 1 || keyno > 3)
544     return gpg_error (GPG_ERR_INV_ID);
545   keyno--;
546
547   rc = iso7816_get_data (app->slot, 0x006E, &buffer, &buflen);
548   if (rc)
549     {
550       log_error ("error reading application data\n");
551       return gpg_error (GPG_ERR_GENERAL);
552     }
553   fpr = find_tlv (buffer, buflen, 0x00C5, &n, 0);
554   if (!fpr || n != 60)
555     {
556       rc = gpg_error (GPG_ERR_GENERAL);
557       log_error ("error reading fingerprint DO\n");
558       goto leave;
559     }
560   fpr += 20*keyno;
561   for (i=0; i < 20 && !fpr[i]; i++)
562     ;
563   if (i!=20 && !force)
564     {
565       rc = gpg_error (GPG_ERR_EEXIST);
566       log_error ("key already exists\n");
567       goto leave;
568     }
569   else if (i!=20)
570     log_info ("existing key will be replaced\n");
571   else
572     log_info ("generating new key\n");
573
574   rc = iso7816_verify (app->slot, 0x83, "12345678", 8);
575   if (rc)
576     {
577       log_error ("verify CHV3 failed: rc=%04X\n", rc);
578       goto leave;
579     }
580
581   xfree (buffer); buffer = NULL;
582 #if 1
583   rc = iso7816_generate_keypair 
584 #else
585 #warning key generation temporary replaced by reading an existing key.
586   rc = iso7816_read_public_key
587 #endif
588                               (app->slot, 
589                                  keyno == 0? "\xB6" :
590                                  keyno == 1? "\xB8" : "\xA4",
591                                  2,
592                                  &buffer, &buflen);
593   if (rc)
594     {
595       rc = gpg_error (GPG_ERR_CARD);
596       log_error ("generating key failed\n");
597       goto leave;
598     }
599   keydata = find_tlv (buffer, buflen, 0x7F49, &keydatalen, 0);
600   if (!keydata)
601     {
602       log_error ("response does not contain the public key data\n");
603       goto leave;
604     }
605  
606   m = find_tlv (keydata, keydatalen, 0x0081, &mlen, 0);
607   if (!m)
608     {
609       log_error ("response does not contain the RSA modulus\n");
610       goto leave;
611     }
612   log_printhex ("RSA n:", m, mlen);
613   send_key_data (ctrl, "n", m, mlen);
614
615   e = find_tlv (keydata, keydatalen, 0x0082, &elen, 0);
616   if (!e)
617     {
618       log_error ("response does not contain the RSA public exponent\n");
619       goto leave;
620     }
621   log_printhex ("RSA e:", e, elen);
622   send_key_data (ctrl, "e", e, elen);
623
624   created_at = gnupg_get_time ();
625   sprintf (numbuf, "%lu", (unsigned long)created_at);
626   send_status_info (ctrl, "KEY-CREATED-AT",
627                     numbuf, (size_t)strlen(numbuf), NULL, 0);
628
629   rc = store_fpr (app->slot, keyno, (u32)created_at,
630                   m, mlen, e, elen, fprbuf);
631   if (rc)
632     goto leave;
633   send_fpr_if_not_null (ctrl, "KEY-FPR", -1, fprbuf);
634
635
636  leave:
637   xfree (buffer);
638   return rc;
639 }
640
641
642 static int
643 compare_fingerprint (APP app, int keyno, unsigned char *sha1fpr)
644 {
645   const unsigned char *fpr;
646   unsigned char *buffer;
647   size_t buflen, n;
648   int rc, i;
649   
650   assert (keyno >= 1 && keyno <= 3);
651
652   rc = iso7816_get_data (app->slot, 0x006E, &buffer, &buflen);
653   if (rc)
654     {
655       log_error ("error reading application data\n");
656       return gpg_error (GPG_ERR_GENERAL);
657     }
658   fpr = find_tlv (buffer, buflen, 0x00C5, &n, 0);
659   if (!fpr || n != 60)
660     {
661       xfree (buffer);
662       log_error ("error reading fingerprint DO\n");
663       return gpg_error (GPG_ERR_GENERAL);
664     }
665   fpr += (keyno-1)*20;
666   for (i=0; i < 20; i++)
667     if (sha1fpr[i] != fpr[i])
668       {
669         xfree (buffer);
670         return gpg_error (GPG_ERR_WRONG_SECKEY);
671       }
672   xfree (buffer);
673   return 0;
674 }
675
676
677
678 /* Compute a digital signature on INDATA which is expected to be the
679    raw message digest. For this application the KEYIDSTR consists of
680    the serialnumber and the fingerprint delimited by a slash.
681
682    Note that this fucntion may return the error code
683    GPG_ERR_WRONG_CARD to indicate that the card currently present does
684    not match the one required for the requested action (e.g. the
685    serial number does not match). */
686 static int 
687 do_sign (APP app, const char *keyidstr, int hashalgo,
688          int (*pincb)(void*, const char *, char **),
689          void *pincb_arg,
690          const void *indata, size_t indatalen,
691          void **outdata, size_t *outdatalen )
692 {
693   static unsigned char sha1_prefix[15] = /* Object ID is 1.3.14.3.2.26 */
694   { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
695     0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
696   static unsigned char rmd160_prefix[15] = /* Object ID is 1.3.36.3.2.1 */
697   { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
698     0x02, 0x01, 0x05, 0x00, 0x04, 0x14 };
699   int rc;
700   unsigned char data[35];
701   unsigned char tmp_sn[20]; /* actually 16 but we use it also for the fpr. */
702   const char *s;
703   int n;
704   const char *fpr = NULL;
705
706   if (!keyidstr || !*keyidstr)
707     return gpg_error (GPG_ERR_INV_VALUE);
708   if (indatalen != 20)
709     return gpg_error (GPG_ERR_INV_VALUE);
710
711   /* Check whether an OpenPGP card of any version has been requested. */
712   if (strlen (keyidstr) < 32 || strncmp (keyidstr, "D27600012401", 12))
713     return gpg_error (GPG_ERR_INV_ID);
714   
715   for (s=keyidstr, n=0; hexdigitp (s); s++, n++)
716     ;
717   if (n != 32)
718     return gpg_error (GPG_ERR_INV_ID);
719   else if (!*s)
720     ; /* no fingerprint given: we allow this for now. */
721   else if (*s == '/')
722     fpr = s + 1; 
723   else
724     return gpg_error (GPG_ERR_INV_ID);
725
726   for (s=keyidstr, n=0; n < 16; s += 2, n++)
727     tmp_sn[n] = xtoi_2 (s);
728
729   if (app->serialnolen != 16)
730     return gpg_error (GPG_ERR_INV_CARD);
731   if (memcmp (app->serialno, tmp_sn, 16))
732     return gpg_error (GPG_ERR_WRONG_CARD);
733
734   /* If a fingerprint has been speicified check it against the one on
735      the card.  This is allows for a meaningful error message in case
736      the key on the card has been replaced but the shadow information
737      known to gpg was not updated.  If there is no fingerprint, gpg
738      will detect the bodus signature anyway die to the
739      verify-after-signing feature. */
740   if (fpr)
741     {
742       for (s=fpr, n=0; hexdigitp (s); s++, n++)
743         ;
744       if (n != 40)
745         return gpg_error (GPG_ERR_INV_ID);
746       else if (!*s)
747         ; /* okay */
748       else
749         return gpg_error (GPG_ERR_INV_ID);
750
751       for (s=fpr, n=0; n < 20; s += 2, n++)
752         tmp_sn[n] = xtoi_2 (s);
753       rc = compare_fingerprint (app, 1, tmp_sn);
754       if (rc)
755         return rc;
756     }
757
758   if (hashalgo == GCRY_MD_SHA1)
759     memcpy (data, sha1_prefix, 15);
760   else if (hashalgo == GCRY_MD_RMD160)
761     memcpy (data, rmd160_prefix, 15);
762   else 
763     return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
764   memcpy (data+15, indata, indatalen);
765
766
767   if (!app->did_chv1)
768     {
769       char *pinvalue;
770
771 /*        rc = pincb (pincb_arg, "signature PIN", &pinvalue); */
772       pinvalue = xstrdup ("123456");
773       rc = 0;
774       if (rc)
775         {
776           log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
777           return rc;
778         }
779
780       rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue));
781       xfree (pinvalue);
782       if (rc)
783         {
784           log_error ("verify CHV1 failed\n");
785           rc = gpg_error (GPG_ERR_GENERAL);
786           return rc;
787         }
788       app->did_chv1 = 1;
789     }
790
791   rc = iso7816_compute_ds (app->slot, data, 35, outdata, outdatalen);
792
793   return rc;
794 }
795
796
797 /* Select the OpenPGP application on the card in SLOT.  This function
798    must be used before any other OpenPGP application functions. */
799 int
800 app_select_openpgp (APP app, unsigned char **sn, size_t *snlen)
801 {
802   static char const aid[] = { 0xD2, 0x76, 0x00, 0x01, 0x24, 0x01 };
803   int slot = app->slot;
804   int rc;
805   unsigned char *buffer;
806   size_t buflen;
807   
808   rc = iso7816_select_application (slot, aid, sizeof aid);
809   if (!rc)
810     {
811       /* fixme: get the full AID and check that the version is okay
812          with us. */
813       rc = iso7816_get_data (slot, 0x004F, &buffer, &buflen);
814       if (rc)
815         goto leave;
816       if (opt.verbose)
817         {
818           log_info ("got AID: ");
819           log_printhex ("", buffer, buflen);
820         }
821
822       if (sn)
823         {
824           *sn = buffer;
825           *snlen = buflen;
826         }
827       else
828         xfree (buffer);
829
830       dump_all_do (slot);
831
832       app->fnc.learn_status = do_learn_status;
833       app->fnc.setattr = do_setattr;
834       app->fnc.genkey = do_genkey;
835       app->fnc.sign = do_sign;
836    }
837
838 leave:
839   return rc;
840 }
841
842
843
844