2008-02-09 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / scd / card-p15.c
blobb958253735bae4ae23238f4307917467e00e39a9
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 3 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, see <http://www.gnu.org/licenses/>.
20 #include <config.h>
21 #include <errno.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <time.h>
27 #ifdef HAVE_OPENSC
28 #include <opensc/pkcs15.h>
30 #include "scdaemon.h"
31 #include <ksba.h>
32 #include "card-common.h"
35 struct p15private_s {
36 int n_prkey_rsa_objs;
37 struct sc_pkcs15_object *prkey_rsa_objs[32];
38 int n_cert_objs;
39 struct sc_pkcs15_object *cert_objs[32];
43 /* Allocate private data. */
44 static int
45 init_private_data (CARD card)
47 struct p15private_s *priv;
48 int rc;
50 if (card->p15priv)
51 return 0; /* already done. */
53 priv = xtrycalloc (1, sizeof *priv);
54 if (!priv)
55 return gpg_error (gpg_err_code_from_errno (errno));
57 /* OpenSC (0.7.0) is a bit strange in that the get_objects functions
58 tries to be a bit too clever and implicitly does an enumeration
59 which eventually leads to the fact that every call to this
60 fucntion returns one more macthing object. The old code in
61 p15_enum_keypairs assume that it would alwyas return the same
62 numer of objects and used this to figure out what the last object
63 enumerated is. We now do an enum_objects just once and keep it
64 in the private data. */
65 rc = sc_pkcs15_get_objects (card->p15card, SC_PKCS15_TYPE_PRKEY_RSA,
66 priv->prkey_rsa_objs,
67 DIM (priv->prkey_rsa_objs));
68 if (rc < 0)
70 log_error ("private keys enumeration failed: %s\n", sc_strerror (rc));
71 xfree (priv);
72 return gpg_error (GPG_ERR_CARD);
74 priv->n_prkey_rsa_objs = rc;
76 /* Read all certificate objects. */
77 rc = sc_pkcs15_get_objects (card->p15card, SC_PKCS15_TYPE_CERT_X509,
78 priv->cert_objs,
79 DIM (priv->cert_objs));
80 if (rc < 0)
82 log_error ("private keys enumeration failed: %s\n", sc_strerror (rc));
83 xfree (priv);
84 return gpg_error (GPG_ERR_CARD);
86 priv->n_cert_objs = rc;
88 card->p15priv = priv;
89 return 0;
93 /* Release private data used in this module. */
94 void
95 p15_release_private_data (CARD card)
97 if (!card->p15priv)
98 return;
99 xfree (card->p15priv);
100 card->p15priv = NULL;
105 /* See card.c for interface description */
106 static int
107 p15_enum_keypairs (CARD card, int idx,
108 unsigned char *keygrip, char **keyid)
110 int rc;
111 struct p15private_s *priv;
112 struct sc_pkcs15_object *tmpobj;
113 int nobjs;
114 struct sc_pkcs15_prkey_info *pinfo;
115 struct sc_pkcs15_cert_info *certinfo;
116 struct sc_pkcs15_cert *certder;
117 ksba_cert_t cert;
119 rc = init_private_data (card);
120 if (rc)
121 return rc;
122 priv = card->p15priv;
123 nobjs = priv->n_prkey_rsa_objs;
124 rc = 0;
125 if (idx >= nobjs)
126 return -1;
127 pinfo = priv->prkey_rsa_objs[idx]->data;
129 /* now we need to read the certificate so that we can calculate the
130 keygrip */
131 rc = sc_pkcs15_find_cert_by_id (card->p15card, &pinfo->id, &tmpobj);
132 if (rc)
134 log_info ("certificate for private key %d not found: %s\n",
135 idx, sc_strerror (rc));
136 /* note, that we return the ID anyway */
137 rc = gpg_error (GPG_ERR_MISSING_CERT);
138 goto return_keyid;
140 certinfo = tmpobj->data;
141 rc = sc_pkcs15_read_certificate (card->p15card, certinfo, &certder);
142 if (rc)
144 log_info ("failed to read certificate for private key %d: %s\n",
145 idx, sc_strerror (rc));
146 return gpg_error (GPG_ERR_CARD);
149 rc = ksba_cert_new (&cert);
150 if (rc)
152 sc_pkcs15_free_certificate (certder);
153 return rc;
155 rc = ksba_cert_init_from_mem (cert, certder->data, certder->data_len);
156 sc_pkcs15_free_certificate (certder);
157 if (rc)
159 log_error ("failed to parse the certificate for private key %d: %s\n",
160 idx, gpg_strerror (rc));
161 ksba_cert_release (cert);
162 return rc;
164 if (card_help_get_keygrip (cert, keygrip))
166 log_error ("failed to calculate the keygrip of private key %d\n", idx);
167 ksba_cert_release (cert);
168 return gpg_error (GPG_ERR_CARD);
170 ksba_cert_release (cert);
172 rc = 0;
173 return_keyid:
174 if (keyid)
176 char *p;
177 int i;
179 *keyid = p = xtrymalloc (9+pinfo->id.len*2+1);
180 if (!*keyid)
181 return gpg_error (gpg_err_code_from_errno (errno));
182 p = stpcpy (p, "P15-5015.");
183 for (i=0; i < pinfo->id.len; i++, p += 2)
184 sprintf (p, "%02X", pinfo->id.value[i]);
185 *p = 0;
188 return rc;
191 /* See card.c for interface description */
192 static int
193 p15_enum_certs (CARD card, int idx, char **certid, int *type)
195 int rc;
196 struct p15private_s *priv;
197 struct sc_pkcs15_object *obj;
198 struct sc_pkcs15_cert_info *cinfo;
199 int nobjs;
201 rc = init_private_data (card);
202 if (rc)
203 return rc;
204 priv = card->p15priv;
205 nobjs = priv->n_cert_objs;
206 rc = 0;
207 if (idx >= nobjs)
208 return -1;
209 obj = priv->cert_objs[idx];
210 cinfo = obj->data;
212 if (certid)
214 char *p;
215 int i;
217 *certid = p = xtrymalloc (9+cinfo->id.len*2+1);
218 if (!*certid)
219 return gpg_error (gpg_err_code_from_errno (errno));
220 p = stpcpy (p, "P15-5015.");
221 for (i=0; i < cinfo->id.len; i++, p += 2)
222 sprintf (p, "%02X", cinfo->id.value[i]);
223 *p = 0;
225 if (type)
227 if (!obj->df)
228 *type = 0; /* unknown */
229 else if (obj->df->type == SC_PKCS15_CDF)
230 *type = 100;
231 else if (obj->df->type == SC_PKCS15_CDF_TRUSTED)
232 *type = 101;
233 else if (obj->df->type == SC_PKCS15_CDF_USEFUL)
234 *type = 102;
235 else
236 *type = 0; /* error -> unknown */
239 return rc;
244 static int
245 idstr_to_id (const char *idstr, struct sc_pkcs15_id *id)
247 const char *s;
248 int n;
250 /* For now we only support the standard DF */
251 if (strncmp (idstr, "P15-5015.", 9) )
252 return gpg_error (GPG_ERR_INV_ID);
253 for (s=idstr+9, n=0; hexdigitp (s); s++, n++)
255 if (*s || (n&1))
256 return gpg_error (GPG_ERR_INV_ID); /*invalid or odd number of digits*/
257 n /= 2;
258 if (!n || n > SC_PKCS15_MAX_ID_SIZE)
259 return gpg_error (GPG_ERR_INV_ID); /* empty or too large */
260 for (s=idstr+9, n=0; *s; s += 2, n++)
261 id->value[n] = xtoi_2 (s);
262 id->len = n;
263 return 0;
267 /* See card.c for interface description */
268 static int
269 p15_read_cert (CARD card, const char *certidstr,
270 unsigned char **cert, size_t *ncert)
272 struct sc_pkcs15_object *tmpobj;
273 struct sc_pkcs15_id certid;
274 struct sc_pkcs15_cert_info *certinfo;
275 struct sc_pkcs15_cert *certder;
276 int rc;
278 if (!card || !certidstr || !cert || !ncert)
279 return gpg_error (GPG_ERR_INV_VALUE);
280 if (!card->p15card)
281 return gpg_error (GPG_ERR_NO_PKCS15_APP);
283 rc = idstr_to_id (certidstr, &certid);
284 if (rc)
285 return rc;
287 rc = sc_pkcs15_find_cert_by_id (card->p15card, &certid, &tmpobj);
288 if (rc)
290 log_info ("certificate '%s' not found: %s\n",
291 certidstr, sc_strerror (rc));
292 return -1;
294 certinfo = tmpobj->data;
295 rc = sc_pkcs15_read_certificate (card->p15card, certinfo, &certder);
296 if (rc)
298 log_info ("failed to read certificate '%s': %s\n",
299 certidstr, sc_strerror (rc));
300 return gpg_error (GPG_ERR_CARD);
303 *cert = xtrymalloc (certder->data_len);
304 if (!*cert)
306 gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
307 sc_pkcs15_free_certificate (certder);
308 return tmperr;
310 memcpy (*cert, certder->data, certder->data_len);
311 *ncert = certder->data_len;
312 sc_pkcs15_free_certificate (certder);
313 return 0;
320 static int
321 p15_prepare_key (CARD card, const char *keyidstr,
322 int (pincb)(void*, const char *, char **),
323 void *pincb_arg, struct sc_pkcs15_object **r_keyobj)
325 struct sc_pkcs15_id keyid;
326 struct sc_pkcs15_pin_info *pin;
327 struct sc_pkcs15_object *keyobj, *pinobj;
328 char *pinvalue;
329 int rc;
331 rc = idstr_to_id (keyidstr, &keyid);
332 if (rc)
333 return rc;
335 rc = sc_pkcs15_find_prkey_by_id (card->p15card, &keyid, &keyobj);
336 if (rc < 0)
338 log_error ("private key not found: %s\n", sc_strerror(rc));
339 return gpg_error (GPG_ERR_NO_SECKEY);
342 rc = sc_pkcs15_find_pin_by_auth_id (card->p15card,
343 &keyobj->auth_id, &pinobj);
344 if (rc)
346 log_error ("failed to find PIN by auth ID: %s\n", sc_strerror (rc));
347 return gpg_error (GPG_ERR_BAD_PIN_METHOD);
349 pin = pinobj->data;
351 /* Fixme: pack this into a verification loop */
352 /* Fixme: we might want to pass pin->min_length and
353 pin->stored_length */
354 rc = pincb (pincb_arg, pinobj->label, &pinvalue);
355 if (rc)
357 log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
358 return rc;
361 rc = sc_pkcs15_verify_pin (card->p15card, pin,
362 pinvalue, strlen (pinvalue));
363 xfree (pinvalue);
364 if (rc)
366 log_info ("PIN verification failed: %s\n", sc_strerror (rc));
367 return gpg_error (GPG_ERR_BAD_PIN);
370 /* fixme: check wheter we need to release KEYOBJ in case of an error */
371 *r_keyobj = keyobj;
372 return 0;
376 /* See card.c for interface description */
377 static int
378 p15_sign (CARD card, const char *keyidstr, int hashalgo,
379 int (pincb)(void*, const char *, char **),
380 void *pincb_arg,
381 const void *indata, size_t indatalen,
382 unsigned char **outdata, size_t *outdatalen )
384 unsigned int cryptflags;
385 struct sc_pkcs15_object *keyobj;
386 int rc;
387 unsigned char *outbuf = NULL;
388 size_t outbuflen;
390 if (hashalgo != GCRY_MD_SHA1)
391 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
393 rc = p15_prepare_key (card, keyidstr, pincb, pincb_arg, &keyobj);
394 if (rc)
395 return rc;
397 cryptflags = SC_ALGORITHM_RSA_PAD_PKCS1;
399 outbuflen = 1024;
400 outbuf = xtrymalloc (outbuflen);
401 if (!outbuf)
402 return gpg_error (gpg_err_code_from_errno (errno));
404 rc = sc_pkcs15_compute_signature (card->p15card, keyobj,
405 cryptflags,
406 indata, indatalen,
407 outbuf, outbuflen );
408 if (rc < 0)
410 log_error ("failed to create signature: %s\n", sc_strerror (rc));
411 rc = gpg_error (GPG_ERR_CARD);
413 else
415 *outdatalen = rc;
416 *outdata = outbuf;
417 outbuf = NULL;
418 rc = 0;
421 xfree (outbuf);
422 return rc;
426 /* See card.c for description */
427 static int
428 p15_decipher (CARD card, const char *keyidstr,
429 int (pincb)(void*, const char *, char **),
430 void *pincb_arg,
431 const void *indata, size_t indatalen,
432 unsigned char **outdata, size_t *outdatalen )
434 struct sc_pkcs15_object *keyobj;
435 int rc;
436 unsigned char *outbuf = NULL;
437 size_t outbuflen;
439 rc = p15_prepare_key (card, keyidstr, pincb, pincb_arg, &keyobj);
440 if (rc)
441 return rc;
443 if (card && card->scard && card->scard->driver
444 && !strcasecmp (card->scard->driver->short_name, "tcos"))
446 /* very ugly hack to force the use of a local key. We need this
447 until we have fixed the initialization code for TCOS cards */
448 struct sc_pkcs15_prkey_info *prkey = keyobj->data;
449 if ( !(prkey->key_reference & 0x80))
451 prkey->key_reference |= 0x80;
452 log_debug ("using TCOS hack to force the use of local keys\n");
454 if (*keyidstr && keyidstr[strlen(keyidstr)-1] == '6')
456 prkey->key_reference |= 1;
457 log_debug ("warning: using even more TCOS hacks\n");
461 outbuflen = indatalen < 256? 256 : indatalen;
462 outbuf = xtrymalloc (outbuflen);
463 if (!outbuf)
464 return gpg_error (gpg_err_code_from_errno (errno));
466 rc = sc_pkcs15_decipher (card->p15card, keyobj,
468 indata, indatalen,
469 outbuf, outbuflen);
470 if (rc < 0)
472 log_error ("failed to decipher the data: %s\n", sc_strerror (rc));
473 rc = gpg_error (GPG_ERR_CARD);
475 else
477 *outdatalen = rc;
478 *outdata = outbuf;
479 outbuf = NULL;
480 rc = 0;
483 xfree (outbuf);
484 return rc;
489 /* Bind our operations to the card */
490 void
491 card_p15_bind (CARD card)
493 card->fnc.enum_keypairs = p15_enum_keypairs;
494 card->fnc.enum_certs = p15_enum_certs;
495 card->fnc.read_cert = p15_read_cert;
496 card->fnc.sign = p15_sign;
497 card->fnc.decipher = p15_decipher;
499 #endif /*HAVE_OPENSC*/