app-openpgp changes
[gnupg.git] / scd / app-nks.c
blob53435c36020e62f97a61d6e11d3f1c518d819fbe
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. */
103 int sigg_msig_checked;/* True if we checked for a mass signature card. */
104 int sigg_is_msig; /* True if this is a mass signature card. */
106 int need_app_select; /* Need to re-select the application. */
112 static gpg_error_t switch_application (app_t app, int enable_sigg);
116 /* Release local data. */
117 static void
118 do_deinit (app_t app)
120 if (app && app->app_local)
122 xfree (app->app_local);
123 app->app_local = NULL;
128 static int
129 all_zero_p (void *buffer, size_t length)
131 char *p;
133 for (p=buffer; length; length--, p++)
134 if (*p)
135 return 0;
136 return 1;
140 /* Read the file with FID, assume it contains a public key and return
141 its keygrip in the caller provided 41 byte buffer R_GRIPSTR. */
142 static gpg_error_t
143 keygripstr_from_pk_file (app_t app, int fid, char *r_gripstr)
145 gpg_error_t err;
146 unsigned char grip[20];
147 unsigned char *buffer[2];
148 size_t buflen[2];
149 gcry_sexp_t sexp;
150 int i;
151 int offset[2] = { 0, 0 };
153 err = iso7816_select_file (app->slot, fid, 0, NULL, NULL);
154 if (err)
155 return err;
156 err = iso7816_read_record (app->slot, 1, 1, 0, &buffer[0], &buflen[0]);
157 if (err)
158 return err;
159 err = iso7816_read_record (app->slot, 2, 1, 0, &buffer[1], &buflen[1]);
160 if (err)
162 xfree (buffer[0]);
163 return err;
166 if (app->app_local->nks_version < 3)
168 /* Old versions of NKS store the values in a TLV encoded format.
169 We need to do some checks. */
170 for (i=0; i < 2; i++)
172 /* Check that the value appears like an integer encoded as
173 Simple-TLV. We don't check the tag because the tests cards I
174 have use 1 for both, the modulus and the exponent - the
175 example in the documentation gives 2 for the exponent. */
176 if (buflen[i] < 3)
177 err = gpg_error (GPG_ERR_TOO_SHORT);
178 else if (buffer[i][1] != buflen[i]-2 )
179 err = gpg_error (GPG_ERR_INV_OBJ);
180 else
181 offset[i] = 2;
184 else
186 /* Remove leading zeroes to get a correct keygrip. Take care of
187 negative numbers. We should also fix it the same way in
188 libgcrypt but we can't yet rely on it yet. */
189 for (i=0; i < 2; i++)
191 while (buflen[i]-offset[i] > 1
192 && !buffer[i][offset[i]]
193 && !(buffer[i][offset[i]+1] & 0x80))
194 offset[i]++;
198 /* Check whether negative values are not prefixed with a zero and
199 fix that. */
200 for (i=0; i < 2; i++)
202 if ((buflen[i]-offset[i]) && (buffer[i][offset[i]] & 0x80))
204 unsigned char *newbuf;
205 size_t newlen;
207 newlen = 1 + buflen[i] - offset[i];
208 newbuf = xtrymalloc (newlen);
209 if (!newlen)
211 xfree (buffer[0]);
212 xfree (buffer[1]);
213 return gpg_error_from_syserror ();
215 newbuf[0] = 0;
216 memcpy (newbuf+1, buffer[i]+offset[i], buflen[i] - offset[i]);
217 xfree (buffer[i]);
218 buffer[i] = newbuf;
219 buflen[i] = newlen;
220 offset[i] = 0;
224 if (!err)
225 err = gcry_sexp_build (&sexp, NULL,
226 "(public-key (rsa (n %b) (e %b)))",
227 (int)buflen[0]-offset[0], buffer[0]+offset[0],
228 (int)buflen[1]-offset[1], buffer[1]+offset[1]);
230 xfree (buffer[0]);
231 xfree (buffer[1]);
232 if (err)
233 return err;
235 if (!gcry_pk_get_keygrip (sexp, grip))
237 err = gpg_error (GPG_ERR_INTERNAL); /* i.e. RSA not supported by
238 libgcrypt. */
240 else
242 bin2hex (grip, 20, r_gripstr);
244 gcry_sexp_release (sexp);
245 return err;
249 /* TCOS responds to a verify with empty data (i.e. without the Lc
250 byte) with the status of the PIN. PWID is the PIN ID, If SIGG is
251 true, the application is switched into SigG mode.
252 Returns:
253 -1 = Error retrieving the data,
254 -2 = No such PIN,
255 -3 = PIN blocked,
256 -4 = NullPIN activ,
257 n >= 0 = Number of verification attempts left. */
258 static int
259 get_chv_status (app_t app, int sigg, int pwid)
261 unsigned char *result = NULL;
262 size_t resultlen;
263 char command[4];
264 int rc;
266 if (switch_application (app, sigg))
267 return sigg? -2 : -1; /* No such PIN / General error. */
269 command[0] = 0x00;
270 command[1] = 0x20;
271 command[2] = 0x00;
272 command[3] = pwid;
274 if (apdu_send_direct (app->slot, 0, command, 4, 0, &result, &resultlen))
275 rc = -1; /* Error. */
276 else if (resultlen < 2)
277 rc = -1; /* Error. */
278 else
280 unsigned int sw = ((result[resultlen-2] << 8) | result[resultlen-1]);
282 if (sw == 0x6a88)
283 rc = -2; /* No such PIN. */
284 else if (sw == 0x6983)
285 rc = -3; /* PIN is blocked. */
286 else if (sw == 0x6985)
287 rc = -4; /* NullPIN is activ. */
288 else if ((sw & 0xfff0) == 0x63C0)
289 rc = (sw & 0x000f); /* PIN has N tries left. */
290 else
291 rc = -1; /* Other error. */
293 xfree (result);
295 return rc;
299 /* Implement the GETATTR command. This is similar to the LEARN
300 command but returns just one value via the status interface. */
301 static gpg_error_t
302 do_getattr (app_t app, ctrl_t ctrl, const char *name)
304 static struct {
305 const char *name;
306 int special;
307 } table[] = {
308 { "$AUTHKEYID", 1 },
309 { "NKS-VERSION", 2 },
310 { "CHV-STATUS", 3 },
311 { NULL, 0 }
313 gpg_error_t err = 0;
314 int idx;
315 char buffer[100];
317 err = switch_application (app, 0);
318 if (err)
319 return err;
321 for (idx=0; table[idx].name && strcmp (table[idx].name, name); idx++)
323 if (!table[idx].name)
324 return gpg_error (GPG_ERR_INV_NAME);
326 switch (table[idx].special)
328 case 1: /* $AUTHKEYID */
330 /* NetKey 3.0 cards define an authentication key but according
331 to the specs this key is only usable for encryption and not
332 signing. it might work anyway but it has not yet been
333 tested - fixme. Thus for now we use the NKS signature key
334 for authentication. */
335 char const tmp[] = "NKS-NKS3.4531";
336 send_status_info (ctrl, table[idx].name, tmp, strlen (tmp), NULL, 0);
338 break;
340 case 2: /* NKS-VERSION */
341 snprintf (buffer, sizeof buffer, "%d", app->app_local->nks_version);
342 send_status_info (ctrl, table[idx].name,
343 buffer, strlen (buffer), NULL, 0);
344 break;
346 case 3: /* CHV-STATUS */
348 /* Returns: PW1.CH PW2.CH PW1.CH.SIG PW2.CH.SIG That are the
349 two global passwords followed by the two SigG passwords.
350 For the values, see the function get_chv_status. */
351 int tmp[4];
353 /* We use a helper array so that we can control that there is
354 no superfluous application switch. Note that PW2.CH.SIG
355 really has the identifier 0x83 and not 0x82 as one would
356 expect. */
357 tmp[0] = get_chv_status (app, 0, 0x00);
358 tmp[1] = get_chv_status (app, 0, 0x01);
359 tmp[2] = get_chv_status (app, 1, 0x81);
360 tmp[3] = get_chv_status (app, 1, 0x83);
361 snprintf (buffer, sizeof buffer,
362 "%d %d %d %d", tmp[0], tmp[1], tmp[2], tmp[3]);
363 send_status_info (ctrl, table[idx].name,
364 buffer, strlen (buffer), NULL, 0);
366 break;
369 default:
370 err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
371 break;
374 return err;
379 static void
380 do_learn_status_core (app_t app, ctrl_t ctrl, unsigned int flags, int is_sigg)
382 gpg_error_t err;
383 char ct_buf[100], id_buf[100];
384 int i;
385 const char *tag;
387 if (is_sigg)
388 tag = "SIGG";
389 else if (app->app_local->nks_version < 3)
390 tag = "DF01";
391 else
392 tag = "NKS3";
394 /* Output information about all useful objects in the NKS application. */
395 for (i=0; filelist[i].fid; i++)
397 if (filelist[i].nks_ver > app->app_local->nks_version)
398 continue;
400 if (!!filelist[i].is_sigg != !!is_sigg)
401 continue;
403 if (filelist[i].certtype && !(flags &1))
405 size_t len;
407 len = app_help_read_length_of_cert (app->slot,
408 filelist[i].fid, NULL);
409 if (len)
411 /* FIXME: We should store the length in the application's
412 context so that a following readcert does only need to
413 read that many bytes. */
414 snprintf (ct_buf, sizeof ct_buf, "%d", filelist[i].certtype);
415 snprintf (id_buf, sizeof id_buf, "NKS-%s.%04X",
416 tag, filelist[i].fid);
417 send_status_info (ctrl, "CERTINFO",
418 ct_buf, strlen (ct_buf),
419 id_buf, strlen (id_buf),
420 NULL, (size_t)0);
423 else if (filelist[i].iskeypair)
425 char gripstr[40+1];
427 err = keygripstr_from_pk_file (app, filelist[i].fid, gripstr);
428 if (err)
429 log_error ("can't get keygrip from FID 0x%04X: %s\n",
430 filelist[i].fid, gpg_strerror (err));
431 else
433 snprintf (id_buf, sizeof id_buf, "NKS-%s.%04X",
434 tag, filelist[i].fid);
435 send_status_info (ctrl, "KEYPAIRINFO",
436 gripstr, 40,
437 id_buf, strlen (id_buf),
438 NULL, (size_t)0);
447 static gpg_error_t
448 do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
450 gpg_error_t err;
452 err = switch_application (app, 0);
453 if (err)
454 return err;
456 do_learn_status_core (app, ctrl, flags, 0);
458 err = switch_application (app, 1);
459 if (err)
460 return 0; /* Silently ignore if we can't switch to SigG. */
462 do_learn_status_core (app, ctrl, flags, 1);
464 return 0;
470 /* Read the certificate with id CERTID (as returned by learn_status in
471 the CERTINFO status lines) and return it in the freshly allocated
472 buffer put into CERT and the length of the certificate put into
473 CERTLEN. */
474 static gpg_error_t
475 do_readcert (app_t app, const char *certid,
476 unsigned char **cert, size_t *certlen)
478 int i, fid;
479 gpg_error_t err;
480 unsigned char *buffer;
481 const unsigned char *p;
482 size_t buflen, n;
483 int class, tag, constructed, ndef;
484 size_t totobjlen, objlen, hdrlen;
485 int rootca = 0;
486 int is_sigg = 0;
488 *cert = NULL;
489 *certlen = 0;
491 if (!strncmp (certid, "NKS-NKS3.", 9))
493 else if (!strncmp (certid, "NKS-DF01.", 9))
495 else if (!strncmp (certid, "NKS-SIGG.", 9))
496 is_sigg = 1;
497 else
498 return gpg_error (GPG_ERR_INV_ID);
500 err = switch_application (app, is_sigg);
501 if (err)
502 return err;
504 certid += 9;
505 if (!hexdigitp (certid) || !hexdigitp (certid+1)
506 || !hexdigitp (certid+2) || !hexdigitp (certid+3)
507 || certid[4])
508 return gpg_error (GPG_ERR_INV_ID);
509 fid = xtoi_4 (certid);
510 for (i=0; filelist[i].fid; i++)
511 if ((filelist[i].certtype || filelist[i].iskeypair)
512 && filelist[i].fid == fid)
513 break;
514 if (!filelist[i].fid)
515 return gpg_error (GPG_ERR_NOT_FOUND);
517 /* If the requested objects is a plain public key, redirect it to
518 the corresponding certificate. The whole system is a bit messy
519 because we sometime use the key directly or let the caller
520 retrieve the key from the certificate. The rationale for
521 that is to support not-yet stored certificates. */
522 if (filelist[i].iskeypair)
523 fid = filelist[i].iskeypair;
526 /* Read the entire file. fixme: This could be optimized by first
527 reading the header to figure out how long the certificate
528 actually is. */
529 err = iso7816_select_file (app->slot, fid, 0, NULL, NULL);
530 if (err)
532 log_error ("error selecting FID 0x%04X: %s\n", fid, gpg_strerror (err));
533 return err;
536 err = iso7816_read_binary (app->slot, 0, 0, &buffer, &buflen);
537 if (err)
539 log_error ("error reading certificate from FID 0x%04X: %s\n",
540 fid, gpg_strerror (err));
541 return err;
544 if (!buflen || *buffer == 0xff)
546 log_info ("no certificate contained in FID 0x%04X\n", fid);
547 err = gpg_error (GPG_ERR_NOT_FOUND);
548 goto leave;
551 /* Now figure something out about the object. */
552 p = buffer;
553 n = buflen;
554 err = parse_ber_header (&p, &n, &class, &tag, &constructed,
555 &ndef, &objlen, &hdrlen);
556 if (err)
557 goto leave;
558 if ( class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE && constructed )
560 else if ( class == CLASS_UNIVERSAL && tag == TAG_SET && constructed )
561 rootca = 1;
562 else
563 return gpg_error (GPG_ERR_INV_OBJ);
564 totobjlen = objlen + hdrlen;
565 assert (totobjlen <= buflen);
567 err = parse_ber_header (&p, &n, &class, &tag, &constructed,
568 &ndef, &objlen, &hdrlen);
569 if (err)
570 goto leave;
572 if (rootca)
574 else if (class == CLASS_UNIVERSAL && tag == TAG_OBJECT_ID && !constructed)
576 const unsigned char *save_p;
578 /* The certificate seems to be contained in a userCertificate
579 container. Skip this and assume the following sequence is
580 the certificate. */
581 if (n < objlen)
583 err = gpg_error (GPG_ERR_INV_OBJ);
584 goto leave;
586 p += objlen;
587 n -= objlen;
588 save_p = p;
589 err = parse_ber_header (&p, &n, &class, &tag, &constructed,
590 &ndef, &objlen, &hdrlen);
591 if (err)
592 goto leave;
593 if ( !(class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE && constructed) )
594 return gpg_error (GPG_ERR_INV_OBJ);
595 totobjlen = objlen + hdrlen;
596 assert (save_p + totobjlen <= buffer + buflen);
597 memmove (buffer, save_p, totobjlen);
600 *cert = buffer;
601 buffer = NULL;
602 *certlen = totobjlen;
604 leave:
605 xfree (buffer);
606 return err;
610 /* Handle the READKEY command. On success a canonical encoded
611 S-expression with the public key will get stored at PK and its
612 length at PKLEN; the caller must release that buffer. On error PK
613 and PKLEN are not changed and an error code is returned. As of now
614 this function is only useful for the internal authentication key.
615 Other keys are automagically retrieved via by means of the
616 certificate parsing code in commands.c:cmd_readkey. For internal
617 use PK and PKLEN may be NULL to just check for an existing key. */
618 static gpg_error_t
619 do_readkey (app_t app, const char *keyid, unsigned char **pk, size_t *pklen)
621 gpg_error_t err;
622 unsigned char *buffer[2];
623 size_t buflen[2];
624 unsigned short path[1] = { 0x4500 };
626 /* We use a generic name to retrieve PK.AUT.IFD-SPK. */
627 if (!strcmp (keyid, "$IFDAUTHKEY") && app->app_local->nks_version >= 3)
629 else /* Return the error code expected by cmd_readkey. */
630 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
632 /* Access the KEYD file which is always in the master directory. */
633 err = iso7816_select_path (app->slot, path, DIM (path), NULL, NULL);
634 if (err)
635 return err;
636 /* Due to the above select we need to re-select our application. */
637 app->app_local->need_app_select = 1;
638 /* Get the two records. */
639 err = iso7816_read_record (app->slot, 5, 1, 0, &buffer[0], &buflen[0]);
640 if (err)
641 return err;
642 if (all_zero_p (buffer[0], buflen[0]))
644 xfree (buffer[0]);
645 return gpg_error (GPG_ERR_NOT_FOUND);
647 err = iso7816_read_record (app->slot, 6, 1, 0, &buffer[1], &buflen[1]);
648 if (err)
650 xfree (buffer[0]);
651 return err;
654 if (pk && pklen)
656 *pk = make_canon_sexp_from_rsa_pk (buffer[0], buflen[0],
657 buffer[1], buflen[1],
658 pklen);
659 if (!*pk)
660 err = gpg_error_from_syserror ();
663 xfree (buffer[0]);
664 xfree (buffer[1]);
665 return err;
669 /* Handle the WRITEKEY command for NKS. This function expects a
670 canonical encoded S-expression with the public key in KEYDATA and
671 its length in KEYDATALEN. The only supported KEYID is
672 "$IFDAUTHKEY" to store the terminal key on the card. Bit 0 of
673 FLAGS indicates whether an existing key shall get overwritten.
674 PINCB and PINCB_ARG are the usual arguments for the pinentry
675 callback. */
676 static gpg_error_t
677 do_writekey (app_t app, ctrl_t ctrl,
678 const char *keyid, unsigned int flags,
679 gpg_error_t (*pincb)(void*, const char *, char **),
680 void *pincb_arg,
681 const unsigned char *keydata, size_t keydatalen)
683 gpg_error_t err;
684 int force = (flags & 1);
685 const unsigned char *rsa_n = NULL;
686 const unsigned char *rsa_e = NULL;
687 size_t rsa_n_len, rsa_e_len;
688 unsigned int nbits;
690 (void)ctrl;
691 (void)pincb;
692 (void)pincb_arg;
694 if (!strcmp (keyid, "$IFDAUTHKEY") && app->app_local->nks_version >= 3)
696 else
697 return gpg_error (GPG_ERR_INV_ID);
699 if (!force && !do_readkey (app, keyid, NULL, NULL))
700 return gpg_error (GPG_ERR_EEXIST);
702 /* Parse the S-expression. */
703 err = get_rsa_pk_from_canon_sexp (keydata, keydatalen,
704 &rsa_n, &rsa_n_len, &rsa_e, &rsa_e_len);
705 if (err)
706 goto leave;
708 /* Check that the parameters match the requirements. */
709 nbits = app_help_count_bits (rsa_n, rsa_n_len);
710 if (nbits != 1024)
712 log_error (_("RSA modulus missing or not of size %d bits\n"), 1024);
713 err = gpg_error (GPG_ERR_BAD_PUBKEY);
714 goto leave;
717 nbits = app_help_count_bits (rsa_e, rsa_e_len);
718 if (nbits < 2 || nbits > 32)
720 log_error (_("RSA public exponent missing or larger than %d bits\n"),
721 32);
722 err = gpg_error (GPG_ERR_BAD_PUBKEY);
723 goto leave;
726 /* /\* Store them. *\/ */
727 /* err = verify_pin (app, 0, NULL, pincb, pincb_arg); */
728 /* if (err) */
729 /* goto leave; */
731 /* Send the MSE:Store_Public_Key. */
732 err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
733 /* mse = xtrymalloc (1000); */
735 /* mse[0] = 0x80; /\* Algorithm reference. *\/ */
736 /* mse[1] = 1; */
737 /* mse[2] = 0x17; */
738 /* mse[3] = 0x84; /\* Private key reference. *\/ */
739 /* mse[4] = 1; */
740 /* mse[5] = 0x77; */
741 /* mse[6] = 0x7F; /\* Public key parameter. *\/ */
742 /* mse[7] = 0x49; */
743 /* mse[8] = 0x81; */
744 /* mse[9] = 3 + 0x80 + 2 + rsa_e_len; */
745 /* mse[10] = 0x81; /\* RSA modulus of 128 byte. *\/ */
746 /* mse[11] = 0x81; */
747 /* mse[12] = rsa_n_len; */
748 /* memcpy (mse+12, rsa_n, rsa_n_len); */
749 /* mse[10] = 0x82; /\* RSA public exponent of up to 4 bytes. *\/ */
750 /* mse[12] = rsa_e_len; */
751 /* memcpy (mse+12, rsa_e, rsa_e_len); */
752 /* err = iso7816_manage_security_env (app->slot, 0x81, 0xB6, */
753 /* mse, sizeof mse); */
755 leave:
756 return err;
760 static gpg_error_t
761 basic_pin_checks (const char *pinvalue, int minlen, int maxlen)
763 if (strlen (pinvalue) < minlen)
765 log_error ("PIN is too short; minimum length is %d\n", minlen);
766 return gpg_error (GPG_ERR_BAD_PIN);
768 if (strlen (pinvalue) > maxlen)
770 log_error ("PIN is too large; maximum length is %d\n", maxlen);
771 return gpg_error (GPG_ERR_BAD_PIN);
773 return 0;
777 /* Verify the PIN if required. */
778 static gpg_error_t
779 verify_pin (app_t app, int pwid, const char *desc,
780 gpg_error_t (*pincb)(void*, const char *, char **),
781 void *pincb_arg)
783 iso7816_pininfo_t pininfo;
784 int rc;
786 if (!desc)
787 desc = "PIN";
789 memset (&pininfo, 0, sizeof pininfo);
790 pininfo.mode = 1;
791 pininfo.minlen = 6;
792 pininfo.maxlen = 16;
794 if (!opt.disable_keypad
795 && !iso7816_check_keypad (app->slot, ISO7816_VERIFY, &pininfo) )
797 rc = pincb (pincb_arg, desc, NULL);
798 if (rc)
800 log_info (_("PIN callback returned error: %s\n"),
801 gpg_strerror (rc));
802 return rc;
805 rc = iso7816_verify_kp (app->slot, pwid, "", 0, &pininfo);
806 pincb (pincb_arg, NULL, NULL); /* Dismiss the prompt. */
808 else
810 char *pinvalue;
812 rc = pincb (pincb_arg, desc, &pinvalue);
813 if (rc)
815 log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
816 return rc;
819 rc = basic_pin_checks (pinvalue, pininfo.minlen, pininfo.maxlen);
820 if (rc)
822 xfree (pinvalue);
823 return rc;
826 rc = iso7816_verify (app->slot, pwid, pinvalue, strlen (pinvalue));
827 xfree (pinvalue);
830 if (rc)
832 if ( gpg_err_code (rc) == GPG_ERR_USE_CONDITIONS )
833 log_error (_("the NullPIN has not yet been changed\n"));
834 else
835 log_error ("verify PIN failed\n");
836 return rc;
839 return 0;
843 /* Create the signature and return the allocated result in OUTDATA.
844 If a PIN is required the PINCB will be used to ask for the PIN;
845 that callback should return the PIN in an allocated buffer and
846 store that in the 3rd argument. */
847 static gpg_error_t
848 do_sign (app_t app, const char *keyidstr, int hashalgo,
849 gpg_error_t (*pincb)(void*, const char *, char **),
850 void *pincb_arg,
851 const void *indata, size_t indatalen,
852 unsigned char **outdata, size_t *outdatalen )
854 static unsigned char sha1_prefix[15] = /* Object ID is 1.3.14.3.2.26 */
855 { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
856 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
857 static unsigned char rmd160_prefix[15] = /* Object ID is 1.3.36.3.2.1 */
858 { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
859 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 };
860 int rc, i;
861 int is_sigg = 0;
862 int fid;
863 unsigned char kid;
864 unsigned char data[83]; /* Must be large enough for a SHA-1 digest
865 + the largest OID prefix. */
866 size_t datalen;
868 if (!keyidstr || !*keyidstr)
869 return gpg_error (GPG_ERR_INV_VALUE);
870 switch (indatalen)
872 case 16: case 20: case 35: case 47: case 51: case 67: case 83: break;
873 default: return gpg_error (GPG_ERR_INV_VALUE);
876 /* Check that the provided ID is valid. This is not really needed
877 but we do it to enforce correct usage by the caller. */
878 if (!strncmp (keyidstr, "NKS-NKS3.", 9) )
880 else if (!strncmp (keyidstr, "NKS-DF01.", 9) )
882 else if (!strncmp (keyidstr, "NKS-SIGG.", 9) )
883 is_sigg = 1;
884 else
885 return gpg_error (GPG_ERR_INV_ID);
886 keyidstr += 9;
888 rc = switch_application (app, is_sigg);
889 if (rc)
890 return rc;
892 if (is_sigg && app->app_local->sigg_is_msig)
894 log_info ("mass signature cards are not allowed\n");
895 return gpg_error (GPG_ERR_NOT_SUPPORTED);
898 if (!hexdigitp (keyidstr) || !hexdigitp (keyidstr+1)
899 || !hexdigitp (keyidstr+2) || !hexdigitp (keyidstr+3)
900 || keyidstr[4])
901 return gpg_error (GPG_ERR_INV_ID);
902 fid = xtoi_4 (keyidstr);
903 for (i=0; filelist[i].fid; i++)
904 if (filelist[i].iskeypair && filelist[i].fid == fid)
905 break;
906 if (!filelist[i].fid)
907 return gpg_error (GPG_ERR_NOT_FOUND);
908 if (!filelist[i].issignkey)
909 return gpg_error (GPG_ERR_INV_ID);
910 kid = filelist[i].kid;
912 /* Prepare the DER object from INDATA. */
913 if (app->app_local->nks_version > 2 && (indatalen == 35
914 || indatalen == 47
915 || indatalen == 51
916 || indatalen == 67
917 || indatalen == 83))
919 /* The caller send data matching the length of the ASN.1 encoded
920 hash for SHA-{1,224,256,384,512}. Assume that is okay. */
921 assert (indatalen <= sizeof data);
922 memcpy (data, indata, indatalen);
923 datalen = indatalen;
925 else if (indatalen == 35)
927 /* Alright, the caller was so kind to send us an already
928 prepared DER object. This is for TCOS 2. */
929 if (hashalgo == GCRY_MD_SHA1 && !memcmp (indata, sha1_prefix, 15))
931 else if (hashalgo == GCRY_MD_RMD160 && !memcmp (indata,rmd160_prefix,15))
933 else
934 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
935 memcpy (data, indata, indatalen);
936 datalen = 35;
938 else if (indatalen == 20)
940 if (hashalgo == GCRY_MD_SHA1)
941 memcpy (data, sha1_prefix, 15);
942 else if (hashalgo == GCRY_MD_RMD160)
943 memcpy (data, rmd160_prefix, 15);
944 else
945 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
946 memcpy (data+15, indata, indatalen);
947 datalen = 35;
949 else
950 return gpg_error (GPG_ERR_INV_VALUE);
953 /* Send an MSE for PSO:Computer_Signature. */
954 if (app->app_local->nks_version > 2)
956 unsigned char mse[6];
958 mse[0] = 0x80; /* Algorithm reference. */
959 mse[1] = 1;
960 mse[2] = 2; /* RSA, card does pkcs#1 v1.5 padding, no ASN.1 check. */
961 mse[3] = 0x84; /* Private key reference. */
962 mse[4] = 1;
963 mse[5] = kid;
964 rc = iso7816_manage_security_env (app->slot, 0x41, 0xB6,
965 mse, sizeof mse);
967 /* Verify using PW1.CH. */
968 if (!rc)
969 rc = verify_pin (app, 0, NULL, pincb, pincb_arg);
970 /* Compute the signature. */
971 if (!rc)
972 rc = iso7816_compute_ds (app->slot, data, datalen, outdata, outdatalen);
973 return rc;
978 /* Decrypt the data in INDATA and return the allocated result in OUTDATA.
979 If a PIN is required the PINCB will be used to ask for the PIN; it
980 should return the PIN in an allocated buffer and put it into PIN. */
981 static gpg_error_t
982 do_decipher (app_t app, const char *keyidstr,
983 gpg_error_t (*pincb)(void*, const char *, char **),
984 void *pincb_arg,
985 const void *indata, size_t indatalen,
986 unsigned char **outdata, size_t *outdatalen )
988 int rc, i;
989 int is_sigg = 0;
990 int fid;
991 int kid;
993 if (!keyidstr || !*keyidstr || !indatalen)
994 return gpg_error (GPG_ERR_INV_VALUE);
996 /* Check that the provided ID is valid. This is not really needed
997 but we do it to to enforce correct usage by the caller. */
998 if (!strncmp (keyidstr, "NKS-NKS3.", 9) )
1000 else if (!strncmp (keyidstr, "NKS-DF01.", 9) )
1002 else if (!strncmp (keyidstr, "NKS-SIGG.", 9) )
1003 is_sigg = 1;
1004 else
1005 return gpg_error (GPG_ERR_INV_ID);
1006 keyidstr += 9;
1008 rc = switch_application (app, is_sigg);
1009 if (rc)
1010 return rc;
1012 if (!hexdigitp (keyidstr) || !hexdigitp (keyidstr+1)
1013 || !hexdigitp (keyidstr+2) || !hexdigitp (keyidstr+3)
1014 || keyidstr[4])
1015 return gpg_error (GPG_ERR_INV_ID);
1016 fid = xtoi_4 (keyidstr);
1017 for (i=0; filelist[i].fid; i++)
1018 if (filelist[i].iskeypair && filelist[i].fid == fid)
1019 break;
1020 if (!filelist[i].fid)
1021 return gpg_error (GPG_ERR_NOT_FOUND);
1022 if (!filelist[i].isenckey)
1023 return gpg_error (GPG_ERR_INV_ID);
1024 kid = filelist[i].kid;
1026 if (app->app_local->nks_version > 2)
1028 unsigned char mse[6];
1029 mse[0] = 0x80; /* Algorithm reference. */
1030 mse[1] = 1;
1031 mse[2] = 0x0a; /* RSA no padding. (0x1A is pkcs#1.5 padding.) */
1032 mse[3] = 0x84; /* Private key reference. */
1033 mse[4] = 1;
1034 mse[5] = kid;
1035 rc = iso7816_manage_security_env (app->slot, 0x41, 0xB8,
1036 mse, sizeof mse);
1038 else
1040 static const unsigned char mse[] =
1042 0x80, 1, 0x10, /* Select algorithm RSA. */
1043 0x84, 1, 0x81 /* Select local secret key 1 for decryption. */
1045 rc = iso7816_manage_security_env (app->slot, 0xC1, 0xB8,
1046 mse, sizeof mse);
1050 if (!rc)
1051 rc = verify_pin (app, 0, NULL, pincb, pincb_arg);
1053 /* Note that we need to use extended length APDUs for TCOS 3 cards.
1054 Command chaining does not work. */
1055 if (!rc)
1056 rc = iso7816_decipher (app->slot, app->app_local->nks_version > 2? 1:0,
1057 indata, indatalen, 0x81,
1058 outdata, outdatalen);
1059 return rc;
1064 /* Parse a password ID string. Returns NULL on error or a string
1065 suitable as passpahrse prompt on success. On success stores the
1066 reference value for the password at R_PWID and a flag indicating
1067 that the SigG application is to be used at R_SIGG. If NEW_MODE is
1068 true, the returned description is suitable for a new Password.
1069 Supported values for PWIDSTR are:
1071 PW1.CH - Global password 1
1072 PW2.CH - Global password 2
1073 PW1.CH.SIG - SigG password 1
1074 PW2.CH.SIG - SigG password 2
1076 static const char *
1077 parse_pwidstr (const char *pwidstr, int new_mode, int *r_sigg, int *r_pwid)
1079 const char *desc;
1081 if (!pwidstr)
1082 desc = NULL;
1083 else if (!strcmp (pwidstr, "PW1.CH"))
1085 *r_sigg = 0;
1086 *r_pwid = 0x00;
1087 /* TRANSLATORS: Do not translate the "|*|" prefixes but keep
1088 them verbatim at the start of the string. */
1089 desc = (new_mode
1090 ? _("|N|Please enter a new PIN for the standard keys.")
1091 : _("||Please enter the PIN for the standard keys."));
1093 else if (!strcmp (pwidstr, "PW2.CH"))
1095 *r_pwid = 0x01;
1096 desc = (new_mode
1097 ? _("|NP|Please enter a new PIN Unblocking Code (PUK) "
1098 "for the standard keys.")
1099 : _("|P|Please enter the PIN Unblocking Code (PUK) "
1100 "for the standard keys."));
1102 else if (!strcmp (pwidstr, "PW1.CH.SIG"))
1104 *r_pwid = 0x81;
1105 *r_sigg = 1;
1106 desc = (new_mode
1107 ? _("|N|Please enter a new PIN for the key to create "
1108 "qualified signatures.")
1109 : _("||Please enter the PIN for the key to create "
1110 "qualified signatures."));
1112 else if (!strcmp (pwidstr, "PW2.CH.SIG"))
1114 *r_pwid = 0x83; /* Yes, that is 83 and not 82. */
1115 *r_sigg = 1;
1116 desc = (new_mode
1117 ? _("|NP|Please enter a new PIN Unblocking Code (PUK) "
1118 "for the key to create qualified signatures.")
1119 : _("|P|Please enter the PIN Unblocking Code (PUK) "
1120 "for the key to create qualified signatures."));
1122 else
1123 desc = NULL;
1125 return desc;
1129 /* Handle the PASSWD command. See parse_pwidstr() for allowed values
1130 for CHVNOSTR. */
1131 static gpg_error_t
1132 do_change_pin (app_t app, ctrl_t ctrl, const char *pwidstr,
1133 unsigned int flags,
1134 gpg_error_t (*pincb)(void*, const char *, char **),
1135 void *pincb_arg)
1137 gpg_error_t err;
1138 char *newpin = NULL;
1139 char *oldpin = NULL;
1140 size_t newpinlen;
1141 size_t oldpinlen;
1142 int is_sigg;
1143 const char *newdesc;
1144 int pwid;
1145 iso7816_pininfo_t pininfo;
1147 (void)ctrl;
1149 /* The minimum length is enforced by TCOS, the maximum length is
1150 just a reasonable value. */
1151 memset (&pininfo, 0, sizeof pininfo);
1152 pininfo.minlen = 6;
1153 pininfo.maxlen = 16;
1155 newdesc = parse_pwidstr (pwidstr, 1, &is_sigg, &pwid);
1156 if (!newdesc)
1157 return gpg_error (GPG_ERR_INV_ID);
1159 err = switch_application (app, is_sigg);
1160 if (err)
1161 return err;
1163 if ((flags & APP_CHANGE_FLAG_NULLPIN))
1165 /* With the nullpin flag, we do not verify the PIN - it would
1166 fail if the Nullpin is still set. */
1167 oldpin = xtrycalloc (1, 6);
1168 if (!oldpin)
1170 err = gpg_error_from_syserror ();
1171 goto leave;
1173 oldpinlen = 6;
1175 else
1177 const char *desc;
1178 int dummy1, dummy2;
1180 if ((flags & APP_CHANGE_FLAG_RESET))
1182 /* Reset mode: Ask for the alternate PIN. */
1183 const char *altpwidstr;
1185 if (!strcmp (pwidstr, "PW1.CH"))
1186 altpwidstr = "PW2.CH";
1187 else if (!strcmp (pwidstr, "PW2.CH"))
1188 altpwidstr = "PW1.CH";
1189 else if (!strcmp (pwidstr, "PW1.CH.SIG"))
1190 altpwidstr = "PW2.CH.SIG";
1191 else if (!strcmp (pwidstr, "PW2.CH.SIG"))
1192 altpwidstr = "PW1.CH.SIG";
1193 else
1195 err = gpg_error (GPG_ERR_BUG);
1196 goto leave;
1198 desc = parse_pwidstr (altpwidstr, 0, &dummy1, &dummy2);
1200 else
1202 /* Regular change mode: Ask for the old PIN. */
1203 desc = parse_pwidstr (pwidstr, 0, &dummy1, &dummy2);
1205 err = pincb (pincb_arg, desc, &oldpin);
1206 if (err)
1208 log_error ("error getting old PIN: %s\n", gpg_strerror (err));
1209 goto leave;
1211 oldpinlen = strlen (oldpin);
1212 err = basic_pin_checks (oldpin, pininfo.minlen, pininfo.maxlen);
1213 if (err)
1214 goto leave;
1217 err = pincb (pincb_arg, newdesc, &newpin);
1218 if (err)
1220 log_error (_("error getting new PIN: %s\n"), gpg_strerror (err));
1221 goto leave;
1223 newpinlen = strlen (newpin);
1225 err = basic_pin_checks (newpin, pininfo.minlen, pininfo.maxlen);
1226 if (err)
1227 goto leave;
1229 if ((flags & APP_CHANGE_FLAG_RESET))
1231 char *data;
1232 size_t datalen = oldpinlen + newpinlen;
1234 data = xtrymalloc (datalen);
1235 if (!data)
1237 err = gpg_error_from_syserror ();
1238 goto leave;
1240 memcpy (data, oldpin, oldpinlen);
1241 memcpy (data+oldpinlen, newpin, newpinlen);
1242 err = iso7816_reset_retry_counter_with_rc (app->slot, pwid,
1243 data, datalen);
1244 wipememory (data, datalen);
1245 xfree (data);
1247 else
1248 err = iso7816_change_reference_data (app->slot, pwid,
1249 oldpin, oldpinlen,
1250 newpin, newpinlen);
1251 leave:
1252 xfree (oldpin);
1253 xfree (newpin);
1254 return err;
1258 /* Perform a simple verify operation. KEYIDSTR should be NULL or empty. */
1259 static gpg_error_t
1260 do_check_pin (app_t app, const char *pwidstr,
1261 gpg_error_t (*pincb)(void*, const char *, char **),
1262 void *pincb_arg)
1264 gpg_error_t err;
1265 int pwid;
1266 int is_sigg;
1267 const char *desc;
1269 desc = parse_pwidstr (pwidstr, 0, &is_sigg, &pwid);
1270 if (!desc)
1271 return gpg_error (GPG_ERR_INV_ID);
1273 err = switch_application (app, is_sigg);
1274 if (err)
1275 return err;
1277 return verify_pin (app, pwid, desc, pincb, pincb_arg);
1281 /* Return the version of the NKS application. */
1282 static int
1283 get_nks_version (int slot)
1285 unsigned char *result = NULL;
1286 size_t resultlen;
1287 int type;
1289 if (iso7816_apdu_direct (slot, "\x80\xaa\x06\x00\x00", 5, 0,
1290 &result, &resultlen))
1291 return 2; /* NKS 2 does not support this command. */
1293 /* Example value: 04 11 19 22 21 6A 20 80 03 03 01 01 01 00 00 00
1294 vv tt ccccccccccccccccc aa bb cc vvvvvvvvvvv xx
1295 vendor (Philips) -+ | | | | | | |
1296 chip type -----------+ | | | | | |
1297 chip id ----------------+ | | | | |
1298 card type (3 - tcos 3) -------------------+ | | | |
1299 OS version of card type ---------------------+ | | |
1300 OS release of card type ------------------------+ | |
1301 OS vendor internal version ------------------------+ |
1302 RFU -----------------------------------------------------------+
1304 if (resultlen < 16)
1305 type = 0; /* Invalid data returned. */
1306 else
1307 type = result[8];
1308 xfree (result);
1310 return type;
1314 /* If ENABLE_SIGG is true switch to the SigG application if not yet
1315 active. If false switch to the NKS application if not yet active.
1316 Returns 0 on success. */
1317 static gpg_error_t
1318 switch_application (app_t app, int enable_sigg)
1320 gpg_error_t err;
1322 if (((app->app_local->sigg_active && enable_sigg)
1323 || (!app->app_local->sigg_active && !enable_sigg))
1324 && !app->app_local->need_app_select)
1325 return 0; /* Already switched. */
1327 log_info ("app-nks: switching to %s\n", enable_sigg? "SigG":"NKS");
1328 if (enable_sigg)
1329 err = iso7816_select_application (app->slot, aid_sigg, sizeof aid_sigg, 0);
1330 else
1331 err = iso7816_select_application (app->slot, aid_nks, sizeof aid_nks, 0);
1333 if (!err && enable_sigg && app->app_local->nks_version >= 3
1334 && !app->app_local->sigg_msig_checked)
1336 /* Check whether this card is a mass signature card. */
1337 unsigned char *buffer;
1338 size_t buflen;
1339 const unsigned char *tmpl;
1340 size_t tmpllen;
1342 app->app_local->sigg_msig_checked = 1;
1343 app->app_local->sigg_is_msig = 1;
1344 err = iso7816_select_file (app->slot, 0x5349, 0, NULL, NULL);
1345 if (!err)
1346 err = iso7816_read_record (app->slot, 1, 1, 0, &buffer, &buflen);
1347 if (!err)
1349 tmpl = find_tlv (buffer, buflen, 0x7a, &tmpllen);
1350 if (tmpl && tmpllen == 12
1351 && !memcmp (tmpl,
1352 "\x93\x02\x00\x01\xA4\x06\x83\x01\x81\x83\x01\x83",
1353 12))
1354 app->app_local->sigg_is_msig = 0;
1355 xfree (buffer);
1357 if (app->app_local->sigg_is_msig)
1358 log_info ("This is a mass signature card\n");
1361 if (!err)
1363 app->app_local->need_app_select = 0;
1364 app->app_local->sigg_active = enable_sigg;
1366 else
1367 log_error ("app-nks: error switching to %s: %s\n",
1368 enable_sigg? "SigG":"NKS", gpg_strerror (err));
1370 return err;
1374 /* Select the NKS application. */
1375 gpg_error_t
1376 app_select_nks (app_t app)
1378 int slot = app->slot;
1379 int rc;
1381 rc = iso7816_select_application (slot, aid_nks, sizeof aid_nks, 0);
1382 if (!rc)
1384 app->apptype = "NKS";
1386 app->app_local = xtrycalloc (1, sizeof *app->app_local);
1387 if (!app->app_local)
1389 rc = gpg_error (gpg_err_code_from_errno (errno));
1390 goto leave;
1393 app->app_local->nks_version = get_nks_version (slot);
1394 if (opt.verbose)
1395 log_info ("Detected NKS version: %d\n", app->app_local->nks_version);
1397 app->fnc.deinit = do_deinit;
1398 app->fnc.learn_status = do_learn_status;
1399 app->fnc.readcert = do_readcert;
1400 app->fnc.readkey = do_readkey;
1401 app->fnc.getattr = do_getattr;
1402 app->fnc.setattr = NULL;
1403 app->fnc.writekey = do_writekey;
1404 app->fnc.genkey = NULL;
1405 app->fnc.sign = do_sign;
1406 app->fnc.auth = NULL;
1407 app->fnc.decipher = do_decipher;
1408 app->fnc.change_pin = do_change_pin;
1409 app->fnc.check_pin = do_check_pin;
1412 leave:
1413 if (rc)
1414 do_deinit (app);
1415 return rc;