LCOV - code coverage report
Current view: top level - scd - app-p15.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 1656 0.0 %
Date: 2015-11-05 17:10:59 Functions: 0 29 0.0 %

          Line data    Source code
       1             : /* app-p15.c - The pkcs#15 card application.
       2             :  *      Copyright (C) 2005 Free Software Foundation, Inc.
       3             :  *
       4             :  * This file is part of GnuPG.
       5             :  *
       6             :  * GnuPG is free software; you can redistribute it and/or modify
       7             :  * it under the terms of the GNU General Public License as published by
       8             :  * the Free Software Foundation; either version 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 <http://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : /* Information pertaining to the BELPIC developer card samples:
      21             : 
      22             :        Unblock PUK: "222222111111"
      23             :        Reset PIN:   "333333111111")
      24             : 
      25             :    e.g. the APDUs 00:20:00:02:08:2C:33:33:33:11:11:11:FF
      26             :               and 00:24:01:01:08:24:12:34:FF:FF:FF:FF:FF
      27             :    should change the PIN into 1234.
      28             : */
      29             : 
      30             : #include <config.h>
      31             : #include <errno.h>
      32             : #include <stdio.h>
      33             : #include <stdlib.h>
      34             : #include <string.h>
      35             : #include <assert.h>
      36             : #include <time.h>
      37             : 
      38             : #include "scdaemon.h"
      39             : 
      40             : #include "iso7816.h"
      41             : #include "app-common.h"
      42             : #include "tlv.h"
      43             : #include "apdu.h" /* fixme: we should move the card detection to a
      44             :                      separate file */
      45             : 
      46             : /* Types of cards we know and which needs special treatment. */
      47             : typedef enum
      48             :   {
      49             :     CARD_TYPE_UNKNOWN,
      50             :     CARD_TYPE_TCOS,
      51             :     CARD_TYPE_MICARDO,
      52             :     CARD_TYPE_BELPIC   /* Belgian eID card specs. */
      53             :   }
      54             : card_type_t;
      55             : 
      56             : /* A list card types with ATRs noticed with these cards. */
      57             : #define X(a) ((unsigned char const *)(a))
      58             : static struct
      59             : {
      60             :   size_t atrlen;
      61             :   unsigned char const *atr;
      62             :   card_type_t type;
      63             : } card_atr_list[] = {
      64             :   { 19, X("\x3B\xBA\x13\x00\x81\x31\x86\x5D\x00\x64\x05\x0A\x02\x01\x31\x80"
      65             :           "\x90\x00\x8B"),
      66             :     CARD_TYPE_TCOS },  /* SLE44 */
      67             :   { 19, X("\x3B\xBA\x14\x00\x81\x31\x86\x5D\x00\x64\x05\x14\x02\x02\x31\x80"
      68             :           "\x90\x00\x91"),
      69             :     CARD_TYPE_TCOS }, /* SLE66S */
      70             :   { 19, X("\x3B\xBA\x96\x00\x81\x31\x86\x5D\x00\x64\x05\x60\x02\x03\x31\x80"
      71             :           "\x90\x00\x66"),
      72             :     CARD_TYPE_TCOS }, /* SLE66P */
      73             :   { 27, X("\x3B\xFF\x94\x00\xFF\x80\xB1\xFE\x45\x1F\x03\x00\x68\xD2\x76\x00"
      74             :           "\x00\x28\xFF\x05\x1E\x31\x80\x00\x90\x00\x23"),
      75             :     CARD_TYPE_MICARDO }, /* German BMI card */
      76             :   { 19, X("\x3B\x6F\x00\xFF\x00\x68\xD2\x76\x00\x00\x28\xFF\x05\x1E\x31\x80"
      77             :           "\x00\x90\x00"),
      78             :     CARD_TYPE_MICARDO }, /* German BMI card (ATR due to reader problem) */
      79             :   { 26, X("\x3B\xFE\x94\x00\xFF\x80\xB1\xFA\x45\x1F\x03\x45\x73\x74\x45\x49"
      80             :           "\x44\x20\x76\x65\x72\x20\x31\x2E\x30\x43"),
      81             :     CARD_TYPE_MICARDO }, /* EstEID (Estonian Big Brother card) */
      82             : 
      83             :   { 0 }
      84             : };
      85             : #undef X
      86             : 
      87             : 
      88             : /* The AID of PKCS15. */
      89             : static char const pkcs15_aid[] = { 0xA0, 0, 0, 0, 0x63,
      90             :                                    0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35 };
      91             : 
      92             : /* The Belgian eID variant - they didn't understood why a shared AID
      93             :    is useful for a standard.  Oh well. */
      94             : static char const pkcs15be_aid[] = { 0xA0, 0, 0, 0x01, 0x77,
      95             :                                    0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35 };
      96             : 
      97             : 
      98             : /* The PIN types as defined in pkcs#15 v1.1 */
      99             : typedef enum
     100             :   {
     101             :     PIN_TYPE_BCD = 0,
     102             :     PIN_TYPE_ASCII_NUMERIC = 1,
     103             :     PIN_TYPE_UTF8 = 2,
     104             :     PIN_TYPE_HALF_NIBBLE_BCD = 3,
     105             :     PIN_TYPE_ISO9564_1 = 4
     106             :   } pin_type_t;
     107             : 
     108             : 
     109             : /* A bit array with for the key usage flags from the
     110             :    commonKeyAttributes. */
     111             : struct keyusage_flags_s
     112             : {
     113             :     unsigned int encrypt: 1;
     114             :     unsigned int decrypt: 1;
     115             :     unsigned int sign: 1;
     116             :     unsigned int sign_recover: 1;
     117             :     unsigned int wrap: 1;
     118             :     unsigned int unwrap: 1;
     119             :     unsigned int verify: 1;
     120             :     unsigned int verify_recover: 1;
     121             :     unsigned int derive: 1;
     122             :     unsigned int non_repudiation: 1;
     123             : };
     124             : typedef struct keyusage_flags_s keyusage_flags_t;
     125             : 
     126             : 
     127             : 
     128             : /* This is an object to store information about a Certificate
     129             :    Directory File (CDF) in a format suitable for further processing by
     130             :    us. To keep memory management, simple we use a linked list of
     131             :    items; i.e. one such object represents one certificate and the list
     132             :    the entire CDF. */
     133             : struct cdf_object_s
     134             : {
     135             :   /* Link to next item when used in a linked list. */
     136             :   struct cdf_object_s *next;
     137             : 
     138             :   /* Length and allocated buffer with the Id of this object. */
     139             :   size_t objidlen;
     140             :   unsigned char *objid;
     141             : 
     142             :   /* To avoid reading a certificate more than once, we cache it in an
     143             :      allocated memory IMAGE of IMAGELEN. */
     144             :   size_t imagelen;
     145             :   unsigned char *image;
     146             : 
     147             :   /* Set to true if a length and offset is available. */
     148             :   int have_off;
     149             :   /* The offset and length of the object.  They are only valid if
     150             :      HAVE_OFF is true and set to 0 if HAVE_OFF is false. */
     151             :   unsigned long off, len;
     152             : 
     153             :   /* The length of the path as given in the CDF and the path itself.
     154             :      path[0] is the top DF (usually 0x3f00). The path will never be
     155             :      empty. */
     156             :   size_t pathlen;
     157             :   unsigned short path[1];
     158             : };
     159             : typedef struct cdf_object_s *cdf_object_t;
     160             : 
     161             : 
     162             : /* This is an object to store information about a Private Key
     163             :    Directory File (PrKDF) in a format suitable for further processing
     164             :    by us. To keep memory management, simple we use a linked list of
     165             :    items; i.e. one such object represents one certificate and the list
     166             :    the entire PrKDF. */
     167             : struct prkdf_object_s
     168             : {
     169             :   /* Link to next item when used in a linked list. */
     170             :   struct prkdf_object_s *next;
     171             : 
     172             :   /* Length and allocated buffer with the Id of this object. */
     173             :   size_t objidlen;
     174             :   unsigned char *objid;
     175             : 
     176             :   /* Length and allocated buffer with the authId of this object or
     177             :      NULL if no authID is known. */
     178             :   size_t authidlen;
     179             :   unsigned char *authid;
     180             : 
     181             :   /* The key's usage flags. */
     182             :   keyusage_flags_t usageflags;
     183             : 
     184             :   /* The keyReference and a flag telling whether it is valid. */
     185             :   unsigned long key_reference;
     186             :   int key_reference_valid;
     187             : 
     188             :   /* Set to true if a length and offset is available. */
     189             :   int have_off;
     190             :   /* The offset and length of the object.  They are only valid if
     191             :      HAVE_OFF is true and set to 0 if HAVE_OFF is false. */
     192             :   unsigned long off, len;
     193             : 
     194             :   /* The length of the path as given in the PrKDF and the path itself.
     195             :      path[0] is the top DF (usually 0x3f00). */
     196             :   size_t pathlen;
     197             :   unsigned short path[1];
     198             : };
     199             : typedef struct prkdf_object_s *prkdf_object_t;
     200             : 
     201             : 
     202             : /* This is an object to store information about a Authentication
     203             :    Object Directory File (AODF) in a format suitable for further
     204             :    processing by us. To keep memory management, simple we use a linked
     205             :    list of items; i.e. one such object represents one authentication
     206             :    object and the list the entire AOKDF. */
     207             : struct aodf_object_s
     208             : {
     209             :   /* Link to next item when used in a linked list. */
     210             :   struct aodf_object_s *next;
     211             : 
     212             :   /* Length and allocated buffer with the Id of this object. */
     213             :   size_t objidlen;
     214             :   unsigned char *objid;
     215             : 
     216             :   /* Length and allocated buffer with the authId of this object or
     217             :      NULL if no authID is known. */
     218             :   size_t authidlen;
     219             :   unsigned char *authid;
     220             : 
     221             :   /* The PIN Flags. */
     222             :   struct
     223             :   {
     224             :     unsigned int case_sensitive: 1;
     225             :     unsigned int local: 1;
     226             :     unsigned int change_disabled: 1;
     227             :     unsigned int unblock_disabled: 1;
     228             :     unsigned int initialized: 1;
     229             :     unsigned int needs_padding: 1;
     230             :     unsigned int unblocking_pin: 1;
     231             :     unsigned int so_pin: 1;
     232             :     unsigned int disable_allowed: 1;
     233             :     unsigned int integrity_protected: 1;
     234             :     unsigned int confidentiality_protected: 1;
     235             :     unsigned int exchange_ref_data: 1;
     236             :   } pinflags;
     237             : 
     238             :   /* The PIN Type. */
     239             :   pin_type_t pintype;
     240             : 
     241             :   /* The minimum length of a PIN. */
     242             :   unsigned long min_length;
     243             : 
     244             :   /* The stored length of a PIN. */
     245             :   unsigned long stored_length;
     246             : 
     247             :   /* The maximum length of a PIN and a flag telling whether it is valid. */
     248             :   unsigned long max_length;
     249             :   int max_length_valid;
     250             : 
     251             :   /* The pinReference and a flag telling whether it is valid. */
     252             :   unsigned long pin_reference;
     253             :   int pin_reference_valid;
     254             : 
     255             :   /* The padChar and a flag telling whether it is valid. */
     256             :   char pad_char;
     257             :   int pad_char_valid;
     258             : 
     259             : 
     260             :   /* Set to true if a length and offset is available. */
     261             :   int have_off;
     262             :   /* The offset and length of the object.  They are only valid if
     263             :      HAVE_OFF is true and set to 0 if HAVE_OFF is false. */
     264             :   unsigned long off, len;
     265             : 
     266             :   /* The length of the path as given in the Aodf and the path itself.
     267             :      path[0] is the top DF (usually 0x3f00). PATH is optional and thus
     268             :      may be NULL.  Malloced.*/
     269             :   size_t pathlen;
     270             :   unsigned short *path;
     271             : };
     272             : typedef struct aodf_object_s *aodf_object_t;
     273             : 
     274             : 
     275             : /* Context local to this application. */
     276             : struct app_local_s
     277             : {
     278             :   /* The home DF. Note, that we don't yet support a multilevel
     279             :      hierachy.  Thus we assume this is directly below the MF.  */
     280             :   unsigned short home_df;
     281             : 
     282             :   /* The type of the card. */
     283             :   card_type_t card_type;
     284             : 
     285             :   /* Flag indicating whether we may use direct path selection. */
     286             :   int direct_path_selection;
     287             : 
     288             :   /* Structure with the EFIDs of the objects described in the ODF
     289             :      file. */
     290             :   struct
     291             :   {
     292             :     unsigned short private_keys;
     293             :     unsigned short public_keys;
     294             :     unsigned short trusted_public_keys;
     295             :     unsigned short secret_keys;
     296             :     unsigned short certificates;
     297             :     unsigned short trusted_certificates;
     298             :     unsigned short useful_certificates;
     299             :     unsigned short data_objects;
     300             :     unsigned short auth_objects;
     301             :   } odf;
     302             : 
     303             :   /* The PKCS#15 serialnumber from EF(TokeiNFo) or NULL.  Malloced. */
     304             :   unsigned char *serialno;
     305             :   size_t serialnolen;
     306             : 
     307             :   /* Information on all certificates. */
     308             :   cdf_object_t certificate_info;
     309             :   /* Information on all trusted certificates. */
     310             :   cdf_object_t trusted_certificate_info;
     311             :   /* Information on all useful certificates. */
     312             :   cdf_object_t useful_certificate_info;
     313             : 
     314             :   /* Information on all private keys. */
     315             :   prkdf_object_t private_key_info;
     316             : 
     317             :   /* Information on all authentication objects. */
     318             :   aodf_object_t auth_object_info;
     319             : 
     320             : };
     321             : 
     322             : 
     323             : /*** Local prototypes.  ***/
     324             : static gpg_error_t readcert_by_cdf (app_t app, cdf_object_t cdf,
     325             :                                     unsigned char **r_cert, size_t *r_certlen);
     326             : 
     327             : 
     328             : 
     329             : /* Release the CDF object A  */
     330             : static void
     331           0 : release_cdflist (cdf_object_t a)
     332             : {
     333           0 :   while (a)
     334             :     {
     335           0 :       cdf_object_t tmp = a->next;
     336           0 :       xfree (a->image);
     337           0 :       xfree (a->objid);
     338           0 :       xfree (a);
     339           0 :       a = tmp;
     340             :     }
     341           0 : }
     342             : 
     343             : /* Release the PrKDF object A.  */
     344             : static void
     345           0 : release_prkdflist (prkdf_object_t a)
     346             : {
     347           0 :   while (a)
     348             :     {
     349           0 :       prkdf_object_t tmp = a->next;
     350           0 :       xfree (a->objid);
     351           0 :       xfree (a->authid);
     352           0 :       xfree (a);
     353           0 :       a = tmp;
     354             :     }
     355           0 : }
     356             : 
     357             : /* Release just one aodf object. */
     358             : void
     359           0 : release_aodf_object (aodf_object_t a)
     360             : {
     361           0 :   if (a)
     362             :     {
     363           0 :       xfree (a->objid);
     364           0 :       xfree (a->authid);
     365           0 :       xfree (a->path);
     366           0 :       xfree (a);
     367             :     }
     368           0 : }
     369             : 
     370             : /* Release the AODF list A.  */
     371             : static void
     372           0 : release_aodflist (aodf_object_t a)
     373             : {
     374           0 :   while (a)
     375             :     {
     376           0 :       aodf_object_t tmp = a->next;
     377           0 :       release_aodf_object (a);
     378           0 :       a = tmp;
     379             :     }
     380           0 : }
     381             : 
     382             : 
     383             : /* Release all local resources.  */
     384             : static void
     385           0 : do_deinit (app_t app)
     386             : {
     387           0 :   if (app && app->app_local)
     388             :     {
     389           0 :       release_cdflist (app->app_local->certificate_info);
     390           0 :       release_cdflist (app->app_local->trusted_certificate_info);
     391           0 :       release_cdflist (app->app_local->useful_certificate_info);
     392           0 :       release_prkdflist (app->app_local->private_key_info);
     393           0 :       release_aodflist (app->app_local->auth_object_info);
     394           0 :       xfree (app->app_local->serialno);
     395           0 :       xfree (app->app_local);
     396           0 :       app->app_local = NULL;
     397             :     }
     398           0 : }
     399             : 
     400             : 
     401             : 
     402             : /* Do a select and a read for the file with EFID.  EFID_DESC is a
     403             :    desctription of the EF to be used with error messages.  On success
     404             :    BUFFER and BUFLEN contain the entire content of the EF.  The caller
     405             :    must free BUFFER only on success. */
     406             : static gpg_error_t
     407           0 : select_and_read_binary (int slot, unsigned short efid, const char *efid_desc,
     408             :                         unsigned char **buffer, size_t *buflen)
     409             : {
     410             :   gpg_error_t err;
     411             : 
     412           0 :   err = iso7816_select_file (slot, efid, 0, NULL, NULL);
     413           0 :   if (err)
     414             :     {
     415           0 :       log_error ("error selecting %s (0x%04X): %s\n",
     416             :                  efid_desc, efid, gpg_strerror (err));
     417           0 :       return err;
     418             :     }
     419           0 :   err = iso7816_read_binary (slot, 0, 0, buffer, buflen);
     420           0 :   if (err)
     421             :     {
     422           0 :       log_error ("error reading %s (0x%04X): %s\n",
     423             :                  efid_desc, efid, gpg_strerror (err));
     424           0 :       return err;
     425             :     }
     426           0 :   return 0;
     427             : }
     428             : 
     429             : 
     430             : /* This function calls select file to read a file using a complete
     431             :    path which may or may not start at the master file (MF). */
     432             : static gpg_error_t
     433           0 : select_ef_by_path (app_t app, const unsigned short *path, size_t pathlen)
     434             : {
     435             :   gpg_error_t err;
     436             :   int i, j;
     437             : 
     438           0 :   if (!pathlen)
     439           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     440             : 
     441           0 :   if (pathlen && *path != 0x3f00 )
     442           0 :     log_debug ("WARNING: relative path selection not yet implemented\n");
     443             : 
     444           0 :   if (app->app_local->direct_path_selection)
     445             :     {
     446           0 :       err = iso7816_select_path (app->slot, path+1, pathlen-1, NULL, NULL);
     447           0 :       if (err)
     448             :         {
     449           0 :           log_error ("error selecting path ");
     450           0 :           for (j=0; j < pathlen; j++)
     451           0 :             log_printf ("%04hX", path[j]);
     452           0 :           log_printf (": %s\n", gpg_strerror (err));
     453           0 :           return err;
     454             :         }
     455             :     }
     456             :   else
     457             :     {
     458             :       /* FIXME: Need code to remember the last PATH so that we can decide
     459             :          what select commands to send in case the path does not start off
     460             :          with 3F00.  We might also want to use direct path selection if
     461             :          supported by the card. */
     462           0 :       for (i=0; i < pathlen; i++)
     463             :         {
     464           0 :           err = iso7816_select_file (app->slot, path[i],
     465           0 :                                      !(i+1 == pathlen), NULL, NULL);
     466           0 :           if (err)
     467             :             {
     468           0 :               log_error ("error selecting part %d from path ", i);
     469           0 :               for (j=0; j < pathlen; j++)
     470           0 :                 log_printf ("%04hX", path[j]);
     471           0 :               log_printf (": %s\n", gpg_strerror (err));
     472           0 :               return err;
     473             :             }
     474             :         }
     475             :     }
     476           0 :   return 0;
     477             : }
     478             : 
     479             : /* Parse a cert Id string (or a key Id string) and return the binary
     480             :    object Id string in a newly allocated buffer stored at R_OBJID and
     481             :    R_OBJIDLEN.  On Error NULL will be stored there and an error code
     482             :    returned. On success caller needs to free the buffer at R_OBJID. */
     483             : static gpg_error_t
     484           0 : parse_certid (app_t app, const char *certid,
     485             :               unsigned char **r_objid, size_t *r_objidlen)
     486             : {
     487             :   char tmpbuf[10];
     488             :   const char *s;
     489             :   size_t objidlen;
     490             :   unsigned char *objid;
     491             :   int i;
     492             : 
     493           0 :   *r_objid = NULL;
     494           0 :   *r_objidlen = 0;
     495             : 
     496           0 :   if (app->app_local->home_df)
     497           0 :     snprintf (tmpbuf, sizeof tmpbuf,
     498           0 :               "P15-%04X.", (unsigned int)(app->app_local->home_df & 0xffff));
     499             :   else
     500           0 :     strcpy (tmpbuf, "P15.");
     501           0 :   if (strncmp (certid, tmpbuf, strlen (tmpbuf)) )
     502             :     {
     503           0 :       if (!strncmp (certid, "P15.", 4)
     504           0 :           || (!strncmp (certid, "P15-", 4)
     505           0 :               && hexdigitp (certid+4)
     506           0 :               && hexdigitp (certid+5)
     507           0 :               && hexdigitp (certid+6)
     508           0 :               && hexdigitp (certid+7)
     509           0 :               && certid[8] == '.'))
     510           0 :         return gpg_error (GPG_ERR_NOT_FOUND);
     511           0 :       return gpg_error (GPG_ERR_INV_ID);
     512             :     }
     513           0 :   certid += strlen (tmpbuf);
     514             : 
     515           0 :   for (s=certid, objidlen=0; hexdigitp (s); s++, objidlen++)
     516             :     ;
     517           0 :   if (*s || !objidlen || (objidlen%2))
     518           0 :     return gpg_error (GPG_ERR_INV_ID);
     519           0 :   objidlen /= 2;
     520           0 :   objid = xtrymalloc (objidlen);
     521           0 :   if (!objid)
     522           0 :     return gpg_error_from_syserror ();
     523           0 :   for (s=certid, i=0; i < objidlen; i++, s+=2)
     524           0 :     objid[i] = xtoi_2 (s);
     525           0 :   *r_objid = objid;
     526           0 :   *r_objidlen = objidlen;
     527           0 :   return 0;
     528             : }
     529             : 
     530             : 
     531             : /* Find a certificate object by the certificate ID CERTID and store a
     532             :    pointer to it at R_CDF. */
     533             : static gpg_error_t
     534           0 : cdf_object_from_certid (app_t app, const char *certid, cdf_object_t *r_cdf)
     535             : {
     536             :   gpg_error_t err;
     537             :   size_t objidlen;
     538             :   unsigned char *objid;
     539             :   cdf_object_t cdf;
     540             : 
     541           0 :   err = parse_certid (app, certid, &objid, &objidlen);
     542           0 :   if (err)
     543           0 :     return err;
     544             : 
     545           0 :   for (cdf = app->app_local->certificate_info; cdf; cdf = cdf->next)
     546           0 :     if (cdf->objidlen == objidlen && !memcmp (cdf->objid, objid, objidlen))
     547           0 :       break;
     548           0 :   if (!cdf)
     549           0 :     for (cdf = app->app_local->trusted_certificate_info; cdf; cdf = cdf->next)
     550           0 :       if (cdf->objidlen == objidlen && !memcmp (cdf->objid, objid, objidlen))
     551           0 :         break;
     552           0 :   if (!cdf)
     553           0 :     for (cdf = app->app_local->useful_certificate_info; cdf; cdf = cdf->next)
     554           0 :       if (cdf->objidlen == objidlen && !memcmp (cdf->objid, objid, objidlen))
     555           0 :         break;
     556           0 :   xfree (objid);
     557           0 :   if (!cdf)
     558           0 :     return gpg_error (GPG_ERR_NOT_FOUND);
     559           0 :   *r_cdf = cdf;
     560           0 :   return 0;
     561             : }
     562             : 
     563             : 
     564             : /* Find a private key object by the key Id string KEYIDSTR and store a
     565             :    pointer to it at R_PRKDF. */
     566             : static gpg_error_t
     567           0 : prkdf_object_from_keyidstr (app_t app, const char *keyidstr,
     568             :                             prkdf_object_t *r_prkdf)
     569             : {
     570             :   gpg_error_t err;
     571             :   size_t objidlen;
     572             :   unsigned char *objid;
     573             :   prkdf_object_t prkdf;
     574             : 
     575           0 :   err = parse_certid (app, keyidstr, &objid, &objidlen);
     576           0 :   if (err)
     577           0 :     return err;
     578             : 
     579           0 :   for (prkdf = app->app_local->private_key_info; prkdf; prkdf = prkdf->next)
     580           0 :     if (prkdf->objidlen == objidlen && !memcmp (prkdf->objid, objid, objidlen))
     581           0 :       break;
     582           0 :   xfree (objid);
     583           0 :   if (!prkdf)
     584           0 :     return gpg_error (GPG_ERR_NOT_FOUND);
     585           0 :   *r_prkdf = prkdf;
     586           0 :   return 0;
     587             : }
     588             : 
     589             : 
     590             : 
     591             : 
     592             : /* Read and parse the Object Directory File and store away the
     593             :    pointers. ODF_FID shall contain the FID of the ODF.
     594             : 
     595             :    Example of such a file:
     596             : 
     597             :    A0 06 30 04 04 02 60 34  = Private Keys
     598             :    A4 06 30 04 04 02 60 35  = Certificates
     599             :    A5 06 30 04 04 02 60 36  = TrustedCertificates
     600             :    A7 06 30 04 04 02 60 37  = DataObjects
     601             :    A8 06 30 04 04 02 60 38  = AuthObjects
     602             : 
     603             :    These are all PathOrObjects using the path CHOICE element.  The
     604             :    paths are octet strings of length 2.  Using this Path CHOICE
     605             :    element is recommended, so we only implement that for now.
     606             : */
     607             : static gpg_error_t
     608           0 : read_ef_odf (app_t app, unsigned short odf_fid)
     609             : {
     610             :   gpg_error_t err;
     611             :   unsigned char *buffer, *p;
     612             :   size_t buflen;
     613             :   unsigned short value;
     614             :   size_t offset;
     615             : 
     616           0 :   err = select_and_read_binary (app->slot, odf_fid, "ODF", &buffer, &buflen);
     617           0 :   if (err)
     618           0 :     return err;
     619             : 
     620           0 :   if (buflen < 8)
     621             :     {
     622           0 :       log_error ("error: ODF too short\n");
     623           0 :       xfree (buffer);
     624           0 :       return gpg_error (GPG_ERR_INV_OBJ);
     625             :     }
     626           0 :   p = buffer;
     627           0 :   while (buflen && *p && *p != 0xff)
     628             :     {
     629           0 :       if ( buflen >= 8
     630           0 :            && (p[0] & 0xf0) == 0xA0
     631           0 :            && !memcmp (p+1, "\x06\x30\x04\x04\x02", 5) )
     632             :         {
     633           0 :           offset = 6;
     634             :         }
     635           0 :       else if ( buflen >= 12
     636           0 :                 && (p[0] & 0xf0) == 0xA0
     637           0 :                 && !memcmp (p+1, "\x0a\x30\x08\x04\x06\x3F\x00", 7)
     638           0 :                 && app->app_local->home_df == ((p[8]<<8)|p[9]) )
     639             :         {
     640             :           /* We only allow a full path if all files are at the same
     641             :              level and below the home directory.  The extend this we
     642             :              would need to make use of new data type capable of
     643             :              keeping a full path. */
     644           0 :           offset = 10;
     645             :         }
     646             :       else
     647             :         {
     648           0 :           log_error ("ODF format is not supported by us\n");
     649           0 :           xfree (buffer);
     650           0 :           return gpg_error (GPG_ERR_INV_OBJ);
     651             :         }
     652           0 :       switch ((p[0] & 0x0f))
     653             :         {
     654           0 :         case 0: value = app->app_local->odf.private_keys; break;
     655           0 :         case 1: value = app->app_local->odf.public_keys; break;
     656           0 :         case 2: value = app->app_local->odf.trusted_public_keys; break;
     657           0 :         case 3: value = app->app_local->odf.secret_keys; break;
     658           0 :         case 4: value = app->app_local->odf.certificates; break;
     659           0 :         case 5: value = app->app_local->odf.trusted_certificates; break;
     660           0 :         case 6: value = app->app_local->odf.useful_certificates; break;
     661           0 :         case 7: value = app->app_local->odf.data_objects; break;
     662           0 :         case 8: value = app->app_local->odf.auth_objects; break;
     663           0 :         default: value = 0; break;
     664             :         }
     665           0 :       if (value)
     666             :         {
     667           0 :           log_error ("duplicate object type %d in ODF ignored\n",(p[0]&0x0f));
     668           0 :           continue;
     669             :         }
     670           0 :       value = ((p[offset] << 8) | p[offset+1]);
     671           0 :       switch ((p[0] & 0x0f))
     672             :         {
     673           0 :         case 0: app->app_local->odf.private_keys = value; break;
     674           0 :         case 1: app->app_local->odf.public_keys = value; break;
     675           0 :         case 2: app->app_local->odf.trusted_public_keys = value; break;
     676           0 :         case 3: app->app_local->odf.secret_keys = value; break;
     677           0 :         case 4: app->app_local->odf.certificates = value; break;
     678           0 :         case 5: app->app_local->odf.trusted_certificates = value; break;
     679           0 :         case 6: app->app_local->odf.useful_certificates = value; break;
     680           0 :         case 7: app->app_local->odf.data_objects = value; break;
     681           0 :         case 8: app->app_local->odf.auth_objects = value; break;
     682             :         default:
     683           0 :           log_error ("unknown object type %d in ODF ignored\n", (p[0]&0x0f));
     684             :         }
     685           0 :       offset += 2;
     686             : 
     687           0 :       if (buflen < offset)
     688           0 :         break;
     689           0 :       p += offset;
     690           0 :       buflen -= offset;
     691             :     }
     692             : 
     693           0 :   if (buflen)
     694           0 :     log_info ("warning: %u bytes of garbage detected at end of ODF\n",
     695             :               (unsigned int)buflen);
     696             : 
     697           0 :   xfree (buffer);
     698           0 :   return 0;
     699             : }
     700             : 
     701             : 
     702             : /* Parse the BIT STRING with the keyUsageFlags from the
     703             :    CommonKeyAttributes. */
     704             : static gpg_error_t
     705           0 : parse_keyusage_flags (const unsigned char *der, size_t derlen,
     706             :                       keyusage_flags_t *usageflags)
     707             : {
     708             :   unsigned int bits, mask;
     709             :   int i, unused, full;
     710             : 
     711           0 :   memset (usageflags, 0, sizeof *usageflags);
     712           0 :   if (!derlen)
     713           0 :     return gpg_error (GPG_ERR_INV_OBJ);
     714             : 
     715           0 :   unused = *der++; derlen--;
     716           0 :   if ((!derlen && unused) || unused/8 > derlen)
     717           0 :     return gpg_error (GPG_ERR_ENCODING_PROBLEM);
     718           0 :   full = derlen - (unused+7)/8;
     719           0 :   unused %= 8;
     720           0 :   mask = 0;
     721           0 :   for (i=1; unused; i <<= 1, unused--)
     722           0 :     mask |= i;
     723             : 
     724             :   /* First octet */
     725           0 :   if (derlen)
     726             :     {
     727           0 :       bits = *der++; derlen--;
     728           0 :       if (full)
     729           0 :         full--;
     730             :       else
     731             :         {
     732           0 :           bits &= ~mask;
     733           0 :           mask = 0;
     734             :         }
     735             :     }
     736             :   else
     737           0 :     bits = 0;
     738           0 :   if ((bits & 0x80)) usageflags->encrypt = 1;
     739           0 :   if ((bits & 0x40)) usageflags->decrypt = 1;
     740           0 :   if ((bits & 0x20)) usageflags->sign = 1;
     741           0 :   if ((bits & 0x10)) usageflags->sign_recover = 1;
     742           0 :   if ((bits & 0x08)) usageflags->wrap = 1;
     743           0 :   if ((bits & 0x04)) usageflags->unwrap = 1;
     744           0 :   if ((bits & 0x02)) usageflags->verify = 1;
     745           0 :   if ((bits & 0x01)) usageflags->verify_recover = 1;
     746             : 
     747             :   /* Second octet. */
     748           0 :   if (derlen)
     749             :     {
     750           0 :       bits = *der++; derlen--;
     751           0 :       if (full)
     752           0 :         full--;
     753             :       else
     754             :         {
     755           0 :           bits &= ~mask;
     756           0 :           mask = 0;
     757             :         }
     758             :     }
     759             :   else
     760           0 :     bits = 0;
     761           0 :   if ((bits & 0x80)) usageflags->derive = 1;
     762           0 :   if ((bits & 0x40)) usageflags->non_repudiation = 1;
     763             : 
     764           0 :   return 0;
     765             : }
     766             : 
     767             : /* Read and  parse the Private Key Directory Files. */
     768             : /*
     769             :   6034 (privatekeys)
     770             : 
     771             : 30 33 30 11 0C 08 53 4B 2E  43 48 2E 44 53 03 02   030...SK.CH.DS..
     772             : 06 80 04 01 07 30 0C 04 01  01 03 03 06 00 40 02   .....0........@.
     773             : 02 00 50 A1 10 30 0E 30 08  04 06 3F 00 40 16 00   ..P..0.0...?.@..
     774             : 50 02 02 04 00 30 33 30 11  0C 08 53 4B 2E 43 48   P....030...SK.CH
     775             : 2E 4B 45 03 02 06 80 04 01  0A 30 0C 04 01 0C 03   .KE.......0.....
     776             : 03 06 44 00 02 02 00 52 A1  10 30 0E 30 08 04 06   ..D....R..0.0...
     777             : 3F 00 40 16 00 52 02 02 04  00 30 34 30 12 0C 09   ?.@..R....040...
     778             : 53 4B 2E 43 48 2E 41 55 54  03 02 06 80 04 01 0A   SK.CH.AUT.......
     779             : 30 0C 04 01 0D 03 03 06 20  00 02 02 00 51 A1 10   0....... ....Q..
     780             : 30 0E 30 08 04 06 3F 00 40  16 00 51 02 02 04 00   0.0...?.@..Q....
     781             : 30 37 30 15 0C 0C 53 4B 2E  43 48 2E 44 53 2D 53   070...SK.CH.DS-S
     782             : 50 58 03 02 06 80 04 01 0A  30 0C 04 01 02 03 03   PX.......0......
     783             : 06 20 00 02 02 00 53 A1 10  30 0E 30 08 04 06 3F   . ....S..0.0...?
     784             : 00 40 16 00 53 02 02 04 00  00 00 00 00 00 00 00   .@..S...........
     785             : 00 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00   ................
     786             : 00 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00   ................
     787             : 
     788             :    0 30   51: SEQUENCE {
     789             :    2 30   17:   SEQUENCE { -- commonObjectAttributes
     790             :    4 0C    8:     UTF8String 'SK.CH.DS'
     791             :   14 03    2:     BIT STRING 6 unused bits
     792             :             :       '01'B (bit 0)
     793             :   18 04    1:     OCTET STRING --authid
     794             :             :       07
     795             :             :     }
     796             :   21 30   12:   SEQUENCE { -- commonKeyAttributes
     797             :   23 04    1:     OCTET STRING
     798             :             :       01
     799             :   26 03    3:     BIT STRING 6 unused bits
     800             :             :       '1000000000'B (bit 9)
     801             :   31 02    2:     INTEGER 80  -- keyReference (optional)
     802             :             :     }
     803             :   35 A1   16:   [1] {  -- keyAttributes
     804             :   37 30   14:     SEQUENCE { -- privateRSAKeyAttributes
     805             :   39 30    8:       SEQUENCE { -- objectValue
     806             :   41 04    6:         OCTET STRING --path
     807             :             :           3F 00 40 16 00 50
     808             :             :         }
     809             :   49 02    2:       INTEGER 1024 -- modulus
     810             :             :       }
     811             :             :     }
     812             :             :   }
     813             : 
     814             : 
     815             : */
     816             : static gpg_error_t
     817           0 : read_ef_prkdf (app_t app, unsigned short fid, prkdf_object_t *result)
     818             : {
     819             :   gpg_error_t err;
     820           0 :   unsigned char *buffer = NULL;
     821             :   size_t buflen;
     822             :   const unsigned char *p;
     823             :   size_t n, objlen, hdrlen;
     824             :   int class, tag, constructed, ndef;
     825           0 :   prkdf_object_t prkdflist = NULL;
     826             :   int i;
     827             : 
     828           0 :   if (!fid)
     829           0 :     return gpg_error (GPG_ERR_NO_DATA); /* No private keys. */
     830             : 
     831           0 :   err = select_and_read_binary (app->slot, fid, "PrKDF", &buffer, &buflen);
     832           0 :   if (err)
     833           0 :     return err;
     834             : 
     835           0 :   p = buffer;
     836           0 :   n = buflen;
     837             : 
     838             :   /* FIXME: This shares a LOT of code with read_ef_cdf! */
     839             : 
     840             :   /* Loop over the records.  We stop as soon as we detect a new record
     841             :      starting with 0x00 or 0xff as these values are commonly used to
     842             :      pad data blocks and are no valid ASN.1 encoding. */
     843           0 :   while (n && *p && *p != 0xff)
     844             :     {
     845             :       const unsigned char *pp;
     846             :       size_t nn;
     847             :       int where;
     848           0 :       const char *errstr = NULL;
     849           0 :       prkdf_object_t prkdf = NULL;
     850             :       unsigned long ul;
     851             :       const unsigned char *objid;
     852             :       size_t objidlen;
     853           0 :       const unsigned char *authid = NULL;
     854           0 :       size_t authidlen = 0;
     855             :       keyusage_flags_t usageflags;
     856           0 :       unsigned long key_reference = 0;
     857           0 :       int key_reference_valid = 0;
     858             :       const char *s;
     859             : 
     860           0 :       err = parse_ber_header (&p, &n, &class, &tag, &constructed,
     861             :                               &ndef, &objlen, &hdrlen);
     862           0 :       if (!err && (objlen > n || tag != TAG_SEQUENCE))
     863           0 :         err = gpg_error (GPG_ERR_INV_OBJ);
     864           0 :       if (err)
     865             :         {
     866           0 :           log_error ("error parsing PrKDF record: %s\n", gpg_strerror (err));
     867           0 :           goto leave;
     868             :         }
     869           0 :       pp = p;
     870           0 :       nn = objlen;
     871           0 :       p += objlen;
     872           0 :       n -= objlen;
     873             : 
     874             :       /* Parse the commonObjectAttributes.  */
     875           0 :       where = __LINE__;
     876           0 :       err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
     877             :                               &ndef, &objlen, &hdrlen);
     878           0 :       if (!err && (objlen > nn || tag != TAG_SEQUENCE))
     879           0 :         err = gpg_error (GPG_ERR_INV_OBJ);
     880           0 :       if (err)
     881           0 :         goto parse_error;
     882             :       {
     883           0 :         const unsigned char *ppp = pp;
     884           0 :         size_t nnn = objlen;
     885             : 
     886           0 :         pp += objlen;
     887           0 :         nn -= objlen;
     888             : 
     889             :         /* Search the optional AuthId.  We need to skip the optional
     890             :            Label (UTF8STRING) and the optional CommonObjectFlags
     891             :            (BITSTRING). */
     892           0 :         where = __LINE__;
     893           0 :         err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
     894             :                                 &ndef, &objlen, &hdrlen);
     895           0 :         if (!err && (objlen > nnn || class != CLASS_UNIVERSAL))
     896           0 :           err = gpg_error (GPG_ERR_INV_OBJ);
     897           0 :         if (gpg_err_code (err) == GPG_ERR_EOF)
     898           0 :           goto no_authid;
     899           0 :         if (err)
     900           0 :           goto parse_error;
     901           0 :         if (tag == TAG_UTF8_STRING)
     902             :           {
     903           0 :             ppp += objlen; /* Skip the Label. */
     904           0 :             nnn -= objlen;
     905             : 
     906           0 :             where = __LINE__;
     907           0 :             err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
     908             :                                     &ndef, &objlen, &hdrlen);
     909           0 :             if (!err && (objlen > nnn || class != CLASS_UNIVERSAL))
     910           0 :               err = gpg_error (GPG_ERR_INV_OBJ);
     911           0 :             if (gpg_err_code (err) == GPG_ERR_EOF)
     912           0 :               goto no_authid;
     913           0 :             if (err)
     914           0 :               goto parse_error;
     915             :           }
     916           0 :         if (tag == TAG_BIT_STRING)
     917             :           {
     918           0 :             ppp += objlen; /* Skip the CommonObjectFlags.  */
     919           0 :             nnn -= objlen;
     920             : 
     921           0 :             where = __LINE__;
     922           0 :             err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
     923             :                                     &ndef, &objlen, &hdrlen);
     924           0 :             if (!err && (objlen > nnn || class != CLASS_UNIVERSAL))
     925           0 :               err = gpg_error (GPG_ERR_INV_OBJ);
     926           0 :             if (gpg_err_code (err) == GPG_ERR_EOF)
     927           0 :               goto no_authid;
     928           0 :             if (err)
     929           0 :               goto parse_error;
     930             :           }
     931           0 :         if (tag == TAG_OCTET_STRING && objlen)
     932             :           {
     933           0 :             authid = ppp;
     934           0 :             authidlen = objlen;
     935             :           }
     936             :       no_authid:
     937             :         ;
     938             :       }
     939             : 
     940             :       /* Parse the commonKeyAttributes.  */
     941           0 :       where = __LINE__;
     942           0 :       err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
     943             :                               &ndef, &objlen, &hdrlen);
     944           0 :       if (!err && (objlen > nn || tag != TAG_SEQUENCE))
     945           0 :         err = gpg_error (GPG_ERR_INV_OBJ);
     946           0 :       if (err)
     947           0 :         goto parse_error;
     948             :       {
     949           0 :         const unsigned char *ppp = pp;
     950           0 :         size_t nnn = objlen;
     951             : 
     952           0 :         pp += objlen;
     953           0 :         nn -= objlen;
     954             : 
     955             :         /* Get the Id. */
     956           0 :         where = __LINE__;
     957           0 :         err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
     958             :                               &ndef, &objlen, &hdrlen);
     959           0 :         if (!err && (objlen > nnn
     960           0 :                      || class != CLASS_UNIVERSAL || tag != TAG_OCTET_STRING))
     961           0 :           err = gpg_error (GPG_ERR_INV_OBJ);
     962           0 :         if (err)
     963           0 :           goto parse_error;
     964           0 :         objid = ppp;
     965           0 :         objidlen = objlen;
     966           0 :         ppp += objlen;
     967           0 :         nnn -= objlen;
     968             : 
     969             :         /* Get the KeyUsageFlags. */
     970           0 :         where = __LINE__;
     971           0 :         err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
     972             :                               &ndef, &objlen, &hdrlen);
     973           0 :         if (!err && (objlen > nnn
     974           0 :                      || class != CLASS_UNIVERSAL || tag != TAG_BIT_STRING))
     975           0 :           err = gpg_error (GPG_ERR_INV_OBJ);
     976           0 :         if (err)
     977           0 :           goto parse_error;
     978           0 :         err = parse_keyusage_flags (ppp, objlen, &usageflags);
     979           0 :         if (err)
     980           0 :           goto parse_error;
     981           0 :         ppp += objlen;
     982           0 :         nnn -= objlen;
     983             : 
     984             :         /* Find the keyReference */
     985           0 :         where = __LINE__;
     986           0 :         err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
     987             :                               &ndef, &objlen, &hdrlen);
     988           0 :         if (gpg_err_code (err) == GPG_ERR_EOF)
     989           0 :           goto leave_cki;
     990           0 :         if (!err && objlen > nnn)
     991           0 :           err = gpg_error (GPG_ERR_INV_OBJ);
     992           0 :         if (err)
     993           0 :           goto parse_error;
     994           0 :         if (class == CLASS_UNIVERSAL && tag == TAG_BOOLEAN)
     995             :           {
     996             :             /* Skip the native element. */
     997           0 :             ppp += objlen;
     998           0 :             nnn -= objlen;
     999             : 
    1000           0 :             err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
    1001             :                                     &ndef, &objlen, &hdrlen);
    1002           0 :             if (gpg_err_code (err) == GPG_ERR_EOF)
    1003           0 :               goto leave_cki;
    1004           0 :             if (!err && objlen > nnn)
    1005           0 :               err = gpg_error (GPG_ERR_INV_OBJ);
    1006           0 :             if (err)
    1007           0 :               goto parse_error;
    1008             :           }
    1009           0 :         if (class == CLASS_UNIVERSAL && tag == TAG_BIT_STRING)
    1010             :           {
    1011             :             /* Skip the accessFlags. */
    1012           0 :             ppp += objlen;
    1013           0 :             nnn -= objlen;
    1014             : 
    1015           0 :             err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
    1016             :                                     &ndef, &objlen, &hdrlen);
    1017           0 :             if (gpg_err_code (err) == GPG_ERR_EOF)
    1018           0 :               goto leave_cki;
    1019           0 :             if (!err && objlen > nnn)
    1020           0 :               err = gpg_error (GPG_ERR_INV_OBJ);
    1021           0 :             if (err)
    1022           0 :               goto parse_error;
    1023             :           }
    1024           0 :         if (class == CLASS_UNIVERSAL && tag == TAG_INTEGER)
    1025             :           {
    1026             :             /* Yep, this is the keyReference.  */
    1027           0 :             for (ul=0; objlen; objlen--)
    1028             :               {
    1029           0 :                 ul <<= 8;
    1030           0 :                 ul |= (*ppp++) & 0xff;
    1031           0 :                 nnn--;
    1032             :             }
    1033           0 :             key_reference = ul;
    1034           0 :             key_reference_valid = 1;
    1035             :           }
    1036             : 
    1037             :       leave_cki:
    1038             :         ;
    1039             :       }
    1040             : 
    1041             : 
    1042             :       /* Skip subClassAttributes.  */
    1043           0 :       where = __LINE__;
    1044           0 :       err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
    1045             :                               &ndef, &objlen, &hdrlen);
    1046           0 :       if (!err && objlen > nn)
    1047           0 :         err = gpg_error (GPG_ERR_INV_OBJ);
    1048           0 :       if (err)
    1049           0 :         goto parse_error;
    1050           0 :       if (class == CLASS_CONTEXT && tag == 0)
    1051             :         {
    1052           0 :           pp += objlen;
    1053           0 :           nn -= objlen;
    1054             : 
    1055           0 :           where = __LINE__;
    1056           0 :           err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
    1057             :                                   &ndef, &objlen, &hdrlen);
    1058             :         }
    1059             :       /* Parse the keyAttributes.  */
    1060           0 :       if (!err && (objlen > nn || class != CLASS_CONTEXT || tag != 1))
    1061           0 :         err = gpg_error (GPG_ERR_INV_OBJ);
    1062           0 :       if (err)
    1063           0 :         goto parse_error;
    1064           0 :       nn = objlen;
    1065             : 
    1066           0 :       where = __LINE__;
    1067           0 :       err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
    1068             :                               &ndef, &objlen, &hdrlen);
    1069           0 :       if (!err && objlen > nn)
    1070           0 :         err = gpg_error (GPG_ERR_INV_OBJ);
    1071           0 :       if (err)
    1072           0 :         goto parse_error;
    1073           0 :       if (class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE)
    1074             :         ; /* RSA */
    1075           0 :       else if (class == CLASS_CONTEXT)
    1076             :         {
    1077           0 :           switch (tag)
    1078             :             {
    1079           0 :             case 0: errstr = "EC key objects are not supported"; break;
    1080           0 :             case 1: errstr = "DH key objects are not supported"; break;
    1081           0 :             case 2: errstr = "DSA key objects are not supported"; break;
    1082           0 :             case 3: errstr = "KEA key objects are not supported"; break;
    1083           0 :             default: errstr = "unknown privateKeyObject"; break;
    1084             :             }
    1085           0 :           goto parse_error;
    1086             :         }
    1087             :       else
    1088             :         {
    1089           0 :           err = gpg_error (GPG_ERR_INV_OBJ);
    1090           0 :           goto parse_error;
    1091             :         }
    1092             : 
    1093           0 :       nn = objlen;
    1094             : 
    1095             :       /* Check that the reference is a Path object.  */
    1096           0 :       where = __LINE__;
    1097           0 :       err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
    1098             :                               &ndef, &objlen, &hdrlen);
    1099           0 :       if (!err && objlen > nn)
    1100           0 :         err = gpg_error (GPG_ERR_INV_OBJ);
    1101           0 :       if (err)
    1102           0 :         goto parse_error;
    1103           0 :       if (class != CLASS_UNIVERSAL || tag != TAG_SEQUENCE)
    1104             :         {
    1105           0 :           errstr = "unsupported reference type";
    1106           0 :           goto parse_error;
    1107             :         }
    1108           0 :       nn = objlen;
    1109             : 
    1110             :       /* Parse the Path object. */
    1111           0 :       where = __LINE__;
    1112           0 :       err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
    1113             :                               &ndef, &objlen, &hdrlen);
    1114           0 :       if (!err && objlen > nn)
    1115           0 :         err = gpg_error (GPG_ERR_INV_OBJ);
    1116           0 :       if (err)
    1117           0 :         goto parse_error;
    1118             : 
    1119             :       /* Make sure that the next element is a non zero path and of
    1120             :          even length (FID are two bytes each). */
    1121           0 :       if (class != CLASS_UNIVERSAL || tag != TAG_OCTET_STRING
    1122           0 :           ||  !objlen || (objlen & 1) )
    1123             :         {
    1124           0 :           errstr = "invalid path reference";
    1125           0 :           goto parse_error;
    1126             :         }
    1127             :       /* Create a new PrKDF list item. */
    1128           0 :       prkdf = xtrycalloc (1, (sizeof *prkdf
    1129             :                               - sizeof(unsigned short)
    1130             :                               + objlen/2 * sizeof(unsigned short)));
    1131           0 :       if (!prkdf)
    1132             :         {
    1133           0 :           err = gpg_error_from_syserror ();
    1134           0 :           goto leave;
    1135             :         }
    1136           0 :       prkdf->objidlen = objidlen;
    1137           0 :       prkdf->objid = xtrymalloc (objidlen);
    1138           0 :       if (!prkdf->objid)
    1139             :         {
    1140           0 :           err = gpg_error_from_syserror ();
    1141           0 :           xfree (prkdf);
    1142           0 :           goto leave;
    1143             :         }
    1144           0 :       memcpy (prkdf->objid, objid, objidlen);
    1145           0 :       if (authid)
    1146             :         {
    1147           0 :           prkdf->authidlen = authidlen;
    1148           0 :           prkdf->authid = xtrymalloc (authidlen);
    1149           0 :           if (!prkdf->authid)
    1150             :             {
    1151           0 :               err = gpg_error_from_syserror ();
    1152           0 :               xfree (prkdf->objid);
    1153           0 :               xfree (prkdf);
    1154           0 :               goto leave;
    1155             :             }
    1156           0 :           memcpy (prkdf->authid, authid, authidlen);
    1157             :         }
    1158             : 
    1159           0 :       prkdf->pathlen = objlen/2;
    1160           0 :       for (i=0; i < prkdf->pathlen; i++, pp += 2, nn -= 2)
    1161           0 :         prkdf->path[i] = ((pp[0] << 8) | pp[1]);
    1162             : 
    1163           0 :       prkdf->usageflags = usageflags;
    1164           0 :       prkdf->key_reference = key_reference;
    1165           0 :       prkdf->key_reference_valid = key_reference_valid;
    1166             : 
    1167           0 :       if (nn)
    1168             :         {
    1169             :           /* An index and length follows. */
    1170           0 :           prkdf->have_off = 1;
    1171           0 :           where = __LINE__;
    1172           0 :           err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
    1173             :                                   &ndef, &objlen, &hdrlen);
    1174           0 :           if (!err && (objlen > nn
    1175           0 :                        || class != CLASS_UNIVERSAL || tag != TAG_INTEGER))
    1176           0 :             err = gpg_error (GPG_ERR_INV_OBJ);
    1177           0 :           if (err)
    1178           0 :             goto parse_error;
    1179             : 
    1180           0 :           for (ul=0; objlen; objlen--)
    1181             :             {
    1182           0 :               ul <<= 8;
    1183           0 :               ul |= (*pp++) & 0xff;
    1184           0 :               nn--;
    1185             :             }
    1186           0 :           prkdf->off = ul;
    1187             : 
    1188           0 :           where = __LINE__;
    1189           0 :           err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
    1190             :                                   &ndef, &objlen, &hdrlen);
    1191           0 :           if (!err && (objlen > nn
    1192           0 :                        || class != CLASS_CONTEXT || tag != 0))
    1193           0 :             err = gpg_error (GPG_ERR_INV_OBJ);
    1194           0 :           if (err)
    1195           0 :             goto parse_error;
    1196             : 
    1197           0 :           for (ul=0; objlen; objlen--)
    1198             :             {
    1199           0 :               ul <<= 8;
    1200           0 :               ul |= (*pp++) & 0xff;
    1201           0 :               nn--;
    1202             :             }
    1203           0 :           prkdf->len = ul;
    1204             :         }
    1205             : 
    1206             : 
    1207           0 :       log_debug ("PrKDF %04hX: id=", fid);
    1208           0 :       for (i=0; i < prkdf->objidlen; i++)
    1209           0 :         log_printf ("%02X", prkdf->objid[i]);
    1210           0 :       log_printf (" path=");
    1211           0 :       for (i=0; i < prkdf->pathlen; i++)
    1212           0 :         log_printf ("%04hX", prkdf->path[i]);
    1213           0 :       if (prkdf->have_off)
    1214           0 :         log_printf ("[%lu/%lu]", prkdf->off, prkdf->len);
    1215           0 :       if (prkdf->authid)
    1216             :         {
    1217           0 :           log_printf (" authid=");
    1218           0 :           for (i=0; i < prkdf->authidlen; i++)
    1219           0 :             log_printf ("%02X", prkdf->authid[i]);
    1220             :         }
    1221           0 :       if (prkdf->key_reference_valid)
    1222           0 :         log_printf (" keyref=0x%02lX", prkdf->key_reference);
    1223           0 :       log_printf (" usage=");
    1224           0 :       s = "";
    1225           0 :       if (prkdf->usageflags.encrypt) log_printf ("%sencrypt", s), s = ",";
    1226           0 :       if (prkdf->usageflags.decrypt) log_printf ("%sdecrypt", s), s = ",";
    1227           0 :       if (prkdf->usageflags.sign   ) log_printf ("%ssign", s), s = ",";
    1228           0 :       if (prkdf->usageflags.sign_recover)
    1229           0 :         log_printf ("%ssign_recover", s), s = ",";
    1230           0 :       if (prkdf->usageflags.wrap   ) log_printf ("%swrap", s), s = ",";
    1231           0 :       if (prkdf->usageflags.unwrap ) log_printf ("%sunwrap", s), s = ",";
    1232           0 :       if (prkdf->usageflags.verify ) log_printf ("%sverify", s), s = ",";
    1233           0 :       if (prkdf->usageflags.verify_recover)
    1234           0 :         log_printf ("%sverify_recover", s), s = ",";
    1235           0 :       if (prkdf->usageflags.derive ) log_printf ("%sderive", s), s = ",";
    1236           0 :       if (prkdf->usageflags.non_repudiation)
    1237           0 :         log_printf ("%snon_repudiation", s), s = ",";
    1238           0 :       log_printf ("\n");
    1239             : 
    1240             :       /* Put it into the list. */
    1241           0 :       prkdf->next = prkdflist;
    1242           0 :       prkdflist = prkdf;
    1243           0 :       prkdf = NULL;
    1244           0 :       continue; /* Ready. */
    1245             : 
    1246             :     parse_error:
    1247           0 :       log_error ("error parsing PrKDF record (%d): %s - skipped\n",
    1248             :                  where, errstr? errstr : gpg_strerror (err));
    1249           0 :       if (prkdf)
    1250             :         {
    1251           0 :           xfree (prkdf->objid);
    1252           0 :           xfree (prkdf->authid);
    1253           0 :           xfree (prkdf);
    1254             :         }
    1255           0 :       err = 0;
    1256             :     } /* End looping over all records. */
    1257             : 
    1258             :  leave:
    1259           0 :   xfree (buffer);
    1260           0 :   if (err)
    1261           0 :     release_prkdflist (prkdflist);
    1262             :   else
    1263           0 :     *result = prkdflist;
    1264           0 :   return err;
    1265             : }
    1266             : 
    1267             : 
    1268             : /* Read and parse the Certificate Directory Files identified by FID.
    1269             :    On success a newlist of CDF object gets stored at RESULT and the
    1270             :    caller is then responsible of releasing this list.  On error a
    1271             :    error code is returned and RESULT won't get changed.  */
    1272             : static gpg_error_t
    1273           0 : read_ef_cdf (app_t app, unsigned short fid, cdf_object_t *result)
    1274             : {
    1275             :   gpg_error_t err;
    1276           0 :   unsigned char *buffer = NULL;
    1277             :   size_t buflen;
    1278             :   const unsigned char *p;
    1279             :   size_t n, objlen, hdrlen;
    1280             :   int class, tag, constructed, ndef;
    1281           0 :   cdf_object_t cdflist = NULL;
    1282             :   int i;
    1283             : 
    1284           0 :   if (!fid)
    1285           0 :     return gpg_error (GPG_ERR_NO_DATA); /* No certificates. */
    1286             : 
    1287           0 :   err = select_and_read_binary (app->slot, fid, "CDF", &buffer, &buflen);
    1288           0 :   if (err)
    1289           0 :     return err;
    1290             : 
    1291           0 :   p = buffer;
    1292           0 :   n = buflen;
    1293             : 
    1294             :   /* Loop over the records.  We stop as soon as we detect a new record
    1295             :      starting with 0x00 or 0xff as these values are commonly used to
    1296             :      pad data blocks and are no valid ASN.1 encoding. */
    1297           0 :   while (n && *p && *p != 0xff)
    1298             :     {
    1299             :       const unsigned char *pp;
    1300             :       size_t nn;
    1301             :       int where;
    1302           0 :       const char *errstr = NULL;
    1303           0 :       cdf_object_t cdf = NULL;
    1304             :       unsigned long ul;
    1305             :       const unsigned char *objid;
    1306             :       size_t objidlen;
    1307             : 
    1308           0 :       err = parse_ber_header (&p, &n, &class, &tag, &constructed,
    1309             :                               &ndef, &objlen, &hdrlen);
    1310           0 :       if (!err && (objlen > n || tag != TAG_SEQUENCE))
    1311           0 :         err = gpg_error (GPG_ERR_INV_OBJ);
    1312           0 :       if (err)
    1313             :         {
    1314           0 :           log_error ("error parsing CDF record: %s\n", gpg_strerror (err));
    1315           0 :           goto leave;
    1316             :         }
    1317           0 :       pp = p;
    1318           0 :       nn = objlen;
    1319           0 :       p += objlen;
    1320           0 :       n -= objlen;
    1321             : 
    1322             :       /* Skip the commonObjectAttributes.  */
    1323           0 :       where = __LINE__;
    1324           0 :       err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
    1325             :                               &ndef, &objlen, &hdrlen);
    1326           0 :       if (!err && (objlen > nn || tag != TAG_SEQUENCE))
    1327           0 :         err = gpg_error (GPG_ERR_INV_OBJ);
    1328           0 :       if (err)
    1329           0 :         goto parse_error;
    1330           0 :       pp += objlen;
    1331           0 :       nn -= objlen;
    1332             : 
    1333             :       /* Parse the commonCertificateAttributes.  */
    1334           0 :       where = __LINE__;
    1335           0 :       err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
    1336             :                               &ndef, &objlen, &hdrlen);
    1337           0 :       if (!err && (objlen > nn || tag != TAG_SEQUENCE))
    1338           0 :         err = gpg_error (GPG_ERR_INV_OBJ);
    1339           0 :       if (err)
    1340           0 :         goto parse_error;
    1341             :       {
    1342           0 :         const unsigned char *ppp = pp;
    1343           0 :         size_t nnn = objlen;
    1344             : 
    1345           0 :         pp += objlen;
    1346           0 :         nn -= objlen;
    1347             : 
    1348             :         /* Get the Id. */
    1349           0 :         where = __LINE__;
    1350           0 :         err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
    1351             :                               &ndef, &objlen, &hdrlen);
    1352           0 :         if (!err && (objlen > nnn
    1353           0 :                      || class != CLASS_UNIVERSAL || tag != TAG_OCTET_STRING))
    1354           0 :           err = gpg_error (GPG_ERR_INV_OBJ);
    1355           0 :         if (err)
    1356           0 :           goto parse_error;
    1357           0 :         objid = ppp;
    1358           0 :         objidlen = objlen;
    1359             :       }
    1360             : 
    1361             :       /* Parse the certAttribute.  */
    1362           0 :       where = __LINE__;
    1363           0 :       err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
    1364             :                               &ndef, &objlen, &hdrlen);
    1365           0 :       if (!err && (objlen > nn || class != CLASS_CONTEXT || tag != 1))
    1366           0 :         err = gpg_error (GPG_ERR_INV_OBJ);
    1367           0 :       if (err)
    1368           0 :         goto parse_error;
    1369           0 :       nn = objlen;
    1370             : 
    1371           0 :       where = __LINE__;
    1372           0 :       err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
    1373             :                               &ndef, &objlen, &hdrlen);
    1374           0 :       if (!err && (objlen > nn
    1375           0 :                    || class != CLASS_UNIVERSAL || tag != TAG_SEQUENCE))
    1376           0 :         err = gpg_error (GPG_ERR_INV_OBJ);
    1377           0 :       if (err)
    1378           0 :         goto parse_error;
    1379           0 :       nn = objlen;
    1380             : 
    1381             :       /* Check that the reference is a Path object.  */
    1382           0 :       where = __LINE__;
    1383           0 :       err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
    1384             :                               &ndef, &objlen, &hdrlen);
    1385           0 :       if (!err && objlen > nn)
    1386           0 :         err = gpg_error (GPG_ERR_INV_OBJ);
    1387           0 :       if (err)
    1388           0 :         goto parse_error;
    1389           0 :       if (class != CLASS_UNIVERSAL || tag != TAG_SEQUENCE)
    1390             :         {
    1391           0 :           errstr = "unsupported reference type";
    1392           0 :           continue;
    1393             :         }
    1394           0 :       nn = objlen;
    1395             : 
    1396             :       /* Parse the Path object. */
    1397           0 :       where = __LINE__;
    1398           0 :       err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
    1399             :                               &ndef, &objlen, &hdrlen);
    1400           0 :       if (!err && objlen > nn)
    1401           0 :         err = gpg_error (GPG_ERR_INV_OBJ);
    1402           0 :       if (err)
    1403           0 :         goto parse_error;
    1404             : 
    1405             :       /* Make sure that the next element is a non zero path and of
    1406             :          even length (FID are two bytes each). */
    1407           0 :       if (class != CLASS_UNIVERSAL || tag != TAG_OCTET_STRING
    1408           0 :           ||  !objlen || (objlen & 1) )
    1409             :         {
    1410           0 :           errstr = "invalid path reference";
    1411           0 :           goto parse_error;
    1412             :         }
    1413             :       /* Create a new CDF list item. */
    1414           0 :       cdf = xtrycalloc (1, (sizeof *cdf
    1415             :                             - sizeof(unsigned short)
    1416             :                             + objlen/2 * sizeof(unsigned short)));
    1417           0 :       if (!cdf)
    1418             :         {
    1419           0 :           err = gpg_error_from_syserror ();
    1420           0 :           goto leave;
    1421             :         }
    1422           0 :       cdf->objidlen = objidlen;
    1423           0 :       cdf->objid = xtrymalloc (objidlen);
    1424           0 :       if (!cdf->objid)
    1425             :         {
    1426           0 :           err = gpg_error_from_syserror ();
    1427           0 :           xfree (cdf);
    1428           0 :           goto leave;
    1429             :         }
    1430           0 :       memcpy (cdf->objid, objid, objidlen);
    1431             : 
    1432           0 :       cdf->pathlen = objlen/2;
    1433           0 :       for (i=0; i < cdf->pathlen; i++, pp += 2, nn -= 2)
    1434           0 :         cdf->path[i] = ((pp[0] << 8) | pp[1]);
    1435             : 
    1436           0 :       if (nn)
    1437             :         {
    1438             :           /* An index and length follows. */
    1439           0 :           cdf->have_off = 1;
    1440           0 :           where = __LINE__;
    1441           0 :           err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
    1442             :                                   &ndef, &objlen, &hdrlen);
    1443           0 :           if (!err && (objlen > nn
    1444           0 :                        || class != CLASS_UNIVERSAL || tag != TAG_INTEGER))
    1445           0 :             err = gpg_error (GPG_ERR_INV_OBJ);
    1446           0 :           if (err)
    1447           0 :             goto parse_error;
    1448             : 
    1449           0 :           for (ul=0; objlen; objlen--)
    1450             :             {
    1451           0 :               ul <<= 8;
    1452           0 :               ul |= (*pp++) & 0xff;
    1453           0 :               nn--;
    1454             :             }
    1455           0 :           cdf->off = ul;
    1456             : 
    1457           0 :           where = __LINE__;
    1458           0 :           err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
    1459             :                                   &ndef, &objlen, &hdrlen);
    1460           0 :           if (!err && (objlen > nn
    1461           0 :                        || class != CLASS_CONTEXT || tag != 0))
    1462           0 :             err = gpg_error (GPG_ERR_INV_OBJ);
    1463           0 :           if (err)
    1464           0 :             goto parse_error;
    1465             : 
    1466           0 :           for (ul=0; objlen; objlen--)
    1467             :             {
    1468           0 :               ul <<= 8;
    1469           0 :               ul |= (*pp++) & 0xff;
    1470           0 :               nn--;
    1471             :             }
    1472           0 :           cdf->len = ul;
    1473             :         }
    1474             : 
    1475           0 :       log_debug ("CDF %04hX: id=", fid);
    1476           0 :       for (i=0; i < cdf->objidlen; i++)
    1477           0 :         log_printf ("%02X", cdf->objid[i]);
    1478           0 :       log_printf (" path=");
    1479           0 :       for (i=0; i < cdf->pathlen; i++)
    1480           0 :         log_printf ("%04hX", cdf->path[i]);
    1481           0 :       if (cdf->have_off)
    1482           0 :         log_printf ("[%lu/%lu]", cdf->off, cdf->len);
    1483           0 :       log_printf ("\n");
    1484             : 
    1485             :       /* Put it into the list. */
    1486           0 :       cdf->next = cdflist;
    1487           0 :       cdflist = cdf;
    1488           0 :       cdf = NULL;
    1489           0 :       continue; /* Ready. */
    1490             : 
    1491             :     parse_error:
    1492           0 :       log_error ("error parsing CDF record (%d): %s - skipped\n",
    1493             :                  where, errstr? errstr : gpg_strerror (err));
    1494           0 :       xfree (cdf);
    1495           0 :       err = 0;
    1496             :     } /* End looping over all records. */
    1497             : 
    1498             :  leave:
    1499           0 :   xfree (buffer);
    1500           0 :   if (err)
    1501           0 :     release_cdflist (cdflist);
    1502             :   else
    1503           0 :     *result = cdflist;
    1504           0 :   return err;
    1505             : }
    1506             : 
    1507             : 
    1508             : /*
    1509             : SEQUENCE {
    1510             :   SEQUENCE { -- CommonObjectAttributes
    1511             :     UTF8String 'specific PIN for DS'
    1512             :     BIT STRING 0 unused bits
    1513             :       '00000011'B
    1514             :     }
    1515             :   SEQUENCE { -- CommonAuthenticationObjectAttributes
    1516             :     OCTET STRING
    1517             :       07    -- iD
    1518             :     }
    1519             : 
    1520             :   [1] { -- typeAttributes
    1521             :     SEQUENCE { -- PinAttributes
    1522             :       BIT STRING 0 unused bits
    1523             :         '0000100000110010'B  -- local,initialized,needs-padding
    1524             :                              -- exchangeRefData
    1525             :       ENUMERATED 1           -- ascii-numeric
    1526             :       INTEGER 6              -- minLength
    1527             :       INTEGER 6              -- storedLength
    1528             :       INTEGER 8              -- maxLength
    1529             :       [0]
    1530             :         02                   -- pinReference
    1531             :       GeneralizedTime 19/04/2002 12:12 GMT  -- lastPinChange
    1532             :       SEQUENCE {
    1533             :         OCTET STRING
    1534             :           3F 00 40 16        -- path to DF of PIN
    1535             :         }
    1536             :       }
    1537             :     }
    1538             :   }
    1539             : 
    1540             : */
    1541             : /* Read and parse an Authentication Object Directory File identified
    1542             :    by FID.  On success a newlist of AODF objects gets stored at RESULT
    1543             :    and the caller is responsible of releasing this list.  On error a
    1544             :    error code is returned and RESULT won't get changed.  */
    1545             : static gpg_error_t
    1546           0 : read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
    1547             : {
    1548             :   gpg_error_t err;
    1549           0 :   unsigned char *buffer = NULL;
    1550             :   size_t buflen;
    1551             :   const unsigned char *p;
    1552             :   size_t n, objlen, hdrlen;
    1553             :   int class, tag, constructed, ndef;
    1554           0 :   aodf_object_t aodflist = NULL;
    1555             :   int i;
    1556             : 
    1557           0 :   if (!fid)
    1558           0 :     return gpg_error (GPG_ERR_NO_DATA); /* No authentication objects. */
    1559             : 
    1560           0 :   err = select_and_read_binary (app->slot, fid, "AODF", &buffer, &buflen);
    1561           0 :   if (err)
    1562           0 :     return err;
    1563             : 
    1564           0 :   p = buffer;
    1565           0 :   n = buflen;
    1566             : 
    1567             :   /* FIXME: This shares a LOT of code with read_ef_prkdf! */
    1568             : 
    1569             :   /* Loop over the records.  We stop as soon as we detect a new record
    1570             :      starting with 0x00 or 0xff as these values are commonly used to
    1571             :      pad data blocks and are no valid ASN.1 encoding. */
    1572           0 :   while (n && *p && *p != 0xff)
    1573             :     {
    1574             :       const unsigned char *pp;
    1575             :       size_t nn;
    1576             :       int where;
    1577           0 :       const char *errstr = NULL;
    1578           0 :       aodf_object_t aodf = NULL;
    1579             :       unsigned long ul;
    1580             :       const char *s;
    1581             : 
    1582           0 :       err = parse_ber_header (&p, &n, &class, &tag, &constructed,
    1583             :                               &ndef, &objlen, &hdrlen);
    1584           0 :       if (!err && (objlen > n || tag != TAG_SEQUENCE))
    1585           0 :         err = gpg_error (GPG_ERR_INV_OBJ);
    1586           0 :       if (err)
    1587             :         {
    1588           0 :           log_error ("error parsing AODF record: %s\n", gpg_strerror (err));
    1589           0 :           goto leave;
    1590             :         }
    1591           0 :       pp = p;
    1592           0 :       nn = objlen;
    1593           0 :       p += objlen;
    1594           0 :       n -= objlen;
    1595             : 
    1596             :       /* Allocate memory for a new AODF list item. */
    1597           0 :       aodf = xtrycalloc (1, sizeof *aodf);
    1598           0 :       if (!aodf)
    1599           0 :         goto no_core;
    1600             : 
    1601             :       /* Parse the commonObjectAttributes.  */
    1602           0 :       where = __LINE__;
    1603           0 :       err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
    1604             :                               &ndef, &objlen, &hdrlen);
    1605           0 :       if (!err && (objlen > nn || tag != TAG_SEQUENCE))
    1606           0 :         err = gpg_error (GPG_ERR_INV_OBJ);
    1607           0 :       if (err)
    1608           0 :         goto parse_error;
    1609             :       {
    1610           0 :         const unsigned char *ppp = pp;
    1611           0 :         size_t nnn = objlen;
    1612             : 
    1613           0 :         pp += objlen;
    1614           0 :         nn -= objlen;
    1615             : 
    1616             :         /* Search the optional AuthId.  We need to skip the optional
    1617             :            Label (UTF8STRING) and the optional CommonObjectFlags
    1618             :            (BITSTRING). */
    1619           0 :         where = __LINE__;
    1620           0 :         err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
    1621             :                                 &ndef, &objlen, &hdrlen);
    1622           0 :         if (!err && (objlen > nnn || class != CLASS_UNIVERSAL))
    1623           0 :           err = gpg_error (GPG_ERR_INV_OBJ);
    1624           0 :         if (gpg_err_code (err) == GPG_ERR_EOF)
    1625           0 :           goto no_authid;
    1626           0 :         if (err)
    1627           0 :           goto parse_error;
    1628           0 :         if (tag == TAG_UTF8_STRING)
    1629             :           {
    1630           0 :             ppp += objlen; /* Skip the Label. */
    1631           0 :             nnn -= objlen;
    1632             : 
    1633           0 :             where = __LINE__;
    1634           0 :             err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
    1635             :                                     &ndef, &objlen, &hdrlen);
    1636           0 :             if (!err && (objlen > nnn || class != CLASS_UNIVERSAL))
    1637           0 :               err = gpg_error (GPG_ERR_INV_OBJ);
    1638           0 :             if (gpg_err_code (err) == GPG_ERR_EOF)
    1639           0 :               goto no_authid;
    1640           0 :             if (err)
    1641           0 :               goto parse_error;
    1642             :           }
    1643           0 :         if (tag == TAG_BIT_STRING)
    1644             :           {
    1645           0 :             ppp += objlen; /* Skip the CommonObjectFlags.  */
    1646           0 :             nnn -= objlen;
    1647             : 
    1648           0 :             where = __LINE__;
    1649           0 :             err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
    1650             :                                     &ndef, &objlen, &hdrlen);
    1651           0 :             if (!err && (objlen > nnn || class != CLASS_UNIVERSAL))
    1652           0 :               err = gpg_error (GPG_ERR_INV_OBJ);
    1653           0 :             if (gpg_err_code (err) == GPG_ERR_EOF)
    1654           0 :               goto no_authid;
    1655           0 :             if (err)
    1656           0 :               goto parse_error;
    1657             :           }
    1658           0 :         if (tag == TAG_OCTET_STRING && objlen)
    1659             :           {
    1660           0 :             aodf->authidlen = objlen;
    1661           0 :             aodf->authid = xtrymalloc (objlen);
    1662           0 :             if (!aodf->authid)
    1663           0 :               goto no_core;
    1664           0 :             memcpy (aodf->authid, ppp, objlen);
    1665             :           }
    1666             :       no_authid:
    1667             :         ;
    1668             :       }
    1669             : 
    1670             :       /* Parse the CommonAuthenticationObjectAttributes.  */
    1671           0 :       where = __LINE__;
    1672           0 :       err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
    1673             :                               &ndef, &objlen, &hdrlen);
    1674           0 :       if (!err && (objlen > nn || tag != TAG_SEQUENCE))
    1675           0 :         err = gpg_error (GPG_ERR_INV_OBJ);
    1676           0 :       if (err)
    1677           0 :         goto parse_error;
    1678             :       {
    1679           0 :         const unsigned char *ppp = pp;
    1680           0 :         size_t nnn = objlen;
    1681             : 
    1682           0 :         pp += objlen;
    1683           0 :         nn -= objlen;
    1684             : 
    1685             :         /* Get the Id. */
    1686           0 :         where = __LINE__;
    1687           0 :         err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
    1688             :                               &ndef, &objlen, &hdrlen);
    1689           0 :         if (!err && (objlen > nnn
    1690           0 :                      || class != CLASS_UNIVERSAL || tag != TAG_OCTET_STRING))
    1691           0 :           err = gpg_error (GPG_ERR_INV_OBJ);
    1692           0 :         if (err)
    1693           0 :           goto parse_error;
    1694             : 
    1695           0 :         aodf->objidlen = objlen;
    1696           0 :         aodf->objid = xtrymalloc (objlen);
    1697           0 :         if (!aodf->objid)
    1698           0 :           goto no_core;
    1699           0 :         memcpy (aodf->objid, ppp, objlen);
    1700             :       }
    1701             : 
    1702             :       /* Parse the typeAttributes.  */
    1703           0 :       where = __LINE__;
    1704           0 :       err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
    1705             :                               &ndef, &objlen, &hdrlen);
    1706           0 :       if (!err && (objlen > nn || class != CLASS_CONTEXT || tag != 1))
    1707           0 :         err = gpg_error (GPG_ERR_INV_OBJ);
    1708           0 :       if (err)
    1709           0 :         goto parse_error;
    1710           0 :       nn = objlen;
    1711             : 
    1712           0 :       where = __LINE__;
    1713           0 :       err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
    1714             :                               &ndef, &objlen, &hdrlen);
    1715           0 :       if (!err && objlen > nn)
    1716           0 :         err = gpg_error (GPG_ERR_INV_OBJ);
    1717           0 :       if (err)
    1718           0 :         goto parse_error;
    1719           0 :       if (class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE)
    1720             :         ; /* PinAttributes */
    1721           0 :       else if (class == CLASS_CONTEXT)
    1722             :         {
    1723           0 :           switch (tag)
    1724             :             {
    1725           0 :             case 0: errstr = "biometric auth types are not supported"; break;
    1726           0 :             case 1: errstr = "authKey auth types are not supported"; break;
    1727           0 :             case 2: errstr = "external auth type are not supported"; break;
    1728           0 :             default: errstr = "unknown privateKeyObject"; break;
    1729             :             }
    1730           0 :           goto parse_error;
    1731             :         }
    1732             :       else
    1733             :         {
    1734           0 :           err = gpg_error (GPG_ERR_INV_OBJ);
    1735           0 :           goto parse_error;
    1736             :         }
    1737             : 
    1738           0 :       nn = objlen;
    1739             : 
    1740             :       /* PinFlags */
    1741           0 :       where = __LINE__;
    1742           0 :       err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
    1743             :                               &ndef, &objlen, &hdrlen);
    1744           0 :       if (!err && (objlen > nn || !objlen
    1745           0 :                    || class != CLASS_UNIVERSAL || tag != TAG_BIT_STRING))
    1746           0 :         err = gpg_error (GPG_ERR_INV_OBJ);
    1747           0 :       if (err)
    1748           0 :         goto parse_error;
    1749             : 
    1750             :       {
    1751             :         unsigned int bits, mask;
    1752             :         int unused, full;
    1753             : 
    1754           0 :         unused = *pp++; nn--; objlen--;
    1755           0 :         if ((!objlen && unused) || unused/8 > objlen)
    1756             :           {
    1757           0 :             err = gpg_error (GPG_ERR_ENCODING_PROBLEM);
    1758           0 :             goto parse_error;
    1759             :           }
    1760           0 :         full = objlen - (unused+7)/8;
    1761           0 :         unused %= 8;
    1762           0 :         mask = 0;
    1763           0 :         for (i=1; unused; i <<= 1, unused--)
    1764           0 :           mask |= i;
    1765             : 
    1766             :         /* The first octet */
    1767           0 :         bits = 0;
    1768           0 :         if (objlen)
    1769             :           {
    1770           0 :             bits = *pp++; nn--; objlen--;
    1771           0 :             if (full)
    1772           0 :               full--;
    1773             :             else
    1774             :               {
    1775           0 :                 bits &= ~mask;
    1776           0 :                 mask = 0;
    1777             :               }
    1778             :           }
    1779           0 :         if ((bits & 0x80)) /* ASN.1 bit 0. */
    1780           0 :           aodf->pinflags.case_sensitive = 1;
    1781           0 :         if ((bits & 0x40)) /* ASN.1 bit 1. */
    1782           0 :           aodf->pinflags.local = 1;
    1783           0 :         if ((bits & 0x20))
    1784           0 :           aodf->pinflags.change_disabled = 1;
    1785           0 :         if ((bits & 0x10))
    1786           0 :           aodf->pinflags.unblock_disabled = 1;
    1787           0 :         if ((bits & 0x08))
    1788           0 :           aodf->pinflags.initialized = 1;
    1789           0 :         if ((bits & 0x04))
    1790           0 :           aodf->pinflags.needs_padding = 1;
    1791           0 :         if ((bits & 0x02))
    1792           0 :           aodf->pinflags.unblocking_pin = 1;
    1793           0 :         if ((bits & 0x01))
    1794           0 :           aodf->pinflags.so_pin = 1;
    1795             :         /* The second octet. */
    1796           0 :         bits = 0;
    1797           0 :         if (objlen)
    1798             :           {
    1799           0 :             bits = *pp++; nn--; objlen--;
    1800           0 :             if (full)
    1801           0 :               full--;
    1802             :             else
    1803             :               {
    1804           0 :                 bits &= ~mask;
    1805           0 :                 mask = 0;
    1806             :               }
    1807             :           }
    1808           0 :         if ((bits & 0x80))
    1809           0 :           aodf->pinflags.disable_allowed = 1;
    1810           0 :         if ((bits & 0x40))
    1811           0 :           aodf->pinflags.integrity_protected = 1;
    1812           0 :         if ((bits & 0x20))
    1813           0 :           aodf->pinflags.confidentiality_protected = 1;
    1814           0 :         if ((bits & 0x10))
    1815           0 :           aodf->pinflags.exchange_ref_data = 1;
    1816             :         /* Skip remaining bits. */
    1817           0 :         pp += objlen;
    1818           0 :         nn -= objlen;
    1819             :       }
    1820             : 
    1821             : 
    1822             :       /* PinType */
    1823           0 :       where = __LINE__;
    1824           0 :       err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
    1825             :                               &ndef, &objlen, &hdrlen);
    1826           0 :       if (!err && (objlen > nn
    1827           0 :                    || class != CLASS_UNIVERSAL || tag != TAG_ENUMERATED))
    1828           0 :         err = gpg_error (GPG_ERR_INV_OBJ);
    1829           0 :       if (!err && (objlen > sizeof (pin_type_t) || objlen > sizeof (ul)))
    1830           0 :         err = gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
    1831           0 :       if (err)
    1832           0 :         goto parse_error;
    1833             : 
    1834           0 :       for (ul=0; objlen; objlen--)
    1835             :         {
    1836           0 :           ul <<= 8;
    1837           0 :           ul |= (*pp++) & 0xff;
    1838           0 :           nn--;
    1839             :         }
    1840           0 :       aodf->pintype = ul;
    1841             : 
    1842             : 
    1843             :       /* minLength */
    1844           0 :       where = __LINE__;
    1845           0 :       err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
    1846             :                               &ndef, &objlen, &hdrlen);
    1847           0 :       if (!err && (objlen > nn
    1848           0 :                    || class != CLASS_UNIVERSAL || tag != TAG_INTEGER))
    1849           0 :         err = gpg_error (GPG_ERR_INV_OBJ);
    1850           0 :       if (!err && objlen > sizeof (ul))
    1851           0 :         err = gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
    1852           0 :       if (err)
    1853           0 :         goto parse_error;
    1854           0 :       for (ul=0; objlen; objlen--)
    1855             :         {
    1856           0 :           ul <<= 8;
    1857           0 :           ul |= (*pp++) & 0xff;
    1858           0 :           nn--;
    1859             :         }
    1860           0 :       aodf->min_length = ul;
    1861             : 
    1862             : 
    1863             :       /* storedLength */
    1864           0 :       where = __LINE__;
    1865           0 :       err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
    1866             :                               &ndef, &objlen, &hdrlen);
    1867           0 :       if (!err && (objlen > nn
    1868           0 :                    || class != CLASS_UNIVERSAL || tag != TAG_INTEGER))
    1869           0 :         err = gpg_error (GPG_ERR_INV_OBJ);
    1870           0 :       if (!err && objlen > sizeof (ul))
    1871           0 :         err = gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
    1872           0 :       if (err)
    1873           0 :         goto parse_error;
    1874           0 :       for (ul=0; objlen; objlen--)
    1875             :         {
    1876           0 :           ul <<= 8;
    1877           0 :           ul |= (*pp++) & 0xff;
    1878           0 :           nn--;
    1879             :         }
    1880           0 :       aodf->stored_length = ul;
    1881             : 
    1882             :       /* optional maxLength */
    1883           0 :       where = __LINE__;
    1884           0 :       err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
    1885             :                               &ndef, &objlen, &hdrlen);
    1886           0 :       if (gpg_err_code (err) == GPG_ERR_EOF)
    1887           0 :         goto ready;
    1888           0 :       if (!err && objlen > nn)
    1889           0 :         err = gpg_error (GPG_ERR_INV_OBJ);
    1890           0 :       if (err)
    1891           0 :         goto parse_error;
    1892           0 :       if (class == CLASS_UNIVERSAL && tag == TAG_INTEGER)
    1893             :         {
    1894           0 :           if (objlen > sizeof (ul))
    1895             :             {
    1896           0 :               err = gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
    1897           0 :               goto parse_error;
    1898             :             }
    1899           0 :           for (ul=0; objlen; objlen--)
    1900             :             {
    1901           0 :               ul <<= 8;
    1902           0 :               ul |= (*pp++) & 0xff;
    1903           0 :               nn--;
    1904             :             }
    1905           0 :           aodf->max_length = ul;
    1906           0 :           aodf->max_length_valid = 1;
    1907             : 
    1908           0 :           where = __LINE__;
    1909           0 :           err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
    1910             :                                   &ndef, &objlen, &hdrlen);
    1911           0 :           if (gpg_err_code (err) == GPG_ERR_EOF)
    1912           0 :             goto ready;
    1913           0 :           if (!err && objlen > nn)
    1914           0 :             err = gpg_error (GPG_ERR_INV_OBJ);
    1915           0 :           if (err)
    1916           0 :             goto parse_error;
    1917             :         }
    1918             : 
    1919             :       /* Optional pinReference. */
    1920           0 :       if (class == CLASS_CONTEXT && tag == 0)
    1921             :         {
    1922           0 :           if (objlen > sizeof (ul))
    1923             :             {
    1924           0 :               err = gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
    1925           0 :               goto parse_error;
    1926             :             }
    1927           0 :           for (ul=0; objlen; objlen--)
    1928             :             {
    1929           0 :               ul <<= 8;
    1930           0 :               ul |= (*pp++) & 0xff;
    1931           0 :               nn--;
    1932             :             }
    1933           0 :           aodf->pin_reference = ul;
    1934           0 :           aodf->pin_reference_valid = 1;
    1935             : 
    1936           0 :           where = __LINE__;
    1937           0 :           err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
    1938             :                                   &ndef, &objlen, &hdrlen);
    1939           0 :           if (gpg_err_code (err) == GPG_ERR_EOF)
    1940           0 :             goto ready;
    1941           0 :           if (!err && objlen > nn)
    1942           0 :             err = gpg_error (GPG_ERR_INV_OBJ);
    1943           0 :           if (err)
    1944           0 :             goto parse_error;
    1945             :         }
    1946             : 
    1947             :       /* Optional padChar. */
    1948           0 :       if (class == CLASS_UNIVERSAL && tag == TAG_OCTET_STRING)
    1949             :         {
    1950           0 :           if (objlen != 1)
    1951             :             {
    1952           0 :               errstr = "padChar is not of size(1)";
    1953           0 :               goto parse_error;
    1954             :             }
    1955           0 :           aodf->pad_char = *pp++; nn--;
    1956           0 :           aodf->pad_char_valid = 1;
    1957             : 
    1958           0 :           where = __LINE__;
    1959           0 :           err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
    1960             :                                   &ndef, &objlen, &hdrlen);
    1961           0 :           if (gpg_err_code (err) == GPG_ERR_EOF)
    1962           0 :             goto ready;
    1963           0 :           if (!err && objlen > nn)
    1964           0 :             err = gpg_error (GPG_ERR_INV_OBJ);
    1965           0 :           if (err)
    1966           0 :             goto parse_error;
    1967             :         }
    1968             : 
    1969             :       /* Skip optional lastPinChange. */
    1970           0 :       if (class == CLASS_UNIVERSAL && tag == TAG_GENERALIZED_TIME)
    1971             :         {
    1972           0 :           pp += objlen;
    1973           0 :           nn -= objlen;
    1974             : 
    1975           0 :           where = __LINE__;
    1976           0 :           err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
    1977             :                                   &ndef, &objlen, &hdrlen);
    1978           0 :           if (gpg_err_code (err) == GPG_ERR_EOF)
    1979           0 :             goto ready;
    1980           0 :           if (!err && objlen > nn)
    1981           0 :             err = gpg_error (GPG_ERR_INV_OBJ);
    1982           0 :           if (err)
    1983           0 :             goto parse_error;
    1984             :         }
    1985             : 
    1986             :       /* Optional Path object.  */
    1987           0 :       if (class == CLASS_UNIVERSAL || tag == TAG_SEQUENCE)
    1988             :         {
    1989           0 :           const unsigned char *ppp = pp;
    1990           0 :           size_t nnn = objlen;
    1991             : 
    1992           0 :           pp += objlen;
    1993           0 :           nn -= objlen;
    1994             : 
    1995           0 :           where = __LINE__;
    1996           0 :           err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
    1997             :                                   &ndef, &objlen, &hdrlen);
    1998           0 :           if (!err && objlen > nnn)
    1999           0 :             err = gpg_error (GPG_ERR_INV_OBJ);
    2000           0 :           if (err)
    2001           0 :             goto parse_error;
    2002             : 
    2003             :           /* Make sure that the next element is a non zero FID and of
    2004             :              even length (FID are two bytes each). */
    2005           0 :           if (class != CLASS_UNIVERSAL || tag != TAG_OCTET_STRING
    2006           0 :               ||  !objlen || (objlen & 1) )
    2007             :             {
    2008           0 :               errstr = "invalid path reference";
    2009           0 :               goto parse_error;
    2010             :             }
    2011             : 
    2012           0 :           aodf->pathlen = objlen/2;
    2013           0 :           aodf->path = xtrymalloc (aodf->pathlen);
    2014           0 :           if (!aodf->path)
    2015           0 :             goto no_core;
    2016           0 :           for (i=0; i < aodf->pathlen; i++, ppp += 2, nnn -= 2)
    2017           0 :             aodf->path[i] = ((ppp[0] << 8) | ppp[1]);
    2018             : 
    2019           0 :           if (nnn)
    2020             :             {
    2021             :               /* An index and length follows. */
    2022           0 :               aodf->have_off = 1;
    2023           0 :               where = __LINE__;
    2024           0 :               err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
    2025             :                                       &ndef, &objlen, &hdrlen);
    2026           0 :               if (!err && (objlen > nnn
    2027           0 :                        || class != CLASS_UNIVERSAL || tag != TAG_INTEGER))
    2028           0 :                 err = gpg_error (GPG_ERR_INV_OBJ);
    2029           0 :               if (err)
    2030           0 :                 goto parse_error;
    2031             : 
    2032           0 :               for (ul=0; objlen; objlen--)
    2033             :                 {
    2034           0 :                   ul <<= 8;
    2035           0 :                   ul |= (*ppp++) & 0xff;
    2036           0 :                   nnn--;
    2037             :                 }
    2038           0 :               aodf->off = ul;
    2039             : 
    2040           0 :               where = __LINE__;
    2041           0 :               err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
    2042             :                                       &ndef, &objlen, &hdrlen);
    2043           0 :               if (!err && (objlen > nnn
    2044           0 :                            || class != CLASS_CONTEXT || tag != 0))
    2045           0 :                 err = gpg_error (GPG_ERR_INV_OBJ);
    2046           0 :               if (err)
    2047           0 :                 goto parse_error;
    2048             : 
    2049           0 :               for (ul=0; objlen; objlen--)
    2050             :                 {
    2051           0 :                   ul <<= 8;
    2052           0 :                   ul |= (*ppp++) & 0xff;
    2053           0 :                   nnn--;
    2054             :                 }
    2055           0 :               aodf->len = ul;
    2056             :             }
    2057             :         }
    2058             : 
    2059             :       /* Igonore further objects which might be there due to future
    2060             :          extensions of pkcs#15. */
    2061             : 
    2062             :     ready:
    2063           0 :       log_debug ("AODF %04hX: id=", fid);
    2064           0 :       for (i=0; i < aodf->objidlen; i++)
    2065           0 :         log_printf ("%02X", aodf->objid[i]);
    2066           0 :       if (aodf->authid)
    2067             :         {
    2068           0 :           log_printf (" authid=");
    2069           0 :           for (i=0; i < aodf->authidlen; i++)
    2070           0 :             log_printf ("%02X", aodf->authid[i]);
    2071             :         }
    2072           0 :       log_printf (" flags=");
    2073           0 :       s = "";
    2074           0 :       if (aodf->pinflags.case_sensitive)
    2075           0 :         log_printf ("%scase_sensitive", s), s = ",";
    2076           0 :       if (aodf->pinflags.local)
    2077           0 :         log_printf ("%slocal", s), s = ",";
    2078           0 :       if (aodf->pinflags.change_disabled)
    2079           0 :         log_printf ("%schange_disabled", s), s = ",";
    2080           0 :       if (aodf->pinflags.unblock_disabled)
    2081           0 :         log_printf ("%sunblock_disabled", s), s = ",";
    2082           0 :       if (aodf->pinflags.initialized)
    2083           0 :         log_printf ("%sinitialized", s), s = ",";
    2084           0 :       if (aodf->pinflags.needs_padding)
    2085           0 :         log_printf ("%sneeds_padding", s), s = ",";
    2086           0 :       if (aodf->pinflags.unblocking_pin)
    2087           0 :         log_printf ("%sunblocking_pin", s), s = ",";
    2088           0 :       if (aodf->pinflags.so_pin)
    2089           0 :         log_printf ("%sso_pin", s), s = ",";
    2090           0 :       if (aodf->pinflags.disable_allowed)
    2091           0 :         log_printf ("%sdisable_allowed", s), s = ",";
    2092           0 :       if (aodf->pinflags.integrity_protected)
    2093           0 :         log_printf ("%sintegrity_protected", s), s = ",";
    2094           0 :       if (aodf->pinflags.confidentiality_protected)
    2095           0 :         log_printf ("%sconfidentiality_protected", s), s = ",";
    2096           0 :       if (aodf->pinflags.exchange_ref_data)
    2097           0 :         log_printf ("%sexchange_ref_data", s), s = ",";
    2098             :       {
    2099             :         char numbuf[50];
    2100           0 :         switch (aodf->pintype)
    2101             :           {
    2102           0 :           case PIN_TYPE_BCD: s = "bcd"; break;
    2103           0 :           case PIN_TYPE_ASCII_NUMERIC: s = "ascii-numeric"; break;
    2104           0 :           case PIN_TYPE_UTF8: s = "utf8"; break;
    2105           0 :           case PIN_TYPE_HALF_NIBBLE_BCD: s = "half-nibble-bcd"; break;
    2106           0 :           case PIN_TYPE_ISO9564_1: s = "iso9564-1"; break;
    2107             :           default:
    2108           0 :             sprintf (numbuf, "%lu", (unsigned long)aodf->pintype);
    2109           0 :             s = numbuf;
    2110             :           }
    2111           0 :         log_printf (" type=%s", s);
    2112             :       }
    2113           0 :       log_printf (" min=%lu", aodf->min_length);
    2114           0 :       log_printf (" stored=%lu", aodf->stored_length);
    2115           0 :       if (aodf->max_length_valid)
    2116           0 :         log_printf (" max=%lu", aodf->max_length);
    2117           0 :       if (aodf->pad_char_valid)
    2118           0 :         log_printf (" pad=0x%02x", aodf->pad_char);
    2119           0 :       if (aodf->pin_reference_valid)
    2120           0 :         log_printf (" pinref=0x%02lX", aodf->pin_reference);
    2121           0 :       if (aodf->pathlen)
    2122             :         {
    2123           0 :           log_printf (" path=");
    2124           0 :           for (i=0; i < aodf->pathlen; i++)
    2125           0 :             log_printf ("%04hX", aodf->path[i]);
    2126           0 :           if (aodf->have_off)
    2127           0 :             log_printf ("[%lu/%lu]", aodf->off, aodf->len);
    2128             :         }
    2129           0 :       log_printf ("\n");
    2130             : 
    2131             :       /* Put it into the list. */
    2132           0 :       aodf->next = aodflist;
    2133           0 :       aodflist = aodf;
    2134           0 :       aodf = NULL;
    2135           0 :       continue; /* Ready. */
    2136             : 
    2137             :     no_core:
    2138           0 :       err = gpg_error_from_syserror ();
    2139           0 :       release_aodf_object (aodf);
    2140           0 :       goto leave;
    2141             : 
    2142             :     parse_error:
    2143           0 :       log_error ("error parsing AODF record (%d): %s - skipped\n",
    2144             :                  where, errstr? errstr : gpg_strerror (err));
    2145           0 :       err = 0;
    2146           0 :       release_aodf_object (aodf);
    2147             :     } /* End looping over all records. */
    2148             : 
    2149             :  leave:
    2150           0 :   xfree (buffer);
    2151           0 :   if (err)
    2152           0 :     release_aodflist (aodflist);
    2153             :   else
    2154           0 :     *result = aodflist;
    2155           0 :   return err;
    2156             : }
    2157             : 
    2158             : 
    2159             : 
    2160             : 
    2161             : 
    2162             : /* Read and parse the EF(TokenInfo).
    2163             : 
    2164             : TokenInfo ::= SEQUENCE {
    2165             :     version             INTEGER {v1(0)} (v1,...),
    2166             :     serialNumber        OCTET STRING,
    2167             :     manufacturerID      Label OPTIONAL,
    2168             :     label               [0] Label OPTIONAL,
    2169             :     tokenflags          TokenFlags,
    2170             :     seInfo              SEQUENCE OF SecurityEnvironmentInfo OPTIONAL,
    2171             :     recordInfo          [1] RecordInfo OPTIONAL,
    2172             :     supportedAlgorithms [2] SEQUENCE OF AlgorithmInfo OPTIONAL,
    2173             :     ...,
    2174             :     issuerId            [3] Label OPTIONAL,
    2175             :     holderId            [4] Label OPTIONAL,
    2176             :     lastUpdate          [5] LastUpdate OPTIONAL,
    2177             :     preferredLanguage   PrintableString OPTIONAL -- In accordance with
    2178             :     -- IETF RFC 1766
    2179             : } (CONSTRAINED BY { -- Each AlgorithmInfo.reference value must be unique --})
    2180             : 
    2181             : TokenFlags ::= BIT STRING {
    2182             :     readOnly            (0),
    2183             :     loginRequired       (1),
    2184             :     prnGeneration       (2),
    2185             :     eidCompliant        (3)
    2186             : }
    2187             : 
    2188             : 
    2189             :  5032:
    2190             : 
    2191             : 30 31 02 01 00 04 04 05 45  36 9F 0C 0C 44 2D 54   01......E6...D-T
    2192             : 72 75 73 74 20 47 6D 62 48  80 14 4F 66 66 69 63   rust GmbH..Offic
    2193             : 65 20 69 64 65 6E 74 69 74  79 20 63 61 72 64 03   e identity card.
    2194             : 02 00 40 20 63 61 72 64 03  02 00 40 00 00 00 00   ..@ card...@....
    2195             : 00 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00   ................
    2196             : 
    2197             :    0   49: SEQUENCE {
    2198             :    2    1:   INTEGER 0
    2199             :    5    4:   OCTET STRING 05 45 36 9F
    2200             :   11   12:   UTF8String 'D-Trust GmbH'
    2201             :   25   20:   [0] 'Office identity card'
    2202             :   47    2:   BIT STRING
    2203             :          :     '00000010'B (bit 1)
    2204             :          :     Error: Spurious zero bits in bitstring.
    2205             :          :   }
    2206             : 
    2207             : 
    2208             : 
    2209             : 
    2210             :  */
    2211             : static gpg_error_t
    2212           0 : read_ef_tokeninfo (app_t app)
    2213             : {
    2214             :   gpg_error_t err;
    2215           0 :   unsigned char *buffer = NULL;
    2216             :   size_t buflen;
    2217             :   const unsigned char *p;
    2218             :   size_t n, objlen, hdrlen;
    2219             :   int class, tag, constructed, ndef;
    2220             :   unsigned long ul;
    2221             : 
    2222           0 :   err = select_and_read_binary (app->slot, 0x5032, "TokenInfo",
    2223             :                                 &buffer, &buflen);
    2224           0 :   if (err)
    2225           0 :     return err;
    2226             : 
    2227           0 :   p = buffer;
    2228           0 :   n = buflen;
    2229             : 
    2230           0 :   err = parse_ber_header (&p, &n, &class, &tag, &constructed,
    2231             :                           &ndef, &objlen, &hdrlen);
    2232           0 :   if (!err && (objlen > n || tag != TAG_SEQUENCE))
    2233           0 :     err = gpg_error (GPG_ERR_INV_OBJ);
    2234           0 :   if (err)
    2235             :     {
    2236           0 :       log_error ("error parsing TokenInfo: %s\n", gpg_strerror (err));
    2237           0 :       goto leave;
    2238             :     }
    2239             : 
    2240           0 :   n = objlen;
    2241             : 
    2242             :   /* Version.  */
    2243           0 :   err = parse_ber_header (&p, &n, &class, &tag, &constructed,
    2244             :                           &ndef, &objlen, &hdrlen);
    2245           0 :   if (!err && (objlen > n || tag != TAG_INTEGER))
    2246           0 :     err = gpg_error (GPG_ERR_INV_OBJ);
    2247           0 :   if (err)
    2248           0 :     goto leave;
    2249             : 
    2250           0 :   for (ul=0; objlen; objlen--)
    2251             :     {
    2252           0 :       ul <<= 8;
    2253           0 :       ul |= (*p++) & 0xff;
    2254           0 :       n--;
    2255             :     }
    2256           0 :   if (ul)
    2257             :     {
    2258           0 :       log_error ("invalid version %lu in TokenInfo\n", ul);
    2259           0 :       err = gpg_error (GPG_ERR_INV_OBJ);
    2260           0 :       goto leave;
    2261             :     }
    2262             : 
    2263             :   /* serialNumber.  */
    2264           0 :   err = parse_ber_header (&p, &n, &class, &tag, &constructed,
    2265             :                           &ndef, &objlen, &hdrlen);
    2266           0 :   if (!err && (objlen > n || tag != TAG_OCTET_STRING || !objlen))
    2267           0 :     err = gpg_error (GPG_ERR_INV_OBJ);
    2268           0 :   if (err)
    2269           0 :     goto leave;
    2270             : 
    2271           0 :   xfree (app->app_local->serialno);
    2272           0 :   app->app_local->serialno = xtrymalloc (objlen);
    2273           0 :   if (!app->app_local->serialno)
    2274             :     {
    2275           0 :       err = gpg_error_from_syserror ();
    2276           0 :       goto leave;
    2277             :     }
    2278           0 :   memcpy (app->app_local->serialno, p, objlen);
    2279           0 :   app->app_local->serialnolen = objlen;
    2280           0 :   log_printhex ("Serialnumber from EF(TokenInfo) is:", p, objlen);
    2281             : 
    2282             :  leave:
    2283           0 :   xfree (buffer);
    2284           0 :   return err;
    2285             : }
    2286             : 
    2287             : 
    2288             : /* Get all the basic information from the pkcs#15 card, check the
    2289             :    structure and initialize our local context.  This is used once at
    2290             :    application initialization. */
    2291             : static gpg_error_t
    2292           0 : read_p15_info (app_t app)
    2293             : {
    2294             :   gpg_error_t err;
    2295             : 
    2296           0 :   if (!read_ef_tokeninfo (app))
    2297             :     {
    2298             :       /* If we don't have a serial number yet but the TokenInfo provides
    2299             :          one, use that. */
    2300           0 :       if (!app->serialno && app->app_local->serialno)
    2301             :         {
    2302           0 :           app->serialno = app->app_local->serialno;
    2303           0 :           app->serialnolen = app->app_local->serialnolen;
    2304           0 :           app->app_local->serialno = NULL;
    2305           0 :           app->app_local->serialnolen = 0;
    2306           0 :           err = app_munge_serialno (app);
    2307           0 :           if (err)
    2308           0 :             return err;
    2309             :         }
    2310             :     }
    2311             : 
    2312             :   /* Read the ODF so that we know the location of all directory
    2313             :      files. */
    2314             :   /* Fixme: We might need to get a non-standard ODF FID from TokenInfo. */
    2315           0 :   err = read_ef_odf (app, 0x5031);
    2316           0 :   if (err)
    2317           0 :     return err;
    2318             : 
    2319             :   /* Read certificate information. */
    2320           0 :   assert (!app->app_local->certificate_info);
    2321           0 :   assert (!app->app_local->trusted_certificate_info);
    2322           0 :   assert (!app->app_local->useful_certificate_info);
    2323           0 :   err = read_ef_cdf (app, app->app_local->odf.certificates,
    2324           0 :                      &app->app_local->certificate_info);
    2325           0 :   if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
    2326           0 :     err = read_ef_cdf (app, app->app_local->odf.trusted_certificates,
    2327           0 :                        &app->app_local->trusted_certificate_info);
    2328           0 :   if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
    2329           0 :     err = read_ef_cdf (app, app->app_local->odf.useful_certificates,
    2330           0 :                        &app->app_local->useful_certificate_info);
    2331           0 :   if (gpg_err_code (err) == GPG_ERR_NO_DATA)
    2332           0 :     err = 0;
    2333           0 :   if (err)
    2334           0 :     return err;
    2335             : 
    2336             :   /* Read information about private keys. */
    2337           0 :   assert (!app->app_local->private_key_info);
    2338           0 :   err = read_ef_prkdf (app, app->app_local->odf.private_keys,
    2339           0 :                        &app->app_local->private_key_info);
    2340           0 :   if (gpg_err_code (err) == GPG_ERR_NO_DATA)
    2341           0 :     err = 0;
    2342           0 :   if (err)
    2343           0 :     return err;
    2344             : 
    2345             :   /* Read information about authentication objects. */
    2346           0 :   assert (!app->app_local->auth_object_info);
    2347           0 :   err = read_ef_aodf (app, app->app_local->odf.auth_objects,
    2348           0 :                       &app->app_local->auth_object_info);
    2349           0 :   if (gpg_err_code (err) == GPG_ERR_NO_DATA)
    2350           0 :     err = 0;
    2351             : 
    2352             : 
    2353           0 :   return err;
    2354             : }
    2355             : 
    2356             : 
    2357             : /* Helper to do_learn_status: Send information about all certificates
    2358             :    listed in CERTINFO back.  Use CERTTYPE as type of the
    2359             :    certificate. */
    2360             : static gpg_error_t
    2361           0 : send_certinfo (app_t app, ctrl_t ctrl, const char *certtype,
    2362             :                cdf_object_t certinfo)
    2363             : {
    2364           0 :   for (; certinfo; certinfo = certinfo->next)
    2365             :     {
    2366             :       char *buf, *p;
    2367             : 
    2368           0 :       buf = xtrymalloc (9 + certinfo->objidlen*2 + 1);
    2369           0 :       if (!buf)
    2370           0 :         return gpg_error_from_syserror ();
    2371           0 :       p = stpcpy (buf, "P15");
    2372           0 :       if (app->app_local->home_df)
    2373             :         {
    2374           0 :           snprintf (p, 6, "-%04X",
    2375           0 :                     (unsigned int)(app->app_local->home_df & 0xffff));
    2376           0 :           p += 5;
    2377             :         }
    2378           0 :       p = stpcpy (p, ".");
    2379           0 :       bin2hex (certinfo->objid, certinfo->objidlen, p);
    2380             : 
    2381           0 :       send_status_info (ctrl, "CERTINFO",
    2382             :                         certtype, strlen (certtype),
    2383             :                         buf, strlen (buf),
    2384             :                         NULL, (size_t)0);
    2385           0 :       xfree (buf);
    2386             :     }
    2387           0 :   return 0;
    2388             : }
    2389             : 
    2390             : 
    2391             : /* Get the keygrip of the private key object PRKDF.  On success the
    2392             :    keygrip gets returned in the caller provided 41 byte buffer
    2393             :    R_GRIPSTR. */
    2394             : static gpg_error_t
    2395           0 : keygripstr_from_prkdf (app_t app, prkdf_object_t prkdf, char *r_gripstr)
    2396             : {
    2397             :   gpg_error_t err;
    2398             :   cdf_object_t cdf;
    2399             :   unsigned char *der;
    2400             :   size_t derlen;
    2401             :   ksba_cert_t cert;
    2402             : 
    2403             :   /* FIXME: We should check whether a public key directory file and a
    2404             :      matching public key for PRKDF is available.  This should make
    2405             :      extraction of the key much easier.  My current test card doesn't
    2406             :      have one, so we can only use the fallback solution bu looking for
    2407             :      a matching certificate and extract the key from there. */
    2408             : 
    2409             :   /* Look for a matching certificate. A certificate matches if the Id
    2410             :      matches the one of the private key info. */
    2411           0 :   for (cdf = app->app_local->certificate_info; cdf; cdf = cdf->next)
    2412           0 :     if (cdf->objidlen == prkdf->objidlen
    2413           0 :         && !memcmp (cdf->objid, prkdf->objid, prkdf->objidlen))
    2414           0 :       break;
    2415           0 :   if (!cdf)
    2416           0 :     for (cdf = app->app_local->trusted_certificate_info; cdf; cdf = cdf->next)
    2417           0 :       if (cdf->objidlen == prkdf->objidlen
    2418           0 :           && !memcmp (cdf->objid, prkdf->objid, prkdf->objidlen))
    2419           0 :         break;
    2420           0 :   if (!cdf)
    2421           0 :     for (cdf = app->app_local->useful_certificate_info; cdf; cdf = cdf->next)
    2422           0 :       if (cdf->objidlen == prkdf->objidlen
    2423           0 :           && !memcmp (cdf->objid, prkdf->objid, prkdf->objidlen))
    2424           0 :         break;
    2425           0 :   if (!cdf)
    2426           0 :     return gpg_error (GPG_ERR_NOT_FOUND);
    2427             : 
    2428           0 :   err = readcert_by_cdf (app, cdf, &der, &derlen);
    2429           0 :   if (err)
    2430           0 :     return err;
    2431             : 
    2432           0 :   err = ksba_cert_new (&cert);
    2433           0 :   if (!err)
    2434           0 :     err = ksba_cert_init_from_mem (cert, der, derlen);
    2435           0 :   xfree (der);
    2436           0 :   if (!err)
    2437           0 :     err = app_help_get_keygrip_string (cert, r_gripstr);
    2438           0 :   ksba_cert_release (cert);
    2439             : 
    2440           0 :   return err;
    2441             : }
    2442             : 
    2443             : 
    2444             : 
    2445             : 
    2446             : /* Helper to do_learn_status: Send information about all known
    2447             :    keypairs back.  FIXME: much code duplication from
    2448             :    send_certinfo(). */
    2449             : static gpg_error_t
    2450           0 : send_keypairinfo (app_t app, ctrl_t ctrl, prkdf_object_t keyinfo)
    2451             : {
    2452             :   gpg_error_t err;
    2453             : 
    2454           0 :   for (; keyinfo; keyinfo = keyinfo->next)
    2455             :     {
    2456             :       char gripstr[40+1];
    2457             :       char *buf, *p;
    2458             :       int j;
    2459             : 
    2460           0 :       buf = xtrymalloc (9 + keyinfo->objidlen*2 + 1);
    2461           0 :       if (!buf)
    2462           0 :         return gpg_error_from_syserror ();
    2463           0 :       p = stpcpy (buf, "P15");
    2464           0 :       if (app->app_local->home_df)
    2465             :         {
    2466           0 :           snprintf (p, 6, "-%04hX",
    2467           0 :                     (unsigned int)(app->app_local->home_df & 0xffff));
    2468           0 :           p += 5;
    2469             :         }
    2470           0 :       p = stpcpy (p, ".");
    2471           0 :       bin2hex (keyinfo->objid, keyinfo->objidlen, p);
    2472             : 
    2473           0 :       err = keygripstr_from_prkdf (app, keyinfo, gripstr);
    2474           0 :       if (err)
    2475             :         {
    2476           0 :           log_error ("can't get keygrip from ");
    2477           0 :           for (j=0; j < keyinfo->pathlen; j++)
    2478           0 :             log_printf ("%04hX", keyinfo->path[j]);
    2479           0 :           log_printf (": %s\n", gpg_strerror (err));
    2480             :         }
    2481             :       else
    2482             :         {
    2483           0 :           assert (strlen (gripstr) == 40);
    2484           0 :           send_status_info (ctrl, "KEYPAIRINFO",
    2485             :                             gripstr, 40,
    2486             :                             buf, strlen (buf),
    2487             :                             NULL, (size_t)0);
    2488             :         }
    2489           0 :       xfree (buf);
    2490             :     }
    2491           0 :   return 0;
    2492             : }
    2493             : 
    2494             : 
    2495             : 
    2496             : /* This is the handler for the LEARN command.  */
    2497             : static gpg_error_t
    2498           0 : do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
    2499             : {
    2500             :   gpg_error_t err;
    2501             : 
    2502           0 :   if ((flags & 1))
    2503           0 :     err = 0;
    2504             :   else
    2505             :     {
    2506           0 :       err = send_certinfo (app, ctrl, "100", app->app_local->certificate_info);
    2507           0 :       if (!err)
    2508           0 :         err = send_certinfo (app, ctrl, "101",
    2509           0 :                              app->app_local->trusted_certificate_info);
    2510           0 :       if (!err)
    2511           0 :         err = send_certinfo (app, ctrl, "102",
    2512           0 :                              app->app_local->useful_certificate_info);
    2513             :     }
    2514             : 
    2515           0 :   if (!err)
    2516           0 :     err = send_keypairinfo (app, ctrl, app->app_local->private_key_info);
    2517             : 
    2518           0 :   return err;
    2519             : }
    2520             : 
    2521             : 
    2522             : /* Read a certifciate using the information in CDF and return the
    2523             :    certificate in a newly llocated buffer R_CERT and its length
    2524             :    R_CERTLEN. */
    2525             : static gpg_error_t
    2526           0 : readcert_by_cdf (app_t app, cdf_object_t cdf,
    2527             :                  unsigned char **r_cert, size_t *r_certlen)
    2528             : {
    2529             :   gpg_error_t err;
    2530           0 :   unsigned char *buffer = NULL;
    2531             :   const unsigned char *p, *save_p;
    2532             :   size_t buflen, n;
    2533             :   int class, tag, constructed, ndef;
    2534             :   size_t totobjlen, objlen, hdrlen;
    2535             :   int rootca;
    2536             :   int i;
    2537             : 
    2538           0 :   *r_cert = NULL;
    2539           0 :   *r_certlen = 0;
    2540             : 
    2541             :   /* First check whether it has been cached. */
    2542           0 :   if (cdf->image)
    2543             :     {
    2544           0 :       *r_cert = xtrymalloc (cdf->imagelen);
    2545           0 :       if (!*r_cert)
    2546           0 :         return gpg_error_from_syserror ();
    2547           0 :       memcpy (*r_cert, cdf->image, cdf->imagelen);
    2548           0 :       *r_certlen = cdf->imagelen;
    2549           0 :       return 0;
    2550             :     }
    2551             : 
    2552             :   /* Read the entire file.  fixme: This could be optimized by first
    2553             :      reading the header to figure out how long the certificate
    2554             :      actually is. */
    2555           0 :   err = select_ef_by_path (app, cdf->path, cdf->pathlen);
    2556           0 :   if (err)
    2557           0 :     goto leave;
    2558             : 
    2559           0 :   err = iso7816_read_binary (app->slot, cdf->off, cdf->len, &buffer, &buflen);
    2560           0 :   if (!err && (!buflen || *buffer == 0xff))
    2561           0 :     err = gpg_error (GPG_ERR_NOT_FOUND);
    2562           0 :   if (err)
    2563             :     {
    2564           0 :       log_error ("error reading certificate with Id ");
    2565           0 :       for (i=0; i < cdf->objidlen; i++)
    2566           0 :         log_printf ("%02X", cdf->objid[i]);
    2567           0 :       log_printf (": %s\n", gpg_strerror (err));
    2568           0 :       goto leave;
    2569             :     }
    2570             : 
    2571             :   /* Check whether this is really a certificate.  */
    2572           0 :   p = buffer;
    2573           0 :   n = buflen;
    2574           0 :   err = parse_ber_header (&p, &n, &class, &tag, &constructed,
    2575             :                           &ndef, &objlen, &hdrlen);
    2576           0 :   if (err)
    2577           0 :     goto leave;
    2578             : 
    2579           0 :   if (class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE && constructed)
    2580           0 :     rootca = 0;
    2581           0 :   else if ( class == CLASS_UNIVERSAL && tag == TAG_SET && constructed )
    2582           0 :     rootca = 1;
    2583             :   else
    2584             :     {
    2585           0 :       err = gpg_error (GPG_ERR_INV_OBJ);
    2586           0 :       goto leave;
    2587             :     }
    2588           0 :   totobjlen = objlen + hdrlen;
    2589           0 :   assert (totobjlen <= buflen);
    2590             : 
    2591           0 :   err = parse_ber_header (&p, &n, &class, &tag, &constructed,
    2592             :                           &ndef, &objlen, &hdrlen);
    2593           0 :   if (err)
    2594           0 :     goto leave;
    2595             : 
    2596           0 :   if (!rootca
    2597           0 :       && class == CLASS_UNIVERSAL && tag == TAG_OBJECT_ID && !constructed)
    2598             :     {
    2599             :       /* The certificate seems to be contained in a userCertificate
    2600             :          container.  Skip this and assume the following sequence is
    2601             :          the certificate. */
    2602           0 :       if (n < objlen)
    2603             :         {
    2604           0 :           err = gpg_error (GPG_ERR_INV_OBJ);
    2605           0 :           goto leave;
    2606             :         }
    2607           0 :       p += objlen;
    2608           0 :       n -= objlen;
    2609           0 :       save_p = p;
    2610           0 :       err = parse_ber_header (&p, &n, &class, &tag, &constructed,
    2611             :                               &ndef, &objlen, &hdrlen);
    2612           0 :       if (err)
    2613           0 :         goto leave;
    2614           0 :       if ( !(class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE && constructed) )
    2615             :         {
    2616           0 :           err = gpg_error (GPG_ERR_INV_OBJ);
    2617           0 :           goto leave;
    2618             :         }
    2619           0 :       totobjlen = objlen + hdrlen;
    2620           0 :       assert (save_p + totobjlen <= buffer + buflen);
    2621           0 :       memmove (buffer, save_p, totobjlen);
    2622             :     }
    2623             : 
    2624           0 :   *r_cert = buffer;
    2625           0 :   buffer = NULL;
    2626           0 :   *r_certlen = totobjlen;
    2627             : 
    2628             :   /* Try to cache it. */
    2629           0 :   if (!cdf->image && (cdf->image = xtrymalloc (*r_certlen)))
    2630             :     {
    2631           0 :       memcpy (cdf->image, *r_cert, *r_certlen);
    2632           0 :       cdf->imagelen = *r_certlen;
    2633             :     }
    2634             : 
    2635             : 
    2636             :  leave:
    2637           0 :   xfree (buffer);
    2638           0 :   return err;
    2639             : }
    2640             : 
    2641             : 
    2642             : /* Handler for the READCERT command.
    2643             : 
    2644             :    Read the certificate with id CERTID (as returned by learn_status in
    2645             :    the CERTINFO status lines) and return it in the freshly allocated
    2646             :    buffer to be stored at R_CERT and its length at R_CERTLEN.  A error
    2647             :    code will be returned on failure and R_CERT and R_CERTLEN will be
    2648             :    set to (NULL,0). */
    2649             : static gpg_error_t
    2650           0 : do_readcert (app_t app, const char *certid,
    2651             :              unsigned char **r_cert, size_t *r_certlen)
    2652             : {
    2653             :   gpg_error_t err;
    2654             :   cdf_object_t cdf;
    2655             : 
    2656           0 :   *r_cert = NULL;
    2657           0 :   *r_certlen = 0;
    2658           0 :   err = cdf_object_from_certid (app, certid, &cdf);
    2659           0 :   if (!err)
    2660           0 :     err = readcert_by_cdf (app, cdf, r_cert, r_certlen);
    2661           0 :   return err;
    2662             : }
    2663             : 
    2664             : 
    2665             : 
    2666             : /* Implement the GETATTR command.  This is similar to the LEARN
    2667             :    command but returns just one value via the status interface. */
    2668             : static gpg_error_t
    2669           0 : do_getattr (app_t app, ctrl_t ctrl, const char *name)
    2670             : {
    2671             :   gpg_error_t err;
    2672             : 
    2673           0 :   if (!strcmp (name, "$AUTHKEYID"))
    2674             :     {
    2675             :       char *buf, *p;
    2676             :       prkdf_object_t prkdf;
    2677             : 
    2678             :       /* We return the ID of the first private keycapable of
    2679             :          signing. */
    2680           0 :       for (prkdf = app->app_local->private_key_info; prkdf;
    2681           0 :            prkdf = prkdf->next)
    2682           0 :         if (prkdf->usageflags.sign)
    2683           0 :           break;
    2684           0 :       if (prkdf)
    2685             :         {
    2686           0 :           buf = xtrymalloc (9 + prkdf->objidlen*2 + 1);
    2687           0 :           if (!buf)
    2688           0 :             return gpg_error_from_syserror ();
    2689           0 :           p = stpcpy (buf, "P15");
    2690           0 :           if (app->app_local->home_df)
    2691             :             {
    2692           0 :               snprintf (p, 6, "-%04hX",
    2693           0 :                         (unsigned int)(app->app_local->home_df & 0xffff));
    2694           0 :               p += 5;
    2695             :             }
    2696           0 :           p = stpcpy (p, ".");
    2697           0 :           bin2hex (prkdf->objid, prkdf->objidlen, p);
    2698             : 
    2699           0 :           send_status_info (ctrl, name, buf, strlen (buf), NULL, 0);
    2700           0 :           xfree (buf);
    2701           0 :           return 0;
    2702             :         }
    2703             :     }
    2704           0 :   else if (!strcmp (name, "$DISPSERIALNO"))
    2705             :     {
    2706             :       /* For certain cards we return special IDs.  There is no
    2707             :          general rule for it so we need to decide case by case. */
    2708           0 :       if (app->app_local->card_type == CARD_TYPE_BELPIC)
    2709             :         {
    2710             :           /* The eID card has a card number printed on the front matter
    2711             :              which seems to be a good indication. */
    2712             :           unsigned char *buffer;
    2713             :           const unsigned char *p;
    2714             :           size_t buflen, n;
    2715           0 :           unsigned short path[] = { 0x3F00, 0xDF01, 0x4031 };
    2716             : 
    2717           0 :           err = select_ef_by_path (app, path, DIM(path) );
    2718           0 :           if (!err)
    2719           0 :             err = iso7816_read_binary (app->slot, 0, 0, &buffer, &buflen);
    2720           0 :           if (err)
    2721             :             {
    2722           0 :               log_error ("error accessing EF(ID): %s\n", gpg_strerror (err));
    2723           0 :               return err;
    2724             :             }
    2725             : 
    2726           0 :           p = find_tlv (buffer, buflen, 1, &n);
    2727           0 :           if (p && n == 12)
    2728             :             {
    2729             :               char tmp[12+2+1];
    2730           0 :               memcpy (tmp, p, 3);
    2731           0 :               tmp[3] = '-';
    2732           0 :               memcpy (tmp+4, p+3, 7);
    2733           0 :               tmp[11] = '-';
    2734           0 :               memcpy (tmp+12, p+10, 2);
    2735           0 :               tmp[14] = 0;
    2736           0 :               send_status_info (ctrl, name, tmp, strlen (tmp), NULL, 0);
    2737           0 :               xfree (buffer);
    2738           0 :               return 0;
    2739             :             }
    2740           0 :           xfree (buffer);
    2741             :         }
    2742             : 
    2743             :     }
    2744           0 :   return gpg_error (GPG_ERR_INV_NAME);
    2745             : }
    2746             : 
    2747             : 
    2748             : 
    2749             : 
    2750             : /* Micardo cards require special treatment. This is a helper for the
    2751             :    crypto functions to manage the security environment.  We expect that
    2752             :    the key file has already been selected. FID is the one of the
    2753             :    selected key. */
    2754             : static gpg_error_t
    2755           0 : micardo_mse (app_t app, unsigned short fid)
    2756             : {
    2757             :   gpg_error_t err;
    2758             :   int recno;
    2759           0 :   unsigned short refdata = 0;
    2760             :   int se_num;
    2761             :   unsigned char msebuf[10];
    2762             : 
    2763             :   /* Read the KeyD file containing extra information on keys. */
    2764           0 :   err = iso7816_select_file (app->slot, 0x0013, 0, NULL, NULL);
    2765           0 :   if (err)
    2766             :     {
    2767           0 :       log_error ("error reading EF_keyD: %s\n", gpg_strerror (err));
    2768           0 :       return err;
    2769             :     }
    2770             : 
    2771           0 :   for (recno = 1, se_num = -1; ; recno++)
    2772             :     {
    2773             :       unsigned char *buffer;
    2774             :       size_t buflen;
    2775             :       size_t n, nn;
    2776             :       const unsigned char *p, *pp;
    2777             : 
    2778           0 :       err = iso7816_read_record (app->slot, recno, 1, 0, &buffer, &buflen);
    2779           0 :       if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
    2780           0 :         break; /* ready */
    2781           0 :       if (err)
    2782             :         {
    2783           0 :           log_error ("error reading EF_keyD record: %s\n",
    2784             :                      gpg_strerror (err));
    2785           0 :           return err;
    2786             :         }
    2787           0 :       log_printhex ("keyD record:", buffer, buflen);
    2788           0 :       p = find_tlv (buffer, buflen, 0x83, &n);
    2789           0 :       if (p && n == 4 && ((p[2]<<8)|p[3]) == fid)
    2790             :         {
    2791           0 :           refdata = ((p[0]<<8)|p[1]);
    2792             :           /* Locate the SE DO and the there included sec env number. */
    2793           0 :           p = find_tlv (buffer, buflen, 0x7b, &n);
    2794           0 :           if (p && n)
    2795             :             {
    2796           0 :               pp = find_tlv (p, n, 0x80, &nn);
    2797           0 :               if (pp && nn == 1)
    2798             :                 {
    2799           0 :                   se_num = *pp;
    2800           0 :                   xfree (buffer);
    2801           0 :                   break; /* found. */
    2802             :                 }
    2803             :             }
    2804             :         }
    2805           0 :       xfree (buffer);
    2806           0 :     }
    2807           0 :   if (se_num == -1)
    2808             :     {
    2809           0 :       log_error ("CRT for keyfile %04hX not found\n", fid);
    2810           0 :       return gpg_error (GPG_ERR_NOT_FOUND);
    2811             :     }
    2812             : 
    2813             : 
    2814             :   /* Restore the security environment to SE_NUM if needed */
    2815           0 :   if (se_num)
    2816             :     {
    2817           0 :       err = iso7816_manage_security_env (app->slot, 0xf3, se_num, NULL, 0);
    2818           0 :       if (err)
    2819             :         {
    2820           0 :           log_error ("restoring SE to %d failed: %s\n",
    2821             :                      se_num, gpg_strerror (err));
    2822           0 :           return err;
    2823             :         }
    2824             :     }
    2825             : 
    2826             :   /* Set the DST reference data. */
    2827           0 :   msebuf[0] = 0x83;
    2828           0 :   msebuf[1] = 0x03;
    2829           0 :   msebuf[2] = 0x80;
    2830           0 :   msebuf[3] = (refdata >> 8);
    2831           0 :   msebuf[4] = refdata;
    2832           0 :   err = iso7816_manage_security_env (app->slot, 0x41, 0xb6, msebuf, 5);
    2833           0 :   if (err)
    2834             :     {
    2835           0 :       log_error ("setting SE to reference file %04hX failed: %s\n",
    2836             :                  refdata, gpg_strerror (err));
    2837           0 :       return err;
    2838             :     }
    2839           0 :   return 0;
    2840             : }
    2841             : 
    2842             : 
    2843             : 
    2844             : /* Handler for the PKSIGN command.
    2845             : 
    2846             :    Create the signature and return the allocated result in OUTDATA.
    2847             :    If a PIN is required, the PINCB will be used to ask for the PIN;
    2848             :    that callback should return the PIN in an allocated buffer and
    2849             :    store that as the 3rd argument.  */
    2850             : static gpg_error_t
    2851           0 : do_sign (app_t app, const char *keyidstr, int hashalgo,
    2852             :          gpg_error_t (*pincb)(void*, const char *, char **),
    2853             :          void *pincb_arg,
    2854             :          const void *indata, size_t indatalen,
    2855             :          unsigned char **outdata, size_t *outdatalen )
    2856             : {
    2857             :   static unsigned char sha1_prefix[15] = /* Object ID is 1.3.14.3.2.26 */
    2858             :     { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
    2859             :       0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
    2860             :   static unsigned char rmd160_prefix[15] = /* Object ID is 1.3.36.3.2.1 */
    2861             :     { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
    2862             :       0x02, 0x01, 0x05, 0x00, 0x04, 0x14 };
    2863             : 
    2864             :   gpg_error_t err;
    2865             :   int i;
    2866             :   unsigned char data[36];   /* Must be large enough for a SHA-1 digest
    2867             :                                + the largest OID prefix above and also
    2868             :                                fit the 36 bytes of md5sha1.  */
    2869             :   prkdf_object_t prkdf;    /* The private key object. */
    2870             :   aodf_object_t aodf;      /* The associated authentication object. */
    2871           0 :   int no_data_padding = 0; /* True if the card want the data without padding.*/
    2872           0 :   int mse_done = 0;        /* Set to true if the MSE has been done. */
    2873             : 
    2874           0 :   if (!keyidstr || !*keyidstr)
    2875           0 :     return gpg_error (GPG_ERR_INV_VALUE);
    2876           0 :   if (indatalen != 20 && indatalen != 16 && indatalen != 35 && indatalen != 36)
    2877           0 :     return gpg_error (GPG_ERR_INV_VALUE);
    2878             : 
    2879           0 :   err = prkdf_object_from_keyidstr (app, keyidstr, &prkdf);
    2880           0 :   if (err)
    2881           0 :     return err;
    2882           0 :   if (!(prkdf->usageflags.sign || prkdf->usageflags.sign_recover
    2883           0 :         ||prkdf->usageflags.non_repudiation))
    2884             :     {
    2885           0 :       log_error ("key %s may not be used for signing\n", keyidstr);
    2886           0 :       return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
    2887             :     }
    2888             : 
    2889           0 :   if (!prkdf->authid)
    2890             :     {
    2891           0 :       log_error ("no authentication object defined for %s\n", keyidstr);
    2892             :       /* fixme: we might want to go ahead and do without PIN
    2893             :          verification. */
    2894           0 :       return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
    2895             :     }
    2896             : 
    2897             :   /* Find the authentication object to this private key object. */
    2898           0 :   for (aodf = app->app_local->auth_object_info; aodf; aodf = aodf->next)
    2899           0 :     if (aodf->objidlen == prkdf->authidlen
    2900           0 :         && !memcmp (aodf->objid, prkdf->authid, prkdf->authidlen))
    2901           0 :       break;
    2902           0 :   if (!aodf)
    2903             :     {
    2904           0 :       log_error ("authentication object for %s missing\n", keyidstr);
    2905           0 :       return gpg_error (GPG_ERR_INV_CARD);
    2906             :     }
    2907           0 :   if (aodf->authid)
    2908             :     {
    2909           0 :       log_error ("PIN verification is protected by an "
    2910             :                  "additional authentication token\n");
    2911           0 :       return gpg_error (GPG_ERR_BAD_PIN_METHOD);
    2912             :     }
    2913           0 :   if (aodf->pinflags.integrity_protected
    2914           0 :       || aodf->pinflags.confidentiality_protected)
    2915             :     {
    2916           0 :       log_error ("PIN verification requires unsupported protection method\n");
    2917           0 :       return gpg_error (GPG_ERR_BAD_PIN_METHOD);
    2918             :     }
    2919           0 :   if (!aodf->stored_length && aodf->pinflags.needs_padding)
    2920             :     {
    2921           0 :       log_error ("PIN verification requires padding but no length known\n");
    2922           0 :       return gpg_error (GPG_ERR_INV_CARD);
    2923             :     }
    2924             : 
    2925             :   /* Select the key file.  Note that this may change the security
    2926             :      environment thus we do it before PIN verification. */
    2927           0 :   err = select_ef_by_path (app, prkdf->path, prkdf->pathlen);
    2928           0 :   if (err)
    2929             :     {
    2930           0 :       log_error ("error selecting file for key %s: %s\n",
    2931           0 :                  keyidstr, gpg_strerror (errno));
    2932           0 :       return err;
    2933             :     }
    2934             : 
    2935             : 
    2936             :   /* Due to the fact that the non-repudiation signature on a BELPIC
    2937             :      card requires a verify immediately before the DSO we set the
    2938             :      MSE before we do the verification.  Other cards might allow to do
    2939             :      this also but I don't want to break anything, thus we do it only
    2940             :      for the BELPIC card here. */
    2941           0 :   if (app->app_local->card_type == CARD_TYPE_BELPIC)
    2942             :     {
    2943             :       unsigned char mse[5];
    2944             : 
    2945           0 :       mse[0] = 4;    /* Length of the template. */
    2946           0 :       mse[1] = 0x80; /* Algorithm reference tag. */
    2947           0 :       if (hashalgo == MD_USER_TLS_MD5SHA1)
    2948           0 :         mse[2] = 0x01; /* Let card do pkcs#1 0xFF padding. */
    2949             :       else
    2950           0 :         mse[2] = 0x02; /* RSASSA-PKCS1-v1.5 using SHA1. */
    2951           0 :       mse[3] = 0x84; /* Private key reference tag. */
    2952           0 :       mse[4] = prkdf->key_reference_valid? prkdf->key_reference : 0x82;
    2953             : 
    2954           0 :       err = iso7816_manage_security_env (app->slot,
    2955             :                                          0x41, 0xB6,
    2956             :                                          mse, sizeof mse);
    2957           0 :       no_data_padding = 1;
    2958           0 :       mse_done = 1;
    2959             :     }
    2960           0 :   if (err)
    2961             :     {
    2962           0 :       log_error ("MSE failed: %s\n", gpg_strerror (err));
    2963           0 :       return err;
    2964             :     }
    2965             : 
    2966             : 
    2967             :   /* Now that we have all the information available, prepare and run
    2968             :      the PIN verification.*/
    2969             :   if (1)
    2970             :     {
    2971             :       char *pinvalue;
    2972             :       size_t pinvaluelen;
    2973             :       const char *errstr;
    2974             :       const char *s;
    2975             : 
    2976           0 :       if (prkdf->usageflags.non_repudiation
    2977           0 :           && app->app_local->card_type == CARD_TYPE_BELPIC)
    2978           0 :         err = pincb (pincb_arg, "PIN (qualified signature!)", &pinvalue);
    2979             :       else
    2980           0 :         err = pincb (pincb_arg, "PIN", &pinvalue);
    2981           0 :       if (err)
    2982             :         {
    2983           0 :           log_info ("PIN callback returned error: %s\n", gpg_strerror (err));
    2984           0 :           return err;
    2985             :         }
    2986             : 
    2987             :       /* We might need to cope with UTF8 things here.  Not sure how
    2988             :          min_length etc. are exactly defined, for now we take them as
    2989             :          a plain octet count. */
    2990             : 
    2991           0 :       if (strlen (pinvalue) < aodf->min_length)
    2992             :         {
    2993           0 :           log_error ("PIN is too short; minimum length is %lu\n",
    2994             :                      aodf->min_length);
    2995           0 :           err = gpg_error (GPG_ERR_BAD_PIN);
    2996             :         }
    2997           0 :       else if (aodf->stored_length && strlen (pinvalue) > aodf->stored_length)
    2998             :         {
    2999             :           /* This would otherwise truncate the PIN silently. */
    3000           0 :           log_error ("PIN is too large; maximum length is %lu\n",
    3001             :                      aodf->stored_length);
    3002           0 :           err = gpg_error (GPG_ERR_BAD_PIN);
    3003             :         }
    3004           0 :       else if (aodf->max_length_valid && strlen (pinvalue) > aodf->max_length)
    3005             :         {
    3006           0 :           log_error ("PIN is too large; maximum length is %lu\n",
    3007             :                      aodf->max_length);
    3008           0 :           err = gpg_error (GPG_ERR_BAD_PIN);
    3009             :         }
    3010             : 
    3011           0 :       if (err)
    3012             :         {
    3013           0 :           xfree (pinvalue);
    3014           0 :           return err;
    3015             :         }
    3016             : 
    3017           0 :       errstr = NULL;
    3018           0 :       err = 0;
    3019           0 :       switch (aodf->pintype)
    3020             :         {
    3021             :         case PIN_TYPE_BCD:
    3022             :         case PIN_TYPE_ASCII_NUMERIC:
    3023           0 :           for (s=pinvalue; digitp (s); s++)
    3024             :             ;
    3025           0 :           if (*s)
    3026             :             {
    3027           0 :               errstr = "Non-numeric digits found in PIN";
    3028           0 :               err = gpg_error (GPG_ERR_BAD_PIN);
    3029             :             }
    3030           0 :           break;
    3031             :         case PIN_TYPE_UTF8:
    3032           0 :           break;
    3033             :         case PIN_TYPE_HALF_NIBBLE_BCD:
    3034           0 :           errstr = "PIN type Half-Nibble-BCD is not supported";
    3035           0 :           break;
    3036             :         case PIN_TYPE_ISO9564_1:
    3037           0 :           errstr = "PIN type ISO9564-1 is not supported";
    3038           0 :           break;
    3039             :         default:
    3040           0 :           errstr = "Unknown PIN type";
    3041           0 :           break;
    3042             :         }
    3043           0 :       if (errstr)
    3044             :         {
    3045           0 :           log_error ("can't verify PIN: %s\n", errstr);
    3046           0 :           xfree (pinvalue);
    3047           0 :           return err? err : gpg_error (GPG_ERR_BAD_PIN_METHOD);
    3048             :         }
    3049             : 
    3050             : 
    3051           0 :       if (aodf->pintype == PIN_TYPE_BCD )
    3052             :         {
    3053             :           char *paddedpin;
    3054             :           int ndigits;
    3055             : 
    3056           0 :           for (ndigits=0, s=pinvalue; *s; ndigits++, s++)
    3057             :             ;
    3058           0 :           paddedpin = xtrymalloc (aodf->stored_length+1);
    3059           0 :           if (!paddedpin)
    3060             :             {
    3061           0 :               err = gpg_error_from_syserror ();
    3062           0 :               xfree (pinvalue);
    3063           0 :               return err;
    3064             :             }
    3065             : 
    3066           0 :           i = 0;
    3067           0 :           paddedpin[i++] = 0x20 | (ndigits & 0x0f);
    3068           0 :           for (s=pinvalue; i < aodf->stored_length && *s && s[1]; s = s+2 )
    3069           0 :             paddedpin[i++] = (((*s - '0') << 4) | ((s[1] - '0') & 0x0f));
    3070           0 :           if (i < aodf->stored_length && *s)
    3071           0 :             paddedpin[i++] = (((*s - '0') << 4)
    3072           0 :                               |((aodf->pad_char_valid?aodf->pad_char:0)&0x0f));
    3073             : 
    3074           0 :           if (aodf->pinflags.needs_padding)
    3075           0 :             while (i < aodf->stored_length)
    3076           0 :               paddedpin[i++] = aodf->pad_char_valid? aodf->pad_char : 0;
    3077             : 
    3078           0 :           xfree (pinvalue);
    3079           0 :           pinvalue = paddedpin;
    3080           0 :           pinvaluelen = i;
    3081             :         }
    3082           0 :       else if (aodf->pinflags.needs_padding)
    3083             :         {
    3084             :           char *paddedpin;
    3085             : 
    3086           0 :           paddedpin = xtrymalloc (aodf->stored_length+1);
    3087           0 :           if (!paddedpin)
    3088             :             {
    3089           0 :               err = gpg_error_from_syserror ();
    3090           0 :               xfree (pinvalue);
    3091           0 :               return err;
    3092             :             }
    3093           0 :           for (i=0, s=pinvalue; i < aodf->stored_length && *s; i++, s++)
    3094           0 :             paddedpin[i] = *s;
    3095             :           /* Not sure what padding char to use if none has been set.
    3096             :              For now we use 0x00; maybe a space would be better. */
    3097           0 :           for (; i < aodf->stored_length; i++)
    3098           0 :             paddedpin[i] = aodf->pad_char_valid? aodf->pad_char : 0;
    3099           0 :           paddedpin[i] = 0;
    3100           0 :           pinvaluelen = i;
    3101           0 :           xfree (pinvalue);
    3102           0 :           pinvalue = paddedpin;
    3103             :         }
    3104             :       else
    3105           0 :         pinvaluelen = strlen (pinvalue);
    3106             : 
    3107           0 :       err = iso7816_verify (app->slot,
    3108           0 :                             aodf->pin_reference_valid? aodf->pin_reference : 0,
    3109             :                             pinvalue, pinvaluelen);
    3110           0 :       xfree (pinvalue);
    3111           0 :       if (err)
    3112             :         {
    3113           0 :           log_error ("PIN verification failed: %s\n", gpg_strerror (err));
    3114           0 :           return err;
    3115             :         }
    3116           0 :       log_debug ("PIN verification succeeded\n");
    3117             :     }
    3118             : 
    3119             :   /* Prepare the DER object from INDATA. */
    3120           0 :   if (indatalen == 36)
    3121             :     {
    3122             :       /* No ASN.1 container used. */
    3123           0 :       if (hashalgo != MD_USER_TLS_MD5SHA1)
    3124           0 :         return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
    3125           0 :       memcpy (data, indata, indatalen);
    3126             :     }
    3127           0 :   else if (indatalen == 35)
    3128             :     {
    3129             :       /* Alright, the caller was so kind to send us an already
    3130             :          prepared DER object.  Check that it is what we want and that
    3131             :          it matches the hash algorithm. */
    3132           0 :       if (hashalgo == GCRY_MD_SHA1 && !memcmp (indata, sha1_prefix, 15))
    3133             :         ;
    3134           0 :       else if (hashalgo == GCRY_MD_RMD160
    3135           0 :                && !memcmp (indata, rmd160_prefix, 15))
    3136             :         ;
    3137             :       else
    3138           0 :         return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
    3139           0 :       memcpy (data, indata, indatalen);
    3140             :     }
    3141             :   else
    3142             :     {
    3143             :       /* Need to prepend the prefix. */
    3144           0 :       if (hashalgo == GCRY_MD_SHA1)
    3145           0 :         memcpy (data, sha1_prefix, 15);
    3146           0 :       else if (hashalgo == GCRY_MD_RMD160)
    3147           0 :         memcpy (data, rmd160_prefix, 15);
    3148             :       else
    3149           0 :         return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
    3150           0 :       memcpy (data+15, indata, indatalen);
    3151             :     }
    3152             : 
    3153             :   /* Manage security environment needs to be weaked for certain cards. */
    3154           0 :   if (mse_done)
    3155           0 :     err = 0;
    3156           0 :   else if (app->app_local->card_type == CARD_TYPE_TCOS)
    3157             :     {
    3158             :       /* TCOS creates signatures always using the local key 0.  MSE
    3159             :          may not be used. */
    3160             :     }
    3161           0 :   else if (app->app_local->card_type == CARD_TYPE_MICARDO)
    3162             :     {
    3163           0 :       if (!prkdf->pathlen)
    3164           0 :         err = gpg_error (GPG_ERR_BUG);
    3165             :       else
    3166           0 :         err = micardo_mse (app, prkdf->path[prkdf->pathlen-1]);
    3167             :     }
    3168           0 :   else if (prkdf->key_reference_valid)
    3169             :     {
    3170             :       unsigned char mse[3];
    3171             : 
    3172           0 :       mse[0] = 0x84; /* Select asym. key. */
    3173           0 :       mse[1] = 1;
    3174           0 :       mse[2] = prkdf->key_reference;
    3175             : 
    3176           0 :       err = iso7816_manage_security_env (app->slot,
    3177             :                                          0x41, 0xB6,
    3178             :                                          mse, sizeof mse);
    3179             :     }
    3180           0 :   if (err)
    3181             :     {
    3182           0 :       log_error ("MSE failed: %s\n", gpg_strerror (err));
    3183           0 :       return err;
    3184             :     }
    3185             : 
    3186           0 :   if (hashalgo == MD_USER_TLS_MD5SHA1)
    3187           0 :     err = iso7816_compute_ds (app->slot, 0, data, 36, 0, outdata, outdatalen);
    3188           0 :   else if (no_data_padding)
    3189           0 :     err = iso7816_compute_ds (app->slot, 0, data+15, 20, 0,outdata,outdatalen);
    3190             :   else
    3191           0 :     err = iso7816_compute_ds (app->slot, 0, data, 35, 0, outdata, outdatalen);
    3192           0 :   return err;
    3193             : }
    3194             : 
    3195             : 
    3196             : /* Handler for the PKAUTH command.
    3197             : 
    3198             :    This is basically the same as the PKSIGN command but we first check
    3199             :    that the requested key is suitable for authentication; that is, it
    3200             :    must match the criteria used for the attribute $AUTHKEYID.  See
    3201             :    do_sign for calling conventions; there is no HASHALGO, though. */
    3202             : static gpg_error_t
    3203           0 : do_auth (app_t app, const char *keyidstr,
    3204             :          gpg_error_t (*pincb)(void*, const char *, char **),
    3205             :          void *pincb_arg,
    3206             :          const void *indata, size_t indatalen,
    3207             :          unsigned char **outdata, size_t *outdatalen )
    3208             : {
    3209             :   gpg_error_t err;
    3210             :   prkdf_object_t prkdf;
    3211             :   int algo;
    3212             : 
    3213           0 :   if (!keyidstr || !*keyidstr)
    3214           0 :     return gpg_error (GPG_ERR_INV_VALUE);
    3215             : 
    3216           0 :   err = prkdf_object_from_keyidstr (app, keyidstr, &prkdf);
    3217           0 :   if (err)
    3218           0 :     return err;
    3219           0 :   if (!prkdf->usageflags.sign)
    3220             :     {
    3221           0 :       log_error ("key %s may not be used for authentication\n", keyidstr);
    3222           0 :       return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
    3223             :     }
    3224             : 
    3225           0 :   algo = indatalen == 36? MD_USER_TLS_MD5SHA1 : GCRY_MD_SHA1;
    3226           0 :   return do_sign (app, keyidstr, algo, pincb, pincb_arg,
    3227             :                   indata, indatalen, outdata, outdatalen);
    3228             : }
    3229             : 
    3230             : 
    3231             : 
    3232             : /* Assume that EF(DIR) has been selected.  Read its content and figure
    3233             :    out the home EF of pkcs#15.  Return that home DF or 0 if not found
    3234             :    and the value at the address of BELPIC indicates whether it was
    3235             :    found by the belpic aid. */
    3236             : static unsigned short
    3237           0 : read_home_df (int slot, int *r_belpic)
    3238             : {
    3239             :   gpg_error_t err;
    3240             :   unsigned char *buffer;
    3241             :   const unsigned char *p, *pp;
    3242             :   size_t buflen, n, nn;
    3243           0 :   unsigned short result = 0;
    3244             : 
    3245           0 :   *r_belpic = 0;
    3246             : 
    3247           0 :   err = iso7816_read_binary (slot, 0, 0, &buffer, &buflen);
    3248           0 :   if (err)
    3249             :     {
    3250           0 :       log_error ("error reading EF{DIR}: %s\n", gpg_strerror (err));
    3251           0 :       return 0;
    3252             :     }
    3253             : 
    3254             :   /* FIXME: We need to scan all records. */
    3255           0 :   p = find_tlv (buffer, buflen, 0x61, &n);
    3256           0 :   if (p && n)
    3257             :     {
    3258           0 :       pp = find_tlv (p, n, 0x4f, &nn);
    3259           0 :       if (pp && ((nn == sizeof pkcs15_aid && !memcmp (pp, pkcs15_aid, nn))
    3260           0 :                  || (*r_belpic = (nn == sizeof pkcs15be_aid
    3261           0 :                                   && !memcmp (pp, pkcs15be_aid, nn)))))
    3262             :         {
    3263           0 :           pp = find_tlv (p, n, 0x50, &nn);
    3264           0 :           if (pp) /* fixme: Filter log value? */
    3265           0 :             log_info ("pkcs#15 application label from EF(DIR) is '%.*s'\n",
    3266             :                       (int)nn, pp);
    3267           0 :           pp = find_tlv (p, n, 0x51, &nn);
    3268           0 :           if (pp && nn == 4 && *pp == 0x3f && !pp[1])
    3269             :             {
    3270           0 :               result = ((pp[2] << 8) | pp[3]);
    3271           0 :               log_info ("pkcs#15 application directory is 0x%04hX\n", result);
    3272             :             }
    3273             :         }
    3274             :     }
    3275           0 :   xfree (buffer);
    3276           0 :   return result;
    3277             : }
    3278             : 
    3279             : 
    3280             : /*
    3281             :    Select the PKCS#15 application on the card in SLOT.
    3282             :  */
    3283             : gpg_error_t
    3284           0 : app_select_p15 (app_t app)
    3285             : {
    3286           0 :   int slot = app->slot;
    3287             :   int rc;
    3288           0 :   unsigned short def_home_df = 0;
    3289           0 :   card_type_t card_type = CARD_TYPE_UNKNOWN;
    3290           0 :   int direct = 0;
    3291           0 :   int is_belpic = 0;
    3292             : 
    3293           0 :   rc = iso7816_select_application (slot, pkcs15_aid, sizeof pkcs15_aid, 0);
    3294           0 :   if (rc)
    3295             :     { /* Not found: Try to locate it from 2F00.  We use direct path
    3296             :          selection here because it seems that the Belgian eID card
    3297             :          does only allow for that.  Many other cards supports this
    3298             :          selection method too.  Note, that we don't use
    3299             :          select_application above for the Belgian card - the call
    3300             :          works but it seems that it did not switch to the correct DF.
    3301             :          Using the 2f02 just works. */
    3302           0 :       unsigned short path[1] = { 0x2f00 };
    3303             : 
    3304           0 :       rc = iso7816_select_path (app->slot, path, 1, NULL, NULL);
    3305           0 :       if (!rc)
    3306             :         {
    3307           0 :           direct = 1;
    3308           0 :           def_home_df = read_home_df (slot, &is_belpic);
    3309           0 :           if (def_home_df)
    3310             :             {
    3311           0 :               path[0] = def_home_df;
    3312           0 :               rc = iso7816_select_path (app->slot, path, 1, NULL, NULL);
    3313             :             }
    3314             :         }
    3315             :     }
    3316           0 :   if (rc)
    3317             :     { /* Still not found:  Try the default DF. */
    3318           0 :       def_home_df = 0x5015;
    3319           0 :       rc = iso7816_select_file (slot, def_home_df, 1, NULL, NULL);
    3320             :     }
    3321           0 :   if (!rc)
    3322             :     {
    3323             :       /* Determine the type of the card.  The general case is to look
    3324             :          it up from the ATR table.  For the Belgian eID card we know
    3325             :          it instantly from the AID. */
    3326           0 :       if (is_belpic)
    3327             :         {
    3328           0 :           card_type = CARD_TYPE_BELPIC;
    3329             :         }
    3330             :       else
    3331             :         {
    3332             :           unsigned char *atr;
    3333             :           size_t atrlen;
    3334             :           int i;
    3335             : 
    3336           0 :           atr = apdu_get_atr (app->slot, &atrlen);
    3337           0 :           if (!atr)
    3338           0 :             rc = gpg_error (GPG_ERR_INV_CARD);
    3339             :           else
    3340             :             {
    3341           0 :               for (i=0; card_atr_list[i].atrlen; i++)
    3342           0 :                 if (card_atr_list[i].atrlen == atrlen
    3343           0 :                     && !memcmp (card_atr_list[i].atr, atr, atrlen))
    3344             :                   {
    3345           0 :                     card_type = card_atr_list[i].type;
    3346           0 :                     break;
    3347             :                   }
    3348           0 :               xfree (atr);
    3349             :             }
    3350             :         }
    3351             :     }
    3352           0 :   if (!rc)
    3353             :     {
    3354           0 :       app->apptype = "P15";
    3355             : 
    3356           0 :       app->app_local = xtrycalloc (1, sizeof *app->app_local);
    3357           0 :       if (!app->app_local)
    3358             :         {
    3359           0 :           rc = gpg_error_from_syserror ();
    3360           0 :           goto leave;
    3361             :         }
    3362             : 
    3363             :       /* Set the home DF.  Note that we currently can't do that if the
    3364             :          selection via application ID worked.  This will store 0 there
    3365             :          instead.  FIXME: We either need to figure the home_df via the
    3366             :          DIR file or using the return values from the select file
    3367             :          APDU. */
    3368           0 :       app->app_local->home_df = def_home_df;
    3369             : 
    3370             :       /* Store the card type.  FIXME: We might want to put this into
    3371             :          the common APP structure. */
    3372           0 :       app->app_local->card_type = card_type;
    3373             : 
    3374             :       /* Store whether we may and should use direct path selection. */
    3375           0 :       app->app_local->direct_path_selection = direct;
    3376             : 
    3377             :       /* Read basic information and thus check whether this is a real
    3378             :          card.  */
    3379           0 :       rc = read_p15_info (app);
    3380           0 :       if (rc)
    3381           0 :         goto leave;
    3382             : 
    3383             :       /* Special serial number munging.  We need to check for a German
    3384             :          prototype card right here because we need to access to
    3385             :          EF(TokenInfo).  We mark such a serial number by the using a
    3386             :          prefix of FF0100. */
    3387           0 :       if (app->serialnolen == 12
    3388           0 :           && !memcmp (app->serialno, "\xD2\x76\0\0\0\0\0\0\0\0\0\0", 12))
    3389             :         {
    3390             :           /* This is a German card with a silly serial number.  Try to get
    3391             :              the serial number from the EF(TokenInfo). . */
    3392             :           unsigned char *p;
    3393             : 
    3394             :           /* FIXME: actually get it from EF(TokenInfo). */
    3395             : 
    3396           0 :           p = xtrymalloc (3 + app->serialnolen);
    3397           0 :           if (!p)
    3398           0 :             rc = gpg_error (gpg_err_code_from_errno (errno));
    3399             :           else
    3400             :             {
    3401           0 :               memcpy (p, "\xff\x01", 3);
    3402           0 :               memcpy (p+3, app->serialno, app->serialnolen);
    3403           0 :               app->serialnolen += 3;
    3404           0 :               xfree (app->serialno);
    3405           0 :               app->serialno = p;
    3406             :             }
    3407             :         }
    3408             : 
    3409           0 :       app->fnc.deinit = do_deinit;
    3410           0 :       app->fnc.learn_status = do_learn_status;
    3411           0 :       app->fnc.readcert = do_readcert;
    3412           0 :       app->fnc.getattr = do_getattr;
    3413           0 :       app->fnc.setattr = NULL;
    3414           0 :       app->fnc.genkey = NULL;
    3415           0 :       app->fnc.sign = do_sign;
    3416           0 :       app->fnc.auth = do_auth;
    3417           0 :       app->fnc.decipher = NULL;
    3418           0 :       app->fnc.change_pin = NULL;
    3419           0 :       app->fnc.check_pin = NULL;
    3420             : 
    3421             :     leave:
    3422           0 :       if (rc)
    3423           0 :         do_deinit (app);
    3424             :    }
    3425             : 
    3426           0 :   return rc;
    3427             : }

Generated by: LCOV version 1.11