1 /* app-dinsig.c - The DINSIG (DIN V 66291-1) card application.
2 * Copyright (C) 2002, 2004, 2005 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 2 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, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
22 /* The German signature law and its bylaw (SigG and SigV) is currently
23 used with an interface specification described in DIN V 66291-1.
24 The AID to be used is: 'D27600006601'.
26 The file IDs for certificates utilize the generic format:
28 C being the hex digit 'C' (12).
29 x being the service indicator:
30 '0' := SigG conform digital signature.
31 '1' := entity authentication.
32 '2' := key encipherment.
33 '3' := data encipherment.
35 other values are reserved for future use.
36 y being the security environment number using '0' for cards
37 not supporting a SE number.
38 z being the certificate type:
39 '0' := C.CH (base certificate of card holder) or C.ICC.
40 '1' .. '7' := C.CH (business or professional certificate
42 '8' .. 'D' := C.CA (certificate of a CA issue by the Root-CA).
43 'E' := C.RCA (self certified certificate of the Root-CA).
46 The file IDs used by default are:
47 '1F00' EF.SSD (security service descriptor). [o,o]
48 '2F02' EF.GDO (global data objects) [m,m]
49 'A000' EF.PROT (signature log). Cyclic file with 20 records of 53 byte.
50 Read and update after user authentication. [o,o]
51 'B000' EF.PK.RCA.DS (public keys of Root-CA). Size is 512b or size
52 of keys. [m (unless a 'C00E' is present),m]
53 'B001' EF.PK.CA.DS (public keys of CAs). Size is 512b or size
55 'C00n' EF.C.CH.DS (digital signature certificate of card holder)
56 with n := 0 .. 7. Size is 2k or size of cert. Read and
57 update allowed after user authentication. [m,m]
58 'C00m' EF.C.CA.DS (digital signature certificate of CA)
59 with m := 8 .. E. Size is 1k or size of cert. Read always
60 allowed, update after user authentication. [o,o]
61 'C100' EF.C.ICC.AUT (AUT certificate of ICC) [o,m]
62 'C108' EF.C.CA.AUT (AUT certificate of CA) [o,m]
63 'D000' EF.DM (display message) [-,m]
65 The letters in brackets indicate optional or mandatory files: The
66 first for card terminals under full control and the second for
67 "business" card terminals.
84 #include "app-common.h"
89 do_learn_status (app_t app
, ctrl_t ctrl
)
92 char ct_buf
[100], id_buf
[100];
100 /* Return the certificate of the card holder. */
102 len
= app_help_read_length_of_cert (app
->slot
, fid
, &certoff
);
104 return 0; /* Card has not been personalized. */
106 sprintf (ct_buf
, "%d", 101);
107 sprintf (id_buf
, "DINSIG.%04X", fid
);
108 send_status_info (ctrl
, "CERTINFO",
109 ct_buf
, strlen (ct_buf
),
110 id_buf
, strlen (id_buf
),
113 /* Now we need to read the certificate, so that we can get the
114 public key out of it. */
115 err
= iso7816_read_binary (app
->slot
, certoff
, len
-certoff
, &der
, &derlen
);
118 log_info ("error reading entire certificate from FID 0x%04X: %s\n",
119 fid
, gpg_strerror (err
));
123 err
= ksba_cert_new (&cert
);
129 err
= ksba_cert_init_from_mem (cert
, der
, derlen
);
130 xfree (der
); der
= NULL
;
133 log_error ("failed to parse the certificate at FID 0x%04X: %s\n",
134 fid
, gpg_strerror (err
));
135 ksba_cert_release (cert
);
138 err
= app_help_get_keygrip_string (cert
, hexkeygrip
);
141 log_error ("failed to calculate the keygrip for FID 0x%04X\n", fid
);
142 ksba_cert_release (cert
);
143 return gpg_error (GPG_ERR_CARD
);
145 ksba_cert_release (cert
);
147 sprintf (id_buf
, "DINSIG.%04X", fid
);
148 send_status_info (ctrl
, "KEYPAIRINFO",
150 id_buf
, strlen (id_buf
),
158 /* Read the certificate with id CERTID (as returned by learn_status in
159 the CERTINFO status lines) and return it in the freshly allocated
160 buffer put into CERT and the length of the certificate put into
163 FIXME: This needs some cleanups and caching with do_learn_status.
166 do_readcert (app_t app
, const char *certid
,
167 unsigned char **cert
, size_t *certlen
)
171 unsigned char *buffer
;
172 const unsigned char *p
;
174 int class, tag
, constructed
, ndef
;
175 size_t totobjlen
, objlen
, hdrlen
;
180 if (strncmp (certid
, "DINSIG.", 7) )
181 return gpg_error (GPG_ERR_INV_ID
);
183 if (!hexdigitp (certid
) || !hexdigitp (certid
+1)
184 || !hexdigitp (certid
+2) || !hexdigitp (certid
+3)
186 return gpg_error (GPG_ERR_INV_ID
);
187 fid
= xtoi_4 (certid
);
189 return gpg_error (GPG_ERR_NOT_FOUND
);
191 /* Read the entire file. fixme: This could be optimized by first
192 reading the header to figure out how long the certificate
194 err
= iso7816_select_file (app
->slot
, fid
, 0, NULL
, NULL
);
197 log_error ("error selecting FID 0x%04X: %s\n", fid
, gpg_strerror (err
));
201 err
= iso7816_read_binary (app
->slot
, 0, 0, &buffer
, &buflen
);
204 log_error ("error reading certificate from FID 0x%04X: %s\n",
205 fid
, gpg_strerror (err
));
209 if (!buflen
|| *buffer
== 0xff)
211 log_info ("no certificate contained in FID 0x%04X\n", fid
);
212 err
= gpg_error (GPG_ERR_NOT_FOUND
);
216 /* Now figure something out about the object. */
219 err
= parse_ber_header (&p
, &n
, &class, &tag
, &constructed
,
220 &ndef
, &objlen
, &hdrlen
);
223 if ( class == CLASS_UNIVERSAL
&& tag
== TAG_SEQUENCE
&& constructed
)
225 else if ( class == CLASS_UNIVERSAL
&& tag
== TAG_SET
&& constructed
)
228 return gpg_error (GPG_ERR_INV_OBJ
);
229 totobjlen
= objlen
+ hdrlen
;
230 assert (totobjlen
<= buflen
);
232 err
= parse_ber_header (&p
, &n
, &class, &tag
, &constructed
,
233 &ndef
, &objlen
, &hdrlen
);
239 else if (class == CLASS_UNIVERSAL
&& tag
== TAG_OBJECT_ID
&& !constructed
)
241 const unsigned char *save_p
;
243 /* The certificate seems to be contained in a userCertificate
244 container. Skip this and assume the following sequence is
248 err
= gpg_error (GPG_ERR_INV_OBJ
);
254 err
= parse_ber_header (&p
, &n
, &class, &tag
, &constructed
,
255 &ndef
, &objlen
, &hdrlen
);
258 if ( !(class == CLASS_UNIVERSAL
&& tag
== TAG_SEQUENCE
&& constructed
) )
259 return gpg_error (GPG_ERR_INV_OBJ
);
260 totobjlen
= objlen
+ hdrlen
;
261 assert (save_p
+ totobjlen
<= buffer
+ buflen
);
262 memmove (buffer
, save_p
, totobjlen
);
267 *certlen
= totobjlen
;
275 /* Verify the PIN if required. */
277 verify_pin (app_t app
,
278 gpg_error_t (*pincb
)(void*, const char *, char **),
281 if (!app
->did_chv1
|| app
->force_chv1
)
287 rc
= pincb (pincb_arg
, "PIN", &pinvalue
);
290 log_info ("PIN callback returned error: %s\n", gpg_strerror (rc
));
294 /* We require the PIN to be at least 6 and at max 8 bytes.
295 According to the specs, this should all be ASCII. */
296 for (s
=pinvalue
; digitp (s
); s
++)
300 log_error ("Non-numeric digits found in PIN\n");
302 return gpg_error (GPG_ERR_BAD_PIN
);
305 if (strlen (pinvalue
) < 6)
307 log_error ("PIN is too short; minimum length is 6\n");
309 return gpg_error (GPG_ERR_BAD_PIN
);
311 else if (strlen (pinvalue
) > 8)
313 log_error ("PIN is too large; maximum length is 8\n");
315 return gpg_error (GPG_ERR_BAD_PIN
);
318 rc
= iso7816_verify (app
->slot
, 0x81, pinvalue
, strlen (pinvalue
));
319 if (gpg_err_code (rc
) == GPG_ERR_INV_VALUE
)
321 /* We assume that ISO 9564-1 encoding is used and we failed
322 because the first nibble we passed was 3 and not 2. DIN
323 says something about looking up such an encoding in the
324 SSD but I was not able to find any tag relevant to
329 for (ndigits
=0, s
=pinvalue
; *s
; ndigits
++, s
++)
332 paddedpin
[i
++] = 0x20 | (ndigits
& 0x0f);
333 for (s
=pinvalue
; i
< sizeof paddedpin
&& *s
&& s
[1]; s
= s
+2 )
334 paddedpin
[i
++] = (((*s
- '0') << 4) | ((s
[1] - '0') & 0x0f));
335 if (i
< sizeof paddedpin
&& *s
)
336 paddedpin
[i
++] = (((*s
- '0') << 4) | 0x0f);
337 while (i
< sizeof paddedpin
)
338 paddedpin
[i
++] = 0xff;
339 rc
= iso7816_verify (app
->slot
, 0x81, paddedpin
, sizeof paddedpin
);
343 log_error ("verify PIN failed\n");
356 /* Create the signature and return the allocated result in OUTDATA.
357 If a PIN is required the PINCB will be used to ask for the PIN;
358 that callback should return the PIN in an allocated buffer and
359 store that in the 3rd argument. */
361 do_sign (app_t app
, const char *keyidstr
, int hashalgo
,
362 gpg_error_t (*pincb
)(void*, const char *, char **),
364 const void *indata
, size_t indatalen
,
365 unsigned char **outdata
, size_t *outdatalen
)
367 static unsigned char sha1_prefix
[15] = /* Object ID is 1.3.14.3.2.26 */
368 { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
369 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
370 static unsigned char rmd160_prefix
[15] = /* Object ID is 1.3.36.3.2.1 */
371 { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
372 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 };
375 unsigned char data
[35]; /* Must be large enough for a SHA-1 digest
376 + the largest OID _prefix above. */
378 if (!keyidstr
|| !*keyidstr
)
379 return gpg_error (GPG_ERR_INV_VALUE
);
380 if (indatalen
!= 20 && indatalen
!= 16 && indatalen
!= 35)
381 return gpg_error (GPG_ERR_INV_VALUE
);
383 /* Check that the provided ID is vaid. This is not really needed
384 but we do it to to enforce correct usage by the caller. */
385 if (strncmp (keyidstr
, "DINSIG.", 7) )
386 return gpg_error (GPG_ERR_INV_ID
);
388 if (!hexdigitp (keyidstr
) || !hexdigitp (keyidstr
+1)
389 || !hexdigitp (keyidstr
+2) || !hexdigitp (keyidstr
+3)
391 return gpg_error (GPG_ERR_INV_ID
);
392 fid
= xtoi_4 (keyidstr
);
394 return gpg_error (GPG_ERR_NOT_FOUND
);
396 /* Prepare the DER object from INDATA. */
399 /* Alright, the caller was so kind to send us an already
400 prepared DER object. Check that it is what we want and that
401 it matches the hash algorithm. */
402 if (hashalgo
== GCRY_MD_SHA1
&& !memcmp (indata
, sha1_prefix
, 15))
404 else if (hashalgo
== GCRY_MD_RMD160
&& !memcmp (indata
, rmd160_prefix
,15))
407 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM
);
408 memcpy (data
, indata
, indatalen
);
412 if (hashalgo
== GCRY_MD_SHA1
)
413 memcpy (data
, sha1_prefix
, 15);
414 else if (hashalgo
== GCRY_MD_RMD160
)
415 memcpy (data
, rmd160_prefix
, 15);
417 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM
);
418 memcpy (data
+15, indata
, indatalen
);
421 rc
= verify_pin (app
, pincb
, pincb_arg
);
423 rc
= iso7816_compute_ds (app
->slot
, data
, 35, outdata
, outdatalen
);
429 /* Select the DINSIG application on the card in SLOT. This function
430 must be used before any other DINSIG application functions. */
432 app_select_dinsig (APP app
)
434 static char const aid
[] = { 0xD2, 0x76, 0x00, 0x00, 0x66, 0x01 };
435 int slot
= app
->slot
;
438 rc
= iso7816_select_application (slot
, aid
, sizeof aid
, 0);
441 app
->apptype
= "DINSIG";
443 app
->fnc
.learn_status
= do_learn_status
;
444 app
->fnc
.readcert
= do_readcert
;
445 app
->fnc
.getattr
= NULL
;
446 app
->fnc
.setattr
= NULL
;
447 app
->fnc
.genkey
= NULL
;
448 app
->fnc
.sign
= do_sign
;
449 app
->fnc
.auth
= NULL
;
450 app
->fnc
.decipher
= NULL
;
451 app
->fnc
.change_pin
= NULL
;
452 app
->fnc
.check_pin
= NULL
;