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