Fix signal handling race condition.
[gnupg.git] / scd / app-nks.c
blob31ddae0bdca12b6167d81e157db7fdf628435cc0
1 /* app-nks.c - The Telesec NKS 2.0 card application.
2 * Copyright (C) 2004, 2007, 2008 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 #include <config.h>
21 #include <errno.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <assert.h>
26 #include <time.h>
28 #include "scdaemon.h"
29 #include "i18n.h"
30 #include "iso7816.h"
31 #include "app-common.h"
32 #include "tlv.h"
34 static struct
36 int fid; /* File ID. */
37 int certtype; /* Type of certificate or 0 if it is not a certificate. */
38 int iskeypair; /* If true has the FID of the correspoding certificate. */
39 int issignkey; /* True if file is a key usable for signing. */
40 int isenckey; /* True if file is a key usable for decryption. */
41 } filelist[] = {
42 { 0x4531, 0, 0xC000, 1, 0 },
43 { 0xC000, 101 },
44 { 0x4331, 100 },
45 { 0x4332, 100 },
46 { 0xB000, 110 },
47 { 0x45B1, 0, 0xC200, 0, 1 },
48 { 0xC200, 101 },
49 { 0x43B1, 100 },
50 { 0x43B2, 100 },
51 { 0, 0 }
56 /* Read the file with FID, assume it contains a public key and return
57 its keygrip in the caller provided 41 byte buffer R_GRIPSTR. */
58 static gpg_error_t
59 keygripstr_from_pk_file (int slot, int fid, char *r_gripstr)
61 gpg_error_t err;
62 unsigned char grip[20];
63 unsigned char *buffer[2];
64 size_t buflen[2];
65 gcry_sexp_t sexp;
66 int i;
68 err = iso7816_select_file (slot, fid, 0, NULL, NULL);
69 if (err)
70 return err;
71 err = iso7816_read_record (slot, 1, 1, 0, &buffer[0], &buflen[0]);
72 if (err)
73 return err;
74 err = iso7816_read_record (slot, 2, 1, 0, &buffer[1], &buflen[1]);
75 if (err)
77 xfree (buffer[0]);
78 return err;
81 for (i=0; i < 2; i++)
83 /* Check that the value appears like an integer encoded as
84 Simple-TLV. We don't check the tag because the tests cards I
85 have use 1 for both, the modulus and the exponent - the
86 example in the documentation gives 2 for the exponent. */
87 if (buflen[i] < 3)
88 err = gpg_error (GPG_ERR_TOO_SHORT);
89 else if (buffer[i][1] != buflen[i]-2 )
90 err = gpg_error (GPG_ERR_INV_OBJ);
93 if (!err)
94 err = gcry_sexp_build (&sexp, NULL,
95 "(public-key (rsa (n %b) (e %b)))",
96 (int)buflen[0]-2, buffer[0]+2,
97 (int)buflen[1]-2, buffer[1]+2);
99 xfree (buffer[0]);
100 xfree (buffer[1]);
101 if (err)
102 return err;
104 if (!gcry_pk_get_keygrip (sexp, grip))
106 err = gpg_error (GPG_ERR_INTERNAL); /* i.e. RSA not supported by
107 libgcrypt. */
109 else
111 bin2hex (grip, 20, r_gripstr);
113 gcry_sexp_release (sexp);
114 return err;
119 static gpg_error_t
120 do_learn_status (app_t app, ctrl_t ctrl)
122 gpg_error_t err;
123 char ct_buf[100], id_buf[100];
124 int i;
126 /* Output information about all useful objects. */
127 for (i=0; filelist[i].fid; i++)
129 if (filelist[i].certtype)
131 size_t len;
133 len = app_help_read_length_of_cert (app->slot,
134 filelist[i].fid, NULL);
135 if (len)
137 /* FIXME: We should store the length in the application's
138 context so that a following readcert does only need to
139 read that many bytes. */
140 sprintf (ct_buf, "%d", filelist[i].certtype);
141 sprintf (id_buf, "NKS-DF01.%04X", filelist[i].fid);
142 send_status_info (ctrl, "CERTINFO",
143 ct_buf, strlen (ct_buf),
144 id_buf, strlen (id_buf),
145 NULL, (size_t)0);
148 else if (filelist[i].iskeypair)
150 char gripstr[40+1];
152 err = keygripstr_from_pk_file (app->slot, filelist[i].fid, gripstr);
153 if (err)
154 log_error ("can't get keygrip from FID 0x%04X: %s\n",
155 filelist[i].fid, gpg_strerror (err));
156 else
158 sprintf (id_buf, "NKS-DF01.%04X", filelist[i].fid);
159 send_status_info (ctrl, "KEYPAIRINFO",
160 gripstr, 40,
161 id_buf, strlen (id_buf),
162 NULL, (size_t)0);
167 return 0;
173 /* Read the certificate with id CERTID (as returned by learn_status in
174 the CERTINFO status lines) and return it in the freshly allocated
175 buffer put into CERT and the length of the certificate put into
176 CERTLEN. */
177 static gpg_error_t
178 do_readcert (app_t app, const char *certid,
179 unsigned char **cert, size_t *certlen)
181 int i, fid;
182 gpg_error_t err;
183 unsigned char *buffer;
184 const unsigned char *p;
185 size_t buflen, n;
186 int class, tag, constructed, ndef;
187 size_t totobjlen, objlen, hdrlen;
188 int rootca = 0;
190 *cert = NULL;
191 *certlen = 0;
192 if (strncmp (certid, "NKS-DF01.", 9) )
193 return gpg_error (GPG_ERR_INV_ID);
194 certid += 9;
195 if (!hexdigitp (certid) || !hexdigitp (certid+1)
196 || !hexdigitp (certid+2) || !hexdigitp (certid+3)
197 || certid[4])
198 return gpg_error (GPG_ERR_INV_ID);
199 fid = xtoi_4 (certid);
200 for (i=0; filelist[i].fid; i++)
201 if ((filelist[i].certtype || filelist[i].iskeypair)
202 && filelist[i].fid == fid)
203 break;
204 if (!filelist[i].fid)
205 return gpg_error (GPG_ERR_NOT_FOUND);
207 /* If the requested objects is a plain public key, redirect it to
208 the corresponding certificate. The whole system is a bit messy
209 because we sometime use the key directly or let the caller
210 retrieve the key from the certificate. The rationale for
211 that is to support not-yet stored certificates. */
212 if (filelist[i].iskeypair)
213 fid = filelist[i].iskeypair;
216 /* Read the entire file. fixme: This could be optimized by first
217 reading the header to figure out how long the certificate
218 actually is. */
219 err = iso7816_select_file (app->slot, fid, 0, NULL, NULL);
220 if (err)
222 log_error ("error selecting FID 0x%04X: %s\n", fid, gpg_strerror (err));
223 return err;
226 err = iso7816_read_binary (app->slot, 0, 0, &buffer, &buflen);
227 if (err)
229 log_error ("error reading certificate from FID 0x%04X: %s\n",
230 fid, gpg_strerror (err));
231 return err;
234 if (!buflen || *buffer == 0xff)
236 log_info ("no certificate contained in FID 0x%04X\n", fid);
237 err = gpg_error (GPG_ERR_NOT_FOUND);
238 goto leave;
241 /* Now figure something out about the object. */
242 p = buffer;
243 n = buflen;
244 err = parse_ber_header (&p, &n, &class, &tag, &constructed,
245 &ndef, &objlen, &hdrlen);
246 if (err)
247 goto leave;
248 if ( class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE && constructed )
250 else if ( class == CLASS_UNIVERSAL && tag == TAG_SET && constructed )
251 rootca = 1;
252 else
253 return gpg_error (GPG_ERR_INV_OBJ);
254 totobjlen = objlen + hdrlen;
255 assert (totobjlen <= buflen);
257 err = parse_ber_header (&p, &n, &class, &tag, &constructed,
258 &ndef, &objlen, &hdrlen);
259 if (err)
260 goto leave;
262 if (rootca)
264 else if (class == CLASS_UNIVERSAL && tag == TAG_OBJECT_ID && !constructed)
266 const unsigned char *save_p;
268 /* The certificate seems to be contained in a userCertificate
269 container. Skip this and assume the following sequence is
270 the certificate. */
271 if (n < objlen)
273 err = gpg_error (GPG_ERR_INV_OBJ);
274 goto leave;
276 p += objlen;
277 n -= objlen;
278 save_p = p;
279 err = parse_ber_header (&p, &n, &class, &tag, &constructed,
280 &ndef, &objlen, &hdrlen);
281 if (err)
282 goto leave;
283 if ( !(class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE && constructed) )
284 return gpg_error (GPG_ERR_INV_OBJ);
285 totobjlen = objlen + hdrlen;
286 assert (save_p + totobjlen <= buffer + buflen);
287 memmove (buffer, save_p, totobjlen);
290 *cert = buffer;
291 buffer = NULL;
292 *certlen = totobjlen;
294 leave:
295 xfree (buffer);
296 return err;
300 /* Verify the PIN if required. */
301 static gpg_error_t
302 verify_pin (app_t app,
303 gpg_error_t (*pincb)(void*, const char *, char **),
304 void *pincb_arg)
306 iso7816_pininfo_t pininfo;
307 int rc;
309 /* Note that force_chv1 is never set but we do it here anyway so
310 that other applications may reuse this function. For example it
311 makes sense to set force_chv1 for German signature law cards.
312 NKS is very similar to the DINSIG draft standard. */
313 if ( app->did_chv1 && !app->force_chv1 )
314 return 0; /* No need to verify it again. */
316 memset (&pininfo, 0, sizeof pininfo);
317 pininfo.mode = 1;
318 pininfo.minlen = 6;
319 pininfo.maxlen = 16;
321 if (!opt.disable_keypad
322 && !iso7816_check_keypad (app->slot, ISO7816_VERIFY, &pininfo) )
324 rc = pincb (pincb_arg,
325 _("||Please enter your PIN at the reader's keypad"),
326 NULL);
327 if (rc)
329 log_info (_("PIN callback returned error: %s\n"),
330 gpg_strerror (rc));
331 return rc;
334 /* Although it is possible to use a local PIN, we use the global
335 PIN for this application. */
336 rc = iso7816_verify_kp (app->slot, 0, "", 0, &pininfo);
337 /* Dismiss the prompt. */
338 pincb (pincb_arg, NULL, NULL);
340 else
342 char *pinvalue;
344 rc = pincb (pincb_arg, "PIN", &pinvalue);
345 if (rc)
347 log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
348 return rc;
351 /* The following limits are due to TCOS but also defined in the
352 NKS specs. */
353 if (strlen (pinvalue) < pininfo.minlen)
355 log_error ("PIN is too short; minimum length is %d\n",
356 pininfo.minlen);
357 xfree (pinvalue);
358 return gpg_error (GPG_ERR_BAD_PIN);
360 else if (strlen (pinvalue) > pininfo.maxlen)
362 log_error ("PIN is too large; maximum length is %d\n",
363 pininfo.maxlen);
364 xfree (pinvalue);
365 return gpg_error (GPG_ERR_BAD_PIN);
368 /* Although it is possible to use a local PIN, we use the global
369 PIN for this application. */
370 rc = iso7816_verify (app->slot, 0, pinvalue, strlen (pinvalue));
371 xfree (pinvalue);
374 if (rc)
376 if ( gpg_err_code (rc) == GPG_ERR_USE_CONDITIONS )
377 log_error (_("the NullPIN has not yet been changed\n"));
378 else
379 log_error ("verify PIN failed\n");
380 return rc;
382 app->did_chv1 = 1;
384 return 0;
389 /* Create the signature and return the allocated result in OUTDATA.
390 If a PIN is required the PINCB will be used to ask for the PIN;
391 that callback should return the PIN in an allocated buffer and
392 store that in the 3rd argument. */
393 static gpg_error_t
394 do_sign (app_t app, const char *keyidstr, int hashalgo,
395 gpg_error_t (*pincb)(void*, const char *, char **),
396 void *pincb_arg,
397 const void *indata, size_t indatalen,
398 unsigned char **outdata, size_t *outdatalen )
400 static unsigned char sha1_prefix[15] = /* Object ID is 1.3.14.3.2.26 */
401 { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
402 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
403 static unsigned char rmd160_prefix[15] = /* Object ID is 1.3.36.3.2.1 */
404 { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
405 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 };
406 int rc, i;
407 int fid;
408 unsigned char data[35]; /* Must be large enough for a SHA-1 digest
409 + the largest OID _prefix above. */
411 if (!keyidstr || !*keyidstr)
412 return gpg_error (GPG_ERR_INV_VALUE);
413 if (indatalen != 20 && indatalen != 16 && indatalen != 35)
414 return gpg_error (GPG_ERR_INV_VALUE);
416 /* Check that the provided ID is valid. This is not really needed
417 but we do it to enforce correct usage by the caller. */
418 if (strncmp (keyidstr, "NKS-DF01.", 9) )
419 return gpg_error (GPG_ERR_INV_ID);
420 keyidstr += 9;
421 if (!hexdigitp (keyidstr) || !hexdigitp (keyidstr+1)
422 || !hexdigitp (keyidstr+2) || !hexdigitp (keyidstr+3)
423 || keyidstr[4])
424 return gpg_error (GPG_ERR_INV_ID);
425 fid = xtoi_4 (keyidstr);
426 for (i=0; filelist[i].fid; i++)
427 if (filelist[i].iskeypair && filelist[i].fid == fid)
428 break;
429 if (!filelist[i].fid)
430 return gpg_error (GPG_ERR_NOT_FOUND);
431 if (!filelist[i].issignkey)
432 return gpg_error (GPG_ERR_INV_ID);
434 /* Prepare the DER object from INDATA. */
435 if (indatalen == 35)
437 /* Alright, the caller was so kind to send us an already
438 prepared DER object. Check that it is waht we want and that
439 it matches the hash algorithm. */
440 if (hashalgo == GCRY_MD_SHA1 && !memcmp (indata, sha1_prefix, 15))
442 else if (hashalgo == GCRY_MD_RMD160 && !memcmp (indata, rmd160_prefix,15))
444 else
445 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
446 memcpy (data, indata, indatalen);
448 else
450 if (hashalgo == GCRY_MD_SHA1)
451 memcpy (data, sha1_prefix, 15);
452 else if (hashalgo == GCRY_MD_RMD160)
453 memcpy (data, rmd160_prefix, 15);
454 else
455 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
456 memcpy (data+15, indata, indatalen);
459 rc = verify_pin (app, pincb, pincb_arg);
460 if (!rc)
461 rc = iso7816_compute_ds (app->slot, data, 35, outdata, outdatalen);
462 return rc;
468 /* Decrypt the data in INDATA and return the allocated result in OUTDATA.
469 If a PIN is required the PINCB will be used to ask for the PIN; it
470 should return the PIN in an allocated buffer and put it into PIN. */
471 static gpg_error_t
472 do_decipher (app_t app, const char *keyidstr,
473 gpg_error_t (*pincb)(void*, const char *, char **),
474 void *pincb_arg,
475 const void *indata, size_t indatalen,
476 unsigned char **outdata, size_t *outdatalen )
478 static const unsigned char mse_parm[] = {
479 0x80, 1, 0x10, /* Select algorithm RSA. */
480 0x84, 1, 0x81 /* Select local secret key 1 for decryption. */
482 int rc, i;
483 int fid;
485 if (!keyidstr || !*keyidstr || !indatalen)
486 return gpg_error (GPG_ERR_INV_VALUE);
488 /* Check that the provided ID is valid. This is not really needed
489 but we do it to to enforce correct usage by the caller. */
490 if (strncmp (keyidstr, "NKS-DF01.", 9) )
491 return gpg_error (GPG_ERR_INV_ID);
492 keyidstr += 9;
493 if (!hexdigitp (keyidstr) || !hexdigitp (keyidstr+1)
494 || !hexdigitp (keyidstr+2) || !hexdigitp (keyidstr+3)
495 || keyidstr[4])
496 return gpg_error (GPG_ERR_INV_ID);
497 fid = xtoi_4 (keyidstr);
498 for (i=0; filelist[i].fid; i++)
499 if (filelist[i].iskeypair && filelist[i].fid == fid)
500 break;
501 if (!filelist[i].fid)
502 return gpg_error (GPG_ERR_NOT_FOUND);
503 if (!filelist[i].isenckey)
504 return gpg_error (GPG_ERR_INV_ID);
506 /* Do the TCOS specific MSE. */
507 rc = iso7816_manage_security_env (app->slot,
508 0xC1, 0xB8,
509 mse_parm, sizeof mse_parm);
510 if (!rc)
511 rc = verify_pin (app, pincb, pincb_arg);
512 if (!rc)
513 rc = iso7816_decipher (app->slot, indata, indatalen, 0x81,
514 outdata, outdatalen);
515 return rc;
519 /* Handle the PASSWD command. CHVNOSTR is currently ignored; we
520 always use VHV0. RESET_MODE is not yet implemented. */
521 static gpg_error_t
522 do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr,
523 unsigned int flags,
524 gpg_error_t (*pincb)(void*, const char *, char **),
525 void *pincb_arg)
527 gpg_error_t err;
528 char *pinvalue;
529 const char *oldpin;
530 size_t oldpinlen;
532 (void)ctrl;
533 (void)chvnostr;
535 if ((flags & APP_CHANGE_FLAG_RESET))
536 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
538 if ((flags & APP_CHANGE_FLAG_NULLPIN))
540 /* With the nullpin flag, we do not verify the PIN - it would fail
541 if the Nullpin is still set. */
542 oldpin = "\0\0\0\0\0";
543 oldpinlen = 6;
545 else
547 err = verify_pin (app, pincb, pincb_arg);
548 if (err)
549 return err;
550 oldpin = NULL;
551 oldpinlen = 0;
554 /* TRANSLATORS: Do not translate the "|*|" prefixes but
555 keep it at the start of the string. We need this elsewhere
556 to get some infos on the string. */
557 err = pincb (pincb_arg, _("|N|New PIN"), &pinvalue);
558 if (err)
560 log_error (_("error getting new PIN: %s\n"), gpg_strerror (err));
561 return err;
564 err = iso7816_change_reference_data (app->slot, 0x00,
565 oldpin, oldpinlen,
566 pinvalue, strlen (pinvalue));
567 xfree (pinvalue);
568 return err;
572 /* Perform a simple verify operation. KEYIDSTR should be NULL or empty. */
573 static gpg_error_t
574 do_check_pin (app_t app, const char *keyidstr,
575 gpg_error_t (*pincb)(void*, const char *, char **),
576 void *pincb_arg)
578 (void)keyidstr;
579 return verify_pin (app, pincb, pincb_arg);
583 /* Select the NKS 2.0 application. */
584 gpg_error_t
585 app_select_nks (app_t app)
587 static char const aid[] = { 0xD2, 0x76, 0x00, 0x00, 0x03, 0x01, 0x02 };
588 int slot = app->slot;
589 int rc;
591 rc = iso7816_select_application (slot, aid, sizeof aid, 0);
592 if (!rc)
594 app->apptype = "NKS";
596 app->fnc.learn_status = do_learn_status;
597 app->fnc.readcert = do_readcert;
598 app->fnc.getattr = NULL;
599 app->fnc.setattr = NULL;
600 app->fnc.genkey = NULL;
601 app->fnc.sign = do_sign;
602 app->fnc.auth = NULL;
603 app->fnc.decipher = do_decipher;
604 app->fnc.change_pin = do_change_pin;
605 app->fnc.check_pin = do_check_pin;
608 return rc;