2005-04-15 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / scd / card-dinsig.c
blobdf09bfb57dd46c47a88ecd46cb8722385c3e2c40
1 /* card-dinsig.c - German signature law (DINSIG) functions
2 * Copyright (C) 2002 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
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 ard 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 uder 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.
68 FIXME: Needs a lot more explanation.
73 #include <config.h>
74 #include <errno.h>
75 #include <stdio.h>
76 #include <stdlib.h>
77 #include <string.h>
78 #include <time.h>
80 #ifdef HAVE_OPENSC
81 #include <opensc/pkcs15.h>
82 #include "scdaemon.h"
83 #include <ksba.h>
85 #include "card-common.h"
87 static int dinsig_read_cert (CARD card, const char *certidstr,
88 unsigned char **cert, size_t *ncert);
92 /* See card.c for interface description. Frankly we don't do any real
93 enumeration but just check whether the well know files are
94 available. */
95 static int
96 dinsig_enum_keypairs (CARD card, int idx,
97 unsigned char *keygrip, char **keyid)
99 int rc;
100 unsigned char *buf;
101 size_t buflen;
102 ksba_cert_t cert;
104 /* fixme: We should locate the application via the EF(DIR) and not
105 assume a Netkey card */
106 if (!idx)
107 rc = dinsig_read_cert (card, "DINSIG-DF01.C000", &buf, &buflen);
108 else if (idx == 1)
109 rc = dinsig_read_cert (card, "DINSIG-DF01.C200", &buf, &buflen);
110 else
111 rc = -1;
112 if (rc)
113 return rc;
115 rc = ksba_cert_new (&cert);
116 if (rc)
118 xfree (buf);
119 return rc;
122 rc = ksba_cert_init_from_mem (cert, buf, buflen);
123 xfree (buf);
124 if (rc)
126 log_error ("failed to parse the certificate at idx %d: %s\n",
127 idx, gpg_strerror (rc));
128 ksba_cert_release (cert);
129 return rc;
131 if (card_help_get_keygrip (cert, keygrip))
133 log_error ("failed to calculate the keygrip at index %d\n", idx);
134 ksba_cert_release (cert);
135 return gpg_error (GPG_ERR_CARD);
137 ksba_cert_release (cert);
139 /* return the iD */
140 if (keyid)
142 *keyid = xtrymalloc (17);
143 if (!*keyid)
144 return gpg_error (gpg_err_code_from_errno (errno));
145 if (!idx)
146 strcpy (*keyid, "DINSIG-DF01.C000");
147 else
148 strcpy (*keyid, "DINSIG-DF01.C200");
151 return 0;
156 /* See card.c for interface description */
157 static int
158 dinsig_read_cert (CARD card, const char *certidstr,
159 unsigned char **cert, size_t *ncert)
161 int rc;
162 struct sc_path path;
163 struct sc_file *file;
164 unsigned char *buf;
165 int buflen;
167 if (!strcmp (certidstr, "DINSIG-DF01.C000"))
168 sc_format_path ("3F00DF01C000", &path);
169 else if (!strcmp (certidstr, "DINSIG-DF01.C200"))
170 sc_format_path ("3F00DF01C200", &path);
171 else
172 return gpg_error (GPG_ERR_INV_ID);
174 rc = sc_select_file (card->scard, &path, &file);
175 if (rc)
177 log_error ("sc_select_file failed: %s\n", sc_strerror (rc));
178 return map_sc_err (rc);
180 if (file->type != SC_FILE_TYPE_WORKING_EF
181 || file->ef_structure != SC_FILE_EF_TRANSPARENT)
183 log_error ("wrong type or structure of certificate EF\n");
184 sc_file_free (file);
185 return gpg_error (GPG_ERR_CARD);
187 if (file->size < 20) /* check against a somewhat arbitrary length */
189 log_error ("certificate EF too short\n");
190 sc_file_free (file);
191 return gpg_error (GPG_ERR_CARD);
193 buf = xtrymalloc (file->size);
194 if (!buf)
196 gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
197 sc_file_free (file);
198 return tmperr;
201 rc = sc_read_binary (card->scard, 0, buf, file->size, 0);
202 if (rc >= 0 && rc != file->size)
204 log_error ("short read on certificate EF\n");
205 sc_file_free (file);
206 xfree (buf);
207 return gpg_error (GPG_ERR_CARD);
209 sc_file_free (file);
210 if (rc < 0)
212 log_error ("error reading certificate EF: %s\n", sc_strerror (rc));
213 xfree (buf);
214 return map_sc_err (rc);
216 buflen = rc;
218 /* The object is not a plain certificate but wrapped into id-at
219 userCertificate - fixme: we should check the specs and decided
220 whether libksba should support it */
221 if (buflen > 9 && buf[0] == 0x30 && buf[4] == 6 && buf[5] == 3
222 && buf[6] == 0x55 && buf[7] == 4 && buf[8] == 0x24)
224 /* We have to strip the padding. Although this is a good idea
225 anyway, we have to do it due to a KSBA problem; KSBA does not
226 work correct when the buffer is larger than the ASN.1
227 structure and the certificates here are padded with FF. So
228 as a workaround we look at the outer structure to get the
229 size of the entire thing and adjust the buflen. We can only
230 do this when there is a 2 byte length field */
231 size_t seqlen;
232 if (buf[1] == 0x82)
234 seqlen = ((buf[2] << 8) | buf[3]) + 4;
235 if (seqlen < buflen)
236 buflen = seqlen;
238 memmove (buf, buf+9, buflen-9);
239 buflen -= 9;
242 *cert = buf;
243 *ncert = buflen;
244 return 0;
250 /* Bind our operations to the card */
251 void
252 card_dinsig_bind (CARD card)
254 card->fnc.enum_keypairs = dinsig_enum_keypairs;
255 card->fnc.read_cert = dinsig_read_cert;
258 #endif /*HAVE_OPENSC*/