gpg: Initialize the primary key when generating a key.
[gnupg.git] / scd / app-nks.c
1 /* app-nks.c - The Telesec NKS card application.
2  * Copyright (C) 2004, 2007, 2008, 2009 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 /* Notes:
21
22   - We are now targeting TCOS 3 cards and it may happen that there is
23     a regression towards TCOS 2 cards.  Please report.
24
25   - The TKS3 AUT key is not used.  It seems that it is only useful for
26     the internal authentication command and not accessible by other
27     applications.  The key itself is in the encryption class but the
28     corresponding certificate has only the digitalSignature
29     capability.
30
31   - If required, we automagically switch between the NKS application
32     and the SigG application.  This avoids to use the DINSIG
33     application which is somewhat limited, has no support for Secure
34     Messaging as required by TCOS 3 and has no way to change the PIN
35     or even set the NullPIN.
36
37   - We use the prefix NKS-DF01 for TCOS 2 cards and NKS-NKS3 for newer
38     cards.  This is because the NKS application has moved to DF02 with
39     TCOS 3 and thus we better use a DF independent tag.
40
41   - We use only the global PINs for the NKS application.
42
43  */
44
45 #include <config.h>
46 #include <errno.h>
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <string.h>
50 #include <assert.h>
51 #include <time.h>
52
53 #include "scdaemon.h"
54 #include "i18n.h"
55 #include "iso7816.h"
56 #include "app-common.h"
57 #include "tlv.h"
58 #include "apdu.h"
59 #include "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, NULL, NULL);
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, &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, NULL, NULL);
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), NULL, NULL);
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 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 passpahrse 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   err = switch_application (app, is_sigg);
1169   if (err)
1170     return err;
1171
1172   if ((flags & APP_CHANGE_FLAG_NULLPIN))
1173     {
1174       /* With the nullpin flag, we do not verify the PIN - it would
1175          fail if the Nullpin is still set.  */
1176       oldpin = xtrycalloc (1, 6);
1177       if (!oldpin)
1178         {
1179           err = gpg_error_from_syserror ();
1180           goto leave;
1181         }
1182       oldpinlen = 6;
1183     }
1184   else
1185     {
1186       const char *desc;
1187       int dummy1, dummy2;
1188
1189       if ((flags & APP_CHANGE_FLAG_RESET))
1190         {
1191           /* Reset mode: Ask for the alternate PIN.  */
1192           const char *altpwidstr;
1193
1194           if (!strcmp (pwidstr, "PW1.CH"))
1195             altpwidstr = "PW2.CH";
1196           else if (!strcmp (pwidstr, "PW2.CH"))
1197             altpwidstr = "PW1.CH";
1198           else if (!strcmp (pwidstr, "PW1.CH.SIG"))
1199             altpwidstr = "PW2.CH.SIG";
1200           else if (!strcmp (pwidstr, "PW2.CH.SIG"))
1201             altpwidstr = "PW1.CH.SIG";
1202           else
1203             {
1204               err = gpg_error (GPG_ERR_BUG);
1205               goto leave;
1206             }
1207           desc = parse_pwidstr (altpwidstr, 0, &dummy1, &dummy2);
1208         }
1209       else
1210         {
1211           /* Regular change mode:  Ask for the old PIN.  */
1212           desc = parse_pwidstr (pwidstr, 0, &dummy1, &dummy2);
1213         }
1214       err = pincb (pincb_arg, desc, &oldpin);
1215       if (err)
1216         {
1217           log_error ("error getting old PIN: %s\n", gpg_strerror (err));
1218           goto leave;
1219         }
1220       oldpinlen = strlen (oldpin);
1221       err = basic_pin_checks (oldpin, pininfo.minlen, pininfo.maxlen);
1222       if (err)
1223         goto leave;
1224     }
1225
1226   err = pincb (pincb_arg, newdesc, &newpin);
1227   if (err)
1228     {
1229       log_error (_("error getting new PIN: %s\n"), gpg_strerror (err));
1230       goto leave;
1231     }
1232   newpinlen = strlen (newpin);
1233
1234   err = basic_pin_checks (newpin, pininfo.minlen, pininfo.maxlen);
1235   if (err)
1236     goto leave;
1237
1238   if ((flags & APP_CHANGE_FLAG_RESET))
1239     {
1240       char *data;
1241       size_t datalen = oldpinlen + newpinlen;
1242
1243       data = xtrymalloc (datalen);
1244       if (!data)
1245         {
1246           err = gpg_error_from_syserror ();
1247           goto leave;
1248         }
1249       memcpy (data, oldpin, oldpinlen);
1250       memcpy (data+oldpinlen, newpin, newpinlen);
1251       err = iso7816_reset_retry_counter_with_rc (app->slot, pwid,
1252                                                  data, datalen);
1253       wipememory (data, datalen);
1254       xfree (data);
1255     }
1256   else
1257     err = iso7816_change_reference_data (app->slot, pwid,
1258                                          oldpin, oldpinlen,
1259                                          newpin, newpinlen);
1260  leave:
1261   xfree (oldpin);
1262   xfree (newpin);
1263   return err;
1264 }
1265
1266
1267 /* Perform a simple verify operation.  KEYIDSTR should be NULL or empty.  */
1268 static gpg_error_t
1269 do_check_pin (app_t app, const char *pwidstr,
1270               gpg_error_t (*pincb)(void*, const char *, char **),
1271               void *pincb_arg)
1272 {
1273   gpg_error_t err;
1274   int pwid;
1275   int is_sigg;
1276   const char *desc;
1277
1278   desc = parse_pwidstr (pwidstr, 0, &is_sigg, &pwid);
1279   if (!desc)
1280     return gpg_error (GPG_ERR_INV_ID);
1281
1282   err = switch_application (app, is_sigg);
1283   if (err)
1284     return err;
1285
1286   return verify_pin (app, pwid, desc, pincb, pincb_arg);
1287 }
1288
1289
1290 /* Return the version of the NKS application.  */
1291 static int
1292 get_nks_version (int slot)
1293 {
1294   unsigned char *result = NULL;
1295   size_t resultlen;
1296   int type;
1297
1298   if (iso7816_apdu_direct (slot, "\x80\xaa\x06\x00\x00", 5, 0,
1299                            &result, &resultlen))
1300     return 2; /* NKS 2 does not support this command.  */
1301
1302   /* Example value:    04 11 19 22 21 6A 20 80 03 03 01 01 01 00 00 00
1303                        vv tt ccccccccccccccccc aa bb cc vvvvvvvvvvv xx
1304      vendor (Philips) -+  |  |                 |  |  |  |           |
1305      chip type -----------+  |                 |  |  |  |           |
1306      chip id ----------------+                 |  |  |  |           |
1307      card type (3 - tcos 3) -------------------+  |  |  |           |
1308      OS version of card type ---------------------+  |  |           |
1309      OS release of card type ------------------------+  |           |
1310      OS vendor internal version ------------------------+           |
1311      RFU -----------------------------------------------------------+
1312   */
1313   if (resultlen < 16)
1314     type = 0;  /* Invalid data returned.  */
1315   else
1316     type = result[8];
1317   xfree (result);
1318
1319   return type;
1320 }
1321
1322
1323 /* If ENABLE_SIGG is true switch to the SigG application if not yet
1324    active.  If false switch to the NKS application if not yet active.
1325    Returns 0 on success.  */
1326 static gpg_error_t
1327 switch_application (app_t app, int enable_sigg)
1328 {
1329   gpg_error_t err;
1330
1331   if (((app->app_local->sigg_active && enable_sigg)
1332        || (!app->app_local->sigg_active && !enable_sigg))
1333       && !app->app_local->need_app_select)
1334     return 0;  /* Already switched.  */
1335
1336   log_info ("app-nks: switching to %s\n", enable_sigg? "SigG":"NKS");
1337   if (enable_sigg)
1338     err = iso7816_select_application (app->slot, aid_sigg, sizeof aid_sigg, 0);
1339   else
1340     err = iso7816_select_application (app->slot, aid_nks, sizeof aid_nks, 0);
1341
1342   if (!err && enable_sigg && app->app_local->nks_version >= 3
1343       && !app->app_local->sigg_msig_checked)
1344     {
1345       /* Check whether this card is a mass signature card.  */
1346       unsigned char *buffer;
1347       size_t buflen;
1348       const unsigned char *tmpl;
1349       size_t tmpllen;
1350
1351       app->app_local->sigg_msig_checked = 1;
1352       app->app_local->sigg_is_msig = 1;
1353       err = iso7816_select_file (app->slot, 0x5349, 0, NULL, NULL);
1354       if (!err)
1355         err = iso7816_read_record (app->slot, 1, 1, 0, &buffer, &buflen);
1356       if (!err)
1357         {
1358           tmpl = find_tlv (buffer, buflen, 0x7a, &tmpllen);
1359           if (tmpl && tmpllen == 12
1360               && !memcmp (tmpl,
1361                           "\x93\x02\x00\x01\xA4\x06\x83\x01\x81\x83\x01\x83",
1362                           12))
1363             app->app_local->sigg_is_msig = 0;
1364           xfree (buffer);
1365         }
1366       if (app->app_local->sigg_is_msig)
1367         log_info ("This is a mass signature card\n");
1368     }
1369
1370   if (!err)
1371     {
1372       app->app_local->need_app_select = 0;
1373       app->app_local->sigg_active = enable_sigg;
1374     }
1375   else
1376     log_error ("app-nks: error switching to %s: %s\n",
1377                enable_sigg? "SigG":"NKS", gpg_strerror (err));
1378
1379   return err;
1380 }
1381
1382
1383 /* Select the NKS application.  */
1384 gpg_error_t
1385 app_select_nks (app_t app)
1386 {
1387   int slot = app->slot;
1388   int rc;
1389
1390   rc = iso7816_select_application (slot, aid_nks, sizeof aid_nks, 0);
1391   if (!rc)
1392     {
1393       app->apptype = "NKS";
1394
1395       app->app_local = xtrycalloc (1, sizeof *app->app_local);
1396       if (!app->app_local)
1397         {
1398           rc = gpg_error (gpg_err_code_from_errno (errno));
1399           goto leave;
1400         }
1401
1402       app->app_local->nks_version = get_nks_version (slot);
1403       if (opt.verbose)
1404         log_info ("Detected NKS version: %d\n", app->app_local->nks_version);
1405
1406       app->fnc.deinit = do_deinit;
1407       app->fnc.learn_status = do_learn_status;
1408       app->fnc.readcert = do_readcert;
1409       app->fnc.readkey = do_readkey;
1410       app->fnc.getattr = do_getattr;
1411       app->fnc.setattr = NULL;
1412       app->fnc.writekey = do_writekey;
1413       app->fnc.genkey = NULL;
1414       app->fnc.sign = do_sign;
1415       app->fnc.auth = NULL;
1416       app->fnc.decipher = do_decipher;
1417       app->fnc.change_pin = do_change_pin;
1418       app->fnc.check_pin = do_check_pin;
1419    }
1420
1421  leave:
1422   if (rc)
1423     do_deinit (app);
1424   return rc;
1425 }