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