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