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