scd: Suppress gcc warning about possible uninitialized use.
[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   pininfo_t pininfo;
785   int rc;
786
787   if (!desc)
788     desc = "PIN";
789
790   memset (&pininfo, 0, sizeof pininfo);
791   pininfo.fixedlen = -1;
792   pininfo.minlen = 6;
793   pininfo.maxlen = 16;
794
795   if (!opt.disable_pinpad
796       && !iso7816_check_pinpad (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              unsigned int *r_info)
990 {
991   int rc, i;
992   int is_sigg = 0;
993   int fid;
994   int kid;
995
996   (void)r_info;
997
998   if (!keyidstr || !*keyidstr || !indatalen)
999     return gpg_error (GPG_ERR_INV_VALUE);
1000
1001   /* Check that the provided ID is valid.  This is not really needed
1002      but we do it to to enforce correct usage by the caller. */
1003   if (!strncmp (keyidstr, "NKS-NKS3.", 9) )
1004     ;
1005   else if (!strncmp (keyidstr, "NKS-DF01.", 9) )
1006     ;
1007   else if (!strncmp (keyidstr, "NKS-SIGG.", 9) )
1008     is_sigg = 1;
1009   else
1010     return gpg_error (GPG_ERR_INV_ID);
1011   keyidstr += 9;
1012
1013   rc = switch_application (app, is_sigg);
1014   if (rc)
1015     return rc;
1016
1017   if (!hexdigitp (keyidstr) || !hexdigitp (keyidstr+1)
1018       || !hexdigitp (keyidstr+2) || !hexdigitp (keyidstr+3)
1019       || keyidstr[4])
1020     return gpg_error (GPG_ERR_INV_ID);
1021   fid = xtoi_4 (keyidstr);
1022   for (i=0; filelist[i].fid; i++)
1023     if (filelist[i].iskeypair && filelist[i].fid == fid)
1024       break;
1025   if (!filelist[i].fid)
1026     return gpg_error (GPG_ERR_NOT_FOUND);
1027   if (!filelist[i].isenckey)
1028     return gpg_error (GPG_ERR_INV_ID);
1029   kid = filelist[i].kid;
1030
1031   if (app->app_local->nks_version > 2)
1032     {
1033       unsigned char mse[6];
1034       mse[0] = 0x80; /* Algorithm reference.  */
1035       mse[1] = 1;
1036       mse[2] = 0x0a; /* RSA no padding.  (0x1A is pkcs#1.5 padding.)  */
1037       mse[3] = 0x84; /* Private key reference.  */
1038       mse[4] = 1;
1039       mse[5] = kid;
1040       rc = iso7816_manage_security_env (app->slot, 0x41, 0xB8,
1041                                         mse, sizeof mse);
1042     }
1043   else
1044     {
1045       static const unsigned char mse[] =
1046         {
1047           0x80, 1, 0x10, /* Select algorithm RSA. */
1048           0x84, 1, 0x81  /* Select local secret key 1 for decryption. */
1049         };
1050       rc = iso7816_manage_security_env (app->slot, 0xC1, 0xB8,
1051                                         mse, sizeof mse);
1052
1053     }
1054
1055   if (!rc)
1056     rc = verify_pin (app, 0, NULL, pincb, pincb_arg);
1057
1058   /* Note that we need to use extended length APDUs for TCOS 3 cards.
1059      Command chaining does not work.  */
1060   if (!rc)
1061     rc = iso7816_decipher (app->slot, app->app_local->nks_version > 2? 1:0,
1062                            indata, indatalen, 0, 0x81,
1063                            outdata, outdatalen);
1064   return rc;
1065 }
1066
1067
1068
1069 /* Parse a password ID string.  Returns NULL on error or a string
1070    suitable as passpahrse prompt on success.  On success stores the
1071    reference value for the password at R_PWID and a flag indicating
1072    that the SigG application is to be used at R_SIGG.  If NEW_MODE is
1073    true, the returned description is suitable for a new Password.
1074    Supported values for PWIDSTR are:
1075
1076      PW1.CH       - Global password 1
1077      PW2.CH       - Global password 2
1078      PW1.CH.SIG   - SigG password 1
1079      PW2.CH.SIG   - SigG password 2
1080  */
1081 static const char *
1082 parse_pwidstr (const char *pwidstr, int new_mode, int *r_sigg, int *r_pwid)
1083 {
1084   const char *desc;
1085
1086   if (!pwidstr)
1087     desc = NULL;
1088   else if (!strcmp (pwidstr, "PW1.CH"))
1089     {
1090       *r_sigg = 0;
1091       *r_pwid = 0x00;
1092       /* TRANSLATORS: Do not translate the "|*|" prefixes but keep
1093          them verbatim at the start of the string.  */
1094       desc = (new_mode
1095               ? _("|N|Please enter a new PIN for the standard keys.")
1096               : _("||Please enter the PIN for the standard keys."));
1097     }
1098   else if (!strcmp (pwidstr, "PW2.CH"))
1099     {
1100       *r_pwid = 0x01;
1101       desc = (new_mode
1102               ? _("|NP|Please enter a new PIN Unblocking Code (PUK) "
1103                   "for the standard keys.")
1104               : _("|P|Please enter the PIN Unblocking Code (PUK) "
1105                   "for the standard keys."));
1106     }
1107   else if (!strcmp (pwidstr, "PW1.CH.SIG"))
1108     {
1109       *r_pwid = 0x81;
1110       *r_sigg = 1;
1111       desc = (new_mode
1112               ? _("|N|Please enter a new PIN for the key to create "
1113                   "qualified signatures.")
1114               : _("||Please enter the PIN for the key to create "
1115                   "qualified signatures."));
1116     }
1117   else if (!strcmp (pwidstr, "PW2.CH.SIG"))
1118     {
1119       *r_pwid = 0x83;  /* Yes, that is 83 and not 82.  */
1120       *r_sigg = 1;
1121       desc = (new_mode
1122               ? _("|NP|Please enter a new PIN Unblocking Code (PUK) "
1123                   "for the key to create qualified signatures.")
1124               : _("|P|Please enter the PIN Unblocking Code (PUK) "
1125                   "for the key to create qualified signatures."));
1126     }
1127   else
1128     {
1129       *r_pwid = 0; /* Only to avoid gcc warning in calling function.  */
1130       desc = NULL; /* Error.  */
1131     }
1132
1133   return desc;
1134 }
1135
1136
1137 /* Handle the PASSWD command. See parse_pwidstr() for allowed values
1138    for CHVNOSTR.  */
1139 static gpg_error_t
1140 do_change_pin (app_t app, ctrl_t ctrl,  const char *pwidstr,
1141                unsigned int flags,
1142                gpg_error_t (*pincb)(void*, const char *, char **),
1143                void *pincb_arg)
1144 {
1145   gpg_error_t err;
1146   char *newpin = NULL;
1147   char *oldpin = NULL;
1148   size_t newpinlen;
1149   size_t oldpinlen;
1150   int is_sigg;
1151   const char *newdesc;
1152   int pwid;
1153   pininfo_t pininfo;
1154
1155   (void)ctrl;
1156
1157   /* The minimum length is enforced by TCOS, the maximum length is
1158      just a reasonable value.  */
1159   memset (&pininfo, 0, sizeof pininfo);
1160   pininfo.minlen = 6;
1161   pininfo.maxlen = 16;
1162
1163   newdesc = parse_pwidstr (pwidstr, 1, &is_sigg, &pwid);
1164   if (!newdesc)
1165     return gpg_error (GPG_ERR_INV_ID);
1166
1167   err = switch_application (app, is_sigg);
1168   if (err)
1169     return err;
1170
1171   if ((flags & APP_CHANGE_FLAG_NULLPIN))
1172     {
1173       /* With the nullpin flag, we do not verify the PIN - it would
1174          fail if the Nullpin is still set.  */
1175       oldpin = xtrycalloc (1, 6);
1176       if (!oldpin)
1177         {
1178           err = gpg_error_from_syserror ();
1179           goto leave;
1180         }
1181       oldpinlen = 6;
1182     }
1183   else
1184     {
1185       const char *desc;
1186       int dummy1, dummy2;
1187
1188       if ((flags & APP_CHANGE_FLAG_RESET))
1189         {
1190           /* Reset mode: Ask for the alternate PIN.  */
1191           const char *altpwidstr;
1192
1193           if (!strcmp (pwidstr, "PW1.CH"))
1194             altpwidstr = "PW2.CH";
1195           else if (!strcmp (pwidstr, "PW2.CH"))
1196             altpwidstr = "PW1.CH";
1197           else if (!strcmp (pwidstr, "PW1.CH.SIG"))
1198             altpwidstr = "PW2.CH.SIG";
1199           else if (!strcmp (pwidstr, "PW2.CH.SIG"))
1200             altpwidstr = "PW1.CH.SIG";
1201           else
1202             {
1203               err = gpg_error (GPG_ERR_BUG);
1204               goto leave;
1205             }
1206           desc = parse_pwidstr (altpwidstr, 0, &dummy1, &dummy2);
1207         }
1208       else
1209         {
1210           /* Regular change mode:  Ask for the old PIN.  */
1211           desc = parse_pwidstr (pwidstr, 0, &dummy1, &dummy2);
1212         }
1213       err = pincb (pincb_arg, desc, &oldpin);
1214       if (err)
1215         {
1216           log_error ("error getting old PIN: %s\n", gpg_strerror (err));
1217           goto leave;
1218         }
1219       oldpinlen = strlen (oldpin);
1220       err = basic_pin_checks (oldpin, pininfo.minlen, pininfo.maxlen);
1221       if (err)
1222         goto leave;
1223     }
1224
1225   err = pincb (pincb_arg, newdesc, &newpin);
1226   if (err)
1227     {
1228       log_error (_("error getting new PIN: %s\n"), gpg_strerror (err));
1229       goto leave;
1230     }
1231   newpinlen = strlen (newpin);
1232
1233   err = basic_pin_checks (newpin, pininfo.minlen, pininfo.maxlen);
1234   if (err)
1235     goto leave;
1236
1237   if ((flags & APP_CHANGE_FLAG_RESET))
1238     {
1239       char *data;
1240       size_t datalen = oldpinlen + newpinlen;
1241
1242       data = xtrymalloc (datalen);
1243       if (!data)
1244         {
1245           err = gpg_error_from_syserror ();
1246           goto leave;
1247         }
1248       memcpy (data, oldpin, oldpinlen);
1249       memcpy (data+oldpinlen, newpin, newpinlen);
1250       err = iso7816_reset_retry_counter_with_rc (app->slot, pwid,
1251                                                  data, datalen);
1252       wipememory (data, datalen);
1253       xfree (data);
1254     }
1255   else
1256     err = iso7816_change_reference_data (app->slot, pwid,
1257                                          oldpin, oldpinlen,
1258                                          newpin, newpinlen);
1259  leave:
1260   xfree (oldpin);
1261   xfree (newpin);
1262   return err;
1263 }
1264
1265
1266 /* Perform a simple verify operation.  KEYIDSTR should be NULL or empty.  */
1267 static gpg_error_t
1268 do_check_pin (app_t app, const char *pwidstr,
1269               gpg_error_t (*pincb)(void*, const char *, char **),
1270               void *pincb_arg)
1271 {
1272   gpg_error_t err;
1273   int pwid;
1274   int is_sigg;
1275   const char *desc;
1276
1277   desc = parse_pwidstr (pwidstr, 0, &is_sigg, &pwid);
1278   if (!desc)
1279     return gpg_error (GPG_ERR_INV_ID);
1280
1281   err = switch_application (app, is_sigg);
1282   if (err)
1283     return err;
1284
1285   return verify_pin (app, pwid, desc, pincb, pincb_arg);
1286 }
1287
1288
1289 /* Return the version of the NKS application.  */
1290 static int
1291 get_nks_version (int slot)
1292 {
1293   unsigned char *result = NULL;
1294   size_t resultlen;
1295   int type;
1296
1297   if (iso7816_apdu_direct (slot, "\x80\xaa\x06\x00\x00", 5, 0,
1298                            &result, &resultlen))
1299     return 2; /* NKS 2 does not support this command.  */
1300
1301   /* Example value:    04 11 19 22 21 6A 20 80 03 03 01 01 01 00 00 00
1302                        vv tt ccccccccccccccccc aa bb cc vvvvvvvvvvv xx
1303      vendor (Philips) -+  |  |                 |  |  |  |           |
1304      chip type -----------+  |                 |  |  |  |           |
1305      chip id ----------------+                 |  |  |  |           |
1306      card type (3 - tcos 3) -------------------+  |  |  |           |
1307      OS version of card type ---------------------+  |  |           |
1308      OS release of card type ------------------------+  |           |
1309      OS vendor internal version ------------------------+           |
1310      RFU -----------------------------------------------------------+
1311   */
1312   if (resultlen < 16)
1313     type = 0;  /* Invalid data returned.  */
1314   else
1315     type = result[8];
1316   xfree (result);
1317
1318   return type;
1319 }
1320
1321
1322 /* If ENABLE_SIGG is true switch to the SigG application if not yet
1323    active.  If false switch to the NKS application if not yet active.
1324    Returns 0 on success.  */
1325 static gpg_error_t
1326 switch_application (app_t app, int enable_sigg)
1327 {
1328   gpg_error_t err;
1329
1330   if (((app->app_local->sigg_active && enable_sigg)
1331        || (!app->app_local->sigg_active && !enable_sigg))
1332       && !app->app_local->need_app_select)
1333     return 0;  /* Already switched.  */
1334
1335   log_info ("app-nks: switching to %s\n", enable_sigg? "SigG":"NKS");
1336   if (enable_sigg)
1337     err = iso7816_select_application (app->slot, aid_sigg, sizeof aid_sigg, 0);
1338   else
1339     err = iso7816_select_application (app->slot, aid_nks, sizeof aid_nks, 0);
1340
1341   if (!err && enable_sigg && app->app_local->nks_version >= 3
1342       && !app->app_local->sigg_msig_checked)
1343     {
1344       /* Check whether this card is a mass signature card.  */
1345       unsigned char *buffer;
1346       size_t buflen;
1347       const unsigned char *tmpl;
1348       size_t tmpllen;
1349
1350       app->app_local->sigg_msig_checked = 1;
1351       app->app_local->sigg_is_msig = 1;
1352       err = iso7816_select_file (app->slot, 0x5349, 0, NULL, NULL);
1353       if (!err)
1354         err = iso7816_read_record (app->slot, 1, 1, 0, &buffer, &buflen);
1355       if (!err)
1356         {
1357           tmpl = find_tlv (buffer, buflen, 0x7a, &tmpllen);
1358           if (tmpl && tmpllen == 12
1359               && !memcmp (tmpl,
1360                           "\x93\x02\x00\x01\xA4\x06\x83\x01\x81\x83\x01\x83",
1361                           12))
1362             app->app_local->sigg_is_msig = 0;
1363           xfree (buffer);
1364         }
1365       if (app->app_local->sigg_is_msig)
1366         log_info ("This is a mass signature card\n");
1367     }
1368
1369   if (!err)
1370     {
1371       app->app_local->need_app_select = 0;
1372       app->app_local->sigg_active = enable_sigg;
1373     }
1374   else
1375     log_error ("app-nks: error switching to %s: %s\n",
1376                enable_sigg? "SigG":"NKS", gpg_strerror (err));
1377
1378   return err;
1379 }
1380
1381
1382 /* Select the NKS application.  */
1383 gpg_error_t
1384 app_select_nks (app_t app)
1385 {
1386   int slot = app->slot;
1387   int rc;
1388
1389   rc = iso7816_select_application (slot, aid_nks, sizeof aid_nks, 0);
1390   if (!rc)
1391     {
1392       app->apptype = "NKS";
1393
1394       app->app_local = xtrycalloc (1, sizeof *app->app_local);
1395       if (!app->app_local)
1396         {
1397           rc = gpg_error (gpg_err_code_from_errno (errno));
1398           goto leave;
1399         }
1400
1401       app->app_local->nks_version = get_nks_version (slot);
1402       if (opt.verbose)
1403         log_info ("Detected NKS version: %d\n", app->app_local->nks_version);
1404
1405       app->fnc.deinit = do_deinit;
1406       app->fnc.learn_status = do_learn_status;
1407       app->fnc.readcert = do_readcert;
1408       app->fnc.readkey = do_readkey;
1409       app->fnc.getattr = do_getattr;
1410       app->fnc.setattr = NULL;
1411       app->fnc.writekey = do_writekey;
1412       app->fnc.genkey = NULL;
1413       app->fnc.sign = do_sign;
1414       app->fnc.auth = NULL;
1415       app->fnc.decipher = do_decipher;
1416       app->fnc.change_pin = do_change_pin;
1417       app->fnc.check_pin = do_check_pin;
1418    }
1419
1420  leave:
1421   if (rc)
1422     do_deinit (app);
1423   return rc;
1424 }