2006-06-09 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / scd / app-dinsig.c
blob75cd12c5966d67f89e6cd2b9f55fdd86db572d60
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:
27 Cxyz
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.
34 '4' := key agreement.
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
41 of card holder.
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).
44 'F' := reserved.
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
54 of keys. [o,o]
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.
73 #include <config.h>
74 #include <errno.h>
75 #include <stdio.h>
76 #include <stdlib.h>
77 #include <string.h>
78 #include <assert.h>
79 #include <time.h>
81 #include "scdaemon.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)
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 /* Return the certificate of the card holder. */
101 fid = 0xC000;
102 len = app_help_read_length_of_cert (app->slot, fid, &certoff);
103 if (!len)
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),
111 NULL, (size_t)0);
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);
116 if (err)
118 log_info ("error reading entire certificate from FID 0x%04X: %s\n",
119 fid, gpg_strerror (err));
120 return 0;
123 err = ksba_cert_new (&cert);
124 if (err)
126 xfree (der);
127 return err;
129 err = ksba_cert_init_from_mem (cert, der, derlen);
130 xfree (der); der = NULL;
131 if (err)
133 log_error ("failed to parse the certificate at FID 0x%04X: %s\n",
134 fid, gpg_strerror (err));
135 ksba_cert_release (cert);
136 return err;
138 err = app_help_get_keygrip_string (cert, hexkeygrip);
139 if (err)
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",
149 hexkeygrip, 40,
150 id_buf, strlen (id_buf),
151 NULL, (size_t)0);
152 return 0;
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
161 CERTLEN.
163 FIXME: This needs some cleanups and caching with do_learn_status.
165 static gpg_error_t
166 do_readcert (app_t app, const char *certid,
167 unsigned char **cert, size_t *certlen)
169 int fid;
170 gpg_error_t err;
171 unsigned char *buffer;
172 const unsigned char *p;
173 size_t buflen, n;
174 int class, tag, constructed, ndef;
175 size_t totobjlen, objlen, hdrlen;
176 int rootca = 0;
178 *cert = NULL;
179 *certlen = 0;
180 if (strncmp (certid, "DINSIG.", 7) )
181 return gpg_error (GPG_ERR_INV_ID);
182 certid += 7;
183 if (!hexdigitp (certid) || !hexdigitp (certid+1)
184 || !hexdigitp (certid+2) || !hexdigitp (certid+3)
185 || certid[4])
186 return gpg_error (GPG_ERR_INV_ID);
187 fid = xtoi_4 (certid);
188 if (fid != 0xC000 )
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
193 actually is. */
194 err = iso7816_select_file (app->slot, fid, 0, NULL, NULL);
195 if (err)
197 log_error ("error selecting FID 0x%04X: %s\n", fid, gpg_strerror (err));
198 return err;
201 err = iso7816_read_binary (app->slot, 0, 0, &buffer, &buflen);
202 if (err)
204 log_error ("error reading certificate from FID 0x%04X: %s\n",
205 fid, gpg_strerror (err));
206 return 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);
213 goto leave;
216 /* Now figure something out about the object. */
217 p = buffer;
218 n = buflen;
219 err = parse_ber_header (&p, &n, &class, &tag, &constructed,
220 &ndef, &objlen, &hdrlen);
221 if (err)
222 goto leave;
223 if ( class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE && constructed )
225 else if ( class == CLASS_UNIVERSAL && tag == TAG_SET && constructed )
226 rootca = 1;
227 else
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);
234 if (err)
235 goto leave;
237 if (rootca)
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
245 the certificate. */
246 if (n < objlen)
248 err = gpg_error (GPG_ERR_INV_OBJ);
249 goto leave;
251 p += objlen;
252 n -= objlen;
253 save_p = p;
254 err = parse_ber_header (&p, &n, &class, &tag, &constructed,
255 &ndef, &objlen, &hdrlen);
256 if (err)
257 goto leave;
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);
265 *cert = buffer;
266 buffer = NULL;
267 *certlen = totobjlen;
269 leave:
270 xfree (buffer);
271 return err;
275 /* Verify the PIN if required. */
276 static gpg_error_t
277 verify_pin (app_t app,
278 gpg_error_t (*pincb)(void*, const char *, char **),
279 void *pincb_arg)
281 if (!app->did_chv1 || app->force_chv1 )
283 const char *s;
284 char *pinvalue;
285 int rc;
287 rc = pincb (pincb_arg, "PIN", &pinvalue);
288 if (rc)
290 log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
291 return 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++)
298 if (*s)
300 log_error ("Non-numeric digits found in PIN\n");
301 xfree (pinvalue);
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");
308 xfree (pinvalue);
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");
314 xfree (pinvalue);
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
325 this. */
326 char paddedpin[8];
327 int i, ndigits;
329 for (ndigits=0, s=pinvalue; *s; ndigits++, s++)
331 i = 0;
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);
341 if (rc)
343 log_error ("verify PIN failed\n");
344 xfree (pinvalue);
345 return rc;
347 app->did_chv1 = 1;
348 xfree (pinvalue);
351 return 0;
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. */
360 static gpg_error_t
361 do_sign (app_t app, const char *keyidstr, int hashalgo,
362 gpg_error_t (*pincb)(void*, const char *, char **),
363 void *pincb_arg,
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 };
373 int rc;
374 int fid;
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);
387 keyidstr += 7;
388 if (!hexdigitp (keyidstr) || !hexdigitp (keyidstr+1)
389 || !hexdigitp (keyidstr+2) || !hexdigitp (keyidstr+3)
390 || keyidstr[4])
391 return gpg_error (GPG_ERR_INV_ID);
392 fid = xtoi_4 (keyidstr);
393 if (fid != 0xC000)
394 return gpg_error (GPG_ERR_NOT_FOUND);
396 /* Prepare the DER object from INDATA. */
397 if (indatalen == 35)
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))
406 else
407 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
408 memcpy (data, indata, indatalen);
410 else
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);
416 else
417 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
418 memcpy (data+15, indata, indatalen);
421 rc = verify_pin (app, pincb, pincb_arg);
422 if (!rc)
423 rc = iso7816_compute_ds (app->slot, data, 35, outdata, outdatalen);
424 return rc;
429 /* Select the DINSIG application on the card in SLOT. This function
430 must be used before any other DINSIG application functions. */
431 gpg_error_t
432 app_select_dinsig (APP app)
434 static char const aid[] = { 0xD2, 0x76, 0x00, 0x00, 0x66, 0x01 };
435 int slot = app->slot;
436 int rc;
438 rc = iso7816_select_application (slot, aid, sizeof aid, 0);
439 if (!rc)
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;
454 app->force_chv1 = 1;
457 return rc;