Fixed EOF detection for encrypted packets.
[gnupg.git] / scd / app-dinsig.c
blob46e9a6a9bd23e5b93ee7c68bfc7bdf09be173226
1 /* app-dinsig.c - The DINSIG (DIN V 66291-1) card application.
2 * Copyright (C) 2002, 2004, 2005, 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/>.
21 /* The German signature law and its bylaw (SigG and SigV) is currently
22 used with an interface specification described in DIN V 66291-1.
23 The AID to be used is: 'D27600006601'.
25 The file IDs for certificates utilize the generic format:
26 Cxyz
27 C being the hex digit 'C' (12).
28 x being the service indicator:
29 '0' := SigG conform digital signature.
30 '1' := entity authentication.
31 '2' := key encipherment.
32 '3' := data encipherment.
33 '4' := key agreement.
34 other values are reserved for future use.
35 y being the security environment number using '0' for cards
36 not supporting a SE number.
37 z being the certificate type:
38 '0' := C.CH (base certificate of card holder) or C.ICC.
39 '1' .. '7' := C.CH (business or professional certificate
40 of card holder.
41 '8' .. 'D' := C.CA (certificate of a CA issue by the Root-CA).
42 'E' := C.RCA (self certified certificate of the Root-CA).
43 'F' := reserved.
45 The file IDs used by default are:
46 '1F00' EF.SSD (security service descriptor). [o,o]
47 '2F02' EF.GDO (global data objects) [m,m]
48 'A000' EF.PROT (signature log). Cyclic file with 20 records of 53 byte.
49 Read and update after user authentication. [o,o]
50 'B000' EF.PK.RCA.DS (public keys of Root-CA). Size is 512b or size
51 of keys. [m (unless a 'C00E' is present),m]
52 'B001' EF.PK.CA.DS (public keys of CAs). Size is 512b or size
53 of keys. [o,o]
54 'C00n' EF.C.CH.DS (digital signature certificate of card holder)
55 with n := 0 .. 7. Size is 2k or size of cert. Read and
56 update allowed after user authentication. [m,m]
57 'C00m' EF.C.CA.DS (digital signature certificate of CA)
58 with m := 8 .. E. Size is 1k or size of cert. Read always
59 allowed, update after user authentication. [o,o]
60 'C100' EF.C.ICC.AUT (AUT certificate of ICC) [o,m]
61 'C108' EF.C.CA.AUT (AUT certificate of CA) [o,m]
62 'D000' EF.DM (display message) [-,m]
64 The letters in brackets indicate optional or mandatory files: The
65 first for card terminals under full control and the second for
66 "business" card terminals.
72 #include <config.h>
73 #include <errno.h>
74 #include <stdio.h>
75 #include <stdlib.h>
76 #include <string.h>
77 #include <assert.h>
78 #include <time.h>
80 #include "scdaemon.h"
82 #include "i18n.h"
83 #include "iso7816.h"
84 #include "app-common.h"
85 #include "tlv.h"
88 static gpg_error_t
89 do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
91 gpg_error_t err;
92 char ct_buf[100], id_buf[100];
93 char hexkeygrip[41];
94 size_t len, certoff;
95 unsigned char *der;
96 size_t derlen;
97 ksba_cert_t cert;
98 int fid;
100 (void)flags;
102 /* Return the certificate of the card holder. */
103 fid = 0xC000;
104 len = app_help_read_length_of_cert (app->slot, fid, &certoff);
105 if (!len)
106 return 0; /* Card has not been personalized. */
108 sprintf (ct_buf, "%d", 101);
109 sprintf (id_buf, "DINSIG.%04X", fid);
110 send_status_info (ctrl, "CERTINFO",
111 ct_buf, strlen (ct_buf),
112 id_buf, strlen (id_buf),
113 NULL, (size_t)0);
115 /* Now we need to read the certificate, so that we can get the
116 public key out of it. */
117 err = iso7816_read_binary (app->slot, certoff, len-certoff, &der, &derlen);
118 if (err)
120 log_info ("error reading entire certificate from FID 0x%04X: %s\n",
121 fid, gpg_strerror (err));
122 return 0;
125 err = ksba_cert_new (&cert);
126 if (err)
128 xfree (der);
129 return err;
131 err = ksba_cert_init_from_mem (cert, der, derlen);
132 xfree (der); der = NULL;
133 if (err)
135 log_error ("failed to parse the certificate at FID 0x%04X: %s\n",
136 fid, gpg_strerror (err));
137 ksba_cert_release (cert);
138 return err;
140 err = app_help_get_keygrip_string (cert, hexkeygrip);
141 if (err)
143 log_error ("failed to calculate the keygrip for FID 0x%04X\n", fid);
144 ksba_cert_release (cert);
145 return gpg_error (GPG_ERR_CARD);
147 ksba_cert_release (cert);
149 sprintf (id_buf, "DINSIG.%04X", fid);
150 send_status_info (ctrl, "KEYPAIRINFO",
151 hexkeygrip, 40,
152 id_buf, strlen (id_buf),
153 NULL, (size_t)0);
154 return 0;
160 /* Read the certificate with id CERTID (as returned by learn_status in
161 the CERTINFO status lines) and return it in the freshly allocated
162 buffer put into CERT and the length of the certificate put into
163 CERTLEN.
165 FIXME: This needs some cleanups and caching with do_learn_status.
167 static gpg_error_t
168 do_readcert (app_t app, const char *certid,
169 unsigned char **cert, size_t *certlen)
171 int fid;
172 gpg_error_t err;
173 unsigned char *buffer;
174 const unsigned char *p;
175 size_t buflen, n;
176 int class, tag, constructed, ndef;
177 size_t totobjlen, objlen, hdrlen;
178 int rootca = 0;
180 *cert = NULL;
181 *certlen = 0;
182 if (strncmp (certid, "DINSIG.", 7) )
183 return gpg_error (GPG_ERR_INV_ID);
184 certid += 7;
185 if (!hexdigitp (certid) || !hexdigitp (certid+1)
186 || !hexdigitp (certid+2) || !hexdigitp (certid+3)
187 || certid[4])
188 return gpg_error (GPG_ERR_INV_ID);
189 fid = xtoi_4 (certid);
190 if (fid != 0xC000 )
191 return gpg_error (GPG_ERR_NOT_FOUND);
193 /* Read the entire file. fixme: This could be optimized by first
194 reading the header to figure out how long the certificate
195 actually is. */
196 err = iso7816_select_file (app->slot, fid, 0, NULL, NULL);
197 if (err)
199 log_error ("error selecting FID 0x%04X: %s\n", fid, gpg_strerror (err));
200 return err;
203 err = iso7816_read_binary (app->slot, 0, 0, &buffer, &buflen);
204 if (err)
206 log_error ("error reading certificate from FID 0x%04X: %s\n",
207 fid, gpg_strerror (err));
208 return err;
211 if (!buflen || *buffer == 0xff)
213 log_info ("no certificate contained in FID 0x%04X\n", fid);
214 err = gpg_error (GPG_ERR_NOT_FOUND);
215 goto leave;
218 /* Now figure something out about the object. */
219 p = buffer;
220 n = buflen;
221 err = parse_ber_header (&p, &n, &class, &tag, &constructed,
222 &ndef, &objlen, &hdrlen);
223 if (err)
224 goto leave;
225 if ( class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE && constructed )
227 else if ( class == CLASS_UNIVERSAL && tag == TAG_SET && constructed )
228 rootca = 1;
229 else
230 return gpg_error (GPG_ERR_INV_OBJ);
231 totobjlen = objlen + hdrlen;
232 assert (totobjlen <= buflen);
234 err = parse_ber_header (&p, &n, &class, &tag, &constructed,
235 &ndef, &objlen, &hdrlen);
236 if (err)
237 goto leave;
239 if (rootca)
241 else if (class == CLASS_UNIVERSAL && tag == TAG_OBJECT_ID && !constructed)
243 const unsigned char *save_p;
245 /* The certificate seems to be contained in a userCertificate
246 container. Skip this and assume the following sequence is
247 the certificate. */
248 if (n < objlen)
250 err = gpg_error (GPG_ERR_INV_OBJ);
251 goto leave;
253 p += objlen;
254 n -= objlen;
255 save_p = p;
256 err = parse_ber_header (&p, &n, &class, &tag, &constructed,
257 &ndef, &objlen, &hdrlen);
258 if (err)
259 goto leave;
260 if ( !(class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE && constructed) )
261 return gpg_error (GPG_ERR_INV_OBJ);
262 totobjlen = objlen + hdrlen;
263 assert (save_p + totobjlen <= buffer + buflen);
264 memmove (buffer, save_p, totobjlen);
267 *cert = buffer;
268 buffer = NULL;
269 *certlen = totobjlen;
271 leave:
272 xfree (buffer);
273 return err;
277 /* Verify the PIN if required. */
278 static gpg_error_t
279 verify_pin (app_t app,
280 gpg_error_t (*pincb)(void*, const char *, char **),
281 void *pincb_arg)
283 const char *s;
284 int rc;
285 iso7816_pininfo_t pininfo;
287 if ( app->did_chv1 && !app->force_chv1 )
288 return 0; /* No need to verify it again. */
290 memset (&pininfo, 0, sizeof pininfo);
291 pininfo.mode = 1;
292 pininfo.minlen = 6;
293 pininfo.maxlen = 8;
295 if (!opt.disable_keypad
296 && !iso7816_check_keypad (app->slot, ISO7816_VERIFY, &pininfo) )
298 rc = pincb (pincb_arg,
299 _("||Please enter your PIN at the reader's keypad"),
300 NULL);
301 if (rc)
303 log_info (_("PIN callback returned error: %s\n"),
304 gpg_strerror (rc));
305 return rc;
307 rc = iso7816_verify_kp (app->slot, 0x81, "", 0, &pininfo);
308 /* Dismiss the prompt. */
309 pincb (pincb_arg, NULL, NULL);
311 else /* No Keypad. */
313 char *pinvalue;
315 rc = pincb (pincb_arg, "PIN", &pinvalue);
316 if (rc)
318 log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
319 return rc;
322 /* We require the PIN to be at least 6 and at max 8 bytes.
323 According to the specs, this should all be ASCII. */
324 for (s=pinvalue; digitp (s); s++)
326 if (*s)
328 log_error ("Non-numeric digits found in PIN\n");
329 xfree (pinvalue);
330 return gpg_error (GPG_ERR_BAD_PIN);
333 if (strlen (pinvalue) < pininfo.minlen)
335 log_error ("PIN is too short; minimum length is %d\n",
336 pininfo.minlen);
337 xfree (pinvalue);
338 return gpg_error (GPG_ERR_BAD_PIN);
340 else if (strlen (pinvalue) > pininfo.maxlen)
342 log_error ("PIN is too large; maximum length is %d\n",
343 pininfo.maxlen);
344 xfree (pinvalue);
345 return gpg_error (GPG_ERR_BAD_PIN);
348 rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue));
349 if (gpg_err_code (rc) == GPG_ERR_INV_VALUE)
351 /* We assume that ISO 9564-1 encoding is used and we failed
352 because the first nibble we passed was 3 and not 2. DIN
353 says something about looking up such an encoding in the
354 SSD but I was not able to find any tag relevant to
355 this. */
356 char paddedpin[8];
357 int i, ndigits;
359 for (ndigits=0, s=pinvalue; *s; ndigits++, s++)
361 i = 0;
362 paddedpin[i++] = 0x20 | (ndigits & 0x0f);
363 for (s=pinvalue; i < sizeof paddedpin && *s && s[1]; s = s+2 )
364 paddedpin[i++] = (((*s - '0') << 4) | ((s[1] - '0') & 0x0f));
365 if (i < sizeof paddedpin && *s)
366 paddedpin[i++] = (((*s - '0') << 4) | 0x0f);
367 while (i < sizeof paddedpin)
368 paddedpin[i++] = 0xff;
369 rc = iso7816_verify (app->slot, 0x81, paddedpin, sizeof paddedpin);
371 xfree (pinvalue);
374 if (rc)
376 log_error ("verify PIN failed\n");
377 return rc;
379 app->did_chv1 = 1;
380 return 0;
385 /* Create the signature and return the allocated result in OUTDATA.
386 If a PIN is required the PINCB will be used to ask for the PIN;
387 that callback should return the PIN in an allocated buffer and
388 store that in the 3rd argument. */
389 static gpg_error_t
390 do_sign (app_t app, const char *keyidstr, int hashalgo,
391 gpg_error_t (*pincb)(void*, const char *, char **),
392 void *pincb_arg,
393 const void *indata, size_t indatalen,
394 unsigned char **outdata, size_t *outdatalen )
396 static unsigned char sha1_prefix[15] = /* Object ID is 1.3.14.3.2.26 */
397 { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
398 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
399 static unsigned char rmd160_prefix[15] = /* Object ID is 1.3.36.3.2.1 */
400 { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
401 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 };
402 static unsigned char sha256_prefix[19] = /* OID is 2.16.840.1.101.3.4.2.1 */
403 { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
404 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
405 0x00, 0x04, 0x20 };
406 int rc;
407 int fid;
408 unsigned char data[19+32]; /* Must be large enough for a SHA-256 digest
409 + the largest OID _prefix above. */
410 int datalen;
412 if (!keyidstr || !*keyidstr)
413 return gpg_error (GPG_ERR_INV_VALUE);
414 if (indatalen != 20 && indatalen != 16 && indatalen != 32
415 && indatalen != (15+20) && indatalen != (19+32))
416 return gpg_error (GPG_ERR_INV_VALUE);
418 /* Check that the provided ID is vaid. This is not really needed
419 but we do it to to enforce correct usage by the caller. */
420 if (strncmp (keyidstr, "DINSIG.", 7) )
421 return gpg_error (GPG_ERR_INV_ID);
422 keyidstr += 7;
423 if (!hexdigitp (keyidstr) || !hexdigitp (keyidstr+1)
424 || !hexdigitp (keyidstr+2) || !hexdigitp (keyidstr+3)
425 || keyidstr[4])
426 return gpg_error (GPG_ERR_INV_ID);
427 fid = xtoi_4 (keyidstr);
428 if (fid != 0xC000)
429 return gpg_error (GPG_ERR_NOT_FOUND);
431 /* Prepare the DER object from INDATA. */
432 datalen = 35;
433 if (indatalen == 15+20)
435 /* Alright, the caller was so kind to send us an already
436 prepared DER object. Check that it is what we want and that
437 it matches the hash algorithm. */
438 if (hashalgo == GCRY_MD_SHA1 && !memcmp (indata, sha1_prefix, 15))
440 else if (hashalgo == GCRY_MD_RMD160 && !memcmp (indata, rmd160_prefix,15))
442 else
443 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
444 memcpy (data, indata, indatalen);
446 else if (indatalen == 19+32)
448 /* Alright, the caller was so kind to send us an already
449 prepared DER object. Check that it is what we want and that
450 it matches the hash algorithm. */
451 datalen = indatalen;
452 if (hashalgo == GCRY_MD_SHA256 && !memcmp (indata, sha256_prefix, 19))
454 else if (hashalgo == GCRY_MD_SHA1 && !memcmp (indata, sha256_prefix, 19))
456 /* Fixme: This is a kludge. A better solution is not to use
457 SHA1 as default but use an autodetection. However this
458 needs changes in all app-*.c */
459 hashalgo = GCRY_MD_SHA256;
460 datalen = indatalen;
462 else
463 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
464 memcpy (data, indata, indatalen);
466 else
468 int len = 15;
469 if (hashalgo == GCRY_MD_SHA1)
470 memcpy (data, sha1_prefix, len);
471 else if (hashalgo == GCRY_MD_RMD160)
472 memcpy (data, rmd160_prefix, len);
473 else if (hashalgo == GCRY_MD_SHA256)
475 len = 19;
476 datalen = len + indatalen;
477 memcpy (data, sha256_prefix, len);
479 else
480 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
481 memcpy (data+len, indata, indatalen);
484 rc = verify_pin (app, pincb, pincb_arg);
485 if (!rc)
486 rc = iso7816_compute_ds (app->slot, 0, data, datalen, 0,
487 outdata, outdatalen);
488 return rc;
492 #if 0
493 #warning test function - works but may brick your card
494 /* Handle the PASSWD command. CHVNOSTR is currently ignored; we
495 always use VHV0. RESET_MODE is not yet implemented. */
496 static gpg_error_t
497 do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr,
498 unsigned int flags,
499 gpg_error_t (*pincb)(void*, const char *, char **),
500 void *pincb_arg)
502 gpg_error_t err;
503 char *pinvalue;
504 const char *oldpin;
505 size_t oldpinlen;
507 if ((flags & APP_CHANGE_FLAG_RESET))
508 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
510 if ((flags & APP_CHANGE_FLAG_NULLPIN))
512 /* With the nullpin flag, we do not verify the PIN - it would fail
513 if the Nullpin is still set. */
514 oldpin = "\0\0\0\0\0";
515 oldpinlen = 6;
517 else
519 err = verify_pin (app, pincb, pincb_arg);
520 if (err)
521 return err;
522 oldpin = NULL;
523 oldpinlen = 0;
526 /* TRANSLATORS: Do not translate the "|*|" prefixes but
527 keep it at the start of the string. We need this elsewhere
528 to get some infos on the string. */
529 err = pincb (pincb_arg, _("|N|Initial New PIN"), &pinvalue);
530 if (err)
532 log_error (_("error getting new PIN: %s\n"), gpg_strerror (err));
533 return err;
536 err = iso7816_change_reference_data (app->slot, 0x81,
537 oldpin, oldpinlen,
538 pinvalue, strlen (pinvalue));
539 xfree (pinvalue);
540 return err;
542 #endif /*0*/
545 /* Select the DINSIG application on the card in SLOT. This function
546 must be used before any other DINSIG application functions. */
547 gpg_error_t
548 app_select_dinsig (app_t app)
550 static char const aid[] = { 0xD2, 0x76, 0x00, 0x00, 0x66, 0x01 };
551 int slot = app->slot;
552 int rc;
554 rc = iso7816_select_application (slot, aid, sizeof aid, 0);
555 if (!rc)
557 app->apptype = "DINSIG";
559 app->fnc.learn_status = do_learn_status;
560 app->fnc.readcert = do_readcert;
561 app->fnc.getattr = NULL;
562 app->fnc.setattr = NULL;
563 app->fnc.genkey = NULL;
564 app->fnc.sign = do_sign;
565 app->fnc.auth = NULL;
566 app->fnc.decipher = NULL;
567 app->fnc.change_pin = NULL /*do_change_pin*/;
568 app->fnc.check_pin = NULL;
570 app->force_chv1 = 1;
573 return rc;