scd: KEYINFO: Send LF for --data.
[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, ctrl_t ctrl, const char *keyid, unsigned int flags,
622             unsigned char **pk, size_t *pklen)
623 {
624   gpg_error_t err;
625   unsigned char *buffer[2];
626   size_t buflen[2];
627   unsigned short path[1] = { 0x4500 };
628
629   /* We use a generic name to retrieve PK.AUT.IFD-SPK.  */
630   if (!strcmp (keyid, "$IFDAUTHKEY") && app->app_local->nks_version >= 3)
631     ;
632   else /* Return the error code expected by cmd_readkey.  */
633     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
634
635   /* Access the KEYD file which is always in the master directory.  */
636   err = iso7816_select_path (app->slot, path, DIM (path));
637   if (err)
638     return err;
639   /* Due to the above select we need to re-select our application.  */
640   app->app_local->need_app_select = 1;
641   /* Get the two records.  */
642   err = iso7816_read_record (app->slot, 5, 1, 0, &buffer[0], &buflen[0]);
643   if (err)
644     return err;
645   if (all_zero_p (buffer[0], buflen[0]))
646     {
647       xfree (buffer[0]);
648       return gpg_error (GPG_ERR_NOT_FOUND);
649     }
650   err = iso7816_read_record (app->slot, 6, 1, 0, &buffer[1], &buflen[1]);
651   if (err)
652     {
653       xfree (buffer[0]);
654       return err;
655     }
656
657   if ((flags & APP_READKEY_FLAG_INFO))
658     {
659       /* Not yet implemented but we won't get here for any regular
660        * keyrefs anyway, thus the top layer will provide the
661        * keypairinfo from the certificate.  */
662       (void)ctrl;
663     }
664
665   if (pk && pklen)
666     {
667       *pk = make_canon_sexp_from_rsa_pk (buffer[0], buflen[0],
668                                          buffer[1], buflen[1],
669                                          pklen);
670       if (!*pk)
671         err = gpg_error_from_syserror ();
672     }
673
674   xfree (buffer[0]);
675   xfree (buffer[1]);
676   return err;
677 }
678
679
680 /* Handle the WRITEKEY command for NKS.  This function expects a
681    canonical encoded S-expression with the public key in KEYDATA and
682    its length in KEYDATALEN.  The only supported KEYID is
683    "$IFDAUTHKEY" to store the terminal key on the card.  Bit 0 of
684    FLAGS indicates whether an existing key shall get overwritten.
685    PINCB and PINCB_ARG are the usual arguments for the pinentry
686    callback.  */
687 static gpg_error_t
688 do_writekey (app_t app, ctrl_t ctrl,
689              const char *keyid, unsigned int flags,
690              gpg_error_t (*pincb)(void*, const char *, char **),
691              void *pincb_arg,
692              const unsigned char *keydata, size_t keydatalen)
693 {
694   gpg_error_t err;
695   int force = (flags & 1);
696   const unsigned char *rsa_n = NULL;
697   const unsigned char *rsa_e = NULL;
698   size_t rsa_n_len, rsa_e_len;
699   unsigned int nbits;
700
701   (void)ctrl;
702   (void)pincb;
703   (void)pincb_arg;
704
705   if (!strcmp (keyid, "$IFDAUTHKEY") && app->app_local->nks_version >= 3)
706     ;
707   else
708     return gpg_error (GPG_ERR_INV_ID);
709
710   if (!force && !do_readkey (app, ctrl, keyid, 0, NULL, NULL))
711     return gpg_error (GPG_ERR_EEXIST);
712
713   /* Parse the S-expression.  */
714   err = get_rsa_pk_from_canon_sexp (keydata, keydatalen,
715                                     &rsa_n, &rsa_n_len, &rsa_e, &rsa_e_len);
716   if (err)
717     goto leave;
718
719   /* Check that the parameters match the requirements.  */
720   nbits = app_help_count_bits (rsa_n, rsa_n_len);
721   if (nbits != 1024)
722     {
723       log_error (_("RSA modulus missing or not of size %d bits\n"), 1024);
724       err = gpg_error (GPG_ERR_BAD_PUBKEY);
725       goto leave;
726     }
727
728   nbits = app_help_count_bits (rsa_e, rsa_e_len);
729   if (nbits < 2 || nbits > 32)
730     {
731       log_error (_("RSA public exponent missing or larger than %d bits\n"),
732                  32);
733       err = gpg_error (GPG_ERR_BAD_PUBKEY);
734       goto leave;
735     }
736
737 /*   /\* Store them.  *\/ */
738 /*   err = verify_pin (app, 0, NULL, pincb, pincb_arg); */
739 /*   if (err) */
740 /*     goto leave; */
741
742   /* Send the MSE:Store_Public_Key.  */
743   err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
744 /*   mse = xtrymalloc (1000); */
745
746 /*   mse[0] = 0x80; /\* Algorithm reference.  *\/ */
747 /*   mse[1] = 1; */
748 /*   mse[2] = 0x17; */
749 /*   mse[3] = 0x84; /\* Private key reference.  *\/ */
750 /*   mse[4] = 1; */
751 /*   mse[5] = 0x77; */
752 /*   mse[6] = 0x7F; /\* Public key parameter.  *\/ */
753 /*   mse[7] = 0x49; */
754 /*   mse[8] = 0x81; */
755 /*   mse[9] = 3 + 0x80 + 2 + rsa_e_len; */
756 /*   mse[10] = 0x81; /\* RSA modulus of 128 byte.  *\/ */
757 /*   mse[11] = 0x81; */
758 /*   mse[12] = rsa_n_len; */
759 /*   memcpy (mse+12, rsa_n, rsa_n_len); */
760 /*   mse[10] = 0x82; /\* RSA public exponent of up to 4 bytes.  *\/ */
761 /*   mse[12] = rsa_e_len; */
762 /*   memcpy (mse+12, rsa_e, rsa_e_len); */
763 /*   err = iso7816_manage_security_env (app->slot, 0x81, 0xB6, */
764 /*                                      mse, sizeof mse); */
765
766  leave:
767   return err;
768 }
769
770
771 static gpg_error_t
772 basic_pin_checks (const char *pinvalue, int minlen, int maxlen)
773 {
774   if (strlen (pinvalue) < minlen)
775     {
776       log_error ("PIN is too short; minimum length is %d\n", minlen);
777       return gpg_error (GPG_ERR_BAD_PIN);
778     }
779   if (strlen (pinvalue) > maxlen)
780     {
781       log_error ("PIN is too large; maximum length is %d\n", maxlen);
782       return gpg_error (GPG_ERR_BAD_PIN);
783     }
784   return 0;
785 }
786
787
788 /* Verify the PIN if required.  */
789 static gpg_error_t
790 verify_pin (app_t app, int pwid, const char *desc,
791             gpg_error_t (*pincb)(void*, const char *, char **),
792             void *pincb_arg)
793 {
794   pininfo_t pininfo;
795   int rc;
796
797   if (!desc)
798     desc = "PIN";
799
800   memset (&pininfo, 0, sizeof pininfo);
801   pininfo.fixedlen = -1;
802   pininfo.minlen = 6;
803   pininfo.maxlen = 16;
804
805   if (!opt.disable_pinpad
806       && !iso7816_check_pinpad (app->slot, ISO7816_VERIFY, &pininfo) )
807     {
808       rc = pincb (pincb_arg, desc, NULL);
809       if (rc)
810         {
811           log_info (_("PIN callback returned error: %s\n"),
812                     gpg_strerror (rc));
813           return rc;
814         }
815
816       rc = iso7816_verify_kp (app->slot, pwid, &pininfo);
817       pincb (pincb_arg, NULL, NULL);  /* Dismiss the prompt. */
818     }
819   else
820     {
821       char *pinvalue;
822
823       rc = pincb (pincb_arg, desc, &pinvalue);
824       if (rc)
825         {
826           log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
827           return rc;
828         }
829
830       rc = basic_pin_checks (pinvalue, pininfo.minlen, pininfo.maxlen);
831       if (rc)
832         {
833           xfree (pinvalue);
834           return rc;
835         }
836
837       rc = iso7816_verify (app->slot, pwid, pinvalue, strlen (pinvalue));
838       xfree (pinvalue);
839     }
840
841   if (rc)
842     {
843       if ( gpg_err_code (rc) == GPG_ERR_USE_CONDITIONS )
844         log_error (_("the NullPIN has not yet been changed\n"));
845       else
846         log_error ("verify PIN failed\n");
847       return rc;
848     }
849
850   return 0;
851 }
852
853
854 /* Create the signature and return the allocated result in OUTDATA.
855    If a PIN is required the PINCB will be used to ask for the PIN;
856    that callback should return the PIN in an allocated buffer and
857    store that in the 3rd argument.  */
858 static gpg_error_t
859 do_sign (app_t app, const char *keyidstr, int hashalgo,
860          gpg_error_t (*pincb)(void*, const char *, char **),
861          void *pincb_arg,
862          const void *indata, size_t indatalen,
863          unsigned char **outdata, size_t *outdatalen )
864 {
865   static unsigned char sha1_prefix[15] = /* Object ID is 1.3.14.3.2.26 */
866     { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
867       0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
868   static unsigned char rmd160_prefix[15] = /* Object ID is 1.3.36.3.2.1 */
869     { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
870       0x02, 0x01, 0x05, 0x00, 0x04, 0x14 };
871   int rc, i;
872   int is_sigg = 0;
873   int fid;
874   unsigned char kid;
875   unsigned char data[83];   /* Must be large enough for a SHA-1 digest
876                                + the largest OID prefix. */
877   size_t datalen;
878
879   if (!keyidstr || !*keyidstr)
880     return gpg_error (GPG_ERR_INV_VALUE);
881   switch (indatalen)
882     {
883     case 16: case 20: case 35: case 47: case 51: case 67: case 83: break;
884     default: return gpg_error (GPG_ERR_INV_VALUE);
885     }
886
887   /* Check that the provided ID is valid.  This is not really needed
888      but we do it to enforce correct usage by the caller. */
889   if (!strncmp (keyidstr, "NKS-NKS3.", 9) )
890     ;
891   else if (!strncmp (keyidstr, "NKS-DF01.", 9) )
892     ;
893   else if (!strncmp (keyidstr, "NKS-SIGG.", 9) )
894     is_sigg = 1;
895   else
896     return gpg_error (GPG_ERR_INV_ID);
897   keyidstr += 9;
898
899   rc = switch_application (app, is_sigg);
900   if (rc)
901     return rc;
902
903   if (is_sigg && app->app_local->sigg_is_msig)
904     {
905       log_info ("mass signature cards are not allowed\n");
906       return gpg_error (GPG_ERR_NOT_SUPPORTED);
907     }
908
909   if (!hexdigitp (keyidstr) || !hexdigitp (keyidstr+1)
910       || !hexdigitp (keyidstr+2) || !hexdigitp (keyidstr+3)
911       || keyidstr[4])
912     return gpg_error (GPG_ERR_INV_ID);
913   fid = xtoi_4 (keyidstr);
914   for (i=0; filelist[i].fid; i++)
915     if (filelist[i].iskeypair && filelist[i].fid == fid)
916       break;
917   if (!filelist[i].fid)
918     return gpg_error (GPG_ERR_NOT_FOUND);
919   if (!filelist[i].issignkey)
920     return gpg_error (GPG_ERR_INV_ID);
921   kid = filelist[i].kid;
922
923   /* Prepare the DER object from INDATA.  */
924   if (app->app_local->nks_version > 2 && (indatalen == 35
925                                           || indatalen == 47
926                                           || indatalen == 51
927                                           || indatalen == 67
928                                           || indatalen == 83))
929     {
930       /* The caller send data matching the length of the ASN.1 encoded
931          hash for SHA-{1,224,256,384,512}.  Assume that is okay.  */
932       assert (indatalen <= sizeof data);
933       memcpy (data, indata, indatalen);
934       datalen = indatalen;
935     }
936   else if (indatalen == 35)
937     {
938       /* Alright, the caller was so kind to send us an already
939          prepared DER object.  This is for TCOS 2. */
940       if (hashalgo == GCRY_MD_SHA1 && !memcmp (indata, sha1_prefix, 15))
941         ;
942       else if (hashalgo == GCRY_MD_RMD160 && !memcmp (indata,rmd160_prefix,15))
943         ;
944       else
945         return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
946       memcpy (data, indata, indatalen);
947       datalen = 35;
948     }
949   else if (indatalen == 20)
950     {
951       if (hashalgo == GCRY_MD_SHA1)
952         memcpy (data, sha1_prefix, 15);
953       else if (hashalgo == GCRY_MD_RMD160)
954         memcpy (data, rmd160_prefix, 15);
955       else
956         return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
957       memcpy (data+15, indata, indatalen);
958       datalen = 35;
959     }
960   else
961     return gpg_error (GPG_ERR_INV_VALUE);
962
963
964   /* Send an MSE for PSO:Computer_Signature.  */
965   if (app->app_local->nks_version > 2)
966     {
967       unsigned char mse[6];
968
969       mse[0] = 0x80; /* Algorithm reference.  */
970       mse[1] = 1;
971       mse[2] = 2;    /* RSA, card does pkcs#1 v1.5 padding, no ASN.1 check.  */
972       mse[3] = 0x84; /* Private key reference.  */
973       mse[4] = 1;
974       mse[5] = kid;
975       rc = iso7816_manage_security_env (app->slot, 0x41, 0xB6,
976                                         mse, sizeof mse);
977     }
978   /* Verify using PW1.CH.  */
979   if (!rc)
980     rc = verify_pin (app, 0, NULL, pincb, pincb_arg);
981   /* Compute the signature.  */
982   if (!rc)
983     rc = iso7816_compute_ds (app->slot, 0, data, datalen, 0,
984                              outdata, outdatalen);
985   return rc;
986 }
987
988
989
990 /* Decrypt the data in INDATA and return the allocated result in OUTDATA.
991    If a PIN is required the PINCB will be used to ask for the PIN; it
992    should return the PIN in an allocated buffer and put it into PIN.  */
993 static gpg_error_t
994 do_decipher (app_t app, const char *keyidstr,
995              gpg_error_t (*pincb)(void*, const char *, char **),
996              void *pincb_arg,
997              const void *indata, size_t indatalen,
998              unsigned char **outdata, size_t *outdatalen,
999              unsigned int *r_info)
1000 {
1001   int rc, i;
1002   int is_sigg = 0;
1003   int fid;
1004   int kid;
1005
1006   (void)r_info;
1007
1008   if (!keyidstr || !*keyidstr || !indatalen)
1009     return gpg_error (GPG_ERR_INV_VALUE);
1010
1011   /* Check that the provided ID is valid.  This is not really needed
1012      but we do it to enforce correct usage by the caller. */
1013   if (!strncmp (keyidstr, "NKS-NKS3.", 9) )
1014     ;
1015   else if (!strncmp (keyidstr, "NKS-DF01.", 9) )
1016     ;
1017   else if (!strncmp (keyidstr, "NKS-SIGG.", 9) )
1018     is_sigg = 1;
1019   else
1020     return gpg_error (GPG_ERR_INV_ID);
1021   keyidstr += 9;
1022
1023   rc = switch_application (app, is_sigg);
1024   if (rc)
1025     return rc;
1026
1027   if (!hexdigitp (keyidstr) || !hexdigitp (keyidstr+1)
1028       || !hexdigitp (keyidstr+2) || !hexdigitp (keyidstr+3)
1029       || keyidstr[4])
1030     return gpg_error (GPG_ERR_INV_ID);
1031   fid = xtoi_4 (keyidstr);
1032   for (i=0; filelist[i].fid; i++)
1033     if (filelist[i].iskeypair && filelist[i].fid == fid)
1034       break;
1035   if (!filelist[i].fid)
1036     return gpg_error (GPG_ERR_NOT_FOUND);
1037   if (!filelist[i].isenckey)
1038     return gpg_error (GPG_ERR_INV_ID);
1039   kid = filelist[i].kid;
1040
1041   if (app->app_local->nks_version > 2)
1042     {
1043       unsigned char mse[6];
1044       mse[0] = 0x80; /* Algorithm reference.  */
1045       mse[1] = 1;
1046       mse[2] = 0x0a; /* RSA no padding.  (0x1A is pkcs#1.5 padding.)  */
1047       mse[3] = 0x84; /* Private key reference.  */
1048       mse[4] = 1;
1049       mse[5] = kid;
1050       rc = iso7816_manage_security_env (app->slot, 0x41, 0xB8,
1051                                         mse, sizeof mse);
1052     }
1053   else
1054     {
1055       static const unsigned char mse[] =
1056         {
1057           0x80, 1, 0x10, /* Select algorithm RSA. */
1058           0x84, 1, 0x81  /* Select local secret key 1 for decryption. */
1059         };
1060       rc = iso7816_manage_security_env (app->slot, 0xC1, 0xB8,
1061                                         mse, sizeof mse);
1062
1063     }
1064
1065   if (!rc)
1066     rc = verify_pin (app, 0, NULL, pincb, pincb_arg);
1067
1068   /* Note that we need to use extended length APDUs for TCOS 3 cards.
1069      Command chaining does not work.  */
1070   if (!rc)
1071     rc = iso7816_decipher (app->slot, app->app_local->nks_version > 2? 1:0,
1072                            indata, indatalen, 0, 0x81,
1073                            outdata, outdatalen);
1074   return rc;
1075 }
1076
1077
1078
1079 /* Parse a password ID string.  Returns NULL on error or a string
1080    suitable as passphrase prompt on success.  On success stores the
1081    reference value for the password at R_PWID and a flag indicating
1082    that the SigG application is to be used at R_SIGG.  If NEW_MODE is
1083    true, the returned description is suitable for a new Password.
1084    Supported values for PWIDSTR are:
1085
1086      PW1.CH       - Global password 1
1087      PW2.CH       - Global password 2
1088      PW1.CH.SIG   - SigG password 1
1089      PW2.CH.SIG   - SigG password 2
1090  */
1091 static const char *
1092 parse_pwidstr (const char *pwidstr, int new_mode, int *r_sigg, int *r_pwid)
1093 {
1094   const char *desc;
1095
1096   if (!pwidstr)
1097     desc = NULL;
1098   else if (!strcmp (pwidstr, "PW1.CH"))
1099     {
1100       *r_sigg = 0;
1101       *r_pwid = 0x00;
1102       /* TRANSLATORS: Do not translate the "|*|" prefixes but keep
1103          them verbatim at the start of the string.  */
1104       desc = (new_mode
1105               ? _("|N|Please enter a new PIN for the standard keys.")
1106               : _("||Please enter the PIN for the standard keys."));
1107     }
1108   else if (!strcmp (pwidstr, "PW2.CH"))
1109     {
1110       *r_pwid = 0x01;
1111       desc = (new_mode
1112               ? _("|NP|Please enter a new PIN Unblocking Code (PUK) "
1113                   "for the standard keys.")
1114               : _("|P|Please enter the PIN Unblocking Code (PUK) "
1115                   "for the standard keys."));
1116     }
1117   else if (!strcmp (pwidstr, "PW1.CH.SIG"))
1118     {
1119       *r_pwid = 0x81;
1120       *r_sigg = 1;
1121       desc = (new_mode
1122               ? _("|N|Please enter a new PIN for the key to create "
1123                   "qualified signatures.")
1124               : _("||Please enter the PIN for the key to create "
1125                   "qualified signatures."));
1126     }
1127   else if (!strcmp (pwidstr, "PW2.CH.SIG"))
1128     {
1129       *r_pwid = 0x83;  /* Yes, that is 83 and not 82.  */
1130       *r_sigg = 1;
1131       desc = (new_mode
1132               ? _("|NP|Please enter a new PIN Unblocking Code (PUK) "
1133                   "for the key to create qualified signatures.")
1134               : _("|P|Please enter the PIN Unblocking Code (PUK) "
1135                   "for the key to create qualified signatures."));
1136     }
1137   else
1138     {
1139       *r_pwid = 0; /* Only to avoid gcc warning in calling function.  */
1140       desc = NULL; /* Error.  */
1141     }
1142
1143   return desc;
1144 }
1145
1146
1147 /* Handle the PASSWD command. See parse_pwidstr() for allowed values
1148    for CHVNOSTR.  */
1149 static gpg_error_t
1150 do_change_pin (app_t app, ctrl_t ctrl,  const char *pwidstr,
1151                unsigned int flags,
1152                gpg_error_t (*pincb)(void*, const char *, char **),
1153                void *pincb_arg)
1154 {
1155   gpg_error_t err;
1156   char *newpin = NULL;
1157   char *oldpin = NULL;
1158   size_t newpinlen;
1159   size_t oldpinlen;
1160   int is_sigg;
1161   const char *newdesc;
1162   int pwid;
1163   pininfo_t pininfo;
1164
1165   (void)ctrl;
1166
1167   /* The minimum length is enforced by TCOS, the maximum length is
1168      just a reasonable value.  */
1169   memset (&pininfo, 0, sizeof pininfo);
1170   pininfo.minlen = 6;
1171   pininfo.maxlen = 16;
1172
1173   newdesc = parse_pwidstr (pwidstr, 1, &is_sigg, &pwid);
1174   if (!newdesc)
1175     return gpg_error (GPG_ERR_INV_ID);
1176
1177   if ((flags & APP_CHANGE_FLAG_CLEAR))
1178     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1179
1180   err = switch_application (app, is_sigg);
1181   if (err)
1182     return err;
1183
1184   if ((flags & APP_CHANGE_FLAG_NULLPIN))
1185     {
1186       /* With the nullpin flag, we do not verify the PIN - it would
1187          fail if the Nullpin is still set.  */
1188       oldpin = xtrycalloc (1, 6);
1189       if (!oldpin)
1190         {
1191           err = gpg_error_from_syserror ();
1192           goto leave;
1193         }
1194       oldpinlen = 6;
1195     }
1196   else
1197     {
1198       const char *desc;
1199       int dummy1, dummy2;
1200
1201       if ((flags & APP_CHANGE_FLAG_RESET))
1202         {
1203           /* Reset mode: Ask for the alternate PIN.  */
1204           const char *altpwidstr;
1205
1206           if (!strcmp (pwidstr, "PW1.CH"))
1207             altpwidstr = "PW2.CH";
1208           else if (!strcmp (pwidstr, "PW2.CH"))
1209             altpwidstr = "PW1.CH";
1210           else if (!strcmp (pwidstr, "PW1.CH.SIG"))
1211             altpwidstr = "PW2.CH.SIG";
1212           else if (!strcmp (pwidstr, "PW2.CH.SIG"))
1213             altpwidstr = "PW1.CH.SIG";
1214           else
1215             {
1216               err = gpg_error (GPG_ERR_BUG);
1217               goto leave;
1218             }
1219           desc = parse_pwidstr (altpwidstr, 0, &dummy1, &dummy2);
1220         }
1221       else
1222         {
1223           /* Regular change mode:  Ask for the old PIN.  */
1224           desc = parse_pwidstr (pwidstr, 0, &dummy1, &dummy2);
1225         }
1226       err = pincb (pincb_arg, desc, &oldpin);
1227       if (err)
1228         {
1229           log_error ("error getting old PIN: %s\n", gpg_strerror (err));
1230           goto leave;
1231         }
1232       oldpinlen = strlen (oldpin);
1233       err = basic_pin_checks (oldpin, pininfo.minlen, pininfo.maxlen);
1234       if (err)
1235         goto leave;
1236     }
1237
1238   err = pincb (pincb_arg, newdesc, &newpin);
1239   if (err)
1240     {
1241       log_error (_("error getting new PIN: %s\n"), gpg_strerror (err));
1242       goto leave;
1243     }
1244   newpinlen = strlen (newpin);
1245
1246   err = basic_pin_checks (newpin, pininfo.minlen, pininfo.maxlen);
1247   if (err)
1248     goto leave;
1249
1250   if ((flags & APP_CHANGE_FLAG_RESET))
1251     {
1252       char *data;
1253       size_t datalen = oldpinlen + newpinlen;
1254
1255       data = xtrymalloc (datalen);
1256       if (!data)
1257         {
1258           err = gpg_error_from_syserror ();
1259           goto leave;
1260         }
1261       memcpy (data, oldpin, oldpinlen);
1262       memcpy (data+oldpinlen, newpin, newpinlen);
1263       err = iso7816_reset_retry_counter_with_rc (app->slot, pwid,
1264                                                  data, datalen);
1265       wipememory (data, datalen);
1266       xfree (data);
1267     }
1268   else
1269     err = iso7816_change_reference_data (app->slot, pwid,
1270                                          oldpin, oldpinlen,
1271                                          newpin, newpinlen);
1272  leave:
1273   xfree (oldpin);
1274   xfree (newpin);
1275   return err;
1276 }
1277
1278
1279 /* Perform a simple verify operation.  KEYIDSTR should be NULL or empty.  */
1280 static gpg_error_t
1281 do_check_pin (app_t app, const char *pwidstr,
1282               gpg_error_t (*pincb)(void*, const char *, char **),
1283               void *pincb_arg)
1284 {
1285   gpg_error_t err;
1286   int pwid;
1287   int is_sigg;
1288   const char *desc;
1289
1290   desc = parse_pwidstr (pwidstr, 0, &is_sigg, &pwid);
1291   if (!desc)
1292     return gpg_error (GPG_ERR_INV_ID);
1293
1294   err = switch_application (app, is_sigg);
1295   if (err)
1296     return err;
1297
1298   return verify_pin (app, pwid, desc, pincb, pincb_arg);
1299 }
1300
1301
1302 /* Return the version of the NKS application.  */
1303 static int
1304 get_nks_version (int slot)
1305 {
1306   unsigned char *result = NULL;
1307   size_t resultlen;
1308   int type;
1309
1310   if (iso7816_apdu_direct (slot, "\x80\xaa\x06\x00\x00", 5, 0,
1311                            NULL, &result, &resultlen))
1312     return 2; /* NKS 2 does not support this command.  */
1313
1314   /* Example value:    04 11 19 22 21 6A 20 80 03 03 01 01 01 00 00 00
1315                        vv tt ccccccccccccccccc aa bb cc vvvvvvvvvvv xx
1316      vendor (Philips) -+  |  |                 |  |  |  |           |
1317      chip type -----------+  |                 |  |  |  |           |
1318      chip id ----------------+                 |  |  |  |           |
1319      card type (3 - tcos 3) -------------------+  |  |  |           |
1320      OS version of card type ---------------------+  |  |           |
1321      OS release of card type ------------------------+  |           |
1322      OS vendor internal version ------------------------+           |
1323      RFU -----------------------------------------------------------+
1324   */
1325   if (resultlen < 16)
1326     type = 0;  /* Invalid data returned.  */
1327   else
1328     type = result[8];
1329   xfree (result);
1330
1331   return type;
1332 }
1333
1334
1335 /* If ENABLE_SIGG is true switch to the SigG application if not yet
1336    active.  If false switch to the NKS application if not yet active.
1337    Returns 0 on success.  */
1338 static gpg_error_t
1339 switch_application (app_t app, int enable_sigg)
1340 {
1341   gpg_error_t err;
1342
1343   if (((app->app_local->sigg_active && enable_sigg)
1344        || (!app->app_local->sigg_active && !enable_sigg))
1345       && !app->app_local->need_app_select)
1346     return 0;  /* Already switched.  */
1347
1348   log_info ("app-nks: switching to %s\n", enable_sigg? "SigG":"NKS");
1349   if (enable_sigg)
1350     err = iso7816_select_application (app->slot, aid_sigg, sizeof aid_sigg, 0);
1351   else
1352     err = iso7816_select_application (app->slot, aid_nks, sizeof aid_nks, 0);
1353
1354   if (!err && enable_sigg && app->app_local->nks_version >= 3
1355       && !app->app_local->sigg_msig_checked)
1356     {
1357       /* Check whether this card is a mass signature card.  */
1358       unsigned char *buffer;
1359       size_t buflen;
1360       const unsigned char *tmpl;
1361       size_t tmpllen;
1362
1363       app->app_local->sigg_msig_checked = 1;
1364       app->app_local->sigg_is_msig = 1;
1365       err = iso7816_select_file (app->slot, 0x5349, 0);
1366       if (!err)
1367         err = iso7816_read_record (app->slot, 1, 1, 0, &buffer, &buflen);
1368       if (!err)
1369         {
1370           tmpl = find_tlv (buffer, buflen, 0x7a, &tmpllen);
1371           if (tmpl && tmpllen == 12
1372               && !memcmp (tmpl,
1373                           "\x93\x02\x00\x01\xA4\x06\x83\x01\x81\x83\x01\x83",
1374                           12))
1375             app->app_local->sigg_is_msig = 0;
1376           xfree (buffer);
1377         }
1378       if (app->app_local->sigg_is_msig)
1379         log_info ("This is a mass signature card\n");
1380     }
1381
1382   if (!err)
1383     {
1384       app->app_local->need_app_select = 0;
1385       app->app_local->sigg_active = enable_sigg;
1386     }
1387   else
1388     log_error ("app-nks: error switching to %s: %s\n",
1389                enable_sigg? "SigG":"NKS", gpg_strerror (err));
1390
1391   return err;
1392 }
1393
1394
1395 /* Select the NKS application.  */
1396 gpg_error_t
1397 app_select_nks (app_t app)
1398 {
1399   int slot = app->slot;
1400   int rc;
1401
1402   rc = iso7816_select_application (slot, aid_nks, sizeof aid_nks, 0);
1403   if (!rc)
1404     {
1405       app->apptype = "NKS";
1406
1407       app->app_local = xtrycalloc (1, sizeof *app->app_local);
1408       if (!app->app_local)
1409         {
1410           rc = gpg_error (gpg_err_code_from_errno (errno));
1411           goto leave;
1412         }
1413
1414       app->app_local->nks_version = get_nks_version (slot);
1415       if (opt.verbose)
1416         log_info ("Detected NKS version: %d\n", app->app_local->nks_version);
1417
1418       app->fnc.deinit = do_deinit;
1419       app->fnc.learn_status = do_learn_status;
1420       app->fnc.readcert = do_readcert;
1421       app->fnc.readkey = do_readkey;
1422       app->fnc.getattr = do_getattr;
1423       app->fnc.setattr = NULL;
1424       app->fnc.writekey = do_writekey;
1425       app->fnc.genkey = NULL;
1426       app->fnc.sign = do_sign;
1427       app->fnc.auth = NULL;
1428       app->fnc.decipher = do_decipher;
1429       app->fnc.change_pin = do_change_pin;
1430       app->fnc.check_pin = do_check_pin;
1431    }
1432
1433  leave:
1434   if (rc)
1435     do_deinit (app);
1436   return rc;
1437 }