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