d984e9c7ae0dad3739edb95d3253930421e40eab
[gnupg.git] / scd / app-piv.c
1 /* app-piv.c - The OpenPGP card application.
2  * Copyright (C) 2019 g10 Code GmbH
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 3 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, see <https://www.gnu.org/licenses/>.
18  */
19
20 /* Some notes:
21  * - Specs for PIV are at http://dx.doi.org/10.6028/NIST.SP.800-73-4
22  *
23  */
24
25 #include <config.h>
26 #include <errno.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <stdarg.h>
30 #include <string.h>
31 #include <time.h>
32
33 #include "scdaemon.h"
34
35 #include "../common/util.h"
36 #include "../common/i18n.h"
37 #include "iso7816.h"
38 #include "app-common.h"
39 #include "../common/tlv.h"
40 #include "../common/host2net.h"
41 #include "apdu.h" /* We use apdu_send_direct.  */
42
43 #define PIV_ALGORITHM_3DES_ECB_0 0x00
44 #define PIV_ALGORITHM_2DES_ECB   0x01
45 #define PIV_ALGORITHM_2DES_CBC   0x02
46 #define PIV_ALGORITHM_3DES_ECB   0x03
47 #define PIV_ALGORITHM_3DES_CBC   0x04
48 #define PIV_ALGORITHM_RSA        0x07
49 #define PIV_ALGORITHM_AES128_ECB 0x08
50 #define PIV_ALGORITHM_AES128_CBC 0x09
51 #define PIV_ALGORITHM_AES192_ECB 0x0A
52 #define PIV_ALGORITHM_AES192_CBC 0x0B
53 #define PIV_ALGORITHM_AES256_ECB 0x0C
54 #define PIV_ALGORITHM_AES256_CBC 0x0D
55 #define PIV_ALGORITHM_ECC_P256   0x11
56 #define PIV_ALGORITHM_ECC_P384   0x14
57
58
59
60 /* A table describing the DOs of a PIV card.  */
61 struct data_object_s
62 {
63   unsigned int tag;
64   unsigned int mandatory:1;
65   unsigned int acr_contact:2;     /* 0=always, 1=VCI, 2=PIN, 3=PINorOCC */
66   unsigned int acr_contactless:2; /* 0=always, 1=VCI, 2=VCIandPIN,
67                                                       3=VCIand(PINorOCC) */
68   unsigned int binary:1;          /* Data is not human readable.  */
69   unsigned int dont_cache:1;      /* Data item will not be cached.  */
70   unsigned int flush_on_error:1;  /* Flush cached item on error.  */
71   unsigned int keypair:1;         /* Has a public key for a keypair.  */
72   char keyref[3];                 /* The key reference.  */
73   char *oidsuffix; /* Suffix of the OID, prefix is "2.16.840.1.101.3.7." */
74   char *desc;                     /* Description of the DO.  */
75 };
76 typedef struct data_object_s *data_object_t;
77 static struct data_object_s data_objects[] = {
78   { 0x5FC107, 1, 0,1, 1, 0,0, 0, "",   "1.219.0", "Card Capability Container"},
79   { 0x5FC102, 1, 0,0, 1, 0,0, 0, "",   "2.48.0",  "Cardholder Unique Id" },
80   { 0x5FC105, 1, 0,1, 1, 0,0, 1, "9A", "2.1.1",   "Cert PIV Authentication" },
81   { 0x5FC103, 1, 2,2, 1, 0,0, 0, "",   "2.96.16", "Cardholder Fingerprints" },
82   { 0x5FC106, 1, 0,1, 1, 0,0, 0, "",   "2.144.0", "Security Object" },
83   { 0x5FC108, 1, 2,2, 1, 0,0, 0, "",   "2.96.48", "Cardholder Facial Image" },
84   { 0x5FC101, 1, 0,0, 1, 0,0, 1, "9E", "2.5.0",   "Cert Card Authentication"},
85   { 0x5FC10A, 0, 0,1, 1, 0,0, 1, "9C", "2.1.0",   "Cert Digital Signature" },
86   { 0x5FC10B, 0, 0,1, 1, 0,0, 1, "9D", "2.1.2",   "Cert Key Management" },
87   { 0x5FC109, 0, 3,3, 0, 0,0, 0, "",   "2.48.1",  "Printed Information" },
88   { 0x7E,     0, 0,0, 1, 0,0, 0, "",   "2.96.80", "Discovery Object" },
89   { 0x5FC10C, 0, 0,1, 1, 0,0, 0, "",   "2.96.96", "Key History Object" },
90   { 0x5FC10D, 0, 0,1, 1, 0,0, 0, "82", "2.16.1",  "Retired Cert Key Mgm 1" },
91   { 0x5FC10E, 0, 0,1, 1, 0,0, 0, "83", "2.16.2",  "Retired Cert Key Mgm 2" },
92   { 0x5FC10F, 0, 0,1, 1, 0,0, 0, "84", "2.16.3",  "Retired Cert Key Mgm 3" },
93   { 0x5FC110, 0, 0,1, 1, 0,0, 0, "85", "2.16.4",  "Retired Cert Key Mgm 4" },
94   { 0x5FC111, 0, 0,1, 1, 0,0, 0, "86", "2.16.5",  "Retired Cert Key Mgm 5" },
95   { 0x5FC112, 0, 0,1, 1, 0,0, 0, "87", "2.16.6",  "Retired Cert Key Mgm 6" },
96   { 0x5FC113, 0, 0,1, 1, 0,0, 0, "88", "2.16.7",  "Retired Cert Key Mgm 7" },
97   { 0x5FC114, 0, 0,1, 1, 0,0, 0, "89", "2.16.8",  "Retired Cert Key Mgm 8" },
98   { 0x5FC115, 0, 0,1, 1, 0,0, 0, "8A", "2.16.9",  "Retired Cert Key Mgm 9" },
99   { 0x5FC116, 0, 0,1, 1, 0,0, 0, "8B", "2.16.10", "Retired Cert Key Mgm 10" },
100   { 0x5FC117, 0, 0,1, 1, 0,0, 0, "8C", "2.16.11", "Retired Cert Key Mgm 11" },
101   { 0x5FC118, 0, 0,1, 1, 0,0, 0, "8D", "2.16.12", "Retired Cert Key Mgm 12" },
102   { 0x5FC119, 0, 0,1, 1, 0,0, 0, "8E", "2.16.13", "Retired Cert Key Mgm 13" },
103   { 0x5FC11A, 0, 0,1, 1, 0,0, 0, "8F", "2.16.14", "Retired Cert Key Mgm 14" },
104   { 0x5FC11B, 0, 0,1, 1, 0,0, 0, "90", "2.16.15", "Retired Cert Key Mgm 15" },
105   { 0x5FC11C, 0, 0,1, 1, 0,0, 0, "91", "2.16.16", "Retired Cert Key Mgm 16" },
106   { 0x5FC11D, 0, 0,1, 1, 0,0, 0, "92", "2.16.17", "Retired Cert Key Mgm 17" },
107   { 0x5FC11E, 0, 0,1, 1, 0,0, 0, "93", "2.16.18", "Retired Cert Key Mgm 18" },
108   { 0x5FC11F, 0, 0,1, 1, 0,0, 0, "94", "2.16.19", "Retired Cert Key Mgm 19" },
109   { 0x5FC120, 0, 0,1, 1, 0,0, 0, "95", "2.16.20", "Retired Cert Key Mgm 20" },
110   { 0x5FC121, 0, 2,2, 1, 0,0, 0, "",   "2.16.21", "Cardholder Iris Images" },
111   { 0x7F61,   0, 0,0, 1, 0,0, 0, "",   "2.16.22", "BIT Group Template" },
112   { 0x5FC122, 0, 0,0, 1, 0,0, 0, "",   "2.16.23", "SM Cert Signer" },
113   { 0x5FC123, 0, 3,3, 1, 0,0, 0, "",   "2.16.24", "Pairing Code Ref Data" },
114   { 0 }
115   /* Other key reference values without a tag:
116    * "00" Global PIN (not cleared by application switching)
117    * "04" PIV Secure Messaging Key
118    * "80" PIV Application PIN
119    * "81" PIN Unblocking Key
120    * "96" Primary Finger OCC
121    * "97" Secondary Finger OCC
122    * "98" Pairing Code
123    * "9B" PIV Card Application Administration Key
124    */
125 };
126
127
128 /* One cache item for DOs.  */
129 struct cache_s {
130   struct cache_s *next;
131   int tag;
132   size_t length;
133   unsigned char data[1];
134 };
135
136
137 /* Object with application specific data.  */
138 struct app_local_s {
139   /* A linked list with cached DOs.  */
140   struct cache_s *cache;
141
142   /* Various flags.  */
143   struct
144   {
145     unsigned int dummy:1;
146   } flags;
147
148 };
149
150
151 /***** Local prototypes  *****/
152 static gpg_error_t get_keygrip_by_tag (app_t app, unsigned int tag,
153                                        char **r_keygripstr);
154
155
156
157
158 \f
159 /* Deconstructor. */
160 static void
161 do_deinit (app_t app)
162 {
163   if (app && app->app_local)
164     {
165       struct cache_s *c, *c2;
166
167       for (c = app->app_local->cache; c; c = c2)
168         {
169           c2 = c->next;
170           xfree (c);
171         }
172
173       xfree (app->app_local);
174       app->app_local = NULL;
175     }
176 }
177
178
179 /* Wrapper around iso7816_get_data which first tries to get the data
180  * from the cache.  With GET_IMMEDIATE passed as true, the cache is
181  * bypassed.  The tag-53 container is also removed.  */
182 static gpg_error_t
183 get_cached_data (app_t app, int tag,
184                  unsigned char **result, size_t *resultlen,
185                  int get_immediate)
186 {
187   gpg_error_t err;
188   int i;
189   unsigned char *p;
190   const unsigned char *s;
191   size_t len, n;
192   struct cache_s *c;
193
194   *result = NULL;
195   *resultlen = 0;
196
197   if (!get_immediate)
198     {
199       for (c=app->app_local->cache; c; c = c->next)
200         if (c->tag == tag)
201           {
202             if(c->length)
203               {
204                 p = xtrymalloc (c->length);
205                 if (!p)
206                   return gpg_error_from_syserror ();
207                 memcpy (p, c->data, c->length);
208                 *result = p;
209               }
210
211             *resultlen = c->length;
212
213             return 0;
214           }
215     }
216
217   err = iso7816_get_data_odd (app->slot, 0, tag, &p, &len);
218   if (err)
219     return err;
220
221   /* Unless the Discovery Object or the BIT Group Template is
222    * requested, remove the outer container.
223    * (SP800-73.4 Part 2, section 3.1.2)   */
224   if (tag == 0x7E || tag == 0x7F61)
225     ;
226   else if (len && *p == 0x53 && (s = find_tlv (p, len, 0x53, &n)))
227     {
228       memmove (p, s, n);
229       len = n;
230     }
231
232   if (len)
233     *result = p;
234   *resultlen = len;
235
236   /* Check whether we should cache this object. */
237   if (get_immediate)
238     return 0;
239
240   for (i=0; data_objects[i].tag; i++)
241     if (data_objects[i].tag == tag)
242       {
243         if (data_objects[i].dont_cache)
244           return 0;
245         break;
246       }
247
248   /* Okay, cache it. */
249   for (c=app->app_local->cache; c; c = c->next)
250     log_assert (c->tag != tag);
251
252   c = xtrymalloc (sizeof *c + len);
253   if (c)
254     {
255       if (len)
256         memcpy (c->data, p, len);
257       else
258         xfree (p);
259       c->length = len;
260       c->tag = tag;
261       c->next = app->app_local->cache;
262       app->app_local->cache = c;
263     }
264
265   return 0;
266 }
267
268
269 /* Get the DO identified by TAG from the card in SLOT and return a
270  * buffer with its content in RESULT and NBYTES.  The return value is
271  * NULL if not found or a pointer which must be used to release the
272  * buffer holding value.  */
273 static void *
274 get_one_do (app_t app, int tag, unsigned char **result, size_t *nbytes,
275             int *r_err)
276 {
277   gpg_error_t err;
278   int i;
279   unsigned char *buffer;
280   size_t buflen;
281   unsigned char *value;
282   size_t valuelen;
283   gpg_error_t dummyerr;
284
285   if (!r_err)
286     r_err = &dummyerr;
287
288   *result = NULL;
289   *nbytes = 0;
290   *r_err = 0;
291   for (i=0; data_objects[i].tag && data_objects[i].tag != tag; i++)
292     ;
293
294   value = NULL;
295   err = gpg_error (GPG_ERR_ENOENT);
296
297   if (!value) /* Not in a constructed DO, try simple. */
298     {
299       err = get_cached_data (app, tag, &buffer, &buflen,
300                              data_objects[i].dont_cache);
301       if (!err)
302         {
303           value = buffer;
304           valuelen = buflen;
305         }
306     }
307
308   if (!err)
309     {
310       *nbytes = valuelen;
311       *result = value;
312       return buffer;
313     }
314
315   *r_err = err;
316   return NULL;
317 }
318
319
320 static void
321 dump_all_do (int slot)
322 {
323   gpg_error_t err;
324   int i;
325   unsigned char *buffer;
326   size_t buflen;
327
328   for (i=0; data_objects[i].tag; i++)
329     {
330       /* We don't try extended length APDU because such large DO would
331          be pretty useless in a log file.  */
332       err = iso7816_get_data_odd (slot, 0, data_objects[i].tag,
333                                  &buffer, &buflen);
334       if (err)
335         {
336           if (gpg_err_code (err) == GPG_ERR_ENOENT
337               && !data_objects[i].mandatory)
338             ;
339           else
340             log_info ("DO '%s' not available: %s\n",
341                       data_objects[i].desc, gpg_strerror (err));
342         }
343       else
344         {
345           if (data_objects[i].binary)
346             {
347               log_info ("DO '%s': ", data_objects[i].desc);
348               if (buflen > 16 && opt.verbose < 2)
349                 {
350                   log_printhex (buffer, 16, NULL);
351                   log_printf ("[...]\n");
352                 }
353               else
354                 log_printhex (buffer, buflen, "");
355             }
356           else
357             log_info ("DO '%s': '%.*s'\n",
358                       data_objects[i].desc,
359                       (int)buflen, buffer);
360
361         }
362       xfree (buffer); buffer = NULL;
363     }
364 }
365
366
367 /* Parse the key reference KEYREFSTR which is expected to hold a key
368  * reference for a PIN object.  Return the one octet keyref or -1 for
369  * an invalid reference.  */
370 static int
371 parse_pin_keyref (const char *keyrefstr)
372 {
373   if (!keyrefstr)
374     return -1;
375   else if (!ascii_strcasecmp (keyrefstr, "PIV.00"))
376     return 0x00;
377   else if (!ascii_strcasecmp (keyrefstr, "PIV.80"))
378     return 0x80;
379   else if (!ascii_strcasecmp (keyrefstr, "PIV.81"))
380     return 0x81;
381   else
382     return -1;
383 }
384
385
386 /* Return an allocated string with the serial number in a format to be
387  * show to the user.  With FAILMODE is true return NULL if such an
388  * abbreviated S/N is not available, else return the full serial
389  * number as a hex string.  May return NULL on malloc problem.  */
390 static char *
391 get_dispserialno (app_t app, int failmode)
392 {
393   char *result;
394
395   if (app->serialno && app->serialnolen == 3+1+4
396       && !memcmp (app->serialno, "\xff\x02\x00", 3))
397     {
398       /* This is a 4 byte S/N of a Yubikey which seems to be printed
399        * on the token in decimal.  Maybe they will print larger S/N
400        * also in decimal but we can't be sure, thus do it only for
401        * these 32 bit numbers.  */
402       unsigned long sn;
403       sn  = app->serialno[4] * 16777216;
404       sn += app->serialno[5] * 65536;
405       sn += app->serialno[6] * 256;
406       sn += app->serialno[7];
407       result = xtryasprintf ("yk-%lu", sn);
408     }
409   else if (failmode)
410     result = NULL;  /* No Abbreviated S/N.  */
411   else
412     result = app_get_serialno (app);
413
414   return result;
415 }
416
417
418 /* The verify command can be used to retrieve the security status of
419  * the card.  Given the PIN name (e.g. "PIV.80" for thge application
420  * pin, a status is returned:
421  *
422  *        -1 = Error retrieving the data,
423  *        -2 = No such PIN,
424  *        -3 = PIN blocked,
425  *        -5 = Verify still valid,
426  *    n >= 0 = Number of verification attempts left.
427  */
428 static int
429 get_chv_status (app_t app, const char *keyrefstr)
430 {
431   unsigned char apdu[4];
432   unsigned int sw;
433   int result;
434   int keyref;
435
436   keyref = parse_pin_keyref (keyrefstr);
437   if (!keyrefstr)
438     return -1;
439
440   apdu[0] = 0x00;
441   apdu[1] = ISO7816_VERIFY;
442   apdu[2] = 0x00;
443   apdu[3] = keyref;
444   if (!iso7816_apdu_direct (app->slot, apdu, 4, 0, &sw, NULL, NULL))
445     result = -5; /* No need to verification.  */
446   else if (sw == 0x6a88)
447     result = -2; /* No such PIN.  */
448   else if (sw == 0x6983)
449     result = -3; /* PIN is blocked.  */
450   else if ((sw & 0xfff0) == 0x63C0)
451     result = (sw & 0x000f);
452   else
453     result = -1; /* Error.  */
454
455   return result;
456 }
457
458
459 /* Implementation of the GETATTR command.  This is similar to the
460  * LEARN command but returns only one value via status lines.  */
461 static gpg_error_t
462 do_getattr (app_t app, ctrl_t ctrl, const char *name)
463 {
464   static struct {
465     const char *name;
466     int tag;
467     int special;
468   } table[] = {
469     { "SERIALNO",     0x0000, -1 },
470     { "$AUTHKEYID",   0x0000, -2 }, /* Default key for ssh.  */
471     { "$DISPSERIALNO",0x0000, -3 },
472     { "CHV-STATUS",   0x0000, -4 },
473     { "CHV-USAGE",    0x007E, -5 }
474   };
475   gpg_error_t err = 0;
476   int idx;
477   void *relptr;
478   unsigned char *value;
479   size_t valuelen;
480   const unsigned char *s;
481   size_t n;
482
483   for (idx=0; (idx < DIM (table)
484                && ascii_strcasecmp (table[idx].name, name)); idx++)
485     ;
486   if (!(idx < DIM (table)))
487     err = gpg_error (GPG_ERR_INV_NAME);
488   else if (table[idx].special == -1)
489     {
490       char *serial = app_get_serialno (app);
491
492       if (serial)
493         {
494           send_status_direct (ctrl, "SERIALNO", serial);
495           xfree (serial);
496         }
497     }
498   else if (table[idx].special == -2)
499     {
500       char const tmp[] = "PIV.9A"; /* Cert PIV Authenticate.  */
501       send_status_info (ctrl, table[idx].name, tmp, strlen (tmp), NULL, 0);
502     }
503   else if (table[idx].special == -3)
504     {
505       char *tmp = get_dispserialno (app, 1);
506
507       if (tmp)
508         {
509           send_status_info (ctrl, table[idx].name,
510                             tmp, strlen (tmp),
511                             NULL, (size_t)0);
512           xfree (tmp);
513         }
514       else
515         err = gpg_error (GPG_ERR_INV_NAME);  /* No Abbreviated S/N.  */
516     }
517   else if (table[idx].special == -4) /* CHV-STATUS */
518     {
519       int tmp[3];
520
521       tmp[0] = get_chv_status (app, "PIV.00");
522       tmp[1] = get_chv_status (app, "PIV.80");
523       tmp[2] = get_chv_status (app, "PIV.81");
524       err = send_status_printf (ctrl, table[idx].name, "%d %d %d",
525                                 tmp[0], tmp[1], tmp[2]);
526     }
527   else if (table[idx].special == -5) /* CHV-USAGE (aka PIN Usage Policy) */
528     {
529       /* We return 2 hex bytes or nothing in case the discovery object
530        * is not supported.  */
531       relptr = get_one_do (app, table[idx].tag, &value, &valuelen, &err);
532       if (relptr)
533         {
534           s = find_tlv (value, valuelen, 0x7E, &n);
535           if (s && n && (s = find_tlv (s, n, 0x5F2F, &n)) && n >=2 )
536             err = send_status_printf (ctrl, table[idx].name, "%02X %02X",
537                                       s[0], s[1]);
538           xfree (relptr);
539         }
540     }
541   else
542     {
543       relptr = get_one_do (app, table[idx].tag, &value, &valuelen, &err);
544       if (relptr)
545         {
546           send_status_info (ctrl, table[idx].name, value, valuelen, NULL, 0);
547           xfree (relptr);
548         }
549     }
550
551   return err;
552 }
553
554
555 /* Send the KEYPAIRINFO back.  DOBJ describes the data object carrying
556  * the key.  This is used by the LEARN command. */
557 static gpg_error_t
558 send_keypair_and_cert_info (app_t app, ctrl_t ctrl, data_object_t dobj,
559                             int only_keypair)
560 {
561   gpg_error_t err = 0;
562   char *keygripstr = NULL;
563   char idbuf[50];
564
565   err = get_keygrip_by_tag (app, dobj->tag, &keygripstr);
566   if (err)
567     goto leave;
568
569   snprintf (idbuf, sizeof idbuf, "PIV.%s", dobj->keyref);
570   send_status_info (ctrl, "KEYPAIRINFO",
571                     keygripstr, strlen (keygripstr),
572                     idbuf, strlen (idbuf),
573                     NULL, (size_t)0);
574   if (!only_keypair)
575     {
576       /* All certificates are of type 100 (Regular X.509 Cert).  */
577       send_status_info (ctrl, "CERTINFO",
578                         "100", 3,
579                         idbuf, strlen (idbuf),
580                         NULL, (size_t)0);
581     }
582
583  leave:
584   xfree (keygripstr);
585   return err;
586 }
587
588
589 /* Handle the LEARN command.  */
590 static gpg_error_t
591 do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
592 {
593   int i;
594
595   (void)flags;
596
597   do_getattr (app, ctrl, "CHV-USAGE");
598   do_getattr (app, ctrl, "CHV-STATUS");
599
600   for (i=0; data_objects[i].tag; i++)
601     if (data_objects[i].keypair)
602       send_keypair_and_cert_info (app, ctrl, data_objects + i, !!(flags & 1));
603
604
605   return 0;
606 }
607
608
609 /* Core of do-readcert which fetches the certificate based on the
610  * given tag and returns it in a freshly allocated buffer stored at
611  * R_CERT and the length of the certificate stored at R_CERTLEN.  */
612 static gpg_error_t
613 readcert_by_tag (app_t app, unsigned int tag,
614                  unsigned char **r_cert, size_t *r_certlen)
615 {
616   gpg_error_t err;
617   unsigned char *buffer;
618   size_t buflen;
619   void *relptr;
620   const unsigned char *s;
621   size_t n;
622
623   *r_cert = NULL;
624   *r_certlen = 0;
625
626   relptr = get_one_do (app, tag, &buffer, &buflen, NULL);
627   if (!relptr || !buflen)
628    {
629       err = gpg_error (GPG_ERR_NOT_FOUND);
630       goto leave;
631     }
632
633   s = find_tlv (buffer, buflen, 0x71, &n);
634   if (!s || n != 1)
635     {
636       log_error ("piv: no or invalid CertInfo in 0x%X\n", tag);
637       err = gpg_error (GPG_ERR_INV_CERT_OBJ);
638       goto leave;
639     }
640   if (*s == 0x01)
641     {
642       log_error ("piv: gzip compression not yet supported (tag 0x%X)\n", tag);
643       err = gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
644       goto leave;
645     }
646   if (*s)
647     {
648       log_error ("piv: invalid CertInfo 0x%02x in 0x%X\n", *s, tag);
649       err = gpg_error (GPG_ERR_INV_CERT_OBJ);
650       goto leave;
651     }
652
653   /* Note: We don't check that the LRC octet has a length of zero as
654    * required by the specs.  */
655
656   /* Get the cert from the container.  */
657   s = find_tlv (buffer, buflen, 0x70, &n);
658   if (!s || !n)
659     {
660       err = gpg_error (GPG_ERR_NOT_FOUND);
661       goto leave;
662     }
663
664   if (!(*r_cert = xtrymalloc (n)))
665     {
666       err = gpg_error_from_syserror ();
667       goto leave;
668     }
669
670   memcpy (*r_cert, s, n);
671   *r_certlen = n;
672   err = 0;
673
674  leave:
675   xfree (relptr);
676   return err;
677 }
678
679
680 /* Get the keygrip of a key from the certificate stored at TAG.
681  * Caller must free the string at R_KEYGRIPSTR. */
682 static gpg_error_t
683 get_keygrip_by_tag (app_t app, unsigned int tag, char **r_keygripstr)
684 {
685   gpg_error_t err;
686   unsigned char *certbuf = NULL;
687   size_t certbuflen;
688   ksba_cert_t cert = NULL;
689
690   *r_keygripstr = xtrymalloc (40+1);
691   if (!r_keygripstr)
692     {
693       err = gpg_error_from_syserror ();
694       goto leave;
695     }
696
697   /* We need to get the public key from the certificate.  */
698   err = readcert_by_tag (app, tag, &certbuf, &certbuflen);
699   if (err)
700     goto leave;
701
702   /* Compute the keygrip.  */
703   err = ksba_cert_new (&cert);
704   if (err)
705     goto leave;
706   err = ksba_cert_init_from_mem (cert, certbuf, certbuflen);
707   if (err)
708     goto leave;
709   err = app_help_get_keygrip_string (cert, *r_keygripstr);
710
711
712  leave:
713   ksba_cert_release (cert);
714   xfree (certbuf);
715   if (err)
716     {
717       xfree (*r_keygripstr);
718       *r_keygripstr = NULL;
719     }
720   return err;
721 }
722
723
724 /* Locate the data object from the given KEYREF.  The KEYREF may also
725  * be the corresponding OID of the key object.  Returns the data
726  * object or NULL if not found.  */
727 static data_object_t
728 find_dobj_by_keyref (app_t app, const char *keyref)
729 {
730   int i;
731
732   (void)app;
733
734   if (!ascii_strncasecmp (keyref, "PIV.", 4))
735     {
736       keyref += 4;
737       for (i=0; data_objects[i].tag; i++)
738         if (*data_objects[i].keyref
739             && !ascii_strcasecmp (keyref, data_objects[i].keyref))
740           {
741             return data_objects + i;
742           }
743     }
744   else if (!strncmp (keyref, "2.16.840.1.101.3.7.", 19))
745     {
746       keyref += 19;
747       for (i=0; data_objects[i].tag; i++)
748         if (*data_objects[i].keyref
749             && !strcmp (keyref, data_objects[i].oidsuffix))
750           {
751             return data_objects + i;
752           }
753     }
754
755   return NULL;
756 }
757
758
759 /* Read a certificate from the card and returned in a freshly
760  * allocated buffer stored at R_CERT and the length of the certificate
761  * stored at R_CERTLEN.  CERTID is either the OID of the cert's
762  * container or of the form "PIV.<two_hexdigit_keyref>"  */
763 static gpg_error_t
764 do_readcert (app_t app, const char *certid,
765              unsigned char **r_cert, size_t *r_certlen)
766 {
767   data_object_t dobj;
768
769   *r_cert = NULL;
770   *r_certlen = 0;
771
772   dobj = find_dobj_by_keyref (app, certid);
773   if (!dobj)
774     return gpg_error (GPG_ERR_INV_ID);
775
776   return readcert_by_tag (app, dobj->tag, r_cert, r_certlen);
777 }
778
779
780 /* Given a data object DOBJ return the corresponding PIV algorithm and
781  * store it at R_ALGO.  The algorithm is taken from the corresponding
782  * certificate or from a cache.  */
783 static gpg_error_t
784 get_key_algorithm_by_dobj (app_t app, data_object_t dobj, int *r_algo)
785 {
786   gpg_error_t err;
787   unsigned char *certbuf = NULL;
788   size_t certbuflen;
789   ksba_cert_t cert = NULL;
790   ksba_sexp_t k_pkey = NULL;
791   gcry_sexp_t s_pkey = NULL;
792   gcry_sexp_t l1 = NULL;
793   char *algoname = NULL;
794   int algo;
795   size_t n;
796   const char *curve_name;
797
798   *r_algo = 0;
799
800   err = readcert_by_tag (app, dobj->tag, &certbuf, &certbuflen);
801   if (err)
802     goto leave;
803
804   err = ksba_cert_new (&cert);
805   if (err)
806     goto leave;
807
808   err = ksba_cert_init_from_mem (cert, certbuf, certbuflen);
809   if (err)
810     {
811       log_error ("piv: failed to parse the certificate %s: %s\n",
812                  dobj->keyref, gpg_strerror (err));
813       goto leave;
814     }
815   xfree (certbuf);
816   certbuf = NULL;
817
818   k_pkey = ksba_cert_get_public_key (cert);
819   if (!k_pkey)
820     {
821       err = gpg_error (GPG_ERR_NO_PUBKEY);
822       goto leave;
823     }
824   n = gcry_sexp_canon_len (k_pkey, 0, NULL, NULL);
825   err = gcry_sexp_new (&s_pkey, k_pkey, n, 0);
826   if (err)
827     goto leave;
828
829   l1 = gcry_sexp_find_token (s_pkey, "public-key", 0);
830   if (!l1)
831     {
832       err = gpg_error (GPG_ERR_NO_PUBKEY);
833       goto leave;
834     }
835
836   {
837     gcry_sexp_t l_tmp = gcry_sexp_cadr (l1);
838     gcry_sexp_release (l1);
839     l1 = l_tmp;
840   }
841   algoname = gcry_sexp_nth_string (l1, 0);
842   if (!algoname)
843     {
844       err = gpg_error_from_syserror ();
845       goto leave;
846     }
847
848   algo = gcry_pk_map_name (algoname);
849   switch (algo)
850     {
851     case GCRY_PK_RSA:
852       algo = PIV_ALGORITHM_RSA;
853       break;
854
855     case GCRY_PK_ECC:
856     case GCRY_PK_ECDSA:
857     case GCRY_PK_ECDH:
858       curve_name = gcry_pk_get_curve (s_pkey, 0, NULL);
859       if (curve_name && !strcmp (curve_name, "NIST P-256"))
860         algo = PIV_ALGORITHM_ECC_P256;
861       else if (curve_name && !strcmp (curve_name, "NIST P-384"))
862         algo = PIV_ALGORITHM_ECC_P384;
863       else
864         {
865           err = gpg_error (GPG_ERR_UNKNOWN_CURVE);
866           log_error ("piv: certificate %s, curve '%s': %s\n",
867                      dobj->keyref, curve_name, gpg_strerror (err));
868           goto leave;
869         }
870       break;
871
872     default:
873       err = gpg_error (GPG_ERR_PUBKEY_ALGO);
874       log_error ("piv: certificate %s, pubkey algo '%s': %s\n",
875                  dobj->keyref, algoname, gpg_strerror (err));
876       goto leave;
877     }
878   *r_algo = algo;
879
880  leave:
881   gcry_free (algoname);
882   gcry_sexp_release (l1);
883   gcry_sexp_release (s_pkey);
884   ksba_free (k_pkey);
885   xfree (certbuf);
886   return err;
887 }
888
889
890 /* Return an allocated string to be used as prompt.  Returns NULL on
891  * malloc error.  */
892 static char *
893 make_prompt (app_t app, int remaining, const char *firstline)
894 {
895   char *serial, *tmpbuf, *result;
896
897   serial = get_dispserialno (app, 0);
898   if (!serial)
899     return NULL;
900
901   /* TRANSLATORS: Put a \x1f right before a colon.  This can be
902    * used by pinentry to nicely align the names and values.  Keep
903    * the %s at the start and end of the string.  */
904   result = xtryasprintf (_("%s"
905                            "Number\x1f: %s%%0A"
906                            "Holder\x1f: %s"
907                            "%s"),
908                          "\x1e",
909                          serial,
910                          "Unknown", /* Fixme */
911                          "");
912   xfree (serial);
913
914   /* Append a "remaining attempts" info if needed.  */
915   if (remaining != -1 && remaining < 3)
916     {
917       char *rembuf;
918
919       /* TRANSLATORS: This is the number of remaining attempts to
920        * enter a PIN.  Use %%0A (double-percent,0A) for a linefeed. */
921       rembuf = xtryasprintf (_("Remaining attempts: %d"), remaining);
922       if (rembuf)
923         {
924           tmpbuf = strconcat (firstline, "%0A%0A", result,
925                               "%0A%0A", rembuf, NULL);
926           xfree (rembuf);
927         }
928       else
929         tmpbuf = NULL;
930       xfree (result);
931       result = tmpbuf;
932     }
933   else
934     {
935       tmpbuf = strconcat (firstline, "%0A%0A", result, NULL);
936       xfree (result);
937       result = tmpbuf;
938     }
939
940   return result;
941 }
942
943
944 /* Verify the Application PIN KEYREF.  */
945 static gpg_error_t
946 verify_pin (app_t app, int keyref,
947             gpg_error_t (*pincb)(void*,const char *,char **), void *pincb_arg)
948 {
949   gpg_error_t err;
950   unsigned char apdu[4];
951   unsigned int sw;
952   int remaining;
953   const char *label;
954   char *prompt;
955   char *pinvalue = NULL;
956   unsigned int pinlen;
957   char pinbuffer[8];
958   int minlen, maxlen, padding, onlydigits;
959
960   /* First check whether a verify is at all needed.  This is done with
961    * P1 being 0 and no Lc and command data send.  */
962   apdu[0] = 0x00;
963   apdu[1] = ISO7816_VERIFY;
964   apdu[2] = 0x00;
965   apdu[3] = keyref;
966   if (!iso7816_apdu_direct (app->slot, apdu, 4, 0, &sw, NULL, NULL))
967     {
968       /* No need to verification.  */
969       return 0;  /* All fine.  */
970     }
971   if ((sw & 0xfff0) == 0x63C0)
972     remaining = (sw & 0x000f); /* PIN has REMAINING tries left.  */
973   else
974     remaining = -1;
975
976   if (remaining != -1)
977     log_debug ("piv: PIN %2X has %d attempts left\n", keyref, remaining);
978
979   switch (keyref)
980     {
981     case 0x00:
982       minlen = 6;
983       maxlen = 8;
984       padding = 1;
985       onlydigits = 1;
986       label = _("||Please enter the Global-PIN of your PIV card");
987       break;
988     case 0x80:
989       minlen = 6;
990       maxlen = 8;
991       padding = 1;
992       onlydigits = 1;
993       label = _("||Please enter the PIN of your PIV card");
994       break;
995     case 0x81:
996       minlen = 8;
997       maxlen = 8;
998       padding = 0;
999       onlydigits = 0;
1000       label = _("||Please enter the Unblocking Key of your PIV card");
1001       break;
1002
1003     case 0x96:
1004     case 0x97:
1005     case 0x98:
1006     case 0x9B:
1007       return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1008
1009     default:
1010       return gpg_error (GPG_ERR_INV_ID);
1011     }
1012   log_assert (sizeof pinbuffer >= maxlen);
1013
1014
1015   /* Ask for the PIN.  */
1016   prompt = make_prompt (app, remaining, label);
1017   err = pincb (pincb_arg, prompt, &pinvalue);
1018   xfree (prompt);
1019   prompt = NULL;
1020   if (err)
1021     {
1022       log_info (_("PIN callback returned error: %s\n"), gpg_strerror (err));
1023       return err;
1024     }
1025
1026   pinlen = pinvalue? strlen (pinvalue) : 0;
1027   if (pinlen < minlen)
1028     {
1029       log_error (_("PIN for is too short; minimum length is %d\n"), minlen);
1030       if (pinvalue)
1031         wipememory (pinvalue, pinlen);
1032       xfree (pinvalue);
1033       return gpg_error (GPG_ERR_BAD_PIN);
1034     }
1035   if (pinlen > maxlen)
1036     {
1037       log_error (_("PIN for is too long; maximum length is %d\n"), maxlen);
1038       wipememory (pinvalue, pinlen);
1039       xfree (pinvalue);
1040       return gpg_error (GPG_ERR_BAD_PIN);
1041     }
1042   if (onlydigits && strspn (pinvalue, "0123456789") != pinlen)
1043     {
1044       log_error (_("PIN has invalid characters; only digits are allowed\n"));
1045       wipememory (pinvalue, pinlen);
1046       xfree (pinvalue);
1047       return gpg_error (GPG_ERR_BAD_PIN);
1048     }
1049   memcpy (pinbuffer, pinvalue, pinlen);
1050   if (padding)
1051     {
1052       memset (pinbuffer + pinlen, 0xff, maxlen - pinlen);
1053       wipememory (pinvalue, pinlen);
1054       pinlen = maxlen;
1055     }
1056   else
1057     wipememory (pinvalue, pinlen);
1058   xfree (pinvalue);
1059
1060   err = iso7816_verify (app->slot, keyref, pinbuffer, pinlen);
1061   wipememory (pinbuffer, pinlen);
1062   if (err)
1063     log_error ("PIN %02X verification failed: %s\n", keyref,gpg_strerror (err));
1064
1065   return err;
1066 }
1067
1068
1069 /* Handle the PASSWD command.  Valid values for PWIDSTR are
1070  * key references related to PINs; in particular:
1071  *   PIV.00 - The Global PIN
1072  *   PIV.80 - The Application PIN
1073  *   PIV.81 - The PIN Unblocking key
1074  * The supported flags are:
1075  *   APP_CHANGE_FLAG_CLEAR   Clear the PIN verification state.
1076  */
1077 static gpg_error_t
1078 do_change_pin (app_t app, ctrl_t ctrl, const char *pwidstr,
1079                unsigned int flags,
1080                gpg_error_t (*pincb)(void*, const char *, char **),
1081                void *pincb_arg)
1082 {
1083   gpg_error_t err;
1084   int keyref;
1085   unsigned char apdu[4];
1086
1087   char *newpin = NULL;
1088   char *oldpin = NULL;
1089   size_t newpinlen;
1090   size_t oldpinlen;
1091   const char *newdesc;
1092   int pwid;
1093   pininfo_t pininfo;
1094
1095   (void)ctrl;
1096
1097   /* The minimum and maximum lengths are enforced by PIV.  */
1098   memset (&pininfo, 0, sizeof pininfo);
1099   pininfo.minlen = 6;
1100   pininfo.maxlen = 8;
1101
1102   keyref = parse_pin_keyref (pwidstr);
1103   if (keyref == -1)
1104     return gpg_error (GPG_ERR_INV_ID);
1105
1106   if ((flags & ~APP_CHANGE_FLAG_CLEAR))
1107     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1108
1109   /* First see whether the special --clear mode has been requested.  */
1110   if ((flags & APP_CHANGE_FLAG_CLEAR))
1111     {
1112       apdu[0] = 0x00;
1113       apdu[1] = ISO7816_VERIFY;
1114       apdu[2] = 0xff;
1115       apdu[3] = keyref;
1116       err = iso7816_apdu_direct (app->slot, apdu, 4, 0, NULL, NULL, NULL);
1117       goto leave;
1118     }
1119
1120   err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1121
1122  leave:
1123   xfree (oldpin);
1124   xfree (newpin);
1125   return err;
1126 }
1127
1128
1129 /* Perform a simple verify operation for the PIN specified by PWIDSTR.
1130  * For valid values see do_change_pin.  */
1131 static gpg_error_t
1132 do_check_pin (app_t app, const char *pwidstr,
1133               gpg_error_t (*pincb)(void*, const char *, char **),
1134               void *pincb_arg)
1135 {
1136   int keyref;
1137
1138   keyref = parse_pin_keyref (pwidstr);
1139   if (keyref == -1)
1140     return gpg_error (GPG_ERR_INV_ID);
1141
1142   return verify_pin (app, keyref, pincb, pincb_arg);
1143 }
1144
1145
1146 /* Compute a digital signature using the GENERAL AUTHENTICATE command
1147  * on INDATA which is expected to be the raw message digest.  The
1148  * KEYIDSTR has the key reference or its OID (e.g. "PIV.9A").  The
1149  * result is stored at (R_OUTDATA,R_OUTDATALEN); on error (NULL,0) is
1150  * stored there and an error code returned.  For ECDSA the result is
1151  * the simple concatenation of R and S without any DER encoding.  R
1152  * and S are left extended with zeroes to make sure they have an equal
1153  * length.
1154  */
1155 static gpg_error_t
1156 do_auth (app_t app, const char *keyidstr,
1157          gpg_error_t (*pincb)(void*, const char *, char **),
1158          void *pincb_arg,
1159          const void *indata_arg, size_t indatalen,
1160          unsigned char **r_outdata, size_t *r_outdatalen)
1161 {
1162   const unsigned char *indata = indata_arg;
1163   gpg_error_t err;
1164   data_object_t dobj;
1165   unsigned char tmpl[2+2+2+128];
1166   size_t tmpllen;
1167   unsigned char *outdata = NULL;
1168   size_t outdatalen;
1169   const unsigned char *s;
1170   size_t n;
1171   int keyref, algo;
1172
1173   if (!keyidstr || !*keyidstr)
1174     {
1175       err = gpg_error (GPG_ERR_INV_VALUE);
1176       goto leave;
1177     }
1178
1179   /* Fixme: Shall we support the KEYID/FINGERPRINT syntax?  Does it
1180    * make sense for X.509 certs?  */
1181
1182   dobj = find_dobj_by_keyref (app, keyidstr);
1183   if (!dobj)
1184     {
1185       err = gpg_error (GPG_ERR_INV_ID);
1186       goto leave;
1187     }
1188   keyref = xtoi_2 (dobj->keyref);
1189
1190   err = get_key_algorithm_by_dobj (app, dobj, &algo);
1191   if (err)
1192     goto leave;
1193
1194   /* We need to remove the ASN.1 prefix from INDATA.  We use TEMPL as
1195    * a temporary buffer for the OID.  */
1196   if (algo == PIV_ALGORITHM_ECC_P256)
1197     {
1198       tmpllen = sizeof tmpl;
1199       err = gcry_md_get_asnoid (GCRY_MD_SHA256, &tmpl, &tmpllen);
1200       if (err)
1201         {
1202           err = gpg_error (GPG_ERR_INTERNAL);
1203           log_debug ("piv: no OID for hash algo %d\n", GCRY_MD_SHA256);
1204           goto leave;
1205         }
1206       if (indatalen != tmpllen + 32 || memcmp (indata, tmpl, tmpllen))
1207         {
1208           err = GPG_ERR_INV_VALUE;
1209           log_error ("piv: bad formatted input for ECC-P256 auth\n");
1210           goto leave;
1211         }
1212       indata +=tmpllen;
1213       indatalen -= tmpllen;
1214     }
1215   else if (algo == PIV_ALGORITHM_ECC_P384)
1216     {
1217       tmpllen = sizeof tmpl;
1218       err = gcry_md_get_asnoid (GCRY_MD_SHA384, &tmpl, &tmpllen);
1219       if (err)
1220         {
1221           err = gpg_error (GPG_ERR_INTERNAL);
1222           log_debug ("piv: no OID for hash algo %d\n", GCRY_MD_SHA384);
1223           goto leave;
1224         }
1225       if (indatalen != tmpllen + 48 || memcmp (indata, tmpl, tmpllen))
1226         {
1227           err = GPG_ERR_INV_VALUE;
1228           log_error ("piv: bad formatted input for ECC-P384 auth\n");
1229           goto leave;
1230         }
1231       indata += tmpllen;
1232       indatalen -= tmpllen;
1233     }
1234   else if (algo == PIV_ALGORITHM_RSA)
1235     {
1236       err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1237       log_error ("piv: FIXME: implement RSA authentication\n");
1238       goto leave;
1239     }
1240   else
1241     {
1242       err = gpg_error (GPG_ERR_INTERNAL);
1243       log_debug ("piv: unknown PIV  algo %d from helper function\n", algo);
1244       goto leave;
1245     }
1246
1247   /* Because we don't have a dynamic template builder we make sure
1248    * that we can encode all lengths in one octet.  FIXME: Use add_tls
1249    * from app-openpgp as a base for an strconcat like function. */
1250   if (indatalen >= 100)
1251     {
1252       err = gpg_error (GPG_ERR_TOO_LARGE);
1253       goto leave;
1254     }
1255
1256   /* Now verify the Application PIN.  */
1257   err = verify_pin (app, 0x80, pincb, pincb_arg);
1258   if (err)
1259     return err;
1260
1261   /* Build the Dynamic Authentication Template.  */
1262   tmpl[0] = 0x7c;
1263   tmpl[1] = indatalen + 4;
1264   tmpl[2] = 0x82; /* Response. */
1265   tmpl[3] = 0;    /* Must be 0 to get the tag in the answer.  */
1266   tmpl[4] = 0x81; /* Challenge. */
1267   tmpl[5] = indatalen;
1268   memcpy (tmpl+6, indata, indatalen);
1269   tmpllen = indatalen + 6;
1270
1271   /* Note: the -1 requests command chaining.  */
1272   err = iso7816_general_authenticate (app->slot, -1,
1273                                       algo, keyref,
1274                                       tmpl, (int)tmpllen, 0,
1275                                       &outdata, &outdatalen);
1276   if (err)
1277     goto leave;
1278
1279   /* Parse the response.  */
1280   if (outdatalen && *outdata == 0x7c
1281       && (s = find_tlv (outdata, outdatalen, 0x82, &n)))
1282     {
1283       const unsigned char *rval, *sval;
1284       size_t rlen, rlenx, slen, slenx, resultlen;
1285       char *result;
1286       /* The result of an ECDSA signature is
1287        *   SEQUENCE { r INTEGER, s INTEGER }
1288        * We re-pack that by concatenating R and S and making sure that
1289        * both have the same length.  We simplify parsing by using
1290        * find_tlv and not a proper DER parser.  */
1291       s = find_tlv (s, n, 0x30, &n);
1292       if (!s)
1293         goto bad_der;
1294       rval = find_tlv (s, n, 0x02, &rlen);
1295       if (!rval)
1296         goto bad_der;
1297       log_assert (n >= (rval-s)+rlen);
1298       sval = find_tlv (rval+rlen, n-((rval-s)+rlen), 0x02, &slen);
1299       if (!rval)
1300         goto bad_der;
1301       rlenx = slenx = 0;
1302       if (rlen > slen)
1303         slenx = rlen - slen;
1304       else if (slen > rlen)
1305         rlenx = slen - rlen;
1306
1307       resultlen = rlen + rlenx + slen + slenx;
1308       result = xtrycalloc (1, resultlen);
1309       if (!result)
1310         {
1311           err = gpg_error_from_syserror ();
1312           goto leave;
1313         }
1314       memcpy (result + rlenx, rval, rlen);
1315       memcpy (result + rlenx + rlen + slenx, sval, slen);
1316       xfree (outdata);
1317       outdata = result;
1318       outdatalen = resultlen;
1319     }
1320   else
1321     {
1322     bad_der:
1323       err = gpg_error (GPG_ERR_CARD);
1324       log_error ("piv: response does not contain a proper result\n");
1325       goto leave;
1326     }
1327
1328  leave:
1329   if (err)
1330     {
1331       xfree (outdata);
1332       *r_outdata = NULL;
1333       *r_outdatalen = 0;
1334     }
1335   else
1336     {
1337       *r_outdata = outdata;
1338       *r_outdatalen = outdatalen;
1339     }
1340   return err;
1341 }
1342
1343
1344 /* Select the PIV application on the card in SLOT.  This function must
1345  * be used before any other PIV application functions. */
1346 gpg_error_t
1347 app_select_piv (app_t app)
1348 {
1349   static char const aid[] = { 0xA0, 0x00, 0x00, 0x03, 0x08, /* RID=NIST */
1350                               0x00, 0x00, 0x10, 0x00        /* PIX=PIV  */ };
1351   int slot = app->slot;
1352   gpg_error_t err;
1353   unsigned char *apt = NULL;
1354   size_t aptlen;
1355   const unsigned char *s;
1356   size_t n;
1357
1358   /* Note that we select using the AID without the 2 octet version
1359    * number.  This allows for better reporting of future specs.  We
1360    * need to use the use-zero-for-P2-flag.  */
1361   err = iso7816_select_application_ext (slot, aid, sizeof aid, 0x0001,
1362                                         &apt, &aptlen);
1363   if (err)
1364     goto leave;
1365
1366   app->apptype = "PIV";
1367   app->did_chv1 = 0;
1368   app->did_chv2 = 0;
1369   app->did_chv3 = 0;
1370   app->app_local = NULL;
1371
1372   /* Check the Application Property Template.  */
1373   if (opt.verbose)
1374     {
1375       /* We  use a separate log_info to avoid the "DBG:" prefix.  */
1376       log_info ("piv: APT=");
1377       log_printhex (apt, aptlen, "");
1378     }
1379
1380   s = find_tlv (apt, aptlen, 0x4F, &n);
1381   if (!s || n != 6 || memcmp (s, aid+5, 4))
1382     {
1383       /* The PIX does not match.  */
1384       log_error ("piv: missing or invalid DO 0x4F in APT\n");
1385       err = gpg_error (GPG_ERR_CARD);
1386       goto leave;
1387     }
1388   if (s[4] != 1 || s[5] != 0)
1389     {
1390       log_error ("piv: unknown PIV version %u.%u\n", s[4], s[5]);
1391       err = gpg_error (GPG_ERR_CARD);
1392       goto leave;
1393     }
1394   app->card_version = ((s[4] << 8) | s[5]);
1395
1396   s = find_tlv (apt, aptlen, 0x79, &n);
1397   if (!s || n < 7)
1398     {
1399       log_error ("piv: missing or invalid DO 0x79 in APT\n");
1400       err = gpg_error (GPG_ERR_CARD);
1401       goto leave;
1402     }
1403   s = find_tlv (s, n, 0x4F, &n);
1404   if (!s || n != 5 || memcmp (s, aid, 5))
1405     {
1406       /* The RID does not match.  */
1407       log_error ("piv: missing or invalid DO 0x79.4F in APT\n");
1408       err = gpg_error (GPG_ERR_CARD);
1409       goto leave;
1410     }
1411
1412   app->app_local = xtrycalloc (1, sizeof *app->app_local);
1413   if (!app->app_local)
1414     {
1415       err = gpg_error_from_syserror ();
1416       goto leave;
1417     }
1418
1419
1420   /* FIXME: Parse the optional and conditional DOs in the APT.  */
1421
1422   if (opt.verbose)
1423     dump_all_do (slot);
1424
1425   app->fnc.deinit = do_deinit;
1426   app->fnc.learn_status = do_learn_status;
1427   app->fnc.readcert = do_readcert;
1428   app->fnc.readkey = NULL;
1429   app->fnc.getattr = do_getattr;
1430   /* app->fnc.setattr = do_setattr; */
1431   /* app->fnc.writecert = do_writecert; */
1432   /* app->fnc.writekey = do_writekey; */
1433   /* app->fnc.genkey = do_genkey; */
1434   /* app->fnc.sign = do_sign; */
1435   app->fnc.auth = do_auth;
1436   /* app->fnc.decipher = do_decipher; */
1437   app->fnc.change_pin = do_change_pin;
1438   app->fnc.check_pin = do_check_pin;
1439
1440
1441 leave:
1442   xfree (apt);
1443   if (err)
1444     do_deinit (app);
1445   return err;
1446 }