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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
23 /* The German signature law and its bylaw (SigG and SigV) is currently
24 used with an interface specification described in DIN V 66291-1.
25 The AID to be used is: 'D27600006601'.
27 The file IDs for certificates utilize the generic format:
29 C being the hex digit 'C' (12).
30 x being the service indicator:
31 '0' := SigG conform digital signature.
32 '1' := entity authentication.
33 '2' := key encipherment.
34 '3' := data encipherment.
36 other values are reserved for future use.
37 y being the security environment number using '0' for cards
38 not supporting a SE number.
39 z being the certificate type:
40 '0' := C.CH (base certificate of card holder) or C.ICC.
41 '1' .. '7' := C.CH (business or professional certificate
43 '8' .. 'D' := C.CA (certificate of a CA issue by the Root-CA).
44 'E' := C.RCA (self certified certificate of the Root-CA).
47 The file IDs used by default are:
48 '1F00' EF.SSD (security service descriptor). [o,o]
49 '2F02' EF.GDO (global data objects) [m,m]
50 'A000' EF.PROT (signature log). Cyclic file with 20 records of 53 byte.
51 Read and update after user authentication. [o,o]
52 'B000' EF.PK.RCA.DS (public keys of Root-CA). Size is 512b or size
53 of keys. [m (unless a 'C00E' is present),m]
54 'B001' EF.PK.CA.DS (public keys of CAs). Size is 512b or size
56 'C00n' EF.C.CH.DS (digital signature certificate of card holder)
57 with n := 0 .. 7. Size is 2k or size of cert. Read and
58 update allowed after user authentication. [m,m]
59 'C00m' EF.C.CA.DS (digital signature certificate of CA)
60 with m := 8 .. E. Size is 1k or size of cert. Read always
61 allowed, update after user authentication. [o,o]
62 'C100' EF.C.ICC.AUT (AUT certificate of ICC) [o,m]
63 'C108' EF.C.CA.AUT (AUT certificate of CA) [o,m]
64 'D000' EF.DM (display message) [-,m]
66 The letters in brackets indicate optional or mandatory files: The
67 first for card terminals under full control and the second for
68 "business" card terminals.
85 #include "app-common.h"
90 do_learn_status (app_t app
, ctrl_t ctrl
)
93 char ct_buf
[100], id_buf
[100];
101 /* Return the certificate of the card holder. */
103 len
= app_help_read_length_of_cert (app
->slot
, fid
, &certoff
);
105 return 0; /* Card has not been personalized. */
107 sprintf (ct_buf
, "%d", 101);
108 sprintf (id_buf
, "DINSIG.%04X", fid
);
109 send_status_info (ctrl
, "CERTINFO",
110 ct_buf
, strlen (ct_buf
),
111 id_buf
, strlen (id_buf
),
114 /* Now we need to read the certificate, so that we can get the
115 public key out of it. */
116 err
= iso7816_read_binary (app
->slot
, certoff
, len
-certoff
, &der
, &derlen
);
119 log_info ("error reading entire certificate from FID 0x%04X: %s\n",
120 fid
, gpg_strerror (err
));
124 err
= ksba_cert_new (&cert
);
130 err
= ksba_cert_init_from_mem (cert
, der
, derlen
);
131 xfree (der
); der
= NULL
;
134 log_error ("failed to parse the certificate at FID 0x%04X: %s\n",
135 fid
, gpg_strerror (err
));
136 ksba_cert_release (cert
);
139 err
= app_help_get_keygrip_string (cert
, hexkeygrip
);
142 log_error ("failed to calculate the keygrip for FID 0x%04X\n", fid
);
143 ksba_cert_release (cert
);
144 return gpg_error (GPG_ERR_CARD
);
146 ksba_cert_release (cert
);
148 sprintf (id_buf
, "DINSIG.%04X", fid
);
149 send_status_info (ctrl
, "KEYPAIRINFO",
151 id_buf
, strlen (id_buf
),
159 /* Read the certificate with id CERTID (as returned by learn_status in
160 the CERTINFO status lines) and return it in the freshly allocated
161 buffer put into CERT and the length of the certificate put into
164 FIXME: This needs some cleanups and caching with do_learn_status.
167 do_readcert (app_t app
, const char *certid
,
168 unsigned char **cert
, size_t *certlen
)
172 unsigned char *buffer
;
173 const unsigned char *p
;
175 int class, tag
, constructed
, ndef
;
176 size_t totobjlen
, objlen
, hdrlen
;
181 if (strncmp (certid
, "DINSIG.", 7) )
182 return gpg_error (GPG_ERR_INV_ID
);
184 if (!hexdigitp (certid
) || !hexdigitp (certid
+1)
185 || !hexdigitp (certid
+2) || !hexdigitp (certid
+3)
187 return gpg_error (GPG_ERR_INV_ID
);
188 fid
= xtoi_4 (certid
);
190 return gpg_error (GPG_ERR_NOT_FOUND
);
192 /* Read the entire file. fixme: This could be optimized by first
193 reading the header to figure out how long the certificate
195 err
= iso7816_select_file (app
->slot
, fid
, 0, NULL
, NULL
);
198 log_error ("error selecting FID 0x%04X: %s\n", fid
, gpg_strerror (err
));
202 err
= iso7816_read_binary (app
->slot
, 0, 0, &buffer
, &buflen
);
205 log_error ("error reading certificate from FID 0x%04X: %s\n",
206 fid
, gpg_strerror (err
));
210 if (!buflen
|| *buffer
== 0xff)
212 log_info ("no certificate contained in FID 0x%04X\n", fid
);
213 err
= gpg_error (GPG_ERR_NOT_FOUND
);
217 /* Now figure something out about the object. */
220 err
= parse_ber_header (&p
, &n
, &class, &tag
, &constructed
,
221 &ndef
, &objlen
, &hdrlen
);
224 if ( class == CLASS_UNIVERSAL
&& tag
== TAG_SEQUENCE
&& constructed
)
226 else if ( class == CLASS_UNIVERSAL
&& tag
== TAG_SET
&& constructed
)
229 return gpg_error (GPG_ERR_INV_OBJ
);
230 totobjlen
= objlen
+ hdrlen
;
231 assert (totobjlen
<= buflen
);
233 err
= parse_ber_header (&p
, &n
, &class, &tag
, &constructed
,
234 &ndef
, &objlen
, &hdrlen
);
240 else if (class == CLASS_UNIVERSAL
&& tag
== TAG_OBJECT_ID
&& !constructed
)
242 const unsigned char *save_p
;
244 /* The certificate seems to be contained in a userCertificate
245 container. Skip this and assume the following sequence is
249 err
= gpg_error (GPG_ERR_INV_OBJ
);
255 err
= parse_ber_header (&p
, &n
, &class, &tag
, &constructed
,
256 &ndef
, &objlen
, &hdrlen
);
259 if ( !(class == CLASS_UNIVERSAL
&& tag
== TAG_SEQUENCE
&& constructed
) )
260 return gpg_error (GPG_ERR_INV_OBJ
);
261 totobjlen
= objlen
+ hdrlen
;
262 assert (save_p
+ totobjlen
<= buffer
+ buflen
);
263 memmove (buffer
, save_p
, totobjlen
);
268 *certlen
= totobjlen
;
276 /* Verify the PIN if required. */
278 verify_pin (app_t app
,
279 gpg_error_t (*pincb
)(void*, const char *, char **),
282 if (!app
->did_chv1
|| app
->force_chv1
)
288 rc
= pincb (pincb_arg
, "PIN", &pinvalue
);
291 log_info ("PIN callback returned error: %s\n", gpg_strerror (rc
));
295 /* We require the PIN to be at least 6 and at max 8 bytes.
296 According to the specs, this should all be ASCII. */
297 for (s
=pinvalue
; digitp (s
); s
++)
301 log_error ("Non-numeric digits found in PIN\n");
303 return gpg_error (GPG_ERR_BAD_PIN
);
306 if (strlen (pinvalue
) < 6)
308 log_error ("PIN is too short; minimum length is 6\n");
310 return gpg_error (GPG_ERR_BAD_PIN
);
312 else if (strlen (pinvalue
) > 8)
314 log_error ("PIN is too large; maximum length is 8\n");
316 return gpg_error (GPG_ERR_BAD_PIN
);
319 rc
= iso7816_verify (app
->slot
, 0x81, pinvalue
, strlen (pinvalue
));
320 if (gpg_err_code (rc
) == GPG_ERR_INV_VALUE
)
322 /* We assume that ISO 9564-1 encoding is used and we failed
323 because the first nibble we passed was 3 and not 2. DIN
324 says something about looking up such an encoding in the
325 SSD but I was not able to find any tag relevant to
330 for (ndigits
=0, s
=pinvalue
; *s
; ndigits
++, s
++)
333 paddedpin
[i
++] = 0x20 | (ndigits
& 0x0f);
334 for (s
=pinvalue
; i
< sizeof paddedpin
&& *s
&& s
[1]; s
= s
+2 )
335 paddedpin
[i
++] = (((*s
- '0') << 4) | ((s
[1] - '0') & 0x0f));
336 if (i
< sizeof paddedpin
&& *s
)
337 paddedpin
[i
++] = (((*s
- '0') << 4) | 0x0f);
338 while (i
< sizeof paddedpin
)
339 paddedpin
[i
++] = 0xff;
340 rc
= iso7816_verify (app
->slot
, 0x81, paddedpin
, sizeof paddedpin
);
344 log_error ("verify PIN failed\n");
357 /* Create the signature and return the allocated result in OUTDATA.
358 If a PIN is required the PINCB will be used to ask for the PIN;
359 that callback should return the PIN in an allocated buffer and
360 store that in the 3rd argument. */
362 do_sign (app_t app
, const char *keyidstr
, int hashalgo
,
363 gpg_error_t (*pincb
)(void*, const char *, char **),
365 const void *indata
, size_t indatalen
,
366 unsigned char **outdata
, size_t *outdatalen
)
368 static unsigned char sha1_prefix
[15] = /* Object ID is 1.3.14.3.2.26 */
369 { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
370 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
371 static unsigned char rmd160_prefix
[15] = /* Object ID is 1.3.36.3.2.1 */
372 { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
373 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 };
376 unsigned char data
[35]; /* Must be large enough for a SHA-1 digest
377 + the largest OID _prefix above. */
379 if (!keyidstr
|| !*keyidstr
)
380 return gpg_error (GPG_ERR_INV_VALUE
);
381 if (indatalen
!= 20 && indatalen
!= 16 && indatalen
!= 35)
382 return gpg_error (GPG_ERR_INV_VALUE
);
384 /* Check that the provided ID is vaid. This is not really needed
385 but we do it to to enforce correct usage by the caller. */
386 if (strncmp (keyidstr
, "DINSIG.", 7) )
387 return gpg_error (GPG_ERR_INV_ID
);
389 if (!hexdigitp (keyidstr
) || !hexdigitp (keyidstr
+1)
390 || !hexdigitp (keyidstr
+2) || !hexdigitp (keyidstr
+3)
392 return gpg_error (GPG_ERR_INV_ID
);
393 fid
= xtoi_4 (keyidstr
);
395 return gpg_error (GPG_ERR_NOT_FOUND
);
397 /* Prepare the DER object from INDATA. */
400 /* Alright, the caller was so kind to send us an already
401 prepared DER object. Check that it is what we want and that
402 it matches the hash algorithm. */
403 if (hashalgo
== GCRY_MD_SHA1
&& !memcmp (indata
, sha1_prefix
, 15))
405 else if (hashalgo
== GCRY_MD_RMD160
&& !memcmp (indata
, rmd160_prefix
,15))
408 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM
);
409 memcpy (data
, indata
, indatalen
);
413 if (hashalgo
== GCRY_MD_SHA1
)
414 memcpy (data
, sha1_prefix
, 15);
415 else if (hashalgo
== GCRY_MD_RMD160
)
416 memcpy (data
, rmd160_prefix
, 15);
418 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM
);
419 memcpy (data
+15, indata
, indatalen
);
422 rc
= verify_pin (app
, pincb
, pincb_arg
);
424 rc
= iso7816_compute_ds (app
->slot
, data
, 35, outdata
, outdatalen
);
430 /* Select the DINSIG application on the card in SLOT. This function
431 must be used before any other DINSIG application functions. */
433 app_select_dinsig (app_t app
)
435 static char const aid
[] = { 0xD2, 0x76, 0x00, 0x00, 0x66, 0x01 };
436 int slot
= app
->slot
;
439 rc
= iso7816_select_application (slot
, aid
, sizeof aid
, 0);
442 app
->apptype
= "DINSIG";
444 app
->fnc
.learn_status
= do_learn_status
;
445 app
->fnc
.readcert
= do_readcert
;
446 app
->fnc
.getattr
= NULL
;
447 app
->fnc
.setattr
= NULL
;
448 app
->fnc
.genkey
= NULL
;
449 app
->fnc
.sign
= do_sign
;
450 app
->fnc
.auth
= NULL
;
451 app
->fnc
.decipher
= NULL
;
452 app
->fnc
.change_pin
= NULL
;
453 app
->fnc
.check_pin
= NULL
;