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