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