2002-04-24 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / scd / card-p15.c
bloba70bc665e6abf4cae13a3ed270f45f4a57232f26
1 /* card-p15.c - PKCS-15 based card access
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 #include <config.h>
22 #include <errno.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <time.h>
28 #include <opensc-pkcs15.h>
29 #include <ksba.h>
31 #include "scdaemon.h"
32 #include "card-common.h"
35 /* See card.c for interface description */
36 static int
37 p15_enum_keypairs (CARD card, int idx,
38 unsigned char *keygrip, char **keyid)
40 int rc;
41 KsbaError krc;
42 struct sc_pkcs15_object *objs[32], *tmpobj;
43 int nobjs;
44 struct sc_pkcs15_prkey_info *pinfo;
45 struct sc_pkcs15_cert_info *certinfo;
46 struct sc_pkcs15_cert *certder;
47 KsbaCert cert;
49 rc = sc_pkcs15_get_objects (card->p15card, SC_PKCS15_TYPE_PRKEY_RSA,
50 objs, DIM (objs));
51 if (rc < 0)
53 log_error ("private keys enumeration failed: %s\n", sc_strerror (rc));
54 return GNUPG_Card_Error;
56 nobjs = rc;
57 rc = 0;
58 if (idx >= nobjs)
59 return -1;
60 pinfo = objs[idx]->data;
62 /* now we need to read the certificate so that we can calculate the
63 keygrip */
64 rc = sc_pkcs15_find_cert_by_id (card->p15card, &pinfo->id, &tmpobj);
65 if (rc)
67 log_info ("certificate for private key %d not found: %s\n",
68 idx, sc_strerror (rc));
69 /* note, that we return the ID anyway */
70 rc = GNUPG_Missing_Certificate;
71 goto return_keyid;
73 certinfo = tmpobj->data;
74 rc = sc_pkcs15_read_certificate (card->p15card, certinfo, &certder);
75 if (rc)
77 log_info ("failed to read certificate for private key %d: %s\n",
78 idx, sc_strerror (rc));
79 return GNUPG_Card_Error;
82 cert = ksba_cert_new ();
83 if (!cert)
85 sc_pkcs15_free_certificate (certder);
86 return GNUPG_Out_Of_Core;
88 krc = ksba_cert_init_from_mem (cert, certder->data, certder->data_len);
89 sc_pkcs15_free_certificate (certder);
90 if (krc)
92 log_error ("failed to parse the certificate for private key %d: %s\n",
93 idx, ksba_strerror (krc));
94 ksba_cert_release (cert);
95 return GNUPG_Card_Error;
97 if (card_help_get_keygrip (cert, keygrip))
99 log_error ("failed to calculate the keygrip of private key %d\n", idx);
100 ksba_cert_release (cert);
101 return GNUPG_Card_Error;
103 ksba_cert_release (cert);
105 rc = 0;
106 return_keyid:
107 if (keyid)
109 char *p;
110 int i;
112 *keyid = p = xtrymalloc (9+pinfo->id.len*2+1);
113 if (!*keyid)
114 return GNUPG_Out_Of_Core;
115 p = stpcpy (p, "P15-5015.");
116 for (i=0; i < pinfo->id.len; i++, p += 2)
117 sprintf (p, "%02X", pinfo->id.value[i]);
118 *p = 0;
121 return rc;
126 static int
127 idstr_to_id (const char *idstr, struct sc_pkcs15_id *id)
129 const char *s;
130 int n;
132 /* For now we only support the standard DF */
133 if (strncmp (idstr, "P15-5015.", 9) )
134 return GNUPG_Invalid_Id;
135 for (s=idstr+9, n=0; hexdigitp (s); s++, n++)
137 if (*s || (n&1))
138 return GNUPG_Invalid_Id; /* invalid or odd number of digits */
139 n /= 2;
140 if (!n || n > SC_PKCS15_MAX_ID_SIZE)
141 return GNUPG_Invalid_Id; /* empty or too large */
142 for (s=idstr+9, n=0; *s; s += 2, n++)
143 id->value[n] = xtoi_2 (s);
144 id->len = n;
145 return 0;
149 /* See card.c for interface description */
150 static int
151 p15_read_cert (CARD card, const char *certidstr,
152 unsigned char **cert, size_t *ncert)
154 struct sc_pkcs15_object *tmpobj;
155 struct sc_pkcs15_id certid;
156 struct sc_pkcs15_cert_info *certinfo;
157 struct sc_pkcs15_cert *certder;
158 int rc;
160 if (!card || !certidstr || !cert || !ncert)
161 return GNUPG_Invalid_Value;
162 if (!card->p15card)
163 return GNUPG_No_PKCS15_App;
165 rc = idstr_to_id (certidstr, &certid);
166 if (rc)
167 return rc;
169 rc = sc_pkcs15_find_cert_by_id (card->p15card, &certid, &tmpobj);
170 if (rc)
172 log_info ("certificate '%s' not found: %s\n",
173 certidstr, sc_strerror (rc));
174 return -1;
176 certinfo = tmpobj->data;
177 rc = sc_pkcs15_read_certificate (card->p15card, certinfo, &certder);
178 if (rc)
180 log_info ("failed to read certificate '%s': %s\n",
181 certidstr, sc_strerror (rc));
182 return GNUPG_Card_Error;
185 *cert = xtrymalloc (certder->data_len);
186 if (!*cert)
188 sc_pkcs15_free_certificate (certder);
189 return GNUPG_Out_Of_Core;
191 memcpy (*cert, certder->data, certder->data_len);
192 *ncert = certder->data_len;
193 sc_pkcs15_free_certificate (certder);
194 return 0;
201 static int
202 p15_prepare_key (CARD card, const char *keyidstr,
203 int (pincb)(void*, const char *, char **),
204 void *pincb_arg, struct sc_pkcs15_object **r_keyobj)
206 struct sc_pkcs15_id keyid;
207 struct sc_pkcs15_pin_info *pin;
208 struct sc_pkcs15_object *keyobj, *pinobj;
209 char *pinvalue;
210 int rc;
212 rc = idstr_to_id (keyidstr, &keyid);
213 if (rc)
214 return rc;
216 rc = sc_pkcs15_find_prkey_by_id (card->p15card, &keyid, &keyobj);
217 if (rc < 0)
219 log_error ("private key not found: %s\n", sc_strerror(rc));
220 return GNUPG_No_Secret_Key;
223 rc = sc_pkcs15_find_pin_by_auth_id (card->p15card,
224 &keyobj->auth_id, &pinobj);
225 if (rc)
227 log_error ("failed to find PIN by auth ID: %s\n", sc_strerror (rc));
228 return GNUPG_Bad_PIN_Method;
230 pin = pinobj->data;
232 /* Fixme: pack this into a verification loop */
233 /* Fixme: we might want to pass pin->min_length and
234 pin->stored_length */
235 rc = pincb (pincb_arg, pinobj->label, &pinvalue);
236 if (rc)
238 log_info ("PIN callback returned error: %s\n", gnupg_strerror (rc));
239 return rc;
242 rc = sc_pkcs15_verify_pin (card->p15card, pin,
243 pinvalue, strlen (pinvalue));
244 xfree (pinvalue);
245 if (rc)
247 log_info ("PIN verification failed: %s\n", sc_strerror (rc));
248 return GNUPG_Bad_PIN;
251 /* fixme: check wheter we need to release KEYOBJ in case of an error */
252 *r_keyobj = keyobj;
253 return 0;
257 /* See card.c for interface description */
258 static int
259 p15_sign (CARD card, const char *keyidstr, int hashalgo,
260 int (pincb)(void*, const char *, char **),
261 void *pincb_arg,
262 const void *indata, size_t indatalen,
263 void **outdata, size_t *outdatalen )
265 unsigned int cryptflags;
266 struct sc_pkcs15_object *keyobj;
267 int rc;
268 unsigned char *outbuf = NULL;
269 size_t outbuflen;
271 if (hashalgo != GCRY_MD_SHA1)
272 return GNUPG_Unsupported_Algorithm;
274 rc = p15_prepare_key (card, keyidstr, pincb, pincb_arg, &keyobj);
275 if (rc)
276 return rc;
278 cryptflags = SC_ALGORITHM_RSA_PAD_PKCS1;
280 outbuflen = 1024;
281 outbuf = xtrymalloc (outbuflen);
282 if (!outbuf)
283 return GNUPG_Out_Of_Core;
285 rc = sc_pkcs15_compute_signature (card->p15card, keyobj,
286 cryptflags,
287 indata, indatalen,
288 outbuf, outbuflen );
289 if (rc < 0)
291 log_error ("failed to create signature: %s\n", sc_strerror (rc));
292 rc = GNUPG_Card_Error;
294 else
296 *outdatalen = rc;
297 *outdata = outbuf;
298 outbuf = NULL;
299 rc = 0;
302 xfree (outbuf);
303 return rc;
307 /* See card.c for description */
308 static int
309 p15_decipher (CARD card, const char *keyidstr,
310 int (pincb)(void*, const char *, char **),
311 void *pincb_arg,
312 const void *indata, size_t indatalen,
313 void **outdata, size_t *outdatalen )
315 struct sc_pkcs15_object *keyobj;
316 int rc;
317 unsigned char *outbuf = NULL;
318 size_t outbuflen;
320 rc = p15_prepare_key (card, keyidstr, pincb, pincb_arg, &keyobj);
321 if (rc)
322 return rc;
324 if (card && card->scard && card->scard->driver
325 && !strcasecmp (card->scard->driver->short_name, "tcos"))
327 /* very ugly hack to force the use of a local key. We need this
328 until we have fixed the initialization code for TCOS cards */
329 struct sc_pkcs15_prkey_info *prkey = keyobj->data;
330 if ( !(prkey->key_reference & 0x80))
332 prkey->key_reference |= 0x80;
333 log_debug ("using TCOS hack to force the use of local keys\n");
335 if (*keyidstr && keyidstr[strlen(keyidstr)-1] == '6')
337 prkey->key_reference |= 1;
338 log_debug ("warning: using even more TCOS hacks\n");
342 outbuflen = indatalen < 256? 256 : indatalen;
343 outbuf = xtrymalloc (outbuflen);
344 if (!outbuf)
345 return GNUPG_Out_Of_Core;
347 rc = sc_pkcs15_decipher (card->p15card, keyobj,
348 indata, indatalen,
349 outbuf, outbuflen);
350 if (rc < 0)
352 log_error ("failed to decipher the data: %s\n", sc_strerror (rc));
353 rc = GNUPG_Card_Error;
355 else
357 *outdatalen = rc;
358 *outdata = outbuf;
359 outbuf = NULL;
360 rc = 0;
363 xfree (outbuf);
364 return rc;
369 /* Bind our operations to the card */
370 void
371 card_p15_bind (CARD card)
373 card->fnc.enum_keypairs = p15_enum_keypairs;
374 card->fnc.read_cert = p15_read_cert;
375 card->fnc.sign = p15_sign;
376 card->fnc.decipher = p15_decipher;