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