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 <https://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:
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.
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
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).
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
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.
84 #include "app-common.h"
89 do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
92 char ct_buf[100], id_buf[100];
102 /* Return the certificate of the card holder. */
104 len = app_help_read_length_of_cert (app->slot, fid, &certoff);
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),
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);
120 log_info ("error reading entire certificate from FID 0x%04X: %s\n",
121 fid, gpg_strerror (err));
125 err = ksba_cert_new (&cert);
131 err = ksba_cert_init_from_mem (cert, der, derlen);
132 xfree (der); der = NULL;
135 log_error ("failed to parse the certificate at FID 0x%04X: %s\n",
136 fid, gpg_strerror (err));
137 ksba_cert_release (cert);
140 err = app_help_get_keygrip_string (cert, hexkeygrip);
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",
152 id_buf, strlen (id_buf),
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
165 FIXME: This needs some cleanups and caching with do_learn_status.
168 do_readcert (app_t app, const char *certid,
169 unsigned char **cert, size_t *certlen)
173 unsigned char *buffer;
174 const unsigned char *p;
176 int class, tag, constructed, ndef;
177 size_t totobjlen, objlen, hdrlen;
182 if (strncmp (certid, "DINSIG.", 7) )
183 return gpg_error (GPG_ERR_INV_ID);
185 if (!hexdigitp (certid) || !hexdigitp (certid+1)
186 || !hexdigitp (certid+2) || !hexdigitp (certid+3)
188 return gpg_error (GPG_ERR_INV_ID);
189 fid = xtoi_4 (certid);
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
196 err = iso7816_select_file (app->slot, fid, 0, NULL, NULL);
199 log_error ("error selecting FID 0x%04X: %s\n", fid, gpg_strerror (err));
203 err = iso7816_read_binary (app->slot, 0, 0, &buffer, &buflen);
206 log_error ("error reading certificate from FID 0x%04X: %s\n",
207 fid, gpg_strerror (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);
218 /* Now figure something out about the object. */
221 err = parse_ber_header (&p, &n, &class, &tag, &constructed,
222 &ndef, &objlen, &hdrlen);
225 if ( class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE && constructed )
227 else if ( class == CLASS_UNIVERSAL && tag == TAG_SET && constructed )
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);
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
250 err = gpg_error (GPG_ERR_INV_OBJ);
256 err = parse_ber_header (&p, &n, &class, &tag, &constructed,
257 &ndef, &objlen, &hdrlen);
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);
269 *certlen = totobjlen;
277 /* Verify the PIN if required. */
279 verify_pin (app_t app,
280 gpg_error_t (*pincb)(void*, const char *, char **),
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.fixedlen = -1;
295 if (!opt.disable_pinpad
296 && !iso7816_check_pinpad (app->slot, ISO7816_VERIFY, &pininfo) )
298 rc = pincb (pincb_arg,
299 _("||Please enter your PIN at the reader's pinpad"),
303 log_info (_("PIN callback returned error: %s\n"),
307 rc = iso7816_verify_kp (app->slot, 0x81, &pininfo);
308 /* Dismiss the prompt. */
309 pincb (pincb_arg, NULL, NULL);
311 else /* No Pinpad. */
315 rc = pincb (pincb_arg, "PIN", &pinvalue);
318 log_info ("PIN callback returned error: %s\n", gpg_strerror (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++)
328 log_error ("Non-numeric digits found in PIN\n");
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",
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",
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
359 for (ndigits=0, s=pinvalue; *s; ndigits++, s++)
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);
376 log_error ("verify PIN failed\n");
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. */
390 do_sign (app_t app, const char *keyidstr, int hashalgo,
391 gpg_error_t (*pincb)(void*, const char *, char **),
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,
408 unsigned char data[19+32]; /* Must be large enough for a SHA-256 digest
409 + the largest OID _prefix above. */
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);
423 if (!hexdigitp (keyidstr) || !hexdigitp (keyidstr+1)
424 || !hexdigitp (keyidstr+2) || !hexdigitp (keyidstr+3)
426 return gpg_error (GPG_ERR_INV_ID);
427 fid = xtoi_4 (keyidstr);
429 return gpg_error (GPG_ERR_NOT_FOUND);
431 /* Prepare the DER object from INDATA. */
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))
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. */
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;
463 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
464 memcpy (data, indata, indatalen);
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)
476 datalen = len + indatalen;
477 memcpy (data, sha256_prefix, len);
480 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
481 memcpy (data+len, indata, indatalen);
484 rc = verify_pin (app, pincb, pincb_arg);
486 rc = iso7816_compute_ds (app->slot, 0, data, datalen, 0,
487 outdata, outdatalen);
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. */
497 do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr,
499 gpg_error_t (*pincb)(void*, const char *, char **),
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";
519 err = verify_pin (app, pincb, pincb_arg);
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);
532 log_error (_("error getting new PIN: %s\n"), gpg_strerror (err));
536 err = iso7816_change_reference_data (app->slot, 0x81,
538 pinvalue, strlen (pinvalue));
545 /* Select the DINSIG application on the card in SLOT. This function
546 must be used before any other DINSIG application functions. */
548 app_select_dinsig (app_t app)
550 static char const aid[] = { 0xD2, 0x76, 0x00, 0x00, 0x66, 0x01 };
551 int slot = app->slot;
554 rc = iso7816_select_application (slot, aid, sizeof aid, 0);
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;