scd: Introduce a virtual reader table.
[gnupg.git] / scd / app-nks.c
1 /* app-nks.c - The Telesec NKS card application.
2  * Copyright (C) 2004, 2007, 2008, 2009 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 /* Notes:
21
22   - We are now targeting TCOS 3 cards and it may happen that there is
23     a regression towards TCOS 2 cards.  Please report.
24
25   - The TKS3 AUT key is not used.  It seems that it is only useful for
26     the internal authentication command and not accessible by other
27     applications.  The key itself is in the encryption class but the
28     corresponding certificate has only the digitalSignature
29     capability.
30
31   - If required, we automagically switch between the NKS application
32     and the SigG application.  This avoids to use the DINSIG
33     application which is somewhat limited, has no support for Secure
34     Messaging as required by TCOS 3 and has no way to change the PIN
35     or even set the NullPIN.
36
37   - We use the prefix NKS-DF01 for TCOS 2 cards and NKS-NKS3 for newer
38     cards.  This is because the NKS application has moved to DF02 with
39     TCOS 3 and thus we better use a DF independent tag.
40
41   - We use only the global PINs for the NKS application.
42
43  */
44
45 #include <config.h>
46 #include <errno.h>
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <string.h>
50 #include <assert.h>
51 #include <time.h>
52
53 #include "scdaemon.h"
54 #include "i18n.h"
55 #include "iso7816.h"
56 #include "app-common.h"
57 #include "tlv.h"
58 #include "apdu.h"
59
60 static char const aid_nks[]  = { 0xD2, 0x76, 0x00, 0x00, 0x03, 0x01, 0x02 };
61 static char const aid_sigg[] = { 0xD2, 0x76, 0x00, 0x00, 0x66, 0x01 };
62
63
64 static struct
65 {
66   int is_sigg;   /* Valid for SigG application.  */
67   int fid;       /* File ID. */
68   int nks_ver;   /* 0 for NKS version 2, 3 for version 3. */
69   int certtype;  /* Type of certificate or 0 if it is not a certificate. */
70   int iskeypair; /* If true has the FID of the corresponding certificate. */
71   int issignkey; /* True if file is a key usable for signing. */
72   int isenckey;  /* True if file is a key usable for decryption. */
73   unsigned char kid;  /* Corresponding key references.  */
74 } filelist[] = {
75   { 0, 0x4531, 0, 0,  0xC000, 1, 0, 0x80 }, /* EF_PK.NKS.SIG */
76   { 0, 0xC000, 0, 101 },                    /* EF_C.NKS.SIG  */
77   { 0, 0x4331, 0, 100 },
78   { 0, 0x4332, 0, 100 },
79   { 0, 0xB000, 0, 110 },                    /* EF_PK.RCA.NKS */
80   { 0, 0x45B1, 0, 0,  0xC200, 0, 1, 0x81 }, /* EF_PK.NKS.ENC */
81   { 0, 0xC200, 0, 101 },                    /* EF_C.NKS.ENC  */
82   { 0, 0x43B1, 0, 100 },
83   { 0, 0x43B2, 0, 100 },
84 /* The authentication key is not used.  */
85 /*   { 0, 0x4571, 3, 0,  0xC500, 0, 0, 0x82 }, /\* EF_PK.NKS.AUT *\/ */
86 /*   { 0, 0xC500, 3, 101 },                    /\* EF_C.NKS.AUT  *\/ */
87   { 0, 0x45B2, 3, 0,  0xC201, 0, 1, 0x83 }, /* EF_PK.NKS.ENC1024 */
88   { 0, 0xC201, 3, 101 },                    /* EF_C.NKS.ENC1024  */
89   { 1, 0x4531, 3, 0,  0xC000, 1, 1, 0x84 }, /* EF_PK.CH.SIG  */
90   { 1, 0xC000, 0, 101 },                    /* EF_C.CH.SIG  */
91   { 1, 0xC008, 3, 101 },                    /* EF_C.CA.SIG  */
92   { 1, 0xC00E, 3, 111 },                    /* EF_C.RCA.SIG  */
93   { 0, 0 }
94 };
95
96
97
98 /* Object with application (i.e. NKS) specific data.  */
99 struct app_local_s {
100   int nks_version;  /* NKS version.  */
101
102   int sigg_active;  /* True if switched to the SigG application.  */
103   int sigg_msig_checked;/*  True if we checked for a mass signature card.  */
104   int sigg_is_msig; /* True if this is a mass signature card.  */
105
106   int need_app_select; /* Need to re-select the application.  */
107
108 };
109
110
111 \f
112 static gpg_error_t switch_application (app_t app, int enable_sigg);
113
114
115 \f
116 /* Release local data. */
117 static void
118 do_deinit (app_t app)
119 {
120   if (app && app->app_local)
121     {
122       xfree (app->app_local);
123       app->app_local = NULL;
124     }
125 }
126
127
128 static int
129 all_zero_p (void *buffer, size_t length)
130 {
131   char *p;
132
133   for (p=buffer; length; length--, p++)
134     if (*p)
135       return 0;
136   return 1;
137 }
138
139
140 /* Read the file with FID, assume it contains a public key and return
141    its keygrip in the caller provided 41 byte buffer R_GRIPSTR. */
142 static gpg_error_t
143 keygripstr_from_pk_file (app_t app, int fid, char *r_gripstr)
144 {
145   gpg_error_t err;
146   unsigned char grip[20];
147   unsigned char *buffer[2];
148   size_t buflen[2];
149   gcry_sexp_t sexp;
150   int i;
151   int offset[2] = { 0, 0 };
152
153   err = iso7816_select_file (app->slot, fid, 0, NULL, NULL);
154   if (err)
155     return err;
156   err = iso7816_read_record (app->slot, 1, 1, 0, &buffer[0], &buflen[0]);
157   if (err)
158     return err;
159   err = iso7816_read_record (app->slot, 2, 1, 0, &buffer[1], &buflen[1]);
160   if (err)
161     {
162       xfree (buffer[0]);
163       return err;
164     }
165
166   if (app->app_local->nks_version < 3)
167     {
168       /* Old versions of NKS store the values in a TLV encoded format.
169          We need to do some checks.  */
170       for (i=0; i < 2; i++)
171         {
172           /* Check that the value appears like an integer encoded as
173              Simple-TLV.  We don't check the tag because the tests cards I
174              have use 1 for both, the modulus and the exponent - the
175              example in the documentation gives 2 for the exponent. */
176           if (buflen[i] < 3)
177             err = gpg_error (GPG_ERR_TOO_SHORT);
178           else if (buffer[i][1] != buflen[i]-2 )
179             err = gpg_error (GPG_ERR_INV_OBJ);
180           else
181             offset[i] = 2;
182         }
183     }
184   else
185     {
186       /* Remove leading zeroes to get a correct keygrip.  Take care of
187          negative numbers.  We should also fix it the same way in
188          libgcrypt but we can't yet rely on it yet.  */
189       for (i=0; i < 2; i++)
190         {
191           while (buflen[i]-offset[i] > 1
192                  && !buffer[i][offset[i]]
193                  && !(buffer[i][offset[i]+1] & 0x80))
194             offset[i]++;
195         }
196     }
197
198   /* Check whether negative values are not prefixed with a zero and
199      fix that.  */
200   for (i=0; i < 2; i++)
201     {
202       if ((buflen[i]-offset[i]) && (buffer[i][offset[i]] & 0x80))
203         {
204           unsigned char *newbuf;
205           size_t newlen;
206
207           newlen = 1 + buflen[i] - offset[i];
208           newbuf = xtrymalloc (newlen);
209           if (!newlen)
210             {
211               xfree (buffer[0]);
212               xfree (buffer[1]);
213               return gpg_error_from_syserror ();
214             }
215           newbuf[0] = 0;
216           memcpy (newbuf+1, buffer[i]+offset[i], buflen[i] - offset[i]);
217           xfree (buffer[i]);
218           buffer[i] = newbuf;
219           buflen[i] = newlen;
220           offset[i] = 0;
221         }
222     }
223
224   if (!err)
225     err = gcry_sexp_build (&sexp, NULL,
226                            "(public-key (rsa (n %b) (e %b)))",
227                            (int)buflen[0]-offset[0], buffer[0]+offset[0],
228                            (int)buflen[1]-offset[1], buffer[1]+offset[1]);
229
230   xfree (buffer[0]);
231   xfree (buffer[1]);
232   if (err)
233     return err;
234
235   if (!gcry_pk_get_keygrip (sexp, grip))
236     {
237       err = gpg_error (GPG_ERR_INTERNAL); /* i.e. RSA not supported by
238                                              libgcrypt. */
239     }
240   else
241     {
242       bin2hex (grip, 20, r_gripstr);
243     }
244   gcry_sexp_release (sexp);
245   return err;
246 }
247
248
249 /* TCOS responds to a verify with empty data (i.e. without the Lc
250    byte) with the status of the PIN.  PWID is the PIN ID, If SIGG is
251    true, the application is switched into SigG mode.
252    Returns:
253             -1 = Error retrieving the data,
254             -2 = No such PIN,
255             -3 = PIN blocked,
256             -4 = NullPIN activ,
257         n >= 0 = Number of verification attempts left.  */
258 static int
259 get_chv_status (app_t app, int sigg, int pwid)
260 {
261   unsigned char *result = NULL;
262   size_t resultlen;
263   char command[4];
264   int rc;
265
266   if (switch_application (app, sigg))
267     return sigg? -2 : -1; /* No such PIN / General error.  */
268
269   command[0] = 0x00;
270   command[1] = 0x20;
271   command[2] = 0x00;
272   command[3] = pwid;
273
274   if (apdu_send_direct (app->slot, 0, (unsigned char *)command,
275                         4, 0, &result, &resultlen))
276     rc = -1; /* Error. */
277   else if (resultlen < 2)
278     rc = -1; /* Error. */
279   else
280     {
281       unsigned int sw = ((result[resultlen-2] << 8) | result[resultlen-1]);
282
283       if (sw == 0x6a88)
284         rc = -2; /* No such PIN.  */
285       else if (sw == 0x6983)
286         rc = -3; /* PIN is blocked.  */
287       else if (sw == 0x6985)
288         rc = -4; /* NullPIN is activ.  */
289       else if ((sw & 0xfff0) == 0x63C0)
290         rc = (sw & 0x000f); /* PIN has N tries left.  */
291       else
292         rc = -1; /* Other error.  */
293     }
294   xfree (result);
295
296   return rc;
297 }
298
299
300 /* Implement the GETATTR command.  This is similar to the LEARN
301    command but returns just one value via the status interface. */
302 static gpg_error_t
303 do_getattr (app_t app, ctrl_t ctrl, const char *name)
304 {
305   static struct {
306     const char *name;
307     int special;
308   } table[] = {
309     { "$AUTHKEYID",   1 },
310     { "NKS-VERSION",  2 },
311     { "CHV-STATUS",   3 },
312     { NULL, 0 }
313   };
314   gpg_error_t err = 0;
315   int idx;
316   char buffer[100];
317
318   err = switch_application (app, 0);
319   if (err)
320     return err;
321
322   for (idx=0; table[idx].name && strcmp (table[idx].name, name); idx++)
323     ;
324   if (!table[idx].name)
325     return gpg_error (GPG_ERR_INV_NAME);
326
327   switch (table[idx].special)
328     {
329     case 1: /* $AUTHKEYID */
330       {
331         /* NetKey 3.0 cards define an authentication key but according
332            to the specs this key is only usable for encryption and not
333            signing.  it might work anyway but it has not yet been
334            tested - fixme.  Thus for now we use the NKS signature key
335            for authentication.  */
336         char const tmp[] = "NKS-NKS3.4531";
337         send_status_info (ctrl, table[idx].name, tmp, strlen (tmp), NULL, 0);
338       }
339       break;
340
341     case 2: /* NKS-VERSION */
342       snprintf (buffer, sizeof buffer, "%d", app->app_local->nks_version);
343       send_status_info (ctrl, table[idx].name,
344                         buffer, strlen (buffer), NULL, 0);
345       break;
346
347     case 3: /* CHV-STATUS */
348       {
349         /* Returns: PW1.CH PW2.CH PW1.CH.SIG PW2.CH.SIG That are the
350            two global passwords followed by the two SigG passwords.
351            For the values, see the function get_chv_status.  */
352         int tmp[4];
353
354         /* We use a helper array so that we can control that there is
355            no superfluous application switch.  Note that PW2.CH.SIG
356            really has the identifier 0x83 and not 0x82 as one would
357            expect.  */
358         tmp[0] = get_chv_status (app, 0, 0x00);
359         tmp[1] = get_chv_status (app, 0, 0x01);
360         tmp[2] = get_chv_status (app, 1, 0x81);
361         tmp[3] = get_chv_status (app, 1, 0x83);
362         snprintf (buffer, sizeof buffer,
363                   "%d %d %d %d", tmp[0], tmp[1], tmp[2], tmp[3]);
364         send_status_info (ctrl, table[idx].name,
365                           buffer, strlen (buffer), NULL, 0);
366       }
367       break;
368
369
370     default:
371       err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
372       break;
373     }
374
375   return err;
376 }
377
378
379
380 static void
381 do_learn_status_core (app_t app, ctrl_t ctrl, unsigned int flags, int is_sigg)
382 {
383   gpg_error_t err;
384   char ct_buf[100], id_buf[100];
385   int i;
386   const char *tag;
387
388   if (is_sigg)
389     tag = "SIGG";
390   else if (app->app_local->nks_version < 3)
391     tag = "DF01";
392   else
393     tag = "NKS3";
394
395   /* Output information about all useful objects in the NKS application. */
396   for (i=0; filelist[i].fid; i++)
397     {
398       if (filelist[i].nks_ver > app->app_local->nks_version)
399         continue;
400
401       if (!!filelist[i].is_sigg != !!is_sigg)
402         continue;
403
404       if (filelist[i].certtype && !(flags &1))
405         {
406           size_t len;
407
408           len = app_help_read_length_of_cert (app->slot,
409                                               filelist[i].fid, NULL);
410           if (len)
411             {
412               /* FIXME: We should store the length in the application's
413                  context so that a following readcert does only need to
414                  read that many bytes. */
415               snprintf (ct_buf, sizeof ct_buf, "%d", filelist[i].certtype);
416               snprintf (id_buf, sizeof id_buf, "NKS-%s.%04X",
417                         tag, filelist[i].fid);
418               send_status_info (ctrl, "CERTINFO",
419                                 ct_buf, strlen (ct_buf),
420                                 id_buf, strlen (id_buf),
421                                 NULL, (size_t)0);
422             }
423         }
424       else if (filelist[i].iskeypair)
425         {
426           char gripstr[40+1];
427
428           err = keygripstr_from_pk_file (app, filelist[i].fid, gripstr);
429           if (err)
430             log_error ("can't get keygrip from FID 0x%04X: %s\n",
431                        filelist[i].fid, gpg_strerror (err));
432           else
433             {
434               snprintf (id_buf, sizeof id_buf, "NKS-%s.%04X",
435                         tag, filelist[i].fid);
436               send_status_info (ctrl, "KEYPAIRINFO",
437                                 gripstr, 40,
438                                 id_buf, strlen (id_buf),
439                                 NULL, (size_t)0);
440             }
441         }
442     }
443
444
445 }
446
447
448 static gpg_error_t
449 do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
450 {
451   gpg_error_t err;
452
453   err = switch_application (app, 0);
454   if (err)
455     return err;
456
457   do_learn_status_core (app, ctrl, flags, 0);
458
459   err = switch_application (app, 1);
460   if (err)
461     return 0;  /* Silently ignore if we can't switch to SigG.  */
462
463   do_learn_status_core (app, ctrl, flags, 1);
464
465   return 0;
466 }
467
468
469
470
471 /* Read the certificate with id CERTID (as returned by learn_status in
472    the CERTINFO status lines) and return it in the freshly allocated
473    buffer put into CERT and the length of the certificate put into
474    CERTLEN. */
475 static gpg_error_t
476 do_readcert (app_t app, const char *certid,
477              unsigned char **cert, size_t *certlen)
478 {
479   int i, fid;
480   gpg_error_t err;
481   unsigned char *buffer;
482   const unsigned char *p;
483   size_t buflen, n;
484   int class, tag, constructed, ndef;
485   size_t totobjlen, objlen, hdrlen;
486   int rootca = 0;
487   int is_sigg = 0;
488
489   *cert = NULL;
490   *certlen = 0;
491
492   if (!strncmp (certid, "NKS-NKS3.", 9))
493     ;
494   else if (!strncmp (certid, "NKS-DF01.", 9))
495     ;
496   else if (!strncmp (certid, "NKS-SIGG.", 9))
497     is_sigg = 1;
498   else
499     return gpg_error (GPG_ERR_INV_ID);
500
501   err = switch_application (app, is_sigg);
502   if (err)
503     return err;
504
505   certid += 9;
506   if (!hexdigitp (certid) || !hexdigitp (certid+1)
507       || !hexdigitp (certid+2) || !hexdigitp (certid+3)
508       || certid[4])
509     return gpg_error (GPG_ERR_INV_ID);
510   fid = xtoi_4 (certid);
511   for (i=0; filelist[i].fid; i++)
512     if ((filelist[i].certtype || filelist[i].iskeypair)
513         && filelist[i].fid == fid)
514       break;
515   if (!filelist[i].fid)
516     return gpg_error (GPG_ERR_NOT_FOUND);
517
518   /* If the requested objects is a plain public key, redirect it to
519      the corresponding certificate.  The whole system is a bit messy
520      because we sometime use the key directly or let the caller
521      retrieve the key from the certificate.  The rationale for
522      that is to support not-yet stored certificates. */
523   if (filelist[i].iskeypair)
524     fid = filelist[i].iskeypair;
525
526
527   /* Read the entire file.  fixme: This could be optimized by first
528      reading the header to figure out how long the certificate
529      actually is. */
530   err = iso7816_select_file (app->slot, fid, 0, NULL, NULL);
531   if (err)
532     {
533       log_error ("error selecting FID 0x%04X: %s\n", fid, gpg_strerror (err));
534       return err;
535     }
536
537   err = iso7816_read_binary (app->slot, 0, 0, &buffer, &buflen);
538   if (err)
539     {
540       log_error ("error reading certificate from FID 0x%04X: %s\n",
541                  fid, gpg_strerror (err));
542       return err;
543     }
544
545   if (!buflen || *buffer == 0xff)
546     {
547       log_info ("no certificate contained in FID 0x%04X\n", fid);
548       err = gpg_error (GPG_ERR_NOT_FOUND);
549       goto leave;
550     }
551
552   /* Now figure something out about the object. */
553   p = buffer;
554   n = buflen;
555   err = parse_ber_header (&p, &n, &class, &tag, &constructed,
556                           &ndef, &objlen, &hdrlen);
557   if (err)
558     goto leave;
559   if ( class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE && constructed )
560     ;
561   else if ( class == CLASS_UNIVERSAL && tag == TAG_SET && constructed )
562     rootca = 1;
563   else
564     return gpg_error (GPG_ERR_INV_OBJ);
565   totobjlen = objlen + hdrlen;
566   assert (totobjlen <= buflen);
567
568   err = parse_ber_header (&p, &n, &class, &tag, &constructed,
569                           &ndef, &objlen, &hdrlen);
570   if (err)
571     goto leave;
572
573   if (rootca)
574     ;
575   else if (class == CLASS_UNIVERSAL && tag == TAG_OBJECT_ID && !constructed)
576     {
577       const unsigned char *save_p;
578
579       /* The certificate seems to be contained in a userCertificate
580          container.  Skip this and assume the following sequence is
581          the certificate. */
582       if (n < objlen)
583         {
584           err = gpg_error (GPG_ERR_INV_OBJ);
585           goto leave;
586         }
587       p += objlen;
588       n -= objlen;
589       save_p = p;
590       err = parse_ber_header (&p, &n, &class, &tag, &constructed,
591                               &ndef, &objlen, &hdrlen);
592       if (err)
593         goto leave;
594       if ( !(class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE && constructed) )
595         return gpg_error (GPG_ERR_INV_OBJ);
596       totobjlen = objlen + hdrlen;
597       assert (save_p + totobjlen <= buffer + buflen);
598       memmove (buffer, save_p, totobjlen);
599     }
600
601   *cert = buffer;
602   buffer = NULL;
603   *certlen = totobjlen;
604
605  leave:
606   xfree (buffer);
607   return err;
608 }
609
610
611 /* Handle the READKEY command. On success a canonical encoded
612    S-expression with the public key will get stored at PK and its
613    length at PKLEN; the caller must release that buffer.  On error PK
614    and PKLEN are not changed and an error code is returned.  As of now
615    this function is only useful for the internal authentication key.
616    Other keys are automagically retrieved via by means of the
617    certificate parsing code in commands.c:cmd_readkey.  For internal
618    use PK and PKLEN may be NULL to just check for an existing key.  */
619 static gpg_error_t
620 do_readkey (app_t app, const char *keyid, unsigned char **pk, size_t *pklen)
621 {
622   gpg_error_t err;
623   unsigned char *buffer[2];
624   size_t buflen[2];
625   unsigned short path[1] = { 0x4500 };
626
627   /* We use a generic name to retrieve PK.AUT.IFD-SPK.  */
628   if (!strcmp (keyid, "$IFDAUTHKEY") && app->app_local->nks_version >= 3)
629     ;
630   else /* Return the error code expected by cmd_readkey.  */
631     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
632
633   /* Access the KEYD file which is always in the master directory.  */
634   err = iso7816_select_path (app->slot, path, DIM (path), NULL, NULL);
635   if (err)
636     return err;
637   /* Due to the above select we need to re-select our application.  */
638   app->app_local->need_app_select = 1;
639   /* Get the two records.  */
640   err = iso7816_read_record (app->slot, 5, 1, 0, &buffer[0], &buflen[0]);
641   if (err)
642     return err;
643   if (all_zero_p (buffer[0], buflen[0]))
644     {
645       xfree (buffer[0]);
646       return gpg_error (GPG_ERR_NOT_FOUND);
647     }
648   err = iso7816_read_record (app->slot, 6, 1, 0, &buffer[1], &buflen[1]);
649   if (err)
650     {
651       xfree (buffer[0]);
652       return err;
653     }
654
655   if (pk && pklen)
656     {
657       *pk = make_canon_sexp_from_rsa_pk (buffer[0], buflen[0],
658                                          buffer[1], buflen[1],
659                                          pklen);
660       if (!*pk)
661         err = gpg_error_from_syserror ();
662     }
663
664   xfree (buffer[0]);
665   xfree (buffer[1]);
666   return err;
667 }
668
669
670 /* Handle the WRITEKEY command for NKS.  This function expects a
671    canonical encoded S-expression with the public key in KEYDATA and
672    its length in KEYDATALEN.  The only supported KEYID is
673    "$IFDAUTHKEY" to store the terminal key on the card.  Bit 0 of
674    FLAGS indicates whether an existing key shall get overwritten.
675    PINCB and PINCB_ARG are the usual arguments for the pinentry
676    callback.  */
677 static gpg_error_t
678 do_writekey (app_t app, ctrl_t ctrl,
679              const char *keyid, unsigned int flags,
680              gpg_error_t (*pincb)(void*, const char *, char **),
681              void *pincb_arg,
682              const unsigned char *keydata, size_t keydatalen)
683 {
684   gpg_error_t err;
685   int force = (flags & 1);
686   const unsigned char *rsa_n = NULL;
687   const unsigned char *rsa_e = NULL;
688   size_t rsa_n_len, rsa_e_len;
689   unsigned int nbits;
690
691   (void)ctrl;
692   (void)pincb;
693   (void)pincb_arg;
694
695   if (!strcmp (keyid, "$IFDAUTHKEY") && app->app_local->nks_version >= 3)
696     ;
697   else
698     return gpg_error (GPG_ERR_INV_ID);
699
700   if (!force && !do_readkey (app, keyid, NULL, NULL))
701     return gpg_error (GPG_ERR_EEXIST);
702
703   /* Parse the S-expression.  */
704   err = get_rsa_pk_from_canon_sexp (keydata, keydatalen,
705                                     &rsa_n, &rsa_n_len, &rsa_e, &rsa_e_len);
706   if (err)
707     goto leave;
708
709   /* Check that the parameters match the requirements.  */
710   nbits = app_help_count_bits (rsa_n, rsa_n_len);
711   if (nbits != 1024)
712     {
713       log_error (_("RSA modulus missing or not of size %d bits\n"), 1024);
714       err = gpg_error (GPG_ERR_BAD_PUBKEY);
715       goto leave;
716     }
717
718   nbits = app_help_count_bits (rsa_e, rsa_e_len);
719   if (nbits < 2 || nbits > 32)
720     {
721       log_error (_("RSA public exponent missing or larger than %d bits\n"),
722                  32);
723       err = gpg_error (GPG_ERR_BAD_PUBKEY);
724       goto leave;
725     }
726
727 /*   /\* Store them.  *\/ */
728 /*   err = verify_pin (app, 0, NULL, pincb, pincb_arg); */
729 /*   if (err) */
730 /*     goto leave; */
731
732   /* Send the MSE:Store_Public_Key.  */
733   err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
734 /*   mse = xtrymalloc (1000); */
735
736 /*   mse[0] = 0x80; /\* Algorithm reference.  *\/ */
737 /*   mse[1] = 1; */
738 /*   mse[2] = 0x17; */
739 /*   mse[3] = 0x84; /\* Private key reference.  *\/ */
740 /*   mse[4] = 1; */
741 /*   mse[5] = 0x77; */
742 /*   mse[6] = 0x7F; /\* Public key parameter.  *\/ */
743 /*   mse[7] = 0x49; */
744 /*   mse[8] = 0x81; */
745 /*   mse[9] = 3 + 0x80 + 2 + rsa_e_len; */
746 /*   mse[10] = 0x81; /\* RSA modulus of 128 byte.  *\/ */
747 /*   mse[11] = 0x81; */
748 /*   mse[12] = rsa_n_len; */
749 /*   memcpy (mse+12, rsa_n, rsa_n_len); */
750 /*   mse[10] = 0x82; /\* RSA public exponent of up to 4 bytes.  *\/ */
751 /*   mse[12] = rsa_e_len; */
752 /*   memcpy (mse+12, rsa_e, rsa_e_len); */
753 /*   err = iso7816_manage_security_env (app->slot, 0x81, 0xB6, */
754 /*                                      mse, sizeof mse); */
755
756  leave:
757   return err;
758 }
759
760
761 static gpg_error_t
762 basic_pin_checks (const char *pinvalue, int minlen, int maxlen)
763 {
764   if (strlen (pinvalue) < minlen)
765     {
766       log_error ("PIN is too short; minimum length is %d\n", minlen);
767       return gpg_error (GPG_ERR_BAD_PIN);
768     }
769   if (strlen (pinvalue) > maxlen)
770     {
771       log_error ("PIN is too large; maximum length is %d\n", maxlen);
772       return gpg_error (GPG_ERR_BAD_PIN);
773     }
774   return 0;
775 }
776
777
778 /* Verify the PIN if required.  */
779 static gpg_error_t
780 verify_pin (app_t app, int pwid, const char *desc,
781             gpg_error_t (*pincb)(void*, const char *, char **),
782             void *pincb_arg)
783 {
784   iso7816_pininfo_t pininfo;
785   int rc;
786
787   if (!desc)
788     desc = "PIN";
789
790   memset (&pininfo, 0, sizeof pininfo);
791   pininfo.mode = 1;
792   pininfo.minlen = 6;
793   pininfo.maxlen = 16;
794
795   if (!opt.disable_keypad
796       && !iso7816_check_keypad (app->slot, ISO7816_VERIFY, &pininfo) )
797     {
798       rc = pincb (pincb_arg, desc, NULL);
799       if (rc)
800         {
801           log_info (_("PIN callback returned error: %s\n"),
802                     gpg_strerror (rc));
803           return rc;
804         }
805
806       rc = iso7816_verify_kp (app->slot, pwid, &pininfo);
807       pincb (pincb_arg, NULL, NULL);  /* Dismiss the prompt. */
808     }
809   else
810     {
811       char *pinvalue;
812
813       rc = pincb (pincb_arg, desc, &pinvalue);
814       if (rc)
815         {
816           log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
817           return rc;
818         }
819
820       rc = basic_pin_checks (pinvalue, pininfo.minlen, pininfo.maxlen);
821       if (rc)
822         {
823           xfree (pinvalue);
824           return rc;
825         }
826
827       rc = iso7816_verify (app->slot, pwid, pinvalue, strlen (pinvalue));
828       xfree (pinvalue);
829     }
830
831   if (rc)
832     {
833       if ( gpg_err_code (rc) == GPG_ERR_USE_CONDITIONS )
834         log_error (_("the NullPIN has not yet been changed\n"));
835       else
836         log_error ("verify PIN failed\n");
837       return rc;
838     }
839
840   return 0;
841 }
842
843
844 /* Create the signature and return the allocated result in OUTDATA.
845    If a PIN is required the PINCB will be used to ask for the PIN;
846    that callback should return the PIN in an allocated buffer and
847    store that in the 3rd argument.  */
848 static gpg_error_t
849 do_sign (app_t app, const char *keyidstr, int hashalgo,
850          gpg_error_t (*pincb)(void*, const char *, char **),
851          void *pincb_arg,
852          const void *indata, size_t indatalen,
853          unsigned char **outdata, size_t *outdatalen )
854 {
855   static unsigned char sha1_prefix[15] = /* Object ID is 1.3.14.3.2.26 */
856     { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
857       0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
858   static unsigned char rmd160_prefix[15] = /* Object ID is 1.3.36.3.2.1 */
859     { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
860       0x02, 0x01, 0x05, 0x00, 0x04, 0x14 };
861   int rc, i;
862   int is_sigg = 0;
863   int fid;
864   unsigned char kid;
865   unsigned char data[83];   /* Must be large enough for a SHA-1 digest
866                                + the largest OID prefix. */
867   size_t datalen;
868
869   if (!keyidstr || !*keyidstr)
870     return gpg_error (GPG_ERR_INV_VALUE);
871   switch (indatalen)
872     {
873     case 16: case 20: case 35: case 47: case 51: case 67: case 83: break;
874     default: return gpg_error (GPG_ERR_INV_VALUE);
875     }
876
877   /* Check that the provided ID is valid.  This is not really needed
878      but we do it to enforce correct usage by the caller. */
879   if (!strncmp (keyidstr, "NKS-NKS3.", 9) )
880     ;
881   else if (!strncmp (keyidstr, "NKS-DF01.", 9) )
882     ;
883   else if (!strncmp (keyidstr, "NKS-SIGG.", 9) )
884     is_sigg = 1;
885   else
886     return gpg_error (GPG_ERR_INV_ID);
887   keyidstr += 9;
888
889   rc = switch_application (app, is_sigg);
890   if (rc)
891     return rc;
892
893   if (is_sigg && app->app_local->sigg_is_msig)
894     {
895       log_info ("mass signature cards are not allowed\n");
896       return gpg_error (GPG_ERR_NOT_SUPPORTED);
897     }
898
899   if (!hexdigitp (keyidstr) || !hexdigitp (keyidstr+1)
900       || !hexdigitp (keyidstr+2) || !hexdigitp (keyidstr+3)
901       || keyidstr[4])
902     return gpg_error (GPG_ERR_INV_ID);
903   fid = xtoi_4 (keyidstr);
904   for (i=0; filelist[i].fid; i++)
905     if (filelist[i].iskeypair && filelist[i].fid == fid)
906       break;
907   if (!filelist[i].fid)
908     return gpg_error (GPG_ERR_NOT_FOUND);
909   if (!filelist[i].issignkey)
910     return gpg_error (GPG_ERR_INV_ID);
911   kid = filelist[i].kid;
912
913   /* Prepare the DER object from INDATA.  */
914   if (app->app_local->nks_version > 2 && (indatalen == 35
915                                           || indatalen == 47
916                                           || indatalen == 51
917                                           || indatalen == 67
918                                           || indatalen == 83))
919     {
920       /* The caller send data matching the length of the ASN.1 encoded
921          hash for SHA-{1,224,256,384,512}.  Assume that is okay.  */
922       assert (indatalen <= sizeof data);
923       memcpy (data, indata, indatalen);
924       datalen = indatalen;
925     }
926   else if (indatalen == 35)
927     {
928       /* Alright, the caller was so kind to send us an already
929          prepared DER object.  This is for TCOS 2. */
930       if (hashalgo == GCRY_MD_SHA1 && !memcmp (indata, sha1_prefix, 15))
931         ;
932       else if (hashalgo == GCRY_MD_RMD160 && !memcmp (indata,rmd160_prefix,15))
933         ;
934       else
935         return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
936       memcpy (data, indata, indatalen);
937       datalen = 35;
938     }
939   else if (indatalen == 20)
940     {
941       if (hashalgo == GCRY_MD_SHA1)
942         memcpy (data, sha1_prefix, 15);
943       else if (hashalgo == GCRY_MD_RMD160)
944         memcpy (data, rmd160_prefix, 15);
945       else
946         return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
947       memcpy (data+15, indata, indatalen);
948       datalen = 35;
949     }
950   else
951     return gpg_error (GPG_ERR_INV_VALUE);
952
953
954   /* Send an MSE for PSO:Computer_Signature.  */
955   if (app->app_local->nks_version > 2)
956     {
957       unsigned char mse[6];
958
959       mse[0] = 0x80; /* Algorithm reference.  */
960       mse[1] = 1;
961       mse[2] = 2;    /* RSA, card does pkcs#1 v1.5 padding, no ASN.1 check.  */
962       mse[3] = 0x84; /* Private key reference.  */
963       mse[4] = 1;
964       mse[5] = kid;
965       rc = iso7816_manage_security_env (app->slot, 0x41, 0xB6,
966                                         mse, sizeof mse);
967     }
968   /* Verify using PW1.CH.  */
969   if (!rc)
970     rc = verify_pin (app, 0, NULL, pincb, pincb_arg);
971   /* Compute the signature.  */
972   if (!rc)
973     rc = iso7816_compute_ds (app->slot, 0, data, datalen, 0,
974                              outdata, outdatalen);
975   return rc;
976 }
977
978
979
980 /* Decrypt the data in INDATA and return the allocated result in OUTDATA.
981    If a PIN is required the PINCB will be used to ask for the PIN; it
982    should return the PIN in an allocated buffer and put it into PIN.  */
983 static gpg_error_t
984 do_decipher (app_t app, const char *keyidstr,
985              gpg_error_t (*pincb)(void*, const char *, char **),
986              void *pincb_arg,
987              const void *indata, size_t indatalen,
988              unsigned char **outdata, size_t *outdatalen )
989 {
990   int rc, i;
991   int is_sigg = 0;
992   int fid;
993   int kid;
994
995   if (!keyidstr || !*keyidstr || !indatalen)
996     return gpg_error (GPG_ERR_INV_VALUE);
997
998   /* Check that the provided ID is valid.  This is not really needed
999      but we do it to to enforce correct usage by the caller. */
1000   if (!strncmp (keyidstr, "NKS-NKS3.", 9) )
1001     ;
1002   else if (!strncmp (keyidstr, "NKS-DF01.", 9) )
1003     ;
1004   else if (!strncmp (keyidstr, "NKS-SIGG.", 9) )
1005     is_sigg = 1;
1006   else
1007     return gpg_error (GPG_ERR_INV_ID);
1008   keyidstr += 9;
1009
1010   rc = switch_application (app, is_sigg);
1011   if (rc)
1012     return rc;
1013
1014   if (!hexdigitp (keyidstr) || !hexdigitp (keyidstr+1)
1015       || !hexdigitp (keyidstr+2) || !hexdigitp (keyidstr+3)
1016       || keyidstr[4])
1017     return gpg_error (GPG_ERR_INV_ID);
1018   fid = xtoi_4 (keyidstr);
1019   for (i=0; filelist[i].fid; i++)
1020     if (filelist[i].iskeypair && filelist[i].fid == fid)
1021       break;
1022   if (!filelist[i].fid)
1023     return gpg_error (GPG_ERR_NOT_FOUND);
1024   if (!filelist[i].isenckey)
1025     return gpg_error (GPG_ERR_INV_ID);
1026   kid = filelist[i].kid;
1027
1028   if (app->app_local->nks_version > 2)
1029     {
1030       unsigned char mse[6];
1031       mse[0] = 0x80; /* Algorithm reference.  */
1032       mse[1] = 1;
1033       mse[2] = 0x0a; /* RSA no padding.  (0x1A is pkcs#1.5 padding.)  */
1034       mse[3] = 0x84; /* Private key reference.  */
1035       mse[4] = 1;
1036       mse[5] = kid;
1037       rc = iso7816_manage_security_env (app->slot, 0x41, 0xB8,
1038                                         mse, sizeof mse);
1039     }
1040   else
1041     {
1042       static const unsigned char mse[] =
1043         {
1044           0x80, 1, 0x10, /* Select algorithm RSA. */
1045           0x84, 1, 0x81  /* Select local secret key 1 for decryption. */
1046         };
1047       rc = iso7816_manage_security_env (app->slot, 0xC1, 0xB8,
1048                                         mse, sizeof mse);
1049
1050     }
1051
1052   if (!rc)
1053     rc = verify_pin (app, 0, NULL, pincb, pincb_arg);
1054
1055   /* Note that we need to use extended length APDUs for TCOS 3 cards.
1056      Command chaining does not work.  */
1057   if (!rc)
1058     rc = iso7816_decipher (app->slot, app->app_local->nks_version > 2? 1:0,
1059                            indata, indatalen, 0, 0x81,
1060                            outdata, outdatalen);
1061   return rc;
1062 }
1063
1064
1065
1066 /* Parse a password ID string.  Returns NULL on error or a string
1067    suitable as passpahrse prompt on success.  On success stores the
1068    reference value for the password at R_PWID and a flag indicating
1069    that the SigG application is to be used at R_SIGG.  If NEW_MODE is
1070    true, the returned description is suitable for a new Password.
1071    Supported values for PWIDSTR are:
1072
1073      PW1.CH       - Global password 1
1074      PW2.CH       - Global password 2
1075      PW1.CH.SIG   - SigG password 1
1076      PW2.CH.SIG   - SigG password 2
1077  */
1078 static const char *
1079 parse_pwidstr (const char *pwidstr, int new_mode, int *r_sigg, int *r_pwid)
1080 {
1081   const char *desc;
1082
1083   if (!pwidstr)
1084     desc = NULL;
1085   else if (!strcmp (pwidstr, "PW1.CH"))
1086     {
1087       *r_sigg = 0;
1088       *r_pwid = 0x00;
1089       /* TRANSLATORS: Do not translate the "|*|" prefixes but keep
1090          them verbatim at the start of the string.  */
1091       desc = (new_mode
1092               ? _("|N|Please enter a new PIN for the standard keys.")
1093               : _("||Please enter the PIN for the standard keys."));
1094     }
1095   else if (!strcmp (pwidstr, "PW2.CH"))
1096     {
1097       *r_pwid = 0x01;
1098       desc = (new_mode
1099               ? _("|NP|Please enter a new PIN Unblocking Code (PUK) "
1100                   "for the standard keys.")
1101               : _("|P|Please enter the PIN Unblocking Code (PUK) "
1102                   "for the standard keys."));
1103     }
1104   else if (!strcmp (pwidstr, "PW1.CH.SIG"))
1105     {
1106       *r_pwid = 0x81;
1107       *r_sigg = 1;
1108       desc = (new_mode
1109               ? _("|N|Please enter a new PIN for the key to create "
1110                   "qualified signatures.")
1111               : _("||Please enter the PIN for the key to create "
1112                   "qualified signatures."));
1113     }
1114   else if (!strcmp (pwidstr, "PW2.CH.SIG"))
1115     {
1116       *r_pwid = 0x83;  /* Yes, that is 83 and not 82.  */
1117       *r_sigg = 1;
1118       desc = (new_mode
1119               ? _("|NP|Please enter a new PIN Unblocking Code (PUK) "
1120                   "for the key to create qualified signatures.")
1121               : _("|P|Please enter the PIN Unblocking Code (PUK) "
1122                   "for the key to create qualified signatures."));
1123     }
1124   else
1125     desc = NULL;
1126
1127   return desc;
1128 }
1129
1130
1131 /* Handle the PASSWD command. See parse_pwidstr() for allowed values
1132    for CHVNOSTR.  */
1133 static gpg_error_t
1134 do_change_pin (app_t app, ctrl_t ctrl,  const char *pwidstr,
1135                unsigned int flags,
1136                gpg_error_t (*pincb)(void*, const char *, char **),
1137                void *pincb_arg)
1138 {
1139   gpg_error_t err;
1140   char *newpin = NULL;
1141   char *oldpin = NULL;
1142   size_t newpinlen;
1143   size_t oldpinlen;
1144   int is_sigg;
1145   const char *newdesc;
1146   int pwid;
1147   iso7816_pininfo_t pininfo;
1148
1149   (void)ctrl;
1150
1151   /* The minimum length is enforced by TCOS, the maximum length is
1152      just a reasonable value.  */
1153   memset (&pininfo, 0, sizeof pininfo);
1154   pininfo.minlen = 6;
1155   pininfo.maxlen = 16;
1156
1157   newdesc = parse_pwidstr (pwidstr, 1, &is_sigg, &pwid);
1158   if (!newdesc)
1159     return gpg_error (GPG_ERR_INV_ID);
1160
1161   err = switch_application (app, is_sigg);
1162   if (err)
1163     return err;
1164
1165   if ((flags & APP_CHANGE_FLAG_NULLPIN))
1166     {
1167       /* With the nullpin flag, we do not verify the PIN - it would
1168          fail if the Nullpin is still set.  */
1169       oldpin = xtrycalloc (1, 6);
1170       if (!oldpin)
1171         {
1172           err = gpg_error_from_syserror ();
1173           goto leave;
1174         }
1175       oldpinlen = 6;
1176     }
1177   else
1178     {
1179       const char *desc;
1180       int dummy1, dummy2;
1181
1182       if ((flags & APP_CHANGE_FLAG_RESET))
1183         {
1184           /* Reset mode: Ask for the alternate PIN.  */
1185           const char *altpwidstr;
1186
1187           if (!strcmp (pwidstr, "PW1.CH"))
1188             altpwidstr = "PW2.CH";
1189           else if (!strcmp (pwidstr, "PW2.CH"))
1190             altpwidstr = "PW1.CH";
1191           else if (!strcmp (pwidstr, "PW1.CH.SIG"))
1192             altpwidstr = "PW2.CH.SIG";
1193           else if (!strcmp (pwidstr, "PW2.CH.SIG"))
1194             altpwidstr = "PW1.CH.SIG";
1195           else
1196             {
1197               err = gpg_error (GPG_ERR_BUG);
1198               goto leave;
1199             }
1200           desc = parse_pwidstr (altpwidstr, 0, &dummy1, &dummy2);
1201         }
1202       else
1203         {
1204           /* Regular change mode:  Ask for the old PIN.  */
1205           desc = parse_pwidstr (pwidstr, 0, &dummy1, &dummy2);
1206         }
1207       err = pincb (pincb_arg, desc, &oldpin);
1208       if (err)
1209         {
1210           log_error ("error getting old PIN: %s\n", gpg_strerror (err));
1211           goto leave;
1212         }
1213       oldpinlen = strlen (oldpin);
1214       err = basic_pin_checks (oldpin, pininfo.minlen, pininfo.maxlen);
1215       if (err)
1216         goto leave;
1217     }
1218
1219   err = pincb (pincb_arg, newdesc, &newpin);
1220   if (err)
1221     {
1222       log_error (_("error getting new PIN: %s\n"), gpg_strerror (err));
1223       goto leave;
1224     }
1225   newpinlen = strlen (newpin);
1226
1227   err = basic_pin_checks (newpin, pininfo.minlen, pininfo.maxlen);
1228   if (err)
1229     goto leave;
1230
1231   if ((flags & APP_CHANGE_FLAG_RESET))
1232     {
1233       char *data;
1234       size_t datalen = oldpinlen + newpinlen;
1235
1236       data = xtrymalloc (datalen);
1237       if (!data)
1238         {
1239           err = gpg_error_from_syserror ();
1240           goto leave;
1241         }
1242       memcpy (data, oldpin, oldpinlen);
1243       memcpy (data+oldpinlen, newpin, newpinlen);
1244       err = iso7816_reset_retry_counter_with_rc (app->slot, pwid,
1245                                                  data, datalen);
1246       wipememory (data, datalen);
1247       xfree (data);
1248     }
1249   else
1250     err = iso7816_change_reference_data (app->slot, pwid,
1251                                          oldpin, oldpinlen,
1252                                          newpin, newpinlen);
1253  leave:
1254   xfree (oldpin);
1255   xfree (newpin);
1256   return err;
1257 }
1258
1259
1260 /* Perform a simple verify operation.  KEYIDSTR should be NULL or empty.  */
1261 static gpg_error_t
1262 do_check_pin (app_t app, const char *pwidstr,
1263               gpg_error_t (*pincb)(void*, const char *, char **),
1264               void *pincb_arg)
1265 {
1266   gpg_error_t err;
1267   int pwid;
1268   int is_sigg;
1269   const char *desc;
1270
1271   desc = parse_pwidstr (pwidstr, 0, &is_sigg, &pwid);
1272   if (!desc)
1273     return gpg_error (GPG_ERR_INV_ID);
1274
1275   err = switch_application (app, is_sigg);
1276   if (err)
1277     return err;
1278
1279   return verify_pin (app, pwid, desc, pincb, pincb_arg);
1280 }
1281
1282
1283 /* Return the version of the NKS application.  */
1284 static int
1285 get_nks_version (int slot)
1286 {
1287   unsigned char *result = NULL;
1288   size_t resultlen;
1289   int type;
1290
1291   if (iso7816_apdu_direct (slot, "\x80\xaa\x06\x00\x00", 5, 0,
1292                            &result, &resultlen))
1293     return 2; /* NKS 2 does not support this command.  */
1294
1295   /* Example value:    04 11 19 22 21 6A 20 80 03 03 01 01 01 00 00 00
1296                        vv tt ccccccccccccccccc aa bb cc vvvvvvvvvvv xx
1297      vendor (Philips) -+  |  |                 |  |  |  |           |
1298      chip type -----------+  |                 |  |  |  |           |
1299      chip id ----------------+                 |  |  |  |           |
1300      card type (3 - tcos 3) -------------------+  |  |  |           |
1301      OS version of card type ---------------------+  |  |           |
1302      OS release of card type ------------------------+  |           |
1303      OS vendor internal version ------------------------+           |
1304      RFU -----------------------------------------------------------+
1305   */
1306   if (resultlen < 16)
1307     type = 0;  /* Invalid data returned.  */
1308   else
1309     type = result[8];
1310   xfree (result);
1311
1312   return type;
1313 }
1314
1315
1316 /* If ENABLE_SIGG is true switch to the SigG application if not yet
1317    active.  If false switch to the NKS application if not yet active.
1318    Returns 0 on success.  */
1319 static gpg_error_t
1320 switch_application (app_t app, int enable_sigg)
1321 {
1322   gpg_error_t err;
1323
1324   if (((app->app_local->sigg_active && enable_sigg)
1325        || (!app->app_local->sigg_active && !enable_sigg))
1326       && !app->app_local->need_app_select)
1327     return 0;  /* Already switched.  */
1328
1329   log_info ("app-nks: switching to %s\n", enable_sigg? "SigG":"NKS");
1330   if (enable_sigg)
1331     err = iso7816_select_application (app->slot, aid_sigg, sizeof aid_sigg, 0);
1332   else
1333     err = iso7816_select_application (app->slot, aid_nks, sizeof aid_nks, 0);
1334
1335   if (!err && enable_sigg && app->app_local->nks_version >= 3
1336       && !app->app_local->sigg_msig_checked)
1337     {
1338       /* Check whether this card is a mass signature card.  */
1339       unsigned char *buffer;
1340       size_t buflen;
1341       const unsigned char *tmpl;
1342       size_t tmpllen;
1343
1344       app->app_local->sigg_msig_checked = 1;
1345       app->app_local->sigg_is_msig = 1;
1346       err = iso7816_select_file (app->slot, 0x5349, 0, NULL, NULL);
1347       if (!err)
1348         err = iso7816_read_record (app->slot, 1, 1, 0, &buffer, &buflen);
1349       if (!err)
1350         {
1351           tmpl = find_tlv (buffer, buflen, 0x7a, &tmpllen);
1352           if (tmpl && tmpllen == 12
1353               && !memcmp (tmpl,
1354                           "\x93\x02\x00\x01\xA4\x06\x83\x01\x81\x83\x01\x83",
1355                           12))
1356             app->app_local->sigg_is_msig = 0;
1357           xfree (buffer);
1358         }
1359       if (app->app_local->sigg_is_msig)
1360         log_info ("This is a mass signature card\n");
1361     }
1362
1363   if (!err)
1364     {
1365       app->app_local->need_app_select = 0;
1366       app->app_local->sigg_active = enable_sigg;
1367     }
1368   else
1369     log_error ("app-nks: error switching to %s: %s\n",
1370                enable_sigg? "SigG":"NKS", gpg_strerror (err));
1371
1372   return err;
1373 }
1374
1375
1376 /* Select the NKS application.  */
1377 gpg_error_t
1378 app_select_nks (app_t app)
1379 {
1380   int slot = app->slot;
1381   int rc;
1382
1383   rc = iso7816_select_application (slot, aid_nks, sizeof aid_nks, 0);
1384   if (!rc)
1385     {
1386       app->apptype = "NKS";
1387
1388       app->app_local = xtrycalloc (1, sizeof *app->app_local);
1389       if (!app->app_local)
1390         {
1391           rc = gpg_error (gpg_err_code_from_errno (errno));
1392           goto leave;
1393         }
1394
1395       app->app_local->nks_version = get_nks_version (slot);
1396       if (opt.verbose)
1397         log_info ("Detected NKS version: %d\n", app->app_local->nks_version);
1398
1399       app->fnc.deinit = do_deinit;
1400       app->fnc.learn_status = do_learn_status;
1401       app->fnc.readcert = do_readcert;
1402       app->fnc.readkey = do_readkey;
1403       app->fnc.getattr = do_getattr;
1404       app->fnc.setattr = NULL;
1405       app->fnc.writekey = do_writekey;
1406       app->fnc.genkey = NULL;
1407       app->fnc.sign = do_sign;
1408       app->fnc.auth = NULL;
1409       app->fnc.decipher = do_decipher;
1410       app->fnc.change_pin = do_change_pin;
1411       app->fnc.check_pin = do_check_pin;
1412    }
1413
1414  leave:
1415   if (rc)
1416     do_deinit (app);
1417   return rc;
1418 }