scd: Add DES authentication for PIV card.
[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 data object:
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 yubikey:1;  /* This is on a Yubikey.  */
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 /* Remove data object described by TAG from the cache.  */
270 static void
271 flush_cached_data (app_t app, int tag)
272 {
273   struct cache_s *c, *cprev;
274
275   for (c=app->app_local->cache, cprev=NULL; c; cprev=c, c = c->next)
276     if (c->tag == tag)
277       {
278         if (cprev)
279           cprev->next = c->next;
280         else
281           app->app_local->cache = c->next;
282         xfree (c);
283
284         for (c=app->app_local->cache; c ; c = c->next)
285           {
286             log_assert (c->tag != tag); /* Oops: duplicated entry. */
287           }
288         return;
289       }
290 }
291
292
293 /* Get the DO identified by TAG from the card in SLOT and return a
294  * buffer with its content in RESULT and NBYTES.  The return value is
295  * NULL if not found or a pointer which must be used to release the
296  * buffer holding value.  */
297 static void *
298 get_one_do (app_t app, int tag, unsigned char **result, size_t *nbytes,
299             int *r_err)
300 {
301   gpg_error_t err;
302   int i;
303   unsigned char *buffer;
304   size_t buflen;
305   unsigned char *value;
306   size_t valuelen;
307   gpg_error_t dummyerr;
308
309   if (!r_err)
310     r_err = &dummyerr;
311
312   *result = NULL;
313   *nbytes = 0;
314   *r_err = 0;
315   for (i=0; data_objects[i].tag && data_objects[i].tag != tag; i++)
316     ;
317
318   value = NULL;
319   err = gpg_error (GPG_ERR_ENOENT);
320
321   if (!value) /* Not in a constructed DO, try simple. */
322     {
323       err = get_cached_data (app, tag, &buffer, &buflen,
324                              data_objects[i].dont_cache);
325       if (!err)
326         {
327           value = buffer;
328           valuelen = buflen;
329         }
330     }
331
332   if (!err)
333     {
334       *nbytes = valuelen;
335       *result = value;
336       return buffer;
337     }
338
339   *r_err = err;
340   return NULL;
341 }
342
343
344 static void
345 dump_all_do (int slot)
346 {
347   gpg_error_t err;
348   int i;
349   unsigned char *buffer;
350   size_t buflen;
351
352   for (i=0; data_objects[i].tag; i++)
353     {
354       /* We don't try extended length APDU because such large DO would
355          be pretty useless in a log file.  */
356       err = iso7816_get_data_odd (slot, 0, data_objects[i].tag,
357                                  &buffer, &buflen);
358       if (err)
359         {
360           if (gpg_err_code (err) == GPG_ERR_ENOENT
361               && !data_objects[i].mandatory)
362             ;
363           else
364             log_info ("DO '%s' not available: %s\n",
365                       data_objects[i].desc, gpg_strerror (err));
366         }
367       else
368         {
369           if (data_objects[i].binary)
370             {
371               log_info ("DO '%s': ", data_objects[i].desc);
372               if (buflen > 16 && opt.verbose < 2)
373                 {
374                   log_printhex (buffer, 16, NULL);
375                   log_printf ("[...]\n");
376                 }
377               else
378                 log_printhex (buffer, buflen, "");
379             }
380           else
381             log_info ("DO '%s': '%.*s'\n",
382                       data_objects[i].desc,
383                       (int)buflen, buffer);
384
385         }
386       xfree (buffer); buffer = NULL;
387     }
388 }
389
390
391 /* Parse the key reference KEYREFSTR which is expected to hold a key
392  * reference for a PIN object.  Return the one octet keyref or -1 for
393  * an invalid reference.  */
394 static int
395 parse_pin_keyref (const char *keyrefstr)
396 {
397   if (!keyrefstr)
398     return -1;
399   else if (!ascii_strcasecmp (keyrefstr, "PIV.00"))
400     return 0x00;
401   else if (!ascii_strcasecmp (keyrefstr, "PIV.80"))
402     return 0x80;
403   else if (!ascii_strcasecmp (keyrefstr, "PIV.81"))
404     return 0x81;
405   else
406     return -1;
407 }
408
409
410 /* Return an allocated string with the serial number in a format to be
411  * show to the user.  With FAILMODE is true return NULL if such an
412  * abbreviated S/N is not available, else return the full serial
413  * number as a hex string.  May return NULL on malloc problem.  */
414 static char *
415 get_dispserialno (app_t app, int failmode)
416 {
417   char *result;
418
419   if (app->serialno && app->serialnolen == 3+1+4
420       && !memcmp (app->serialno, "\xff\x02\x00", 3))
421     {
422       /* This is a 4 byte S/N of a Yubikey which seems to be printed
423        * on the token in decimal.  Maybe they will print larger S/N
424        * also in decimal but we can't be sure, thus do it only for
425        * these 32 bit numbers.  */
426       unsigned long sn;
427       sn  = app->serialno[4] * 16777216;
428       sn += app->serialno[5] * 65536;
429       sn += app->serialno[6] * 256;
430       sn += app->serialno[7];
431       result = xtryasprintf ("yk-%lu", sn);
432     }
433   else if (failmode)
434     result = NULL;  /* No Abbreviated S/N.  */
435   else
436     result = app_get_serialno (app);
437
438   return result;
439 }
440
441
442 /* The verify command can be used to retrieve the security status of
443  * the card.  Given the PIN name (e.g. "PIV.80" for thge application
444  * pin, a status is returned:
445  *
446  *        -1 = Error retrieving the data,
447  *        -2 = No such PIN,
448  *        -3 = PIN blocked,
449  *        -5 = Verify still valid,
450  *    n >= 0 = Number of verification attempts left.
451  */
452 static int
453 get_chv_status (app_t app, const char *keyrefstr)
454 {
455   unsigned char apdu[4];
456   unsigned int sw;
457   int result;
458   int keyref;
459
460   keyref = parse_pin_keyref (keyrefstr);
461   if (!keyrefstr)
462     return -1;
463
464   apdu[0] = 0x00;
465   apdu[1] = ISO7816_VERIFY;
466   apdu[2] = 0x00;
467   apdu[3] = keyref;
468   if (!iso7816_apdu_direct (app->slot, apdu, 4, 0, &sw, NULL, NULL))
469     result = -5; /* No need to verification.  */
470   else if (sw == 0x6a88)
471     result = -2; /* No such PIN.  */
472   else if (sw == 0x6983)
473     result = -3; /* PIN is blocked.  */
474   else if ((sw & 0xfff0) == 0x63C0)
475     result = (sw & 0x000f);
476   else
477     result = -1; /* Error.  */
478
479   return result;
480 }
481
482
483 /* Implementation of the GETATTR command.  This is similar to the
484  * LEARN command but returns only one value via status lines.  */
485 static gpg_error_t
486 do_getattr (app_t app, ctrl_t ctrl, const char *name)
487 {
488   static struct {
489     const char *name;
490     int tag;
491     int special;
492   } table[] = {
493     { "SERIALNO",     0x0000, -1 },
494     { "$AUTHKEYID",   0x0000, -2 }, /* Default key for ssh.  */
495     { "$DISPSERIALNO",0x0000, -3 },
496     { "CHV-STATUS",   0x0000, -4 },
497     { "CHV-USAGE",    0x007E, -5 }
498   };
499   gpg_error_t err = 0;
500   int idx;
501   void *relptr;
502   unsigned char *value;
503   size_t valuelen;
504   const unsigned char *s;
505   size_t n;
506
507   for (idx=0; (idx < DIM (table)
508                && ascii_strcasecmp (table[idx].name, name)); idx++)
509     ;
510   if (!(idx < DIM (table)))
511     err = gpg_error (GPG_ERR_INV_NAME);
512   else if (table[idx].special == -1)
513     {
514       char *serial = app_get_serialno (app);
515
516       if (serial)
517         {
518           send_status_direct (ctrl, "SERIALNO", serial);
519           xfree (serial);
520         }
521     }
522   else if (table[idx].special == -2)
523     {
524       char const tmp[] = "PIV.9A"; /* Cert PIV Authenticate.  */
525       send_status_info (ctrl, table[idx].name, tmp, strlen (tmp), NULL, 0);
526     }
527   else if (table[idx].special == -3)
528     {
529       char *tmp = get_dispserialno (app, 1);
530
531       if (tmp)
532         {
533           send_status_info (ctrl, table[idx].name,
534                             tmp, strlen (tmp),
535                             NULL, (size_t)0);
536           xfree (tmp);
537         }
538       else
539         err = gpg_error (GPG_ERR_INV_NAME);  /* No Abbreviated S/N.  */
540     }
541   else if (table[idx].special == -4) /* CHV-STATUS */
542     {
543       int tmp[3];
544
545       tmp[0] = get_chv_status (app, "PIV.00");
546       tmp[1] = get_chv_status (app, "PIV.80");
547       tmp[2] = get_chv_status (app, "PIV.81");
548       err = send_status_printf (ctrl, table[idx].name, "%d %d %d",
549                                 tmp[0], tmp[1], tmp[2]);
550     }
551   else if (table[idx].special == -5) /* CHV-USAGE (aka PIN Usage Policy) */
552     {
553       /* We return 2 hex bytes or nothing in case the discovery object
554        * is not supported.  */
555       relptr = get_one_do (app, table[idx].tag, &value, &valuelen, &err);
556       if (relptr)
557         {
558           s = find_tlv (value, valuelen, 0x7E, &n);
559           if (s && n && (s = find_tlv (s, n, 0x5F2F, &n)) && n >=2 )
560             err = send_status_printf (ctrl, table[idx].name, "%02X %02X",
561                                       s[0], s[1]);
562           xfree (relptr);
563         }
564     }
565   else
566     {
567       relptr = get_one_do (app, table[idx].tag, &value, &valuelen, &err);
568       if (relptr)
569         {
570           send_status_info (ctrl, table[idx].name, value, valuelen, NULL, 0);
571           xfree (relptr);
572         }
573     }
574
575   return err;
576 }
577
578
579 /* Authenticate the card using the Card Application Administration
580  * Key.  (VALUE,VALUELEN) has that 24 byte key.  */
581 static gpg_error_t
582 auth_adm_key (app_t app, const unsigned char *value, size_t valuelen)
583 {
584   gpg_error_t err;
585   unsigned char tmpl[4+24];
586   size_t tmpllen;
587   unsigned char *outdata = NULL;
588   size_t outdatalen;
589   const unsigned char *s;
590   char witness[8];
591   size_t n;
592   gcry_cipher_hd_t cipher = NULL;
593
594   /* Prepare decryption.  */
595   err = gcry_cipher_open (&cipher, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_ECB, 0);
596   if (err)
597     goto leave;
598   err = gcry_cipher_setkey (cipher, value, valuelen);
599   if (err)
600     goto leave;
601
602   /* Request a witness.  */
603   tmpl[0] = 0x7c;
604   tmpl[1] = 0x02;
605   tmpl[2] = 0x80;
606   tmpl[3] = 0;    /* (Empty witness requests a witness.)  */
607   tmpllen = 4;
608   err = iso7816_general_authenticate (app->slot, 0,
609                                       PIV_ALGORITHM_3DES_ECB_0, 0x9B,
610                                       tmpl, tmpllen, 0,
611                                       &outdata, &outdatalen);
612   if (err)
613     goto leave;
614   if (!(outdatalen && *outdata == 0x7c
615         && (s = find_tlv (outdata, outdatalen, 0x80, &n))
616         && n == 8))
617     {
618       err = gpg_error (GPG_ERR_CARD);
619       log_error ("piv: improper witness received\n");
620       goto leave;
621     }
622   err = gcry_cipher_decrypt (cipher, witness, 8, s, 8);
623   if (err)
624     goto leave;
625
626   /* Return decrypted witness and send our challenge.  */
627   tmpl[0] = 0x7c;
628   tmpl[1] = 22;
629   tmpl[2] = 0x80;
630   tmpl[3] = 8;
631   memcpy (tmpl+4, witness, 8);
632   tmpl[12] = 0x81;
633   tmpl[13] = 8;
634   gcry_create_nonce (tmpl+14, 8);
635   tmpl[22] = 0x80;
636   tmpl[23] = 0;
637   tmpllen = 24;
638   xfree (outdata);
639   err = iso7816_general_authenticate (app->slot, 0,
640                                       PIV_ALGORITHM_3DES_ECB_0, 0x9B,
641                                       tmpl, tmpllen, 0,
642                                       &outdata, &outdatalen);
643   if (err)
644     goto leave;
645   if (!(outdatalen && *outdata == 0x7c
646         && (s = find_tlv (outdata, outdatalen, 0x82, &n))
647         && n == 8))
648     {
649       err = gpg_error (GPG_ERR_CARD);
650       log_error ("piv: improper challenge received\n");
651       goto leave;
652     }
653   /* (We reuse the witness buffer.) */
654   err = gcry_cipher_decrypt (cipher, witness, 8, s, 8);
655   if (err)
656     goto leave;
657   if (memcmp (witness, tmpl+14, 8))
658     {
659       err = gpg_error (GPG_ERR_BAD_SIGNATURE);
660       goto leave;
661     }
662
663  leave:
664    xfree (outdata);
665    gcry_cipher_close (cipher);
666    return err;
667 }
668
669
670 /* Set a new admin key.  */
671 static gpg_error_t
672 set_adm_key (app_t app, const unsigned char *value, size_t valuelen)
673 {
674   gpg_error_t err;
675   unsigned char apdu[8+24];
676   unsigned int sw;
677
678   /* Check whether it is a weak key and that it is of proper length.  */
679   {
680     gcry_cipher_hd_t cipher;
681
682     err = gcry_cipher_open (&cipher, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_ECB, 0);
683     if (!err)
684       {
685         err = gcry_cipher_setkey (cipher, value, valuelen);
686         gcry_cipher_close (cipher);
687       }
688     if (err)
689       goto leave;
690   }
691
692   if (app->app_local->flags.yubikey)
693     {
694       /* This is a Yubikey.  */
695       if (valuelen != 24)
696         {
697           err = gpg_error (GPG_ERR_INV_LENGTH);
698           goto leave;
699         }
700
701       /* We use a proprietary Yubikey command.  */
702       apdu[0] = 0;
703       apdu[1] = 0xff;
704       apdu[2] = 0xff;
705       apdu[3] = 0xff;  /* touch policy: 0xff=never, 0xfe = always.  */
706       apdu[4] = 3 + 24;
707       apdu[5] = PIV_ALGORITHM_3DES_ECB;
708       apdu[6] = 0x9b;
709       apdu[7] = 24;
710       memcpy (apdu+8, value, 24);
711       err = iso7816_apdu_direct (app->slot, apdu, 8+24, 0, &sw, NULL, NULL);
712       wipememory (apdu+8, 24);
713       if (err)
714         log_error ("piv: setting admin key failed; sw=%04x\n", sw);
715     }
716   else
717     err = gpg_error (GPG_ERR_NOT_SUPPORTED);
718
719
720  leave:
721    return err;
722 }
723
724
725 /* Handle the SETATTR operation. All arguments are already basically
726  * checked. */
727 static gpg_error_t
728 do_setattr (app_t app, const char *name,
729             gpg_error_t (*pincb)(void*, const char *, char **),
730             void *pincb_arg,
731             const unsigned char *value, size_t valuelen)
732 {
733   gpg_error_t err;
734   static struct {
735     const char *name;
736     unsigned short tag;
737     unsigned short flush_tag;  /* The tag which needs to be flushed or 0. */
738     int special;               /* Special mode to use for thus NAME.  */
739   } table[] = {
740     /* Authenticate using the PIV Card Application Administration Key
741      * (0x0B).  Note that Yubico calls this key the "management key"
742      * which we don't do because that term is too similar to "Cert
743      * Management Key" (0x9D).  */
744     { "AUTH-ADM-KEY", 0x0000, 0x0000, 1 },
745     { "SET-ADM-KEY",  0x0000, 0x0000, 2 }
746   };
747   int idx;
748
749   (void)pincb;
750   (void)pincb_arg;
751
752   for (idx=0; (idx < DIM (table)
753                && ascii_strcasecmp (table[idx].name, name)); idx++)
754     ;
755   if (!(idx < DIM (table)))
756     return gpg_error (GPG_ERR_INV_NAME);
757
758   /* Flush the cache before writing it, so that the next get operation
759    * will reread the data from the card and thus get synced in case of
760    * errors (e.g. data truncated by the card). */
761   if (table[idx].tag)
762     flush_cached_data (app, table[idx].flush_tag? table[idx].flush_tag
763                        /* */                    : table[idx].tag);
764
765   switch (table[idx].special)
766     {
767     case 0:
768       err = iso7816_put_data (app->slot, 0, table[idx].tag, value, valuelen);
769       if (err)
770         log_error ("failed to set '%s': %s\n",
771                    table[idx].name, gpg_strerror (err));
772       break;
773
774     case 1:
775       err = auth_adm_key (app, value, valuelen);
776       break;
777
778     case 2:
779       err = set_adm_key (app, value, valuelen);
780       break;
781
782     default:
783       err = gpg_error (GPG_ERR_BUG);
784       break;
785     }
786
787   return err;
788 }
789
790
791 /* Send the KEYPAIRINFO back.  DOBJ describes the data object carrying
792  * the key.  This is used by the LEARN command. */
793 static gpg_error_t
794 send_keypair_and_cert_info (app_t app, ctrl_t ctrl, data_object_t dobj,
795                             int only_keypair)
796 {
797   gpg_error_t err = 0;
798   char *keygripstr = NULL;
799   char idbuf[50];
800
801   err = get_keygrip_by_tag (app, dobj->tag, &keygripstr);
802   if (err)
803     goto leave;
804
805   snprintf (idbuf, sizeof idbuf, "PIV.%s", dobj->keyref);
806   send_status_info (ctrl, "KEYPAIRINFO",
807                     keygripstr, strlen (keygripstr),
808                     idbuf, strlen (idbuf),
809                     NULL, (size_t)0);
810   if (!only_keypair)
811     {
812       /* All certificates are of type 100 (Regular X.509 Cert).  */
813       send_status_info (ctrl, "CERTINFO",
814                         "100", 3,
815                         idbuf, strlen (idbuf),
816                         NULL, (size_t)0);
817     }
818
819  leave:
820   xfree (keygripstr);
821   return err;
822 }
823
824
825 /* Handle the LEARN command.  */
826 static gpg_error_t
827 do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
828 {
829   int i;
830
831   (void)flags;
832
833   do_getattr (app, ctrl, "CHV-USAGE");
834   do_getattr (app, ctrl, "CHV-STATUS");
835
836   for (i=0; data_objects[i].tag; i++)
837     if (data_objects[i].keypair)
838       send_keypair_and_cert_info (app, ctrl, data_objects + i, !!(flags & 1));
839
840
841   return 0;
842 }
843
844
845 /* Core of do-readcert which fetches the certificate based on the
846  * given tag and returns it in a freshly allocated buffer stored at
847  * R_CERT and the length of the certificate stored at R_CERTLEN.  */
848 static gpg_error_t
849 readcert_by_tag (app_t app, unsigned int tag,
850                  unsigned char **r_cert, size_t *r_certlen)
851 {
852   gpg_error_t err;
853   unsigned char *buffer;
854   size_t buflen;
855   void *relptr;
856   const unsigned char *s;
857   size_t n;
858
859   *r_cert = NULL;
860   *r_certlen = 0;
861
862   relptr = get_one_do (app, tag, &buffer, &buflen, NULL);
863   if (!relptr || !buflen)
864    {
865       err = gpg_error (GPG_ERR_NOT_FOUND);
866       goto leave;
867     }
868
869   s = find_tlv (buffer, buflen, 0x71, &n);
870   if (!s || n != 1)
871     {
872       log_error ("piv: no or invalid CertInfo in 0x%X\n", tag);
873       err = gpg_error (GPG_ERR_INV_CERT_OBJ);
874       goto leave;
875     }
876   if (*s == 0x01)
877     {
878       log_error ("piv: gzip compression not yet supported (tag 0x%X)\n", tag);
879       err = gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
880       goto leave;
881     }
882   if (*s)
883     {
884       log_error ("piv: invalid CertInfo 0x%02x in 0x%X\n", *s, tag);
885       err = gpg_error (GPG_ERR_INV_CERT_OBJ);
886       goto leave;
887     }
888
889   /* Note: We don't check that the LRC octet has a length of zero as
890    * required by the specs.  */
891
892   /* Get the cert from the container.  */
893   s = find_tlv (buffer, buflen, 0x70, &n);
894   if (!s || !n)
895     {
896       err = gpg_error (GPG_ERR_NOT_FOUND);
897       goto leave;
898     }
899
900   if (!(*r_cert = xtrymalloc (n)))
901     {
902       err = gpg_error_from_syserror ();
903       goto leave;
904     }
905
906   memcpy (*r_cert, s, n);
907   *r_certlen = n;
908   err = 0;
909
910  leave:
911   xfree (relptr);
912   return err;
913 }
914
915
916 /* Get the keygrip of a key from the certificate stored at TAG.
917  * Caller must free the string at R_KEYGRIPSTR. */
918 static gpg_error_t
919 get_keygrip_by_tag (app_t app, unsigned int tag, char **r_keygripstr)
920 {
921   gpg_error_t err;
922   unsigned char *certbuf = NULL;
923   size_t certbuflen;
924   ksba_cert_t cert = NULL;
925
926   *r_keygripstr = xtrymalloc (40+1);
927   if (!r_keygripstr)
928     {
929       err = gpg_error_from_syserror ();
930       goto leave;
931     }
932
933   /* We need to get the public key from the certificate.  */
934   err = readcert_by_tag (app, tag, &certbuf, &certbuflen);
935   if (err)
936     goto leave;
937
938   /* Compute the keygrip.  */
939   err = ksba_cert_new (&cert);
940   if (err)
941     goto leave;
942   err = ksba_cert_init_from_mem (cert, certbuf, certbuflen);
943   if (err)
944     goto leave;
945   err = app_help_get_keygrip_string (cert, *r_keygripstr);
946
947
948  leave:
949   ksba_cert_release (cert);
950   xfree (certbuf);
951   if (err)
952     {
953       xfree (*r_keygripstr);
954       *r_keygripstr = NULL;
955     }
956   return err;
957 }
958
959
960 /* Locate the data object from the given KEYREF.  The KEYREF may also
961  * be the corresponding OID of the key object.  Returns the data
962  * object or NULL if not found.  */
963 static data_object_t
964 find_dobj_by_keyref (app_t app, const char *keyref)
965 {
966   int i;
967
968   (void)app;
969
970   if (!ascii_strncasecmp (keyref, "PIV.", 4))
971     {
972       keyref += 4;
973       for (i=0; data_objects[i].tag; i++)
974         if (*data_objects[i].keyref
975             && !ascii_strcasecmp (keyref, data_objects[i].keyref))
976           {
977             return data_objects + i;
978           }
979     }
980   else if (!strncmp (keyref, "2.16.840.1.101.3.7.", 19))
981     {
982       keyref += 19;
983       for (i=0; data_objects[i].tag; i++)
984         if (*data_objects[i].keyref
985             && !strcmp (keyref, data_objects[i].oidsuffix))
986           {
987             return data_objects + i;
988           }
989     }
990
991   return NULL;
992 }
993
994
995 /* Read a certificate from the card and returned in a freshly
996  * allocated buffer stored at R_CERT and the length of the certificate
997  * stored at R_CERTLEN.  CERTID is either the OID of the cert's
998  * container or of the form "PIV.<two_hexdigit_keyref>"  */
999 static gpg_error_t
1000 do_readcert (app_t app, const char *certid,
1001              unsigned char **r_cert, size_t *r_certlen)
1002 {
1003   data_object_t dobj;
1004
1005   *r_cert = NULL;
1006   *r_certlen = 0;
1007
1008   dobj = find_dobj_by_keyref (app, certid);
1009   if (!dobj)
1010     return gpg_error (GPG_ERR_INV_ID);
1011
1012   return readcert_by_tag (app, dobj->tag, r_cert, r_certlen);
1013 }
1014
1015
1016 /* Given a data object DOBJ return the corresponding PIV algorithm and
1017  * store it at R_ALGO.  The algorithm is taken from the corresponding
1018  * certificate or from a cache.  */
1019 static gpg_error_t
1020 get_key_algorithm_by_dobj (app_t app, data_object_t dobj, int *r_algo)
1021 {
1022   gpg_error_t err;
1023   unsigned char *certbuf = NULL;
1024   size_t certbuflen;
1025   ksba_cert_t cert = NULL;
1026   ksba_sexp_t k_pkey = NULL;
1027   gcry_sexp_t s_pkey = NULL;
1028   gcry_sexp_t l1 = NULL;
1029   char *algoname = NULL;
1030   int algo;
1031   size_t n;
1032   const char *curve_name;
1033
1034   *r_algo = 0;
1035
1036   err = readcert_by_tag (app, dobj->tag, &certbuf, &certbuflen);
1037   if (err)
1038     goto leave;
1039
1040   err = ksba_cert_new (&cert);
1041   if (err)
1042     goto leave;
1043
1044   err = ksba_cert_init_from_mem (cert, certbuf, certbuflen);
1045   if (err)
1046     {
1047       log_error ("piv: failed to parse the certificate %s: %s\n",
1048                  dobj->keyref, gpg_strerror (err));
1049       goto leave;
1050     }
1051   xfree (certbuf);
1052   certbuf = NULL;
1053
1054   k_pkey = ksba_cert_get_public_key (cert);
1055   if (!k_pkey)
1056     {
1057       err = gpg_error (GPG_ERR_NO_PUBKEY);
1058       goto leave;
1059     }
1060   n = gcry_sexp_canon_len (k_pkey, 0, NULL, NULL);
1061   err = gcry_sexp_new (&s_pkey, k_pkey, n, 0);
1062   if (err)
1063     goto leave;
1064
1065   l1 = gcry_sexp_find_token (s_pkey, "public-key", 0);
1066   if (!l1)
1067     {
1068       err = gpg_error (GPG_ERR_NO_PUBKEY);
1069       goto leave;
1070     }
1071
1072   {
1073     gcry_sexp_t l_tmp = gcry_sexp_cadr (l1);
1074     gcry_sexp_release (l1);
1075     l1 = l_tmp;
1076   }
1077   algoname = gcry_sexp_nth_string (l1, 0);
1078   if (!algoname)
1079     {
1080       err = gpg_error_from_syserror ();
1081       goto leave;
1082     }
1083
1084   algo = gcry_pk_map_name (algoname);
1085   switch (algo)
1086     {
1087     case GCRY_PK_RSA:
1088       algo = PIV_ALGORITHM_RSA;
1089       break;
1090
1091     case GCRY_PK_ECC:
1092     case GCRY_PK_ECDSA:
1093     case GCRY_PK_ECDH:
1094       curve_name = gcry_pk_get_curve (s_pkey, 0, NULL);
1095       if (curve_name && !strcmp (curve_name, "NIST P-256"))
1096         algo = PIV_ALGORITHM_ECC_P256;
1097       else if (curve_name && !strcmp (curve_name, "NIST P-384"))
1098         algo = PIV_ALGORITHM_ECC_P384;
1099       else
1100         {
1101           err = gpg_error (GPG_ERR_UNKNOWN_CURVE);
1102           log_error ("piv: certificate %s, curve '%s': %s\n",
1103                      dobj->keyref, curve_name, gpg_strerror (err));
1104           goto leave;
1105         }
1106       break;
1107
1108     default:
1109       err = gpg_error (GPG_ERR_PUBKEY_ALGO);
1110       log_error ("piv: certificate %s, pubkey algo '%s': %s\n",
1111                  dobj->keyref, algoname, gpg_strerror (err));
1112       goto leave;
1113     }
1114   *r_algo = algo;
1115
1116  leave:
1117   gcry_free (algoname);
1118   gcry_sexp_release (l1);
1119   gcry_sexp_release (s_pkey);
1120   ksba_free (k_pkey);
1121   xfree (certbuf);
1122   return err;
1123 }
1124
1125
1126 /* Return an allocated string to be used as prompt.  Returns NULL on
1127  * malloc error.  */
1128 static char *
1129 make_prompt (app_t app, int remaining, const char *firstline)
1130 {
1131   char *serial, *tmpbuf, *result;
1132
1133   serial = get_dispserialno (app, 0);
1134   if (!serial)
1135     return NULL;
1136
1137   /* TRANSLATORS: Put a \x1f right before a colon.  This can be
1138    * used by pinentry to nicely align the names and values.  Keep
1139    * the %s at the start and end of the string.  */
1140   result = xtryasprintf (_("%s"
1141                            "Number\x1f: %s%%0A"
1142                            "Holder\x1f: %s"
1143                            "%s"),
1144                          "\x1e",
1145                          serial,
1146                          "Unknown", /* Fixme */
1147                          "");
1148   xfree (serial);
1149
1150   /* Append a "remaining attempts" info if needed.  */
1151   if (remaining != -1 && remaining < 3)
1152     {
1153       char *rembuf;
1154
1155       /* TRANSLATORS: This is the number of remaining attempts to
1156        * enter a PIN.  Use %%0A (double-percent,0A) for a linefeed. */
1157       rembuf = xtryasprintf (_("Remaining attempts: %d"), remaining);
1158       if (rembuf)
1159         {
1160           tmpbuf = strconcat (firstline, "%0A%0A", result,
1161                               "%0A%0A", rembuf, NULL);
1162           xfree (rembuf);
1163         }
1164       else
1165         tmpbuf = NULL;
1166       xfree (result);
1167       result = tmpbuf;
1168     }
1169   else
1170     {
1171       tmpbuf = strconcat (firstline, "%0A%0A", result, NULL);
1172       xfree (result);
1173       result = tmpbuf;
1174     }
1175
1176   return result;
1177 }
1178
1179
1180 /* Verify the Application PIN KEYREF.  */
1181 static gpg_error_t
1182 verify_pin (app_t app, int keyref,
1183             gpg_error_t (*pincb)(void*,const char *,char **), void *pincb_arg)
1184 {
1185   gpg_error_t err;
1186   unsigned char apdu[4];
1187   unsigned int sw;
1188   int remaining;
1189   const char *label;
1190   char *prompt;
1191   char *pinvalue = NULL;
1192   unsigned int pinlen;
1193   char pinbuffer[8];
1194   int minlen, maxlen, padding, onlydigits;
1195
1196   /* First check whether a verify is at all needed.  This is done with
1197    * P1 being 0 and no Lc and command data send.  */
1198   apdu[0] = 0x00;
1199   apdu[1] = ISO7816_VERIFY;
1200   apdu[2] = 0x00;
1201   apdu[3] = keyref;
1202   if (!iso7816_apdu_direct (app->slot, apdu, 4, 0, &sw, NULL, NULL))
1203     {
1204       /* No need to verification.  */
1205       return 0;  /* All fine.  */
1206     }
1207   if ((sw & 0xfff0) == 0x63C0)
1208     remaining = (sw & 0x000f); /* PIN has REMAINING tries left.  */
1209   else
1210     remaining = -1;
1211
1212   if (remaining != -1)
1213     log_debug ("piv: PIN %2X has %d attempts left\n", keyref, remaining);
1214
1215   switch (keyref)
1216     {
1217     case 0x00:
1218       minlen = 6;
1219       maxlen = 8;
1220       padding = 1;
1221       onlydigits = 1;
1222       label = _("||Please enter the Global-PIN of your PIV card");
1223       break;
1224     case 0x80:
1225       minlen = 6;
1226       maxlen = 8;
1227       padding = 1;
1228       onlydigits = 1;
1229       label = _("||Please enter the PIN of your PIV card");
1230       break;
1231     case 0x81:
1232       minlen = 8;
1233       maxlen = 8;
1234       padding = 0;
1235       onlydigits = 0;
1236       label = _("||Please enter the Unblocking Key of your PIV card");
1237       break;
1238
1239     case 0x96:
1240     case 0x97:
1241     case 0x98:
1242     case 0x9B:
1243       return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1244
1245     default:
1246       return gpg_error (GPG_ERR_INV_ID);
1247     }
1248   log_assert (sizeof pinbuffer >= maxlen);
1249
1250
1251   /* Ask for the PIN.  */
1252   prompt = make_prompt (app, remaining, label);
1253   err = pincb (pincb_arg, prompt, &pinvalue);
1254   xfree (prompt);
1255   prompt = NULL;
1256   if (err)
1257     {
1258       log_info (_("PIN callback returned error: %s\n"), gpg_strerror (err));
1259       return err;
1260     }
1261
1262   pinlen = pinvalue? strlen (pinvalue) : 0;
1263   if (pinlen < minlen)
1264     {
1265       log_error (_("PIN for is too short; minimum length is %d\n"), minlen);
1266       if (pinvalue)
1267         wipememory (pinvalue, pinlen);
1268       xfree (pinvalue);
1269       return gpg_error (GPG_ERR_BAD_PIN);
1270     }
1271   if (pinlen > maxlen)
1272     {
1273       log_error (_("PIN for is too long; maximum length is %d\n"), maxlen);
1274       wipememory (pinvalue, pinlen);
1275       xfree (pinvalue);
1276       return gpg_error (GPG_ERR_BAD_PIN);
1277     }
1278   if (onlydigits && strspn (pinvalue, "0123456789") != pinlen)
1279     {
1280       log_error (_("PIN has invalid characters; only digits are allowed\n"));
1281       wipememory (pinvalue, pinlen);
1282       xfree (pinvalue);
1283       return gpg_error (GPG_ERR_BAD_PIN);
1284     }
1285   memcpy (pinbuffer, pinvalue, pinlen);
1286   if (padding)
1287     {
1288       memset (pinbuffer + pinlen, 0xff, maxlen - pinlen);
1289       wipememory (pinvalue, pinlen);
1290       pinlen = maxlen;
1291     }
1292   else
1293     wipememory (pinvalue, pinlen);
1294   xfree (pinvalue);
1295
1296   err = iso7816_verify (app->slot, keyref, pinbuffer, pinlen);
1297   wipememory (pinbuffer, pinlen);
1298   if (err)
1299     log_error ("PIN %02X verification failed: %s\n", keyref,gpg_strerror (err));
1300
1301   return err;
1302 }
1303
1304
1305 /* Handle the PASSWD command.  Valid values for PWIDSTR are
1306  * key references related to PINs; in particular:
1307  *   PIV.00 - The Global PIN
1308  *   PIV.80 - The Application PIN
1309  *   PIV.81 - The PIN Unblocking key
1310  * The supported flags are:
1311  *   APP_CHANGE_FLAG_CLEAR   Clear the PIN verification state.
1312  */
1313 static gpg_error_t
1314 do_change_pin (app_t app, ctrl_t ctrl, const char *pwidstr,
1315                unsigned int flags,
1316                gpg_error_t (*pincb)(void*, const char *, char **),
1317                void *pincb_arg)
1318 {
1319   gpg_error_t err;
1320   int keyref;
1321   unsigned char apdu[4];
1322
1323   char *newpin = NULL;
1324   char *oldpin = NULL;
1325   /* size_t newpinlen; */
1326   /* size_t oldpinlen; */
1327   /* const char *newdesc; */
1328   /* int pwid; */
1329   pininfo_t pininfo;
1330
1331   (void)ctrl;
1332   (void)pincb;
1333   (void)pincb_arg;
1334
1335   /* The minimum and maximum lengths are enforced by PIV.  */
1336   memset (&pininfo, 0, sizeof pininfo);
1337   pininfo.minlen = 6;
1338   pininfo.maxlen = 8;
1339
1340   keyref = parse_pin_keyref (pwidstr);
1341   if (keyref == -1)
1342     return gpg_error (GPG_ERR_INV_ID);
1343
1344   if ((flags & ~APP_CHANGE_FLAG_CLEAR))
1345     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1346
1347   /* First see whether the special --clear mode has been requested.  */
1348   if ((flags & APP_CHANGE_FLAG_CLEAR))
1349     {
1350       apdu[0] = 0x00;
1351       apdu[1] = ISO7816_VERIFY;
1352       apdu[2] = 0xff;
1353       apdu[3] = keyref;
1354       err = iso7816_apdu_direct (app->slot, apdu, 4, 0, NULL, NULL, NULL);
1355       goto leave;
1356     }
1357
1358   err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1359
1360  leave:
1361   xfree (oldpin);
1362   xfree (newpin);
1363   return err;
1364 }
1365
1366
1367 /* Perform a simple verify operation for the PIN specified by PWIDSTR.
1368  * For valid values see do_change_pin.  */
1369 static gpg_error_t
1370 do_check_pin (app_t app, const char *pwidstr,
1371               gpg_error_t (*pincb)(void*, const char *, char **),
1372               void *pincb_arg)
1373 {
1374   int keyref;
1375
1376   keyref = parse_pin_keyref (pwidstr);
1377   if (keyref == -1)
1378     return gpg_error (GPG_ERR_INV_ID);
1379
1380   return verify_pin (app, keyref, pincb, pincb_arg);
1381 }
1382
1383
1384 /* Compute a digital signature using the GENERAL AUTHENTICATE command
1385  * on INDATA which is expected to be the raw message digest.  The
1386  * KEYIDSTR has the key reference or its OID (e.g. "PIV.9A").  The
1387  * result is stored at (R_OUTDATA,R_OUTDATALEN); on error (NULL,0) is
1388  * stored there and an error code returned.  For ECDSA the result is
1389  * the simple concatenation of R and S without any DER encoding.  R
1390  * and S are left extended with zeroes to make sure they have an equal
1391  * length.
1392  */
1393 static gpg_error_t
1394 do_auth (app_t app, const char *keyidstr,
1395          gpg_error_t (*pincb)(void*, const char *, char **),
1396          void *pincb_arg,
1397          const void *indata_arg, size_t indatalen,
1398          unsigned char **r_outdata, size_t *r_outdatalen)
1399 {
1400   const unsigned char *indata = indata_arg;
1401   gpg_error_t err;
1402   data_object_t dobj;
1403   unsigned char tmpl[2+2+2+128];
1404   size_t tmpllen;
1405   unsigned char *outdata = NULL;
1406   size_t outdatalen;
1407   const unsigned char *s;
1408   size_t n;
1409   int keyref, algo;
1410
1411   if (!keyidstr || !*keyidstr)
1412     {
1413       err = gpg_error (GPG_ERR_INV_VALUE);
1414       goto leave;
1415     }
1416
1417   /* Fixme: Shall we support the KEYID/FINGERPRINT syntax?  Does it
1418    * make sense for X.509 certs?  */
1419
1420   dobj = find_dobj_by_keyref (app, keyidstr);
1421   if (!dobj)
1422     {
1423       err = gpg_error (GPG_ERR_INV_ID);
1424       goto leave;
1425     }
1426   keyref = xtoi_2 (dobj->keyref);
1427
1428   err = get_key_algorithm_by_dobj (app, dobj, &algo);
1429   if (err)
1430     goto leave;
1431
1432   /* We need to remove the ASN.1 prefix from INDATA.  We use TEMPL as
1433    * a temporary buffer for the OID.  */
1434   if (algo == PIV_ALGORITHM_ECC_P256)
1435     {
1436       tmpllen = sizeof tmpl;
1437       err = gcry_md_get_asnoid (GCRY_MD_SHA256, &tmpl, &tmpllen);
1438       if (err)
1439         {
1440           err = gpg_error (GPG_ERR_INTERNAL);
1441           log_debug ("piv: no OID for hash algo %d\n", GCRY_MD_SHA256);
1442           goto leave;
1443         }
1444       if (indatalen != tmpllen + 32 || memcmp (indata, tmpl, tmpllen))
1445         {
1446           err = GPG_ERR_INV_VALUE;
1447           log_error ("piv: bad formatted input for ECC-P256 auth\n");
1448           goto leave;
1449         }
1450       indata +=tmpllen;
1451       indatalen -= tmpllen;
1452     }
1453   else if (algo == PIV_ALGORITHM_ECC_P384)
1454     {
1455       tmpllen = sizeof tmpl;
1456       err = gcry_md_get_asnoid (GCRY_MD_SHA384, &tmpl, &tmpllen);
1457       if (err)
1458         {
1459           err = gpg_error (GPG_ERR_INTERNAL);
1460           log_debug ("piv: no OID for hash algo %d\n", GCRY_MD_SHA384);
1461           goto leave;
1462         }
1463       if (indatalen != tmpllen + 48 || memcmp (indata, tmpl, tmpllen))
1464         {
1465           err = GPG_ERR_INV_VALUE;
1466           log_error ("piv: bad formatted input for ECC-P384 auth\n");
1467           goto leave;
1468         }
1469       indata += tmpllen;
1470       indatalen -= tmpllen;
1471     }
1472   else if (algo == PIV_ALGORITHM_RSA)
1473     {
1474       err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1475       log_error ("piv: FIXME: implement RSA authentication\n");
1476       goto leave;
1477     }
1478   else
1479     {
1480       err = gpg_error (GPG_ERR_INTERNAL);
1481       log_debug ("piv: unknown PIV  algo %d from helper function\n", algo);
1482       goto leave;
1483     }
1484
1485   /* Because we don't have a dynamic template builder we make sure
1486    * that we can encode all lengths in one octet.  FIXME: Use add_tls
1487    * from app-openpgp as a base for an strconcat like function. */
1488   if (indatalen >= 100)
1489     {
1490       err = gpg_error (GPG_ERR_TOO_LARGE);
1491       goto leave;
1492     }
1493
1494   /* Now verify the Application PIN.  */
1495   err = verify_pin (app, 0x80, pincb, pincb_arg);
1496   if (err)
1497     return err;
1498
1499   /* Build the Dynamic Authentication Template.  */
1500   tmpl[0] = 0x7c;
1501   tmpl[1] = indatalen + 4;
1502   tmpl[2] = 0x82; /* Response. */
1503   tmpl[3] = 0;    /* Must be 0 to get the tag in the answer.  */
1504   tmpl[4] = 0x81; /* Challenge. */
1505   tmpl[5] = indatalen;
1506   memcpy (tmpl+6, indata, indatalen);
1507   tmpllen = indatalen + 6;
1508
1509   /* Note: the -1 requests command chaining.  */
1510   err = iso7816_general_authenticate (app->slot, -1,
1511                                       algo, keyref,
1512                                       tmpl, (int)tmpllen, 0,
1513                                       &outdata, &outdatalen);
1514   if (err)
1515     goto leave;
1516
1517   /* Parse the response.  */
1518   if (outdatalen && *outdata == 0x7c
1519       && (s = find_tlv (outdata, outdatalen, 0x82, &n)))
1520     {
1521       const unsigned char *rval, *sval;
1522       size_t rlen, rlenx, slen, slenx, resultlen;
1523       char *result;
1524       /* The result of an ECDSA signature is
1525        *   SEQUENCE { r INTEGER, s INTEGER }
1526        * We re-pack that by concatenating R and S and making sure that
1527        * both have the same length.  We simplify parsing by using
1528        * find_tlv and not a proper DER parser.  */
1529       s = find_tlv (s, n, 0x30, &n);
1530       if (!s)
1531         goto bad_der;
1532       rval = find_tlv (s, n, 0x02, &rlen);
1533       if (!rval)
1534         goto bad_der;
1535       log_assert (n >= (rval-s)+rlen);
1536       sval = find_tlv (rval+rlen, n-((rval-s)+rlen), 0x02, &slen);
1537       if (!rval)
1538         goto bad_der;
1539       rlenx = slenx = 0;
1540       if (rlen > slen)
1541         slenx = rlen - slen;
1542       else if (slen > rlen)
1543         rlenx = slen - rlen;
1544
1545       resultlen = rlen + rlenx + slen + slenx;
1546       result = xtrycalloc (1, resultlen);
1547       if (!result)
1548         {
1549           err = gpg_error_from_syserror ();
1550           goto leave;
1551         }
1552       memcpy (result + rlenx, rval, rlen);
1553       memcpy (result + rlenx + rlen + slenx, sval, slen);
1554       xfree (outdata);
1555       outdata = result;
1556       outdatalen = resultlen;
1557     }
1558   else
1559     {
1560     bad_der:
1561       err = gpg_error (GPG_ERR_CARD);
1562       log_error ("piv: response does not contain a proper result\n");
1563       goto leave;
1564     }
1565
1566  leave:
1567   if (err)
1568     {
1569       xfree (outdata);
1570       *r_outdata = NULL;
1571       *r_outdatalen = 0;
1572     }
1573   else
1574     {
1575       *r_outdata = outdata;
1576       *r_outdatalen = outdatalen;
1577     }
1578   return err;
1579 }
1580
1581
1582 /* Select the PIV application on the card in SLOT.  This function must
1583  * be used before any other PIV application functions. */
1584 gpg_error_t
1585 app_select_piv (app_t app)
1586 {
1587   static char const aid[] = { 0xA0, 0x00, 0x00, 0x03, 0x08, /* RID=NIST */
1588                               0x00, 0x00, 0x10, 0x00        /* PIX=PIV  */ };
1589   int slot = app->slot;
1590   gpg_error_t err;
1591   unsigned char *apt = NULL;
1592   size_t aptlen;
1593   const unsigned char *s;
1594   size_t n;
1595
1596   /* Note that we select using the AID without the 2 octet version
1597    * number.  This allows for better reporting of future specs.  We
1598    * need to use the use-zero-for-P2-flag.  */
1599   err = iso7816_select_application_ext (slot, aid, sizeof aid, 0x0001,
1600                                         &apt, &aptlen);
1601   if (err)
1602     goto leave;
1603
1604   app->apptype = "PIV";
1605   app->did_chv1 = 0;
1606   app->did_chv2 = 0;
1607   app->did_chv3 = 0;
1608   app->app_local = NULL;
1609
1610   /* Check the Application Property Template.  */
1611   if (opt.verbose)
1612     {
1613       /* We  use a separate log_info to avoid the "DBG:" prefix.  */
1614       log_info ("piv: APT=");
1615       log_printhex (apt, aptlen, "");
1616     }
1617
1618   s = find_tlv (apt, aptlen, 0x4F, &n);
1619   if (!s || n != 6 || memcmp (s, aid+5, 4))
1620     {
1621       /* The PIX does not match.  */
1622       log_error ("piv: missing or invalid DO 0x4F in APT\n");
1623       err = gpg_error (GPG_ERR_CARD);
1624       goto leave;
1625     }
1626   if (s[4] != 1 || s[5] != 0)
1627     {
1628       log_error ("piv: unknown PIV version %u.%u\n", s[4], s[5]);
1629       err = gpg_error (GPG_ERR_CARD);
1630       goto leave;
1631     }
1632   app->card_version = ((s[4] << 8) | s[5]);
1633
1634   s = find_tlv (apt, aptlen, 0x79, &n);
1635   if (!s || n < 7)
1636     {
1637       log_error ("piv: missing or invalid DO 0x79 in APT\n");
1638       err = gpg_error (GPG_ERR_CARD);
1639       goto leave;
1640     }
1641   s = find_tlv (s, n, 0x4F, &n);
1642   if (!s || n != 5 || memcmp (s, aid, 5))
1643     {
1644       /* The RID does not match.  */
1645       log_error ("piv: missing or invalid DO 0x79.4F in APT\n");
1646       err = gpg_error (GPG_ERR_CARD);
1647       goto leave;
1648     }
1649
1650   app->app_local = xtrycalloc (1, sizeof *app->app_local);
1651   if (!app->app_local)
1652     {
1653       err = gpg_error_from_syserror ();
1654       goto leave;
1655     }
1656
1657   if (app->cardtype && !strcmp (app->cardtype, "yubikey"))
1658     app->app_local->flags.yubikey = 1;
1659
1660
1661   /* FIXME: Parse the optional and conditional DOs in the APT.  */
1662
1663   if (opt.verbose)
1664     dump_all_do (slot);
1665
1666   app->fnc.deinit = do_deinit;
1667   app->fnc.learn_status = do_learn_status;
1668   app->fnc.readcert = do_readcert;
1669   app->fnc.readkey = NULL;
1670   app->fnc.getattr = do_getattr;
1671   app->fnc.setattr = do_setattr;
1672   /* app->fnc.writecert = do_writecert; */
1673   /* app->fnc.writekey = do_writekey; */
1674   /* app->fnc.genkey = do_genkey; */
1675   /* app->fnc.sign = do_sign; */
1676   app->fnc.auth = do_auth;
1677   /* app->fnc.decipher = do_decipher; */
1678   app->fnc.change_pin = do_change_pin;
1679   app->fnc.check_pin = do_check_pin;
1680
1681
1682 leave:
1683   xfree (apt);
1684   if (err)
1685     do_deinit (app);
1686   return err;
1687 }