2006-12-18 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / scd / card-p15.c
blob63d537d5adbcec89e2a05ff8a29cb41dddf49805
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19 * USA.
22 #include <config.h>
23 #include <errno.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <time.h>
29 #ifdef HAVE_OPENSC
30 #include <opensc/pkcs15.h>
32 #include "scdaemon.h"
33 #include <ksba.h>
34 #include "card-common.h"
37 struct p15private_s {
38 int n_prkey_rsa_objs;
39 struct sc_pkcs15_object *prkey_rsa_objs[32];
40 int n_cert_objs;
41 struct sc_pkcs15_object *cert_objs[32];
45 /* Allocate private data. */
46 static int
47 init_private_data (CARD card)
49 struct p15private_s *priv;
50 int rc;
52 if (card->p15priv)
53 return 0; /* already done. */
55 priv = xtrycalloc (1, sizeof *priv);
56 if (!priv)
57 return gpg_error (gpg_err_code_from_errno (errno));
59 /* OpenSC (0.7.0) is a bit strange in that the get_objects functions
60 tries to be a bit too clever and implicitly does an enumeration
61 which eventually leads to the fact that every call to this
62 fucntion returns one more macthing object. The old code in
63 p15_enum_keypairs assume that it would alwyas return the same
64 numer of objects and used this to figure out what the last object
65 enumerated is. We now do an enum_objects just once and keep it
66 in the private data. */
67 rc = sc_pkcs15_get_objects (card->p15card, SC_PKCS15_TYPE_PRKEY_RSA,
68 priv->prkey_rsa_objs,
69 DIM (priv->prkey_rsa_objs));
70 if (rc < 0)
72 log_error ("private keys enumeration failed: %s\n", sc_strerror (rc));
73 xfree (priv);
74 return gpg_error (GPG_ERR_CARD);
76 priv->n_prkey_rsa_objs = rc;
78 /* Read all certificate objects. */
79 rc = sc_pkcs15_get_objects (card->p15card, SC_PKCS15_TYPE_CERT_X509,
80 priv->cert_objs,
81 DIM (priv->cert_objs));
82 if (rc < 0)
84 log_error ("private keys enumeration failed: %s\n", sc_strerror (rc));
85 xfree (priv);
86 return gpg_error (GPG_ERR_CARD);
88 priv->n_cert_objs = rc;
90 card->p15priv = priv;
91 return 0;
95 /* Release private data used in this module. */
96 void
97 p15_release_private_data (CARD card)
99 if (!card->p15priv)
100 return;
101 xfree (card->p15priv);
102 card->p15priv = NULL;
107 /* See card.c for interface description */
108 static int
109 p15_enum_keypairs (CARD card, int idx,
110 unsigned char *keygrip, char **keyid)
112 int rc;
113 struct p15private_s *priv;
114 struct sc_pkcs15_object *tmpobj;
115 int nobjs;
116 struct sc_pkcs15_prkey_info *pinfo;
117 struct sc_pkcs15_cert_info *certinfo;
118 struct sc_pkcs15_cert *certder;
119 ksba_cert_t cert;
121 rc = init_private_data (card);
122 if (rc)
123 return rc;
124 priv = card->p15priv;
125 nobjs = priv->n_prkey_rsa_objs;
126 rc = 0;
127 if (idx >= nobjs)
128 return -1;
129 pinfo = priv->prkey_rsa_objs[idx]->data;
131 /* now we need to read the certificate so that we can calculate the
132 keygrip */
133 rc = sc_pkcs15_find_cert_by_id (card->p15card, &pinfo->id, &tmpobj);
134 if (rc)
136 log_info ("certificate for private key %d not found: %s\n",
137 idx, sc_strerror (rc));
138 /* note, that we return the ID anyway */
139 rc = gpg_error (GPG_ERR_MISSING_CERT);
140 goto return_keyid;
142 certinfo = tmpobj->data;
143 rc = sc_pkcs15_read_certificate (card->p15card, certinfo, &certder);
144 if (rc)
146 log_info ("failed to read certificate for private key %d: %s\n",
147 idx, sc_strerror (rc));
148 return gpg_error (GPG_ERR_CARD);
151 rc = ksba_cert_new (&cert);
152 if (rc)
154 sc_pkcs15_free_certificate (certder);
155 return rc;
157 rc = ksba_cert_init_from_mem (cert, certder->data, certder->data_len);
158 sc_pkcs15_free_certificate (certder);
159 if (rc)
161 log_error ("failed to parse the certificate for private key %d: %s\n",
162 idx, gpg_strerror (rc));
163 ksba_cert_release (cert);
164 return rc;
166 if (card_help_get_keygrip (cert, keygrip))
168 log_error ("failed to calculate the keygrip of private key %d\n", idx);
169 ksba_cert_release (cert);
170 return gpg_error (GPG_ERR_CARD);
172 ksba_cert_release (cert);
174 rc = 0;
175 return_keyid:
176 if (keyid)
178 char *p;
179 int i;
181 *keyid = p = xtrymalloc (9+pinfo->id.len*2+1);
182 if (!*keyid)
183 return gpg_error (gpg_err_code_from_errno (errno));
184 p = stpcpy (p, "P15-5015.");
185 for (i=0; i < pinfo->id.len; i++, p += 2)
186 sprintf (p, "%02X", pinfo->id.value[i]);
187 *p = 0;
190 return rc;
193 /* See card.c for interface description */
194 static int
195 p15_enum_certs (CARD card, int idx, char **certid, int *type)
197 int rc;
198 struct p15private_s *priv;
199 struct sc_pkcs15_object *obj;
200 struct sc_pkcs15_cert_info *cinfo;
201 int nobjs;
203 rc = init_private_data (card);
204 if (rc)
205 return rc;
206 priv = card->p15priv;
207 nobjs = priv->n_cert_objs;
208 rc = 0;
209 if (idx >= nobjs)
210 return -1;
211 obj = priv->cert_objs[idx];
212 cinfo = obj->data;
214 if (certid)
216 char *p;
217 int i;
219 *certid = p = xtrymalloc (9+cinfo->id.len*2+1);
220 if (!*certid)
221 return gpg_error (gpg_err_code_from_errno (errno));
222 p = stpcpy (p, "P15-5015.");
223 for (i=0; i < cinfo->id.len; i++, p += 2)
224 sprintf (p, "%02X", cinfo->id.value[i]);
225 *p = 0;
227 if (type)
229 if (!obj->df)
230 *type = 0; /* unknown */
231 else if (obj->df->type == SC_PKCS15_CDF)
232 *type = 100;
233 else if (obj->df->type == SC_PKCS15_CDF_TRUSTED)
234 *type = 101;
235 else if (obj->df->type == SC_PKCS15_CDF_USEFUL)
236 *type = 102;
237 else
238 *type = 0; /* error -> unknown */
241 return rc;
246 static int
247 idstr_to_id (const char *idstr, struct sc_pkcs15_id *id)
249 const char *s;
250 int n;
252 /* For now we only support the standard DF */
253 if (strncmp (idstr, "P15-5015.", 9) )
254 return gpg_error (GPG_ERR_INV_ID);
255 for (s=idstr+9, n=0; hexdigitp (s); s++, n++)
257 if (*s || (n&1))
258 return gpg_error (GPG_ERR_INV_ID); /*invalid or odd number of digits*/
259 n /= 2;
260 if (!n || n > SC_PKCS15_MAX_ID_SIZE)
261 return gpg_error (GPG_ERR_INV_ID); /* empty or too large */
262 for (s=idstr+9, n=0; *s; s += 2, n++)
263 id->value[n] = xtoi_2 (s);
264 id->len = n;
265 return 0;
269 /* See card.c for interface description */
270 static int
271 p15_read_cert (CARD card, const char *certidstr,
272 unsigned char **cert, size_t *ncert)
274 struct sc_pkcs15_object *tmpobj;
275 struct sc_pkcs15_id certid;
276 struct sc_pkcs15_cert_info *certinfo;
277 struct sc_pkcs15_cert *certder;
278 int rc;
280 if (!card || !certidstr || !cert || !ncert)
281 return gpg_error (GPG_ERR_INV_VALUE);
282 if (!card->p15card)
283 return gpg_error (GPG_ERR_NO_PKCS15_APP);
285 rc = idstr_to_id (certidstr, &certid);
286 if (rc)
287 return rc;
289 rc = sc_pkcs15_find_cert_by_id (card->p15card, &certid, &tmpobj);
290 if (rc)
292 log_info ("certificate '%s' not found: %s\n",
293 certidstr, sc_strerror (rc));
294 return -1;
296 certinfo = tmpobj->data;
297 rc = sc_pkcs15_read_certificate (card->p15card, certinfo, &certder);
298 if (rc)
300 log_info ("failed to read certificate '%s': %s\n",
301 certidstr, sc_strerror (rc));
302 return gpg_error (GPG_ERR_CARD);
305 *cert = xtrymalloc (certder->data_len);
306 if (!*cert)
308 gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
309 sc_pkcs15_free_certificate (certder);
310 return tmperr;
312 memcpy (*cert, certder->data, certder->data_len);
313 *ncert = certder->data_len;
314 sc_pkcs15_free_certificate (certder);
315 return 0;
322 static int
323 p15_prepare_key (CARD card, const char *keyidstr,
324 int (pincb)(void*, const char *, char **),
325 void *pincb_arg, struct sc_pkcs15_object **r_keyobj)
327 struct sc_pkcs15_id keyid;
328 struct sc_pkcs15_pin_info *pin;
329 struct sc_pkcs15_object *keyobj, *pinobj;
330 char *pinvalue;
331 int rc;
333 rc = idstr_to_id (keyidstr, &keyid);
334 if (rc)
335 return rc;
337 rc = sc_pkcs15_find_prkey_by_id (card->p15card, &keyid, &keyobj);
338 if (rc < 0)
340 log_error ("private key not found: %s\n", sc_strerror(rc));
341 return gpg_error (GPG_ERR_NO_SECKEY);
344 rc = sc_pkcs15_find_pin_by_auth_id (card->p15card,
345 &keyobj->auth_id, &pinobj);
346 if (rc)
348 log_error ("failed to find PIN by auth ID: %s\n", sc_strerror (rc));
349 return gpg_error (GPG_ERR_BAD_PIN_METHOD);
351 pin = pinobj->data;
353 /* Fixme: pack this into a verification loop */
354 /* Fixme: we might want to pass pin->min_length and
355 pin->stored_length */
356 rc = pincb (pincb_arg, pinobj->label, &pinvalue);
357 if (rc)
359 log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
360 return rc;
363 rc = sc_pkcs15_verify_pin (card->p15card, pin,
364 pinvalue, strlen (pinvalue));
365 xfree (pinvalue);
366 if (rc)
368 log_info ("PIN verification failed: %s\n", sc_strerror (rc));
369 return gpg_error (GPG_ERR_BAD_PIN);
372 /* fixme: check wheter we need to release KEYOBJ in case of an error */
373 *r_keyobj = keyobj;
374 return 0;
378 /* See card.c for interface description */
379 static int
380 p15_sign (CARD card, const char *keyidstr, int hashalgo,
381 int (pincb)(void*, const char *, char **),
382 void *pincb_arg,
383 const void *indata, size_t indatalen,
384 unsigned char **outdata, size_t *outdatalen )
386 unsigned int cryptflags;
387 struct sc_pkcs15_object *keyobj;
388 int rc;
389 unsigned char *outbuf = NULL;
390 size_t outbuflen;
392 if (hashalgo != GCRY_MD_SHA1)
393 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
395 rc = p15_prepare_key (card, keyidstr, pincb, pincb_arg, &keyobj);
396 if (rc)
397 return rc;
399 cryptflags = SC_ALGORITHM_RSA_PAD_PKCS1;
401 outbuflen = 1024;
402 outbuf = xtrymalloc (outbuflen);
403 if (!outbuf)
404 return gpg_error (gpg_err_code_from_errno (errno));
406 rc = sc_pkcs15_compute_signature (card->p15card, keyobj,
407 cryptflags,
408 indata, indatalen,
409 outbuf, outbuflen );
410 if (rc < 0)
412 log_error ("failed to create signature: %s\n", sc_strerror (rc));
413 rc = gpg_error (GPG_ERR_CARD);
415 else
417 *outdatalen = rc;
418 *outdata = outbuf;
419 outbuf = NULL;
420 rc = 0;
423 xfree (outbuf);
424 return rc;
428 /* See card.c for description */
429 static int
430 p15_decipher (CARD card, const char *keyidstr,
431 int (pincb)(void*, const char *, char **),
432 void *pincb_arg,
433 const void *indata, size_t indatalen,
434 unsigned char **outdata, size_t *outdatalen )
436 struct sc_pkcs15_object *keyobj;
437 int rc;
438 unsigned char *outbuf = NULL;
439 size_t outbuflen;
441 rc = p15_prepare_key (card, keyidstr, pincb, pincb_arg, &keyobj);
442 if (rc)
443 return rc;
445 if (card && card->scard && card->scard->driver
446 && !strcasecmp (card->scard->driver->short_name, "tcos"))
448 /* very ugly hack to force the use of a local key. We need this
449 until we have fixed the initialization code for TCOS cards */
450 struct sc_pkcs15_prkey_info *prkey = keyobj->data;
451 if ( !(prkey->key_reference & 0x80))
453 prkey->key_reference |= 0x80;
454 log_debug ("using TCOS hack to force the use of local keys\n");
456 if (*keyidstr && keyidstr[strlen(keyidstr)-1] == '6')
458 prkey->key_reference |= 1;
459 log_debug ("warning: using even more TCOS hacks\n");
463 outbuflen = indatalen < 256? 256 : indatalen;
464 outbuf = xtrymalloc (outbuflen);
465 if (!outbuf)
466 return gpg_error (gpg_err_code_from_errno (errno));
468 rc = sc_pkcs15_decipher (card->p15card, keyobj,
470 indata, indatalen,
471 outbuf, outbuflen);
472 if (rc < 0)
474 log_error ("failed to decipher the data: %s\n", sc_strerror (rc));
475 rc = gpg_error (GPG_ERR_CARD);
477 else
479 *outdatalen = rc;
480 *outdata = outbuf;
481 outbuf = NULL;
482 rc = 0;
485 xfree (outbuf);
486 return rc;
491 /* Bind our operations to the card */
492 void
493 card_p15_bind (CARD card)
495 card->fnc.enum_keypairs = p15_enum_keypairs;
496 card->fnc.enum_certs = p15_enum_certs;
497 card->fnc.read_cert = p15_read_cert;
498 card->fnc.sign = p15_sign;
499 card->fnc.decipher = p15_decipher;
501 #endif /*HAVE_OPENSC*/