~ubuntu-branches/ubuntu/dapper/gnupg2/dapper

« back to all changes in this revision

Viewing changes to scd/card-p15.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Mueller
  • Date: 2005-03-29 10:30:32 UTC
  • Revision ID: james.westby@ubuntu.com-20050329103032-sj42n2ain3ipx310
Tags: upstream-1.9.15
ImportĀ upstreamĀ versionĀ 1.9.15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* card-p15.c - PKCS-15 based card access
 
2
 *      Copyright (C) 2002 Free Software Foundation, Inc.
 
3
 *
 
4
 * This file is part of GnuPG.
 
5
 *
 
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.
 
10
 *
 
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.
 
15
 *
 
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
 
19
 */
 
20
 
 
21
#include <config.h>
 
22
#include <errno.h>
 
23
#include <stdio.h>
 
24
#include <stdlib.h>
 
25
#include <string.h>
 
26
#include <time.h>
 
27
 
 
28
#ifdef HAVE_OPENSC
 
29
#include <opensc/pkcs15.h>
 
30
 
 
31
#include "scdaemon.h"
 
32
#include <ksba.h>
 
33
#include "card-common.h"
 
34
 
 
35
 
 
36
struct p15private_s {
 
37
  int n_prkey_rsa_objs;
 
38
  struct sc_pkcs15_object *prkey_rsa_objs[32];
 
39
  int n_cert_objs;
 
40
  struct sc_pkcs15_object *cert_objs[32];
 
41
};
 
42
 
 
43
 
 
44
/* Allocate private data. */
 
45
static int 
 
46
init_private_data (CARD card)
 
47
{
 
48
  struct p15private_s *priv;
 
49
  int rc;
 
50
 
 
51
  if (card->p15priv)
 
52
    return 0; /* already done. */
 
53
 
 
54
  priv = xtrycalloc (1, sizeof *priv);
 
55
  if (!priv)
 
56
    return gpg_error (gpg_err_code_from_errno (errno));
 
57
 
 
58
  /* OpenSC (0.7.0) is a bit strange in that the get_objects functions
 
59
     tries to be a bit too clever and implicitly does an enumeration
 
60
     which eventually leads to the fact that every call to this
 
61
     fucntion returns one more macthing object.  The old code in
 
62
     p15_enum_keypairs assume that it would alwyas return the same
 
63
     numer of objects and used this to figure out what the last object
 
64
     enumerated is.  We now do an enum_objects just once and keep it
 
65
     in the private data. */
 
66
  rc = sc_pkcs15_get_objects (card->p15card, SC_PKCS15_TYPE_PRKEY_RSA, 
 
67
                              priv->prkey_rsa_objs,
 
68
                              DIM (priv->prkey_rsa_objs));
 
69
  if (rc < 0) 
 
70
    {
 
71
      log_error ("private keys enumeration failed: %s\n", sc_strerror (rc));
 
72
      xfree (priv);
 
73
      return gpg_error (GPG_ERR_CARD);
 
74
    }
 
75
  priv->n_prkey_rsa_objs = rc;
 
76
 
 
77
  /* Read all certificate objects. */
 
78
  rc = sc_pkcs15_get_objects (card->p15card, SC_PKCS15_TYPE_CERT_X509, 
 
79
                              priv->cert_objs,
 
80
                              DIM (priv->cert_objs));
 
81
  if (rc < 0) 
 
82
    {
 
83
      log_error ("private keys enumeration failed: %s\n", sc_strerror (rc));
 
84
      xfree (priv);
 
85
      return gpg_error (GPG_ERR_CARD);
 
86
    }
 
87
  priv->n_cert_objs = rc;
 
88
 
 
89
  card->p15priv = priv;
 
90
  return 0;
 
91
}
 
92
 
 
93
 
 
94
/* Release private data used in this module. */
 
95
void
 
96
p15_release_private_data (CARD card)
 
97
{
 
98
  if (!card->p15priv)
 
99
    return;
 
100
  xfree (card->p15priv);
 
101
  card->p15priv = NULL;
 
102
}
 
103
 
 
104
 
 
105
 
 
106
/* See card.c for interface description */
 
107
static int
 
108
p15_enum_keypairs (CARD card, int idx,
 
109
                   unsigned char *keygrip, char **keyid)
 
110
{
 
111
  int rc;
 
112
  struct p15private_s *priv;
 
113
  struct sc_pkcs15_object *tmpobj;
 
114
  int nobjs;
 
115
  struct sc_pkcs15_prkey_info *pinfo;
 
116
  struct sc_pkcs15_cert_info *certinfo;
 
117
  struct sc_pkcs15_cert      *certder;
 
118
  ksba_cert_t cert;
 
119
 
 
120
  rc = init_private_data (card);
 
121
  if (rc) 
 
122
      return rc;
 
123
  priv = card->p15priv;
 
124
  nobjs = priv->n_prkey_rsa_objs;
 
125
  rc = 0;
 
126
  if (idx >= nobjs)
 
127
    return -1;
 
128
  pinfo = priv->prkey_rsa_objs[idx]->data;
 
129
  
 
130
  /* now we need to read the certificate so that we can calculate the
 
131
     keygrip */
 
132
  rc = sc_pkcs15_find_cert_by_id (card->p15card, &pinfo->id, &tmpobj);
 
133
  if (rc)
 
134
    {
 
135
      log_info ("certificate for private key %d not found: %s\n",
 
136
                idx, sc_strerror (rc));
 
137
      /* note, that we return the ID anyway */
 
138
      rc = gpg_error (GPG_ERR_MISSING_CERT);
 
139
      goto return_keyid;
 
140
    }
 
141
  certinfo = tmpobj->data;
 
142
  rc = sc_pkcs15_read_certificate (card->p15card, certinfo, &certder);
 
143
  if (rc)
 
144
    {
 
145
      log_info ("failed to read certificate for private key %d: %s\n",
 
146
                idx, sc_strerror (rc));
 
147
      return gpg_error (GPG_ERR_CARD);
 
148
    }
 
149
 
 
150
  rc = ksba_cert_new (&cert);
 
151
  if (rc)
 
152
    {
 
153
      sc_pkcs15_free_certificate (certder);
 
154
      return rc;
 
155
    }
 
156
  rc = ksba_cert_init_from_mem (cert, certder->data, certder->data_len);
 
157
  sc_pkcs15_free_certificate (certder);
 
158
  if (rc)
 
159
    {
 
160
      log_error ("failed to parse the certificate for private key %d: %s\n",
 
161
                 idx, gpg_strerror (rc));
 
162
      ksba_cert_release (cert);
 
163
      return rc;
 
164
    }
 
165
  if (card_help_get_keygrip (cert, keygrip))
 
166
    {
 
167
      log_error ("failed to calculate the keygrip of private key %d\n", idx);
 
168
      ksba_cert_release (cert);
 
169
      return gpg_error (GPG_ERR_CARD);
 
170
    }      
 
171
  ksba_cert_release (cert);
 
172
 
 
173
  rc = 0;
 
174
 return_keyid:
 
175
  if (keyid)
 
176
    {
 
177
      char *p;
 
178
      int i;
 
179
 
 
180
      *keyid = p = xtrymalloc (9+pinfo->id.len*2+1);
 
181
      if (!*keyid)
 
182
        return gpg_error (gpg_err_code_from_errno (errno));
 
183
      p = stpcpy (p, "P15-5015.");
 
184
      for (i=0; i < pinfo->id.len; i++, p += 2)
 
185
        sprintf (p, "%02X", pinfo->id.value[i]);
 
186
      *p = 0;
 
187
    }
 
188
  
 
189
  return rc;
 
190
}
 
191
 
 
192
/* See card.c for interface description */
 
193
static int
 
194
p15_enum_certs (CARD card, int idx, char **certid, int *type)
 
195
{
 
196
  int rc;
 
197
  struct p15private_s *priv;
 
198
  struct sc_pkcs15_object *obj;
 
199
  struct sc_pkcs15_cert_info *cinfo;
 
200
  int nobjs;
 
201
 
 
202
  rc = init_private_data (card);
 
203
  if (rc) 
 
204
      return rc;
 
205
  priv = card->p15priv;
 
206
  nobjs = priv->n_cert_objs;
 
207
  rc = 0;
 
208
  if (idx >= nobjs)
 
209
    return -1;
 
210
  obj =  priv->cert_objs[idx];
 
211
  cinfo = obj->data;
 
212
  
 
213
  if (certid)
 
214
    {
 
215
      char *p;
 
216
      int i;
 
217
 
 
218
      *certid = p = xtrymalloc (9+cinfo->id.len*2+1);
 
219
      if (!*certid)
 
220
        return gpg_error (gpg_err_code_from_errno (errno));
 
221
      p = stpcpy (p, "P15-5015.");
 
222
      for (i=0; i < cinfo->id.len; i++, p += 2)
 
223
        sprintf (p, "%02X", cinfo->id.value[i]);
 
224
      *p = 0;
 
225
    }
 
226
  if (type)
 
227
    {
 
228
      if (!obj->df)
 
229
        *type = 0; /* unknown */
 
230
      else if (obj->df->type == SC_PKCS15_CDF)
 
231
        *type = 100;
 
232
      else if (obj->df->type == SC_PKCS15_CDF_TRUSTED)
 
233
        *type = 101;
 
234
      else if (obj->df->type == SC_PKCS15_CDF_USEFUL)
 
235
        *type = 102;
 
236
      else 
 
237
        *type = 0; /* error -> unknown */
 
238
    }
 
239
  
 
240
  return rc;
 
241
}
 
242
 
 
243
 
 
244
 
 
245
static int
 
246
idstr_to_id (const char *idstr, struct sc_pkcs15_id *id)
 
247
{
 
248
  const char *s;
 
249
  int n;
 
250
 
 
251
  /* For now we only support the standard DF */
 
252
  if (strncmp (idstr, "P15-5015.", 9) ) 
 
253
    return gpg_error (GPG_ERR_INV_ID);
 
254
  for (s=idstr+9, n=0; hexdigitp (s); s++, n++)
 
255
    ;
 
256
  if (*s || (n&1))
 
257
    return gpg_error (GPG_ERR_INV_ID); /*invalid or odd number of digits*/
 
258
  n /= 2;
 
259
  if (!n || n > SC_PKCS15_MAX_ID_SIZE)
 
260
    return gpg_error (GPG_ERR_INV_ID); /* empty or too large */
 
261
  for (s=idstr+9, n=0; *s; s += 2, n++)
 
262
    id->value[n] = xtoi_2 (s);
 
263
  id->len = n;
 
264
  return 0;
 
265
}
 
266
 
 
267
 
 
268
/* See card.c for interface description */
 
269
static int
 
270
p15_read_cert (CARD card, const char *certidstr,
 
271
               unsigned char **cert, size_t *ncert)
 
272
{
 
273
  struct sc_pkcs15_object *tmpobj;
 
274
  struct sc_pkcs15_id certid;
 
275
  struct sc_pkcs15_cert_info *certinfo;
 
276
  struct sc_pkcs15_cert      *certder;
 
277
  int rc;
 
278
 
 
279
  if (!card || !certidstr || !cert || !ncert)
 
280
    return gpg_error (GPG_ERR_INV_VALUE);
 
281
  if (!card->p15card)
 
282
    return gpg_error (GPG_ERR_NO_PKCS15_APP);
 
283
 
 
284
  rc = idstr_to_id (certidstr, &certid);
 
285
  if (rc)
 
286
    return rc;
 
287
 
 
288
  rc = sc_pkcs15_find_cert_by_id (card->p15card, &certid, &tmpobj);
 
289
  if (rc)
 
290
    {
 
291
      log_info ("certificate '%s' not found: %s\n", 
 
292
                certidstr, sc_strerror (rc));
 
293
      return -1;
 
294
    }
 
295
  certinfo = tmpobj->data;
 
296
  rc = sc_pkcs15_read_certificate (card->p15card, certinfo, &certder);
 
297
  if (rc)
 
298
    {
 
299
      log_info ("failed to read certificate '%s': %s\n",
 
300
                certidstr, sc_strerror (rc));
 
301
      return gpg_error (GPG_ERR_CARD);
 
302
    }
 
303
 
 
304
  *cert = xtrymalloc (certder->data_len);
 
305
  if (!*cert)
 
306
    {
 
307
      gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
 
308
      sc_pkcs15_free_certificate (certder);
 
309
      return tmperr;
 
310
    }
 
311
  memcpy (*cert, certder->data, certder->data_len);
 
312
  *ncert = certder->data_len;
 
313
  sc_pkcs15_free_certificate (certder);
 
314
  return 0;
 
315
}
 
316
 
 
317
 
 
318
 
 
319
 
 
320
 
 
321
static int
 
322
p15_prepare_key (CARD card, const char *keyidstr,
 
323
                 int (pincb)(void*, const char *, char **),
 
324
                 void *pincb_arg, struct sc_pkcs15_object **r_keyobj)
 
325
{
 
326
  struct sc_pkcs15_id keyid;
 
327
  struct sc_pkcs15_pin_info *pin;
 
328
  struct sc_pkcs15_object *keyobj, *pinobj;
 
329
  char *pinvalue;
 
330
  int rc;
 
331
 
 
332
  rc = idstr_to_id (keyidstr, &keyid);
 
333
  if (rc)
 
334
    return rc;
 
335
 
 
336
  rc = sc_pkcs15_find_prkey_by_id (card->p15card, &keyid, &keyobj);
 
337
  if (rc < 0)
 
338
    {
 
339
      log_error ("private key not found: %s\n", sc_strerror(rc));
 
340
      return gpg_error (GPG_ERR_NO_SECKEY);
 
341
    }
 
342
 
 
343
  rc = sc_pkcs15_find_pin_by_auth_id (card->p15card,
 
344
                                      &keyobj->auth_id, &pinobj);
 
345
  if (rc)
 
346
    {
 
347
      log_error ("failed to find PIN by auth ID: %s\n", sc_strerror (rc));
 
348
      return gpg_error (GPG_ERR_BAD_PIN_METHOD);
 
349
    }
 
350
  pin = pinobj->data;
 
351
 
 
352
  /* Fixme: pack this into a verification loop */
 
353
  /* Fixme: we might want to pass pin->min_length and 
 
354
     pin->stored_length */
 
355
  rc = pincb (pincb_arg, pinobj->label, &pinvalue);
 
356
  if (rc)
 
357
    {
 
358
      log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
 
359
      return rc;
 
360
    }
 
361
 
 
362
  rc = sc_pkcs15_verify_pin (card->p15card, pin,
 
363
                             pinvalue, strlen (pinvalue));
 
364
  xfree (pinvalue);
 
365
  if (rc)
 
366
    {
 
367
      log_info ("PIN verification failed: %s\n", sc_strerror (rc));
 
368
      return gpg_error (GPG_ERR_BAD_PIN);
 
369
    }
 
370
 
 
371
  /* fixme: check wheter we need to release KEYOBJ in case of an error */
 
372
  *r_keyobj = keyobj;
 
373
  return 0;
 
374
}
 
375
 
 
376
 
 
377
/* See card.c for interface description */
 
378
static int 
 
379
p15_sign (CARD card, const char *keyidstr, int hashalgo,
 
380
          int (pincb)(void*, const char *, char **),
 
381
          void *pincb_arg,
 
382
          const void *indata, size_t indatalen,
 
383
          unsigned char **outdata, size_t *outdatalen )
 
384
{
 
385
  unsigned int cryptflags;
 
386
  struct sc_pkcs15_object *keyobj;
 
387
  int rc;
 
388
  unsigned char *outbuf = NULL;
 
389
  size_t outbuflen;
 
390
 
 
391
  if (hashalgo != GCRY_MD_SHA1)
 
392
    return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
 
393
 
 
394
  rc = p15_prepare_key (card, keyidstr, pincb, pincb_arg, &keyobj);
 
395
  if (rc)
 
396
    return rc;
 
397
 
 
398
  cryptflags = SC_ALGORITHM_RSA_PAD_PKCS1;
 
399
 
 
400
  outbuflen = 1024; 
 
401
  outbuf = xtrymalloc (outbuflen);
 
402
  if (!outbuf)
 
403
    return gpg_error (gpg_err_code_from_errno (errno));
 
404
  
 
405
  rc = sc_pkcs15_compute_signature (card->p15card, keyobj,
 
406
                                    cryptflags,
 
407
                                    indata, indatalen,
 
408
                                    outbuf, outbuflen );
 
409
  if (rc < 0)
 
410
    {
 
411
      log_error ("failed to create signature: %s\n", sc_strerror (rc));
 
412
      rc = gpg_error (GPG_ERR_CARD);
 
413
    }
 
414
  else
 
415
    {
 
416
      *outdatalen = rc;
 
417
      *outdata = outbuf;
 
418
      outbuf = NULL;
 
419
      rc = 0;
 
420
    }
 
421
 
 
422
  xfree (outbuf);
 
423
  return rc;
 
424
}
 
425
 
 
426
 
 
427
/* See card.c for description */
 
428
static int 
 
429
p15_decipher (CARD card, const char *keyidstr,
 
430
              int (pincb)(void*, const char *, char **),
 
431
              void *pincb_arg,
 
432
              const void *indata, size_t indatalen,
 
433
              unsigned char **outdata, size_t *outdatalen )
 
434
{
 
435
  struct sc_pkcs15_object *keyobj;
 
436
  int rc;
 
437
  unsigned char *outbuf = NULL;
 
438
  size_t outbuflen;
 
439
 
 
440
  rc = p15_prepare_key (card, keyidstr, pincb, pincb_arg, &keyobj);
 
441
  if (rc)
 
442
    return rc;
 
443
 
 
444
  if (card && card->scard && card->scard->driver
 
445
      && !strcasecmp (card->scard->driver->short_name, "tcos"))
 
446
    {
 
447
      /* very ugly hack to force the use of a local key.  We need this
 
448
         until we have fixed the initialization code for TCOS cards */
 
449
      struct sc_pkcs15_prkey_info *prkey = keyobj->data;
 
450
      if ( !(prkey->key_reference & 0x80))
 
451
        {
 
452
          prkey->key_reference |= 0x80;
 
453
          log_debug ("using TCOS hack to force the use of local keys\n");
 
454
        }
 
455
      if (*keyidstr && keyidstr[strlen(keyidstr)-1] == '6')
 
456
        {
 
457
          prkey->key_reference |= 1;
 
458
          log_debug ("warning: using even more TCOS hacks\n");
 
459
        }
 
460
    }
 
461
 
 
462
  outbuflen = indatalen < 256? 256 : indatalen; 
 
463
  outbuf = xtrymalloc (outbuflen);
 
464
  if (!outbuf)
 
465
    return gpg_error (gpg_err_code_from_errno (errno));
 
466
 
 
467
  rc = sc_pkcs15_decipher (card->p15card, keyobj, 
 
468
                           0,
 
469
                           indata, indatalen, 
 
470
                           outbuf, outbuflen); 
 
471
  if (rc < 0)
 
472
    {
 
473
      log_error ("failed to decipher the data: %s\n", sc_strerror (rc));
 
474
      rc = gpg_error (GPG_ERR_CARD);
 
475
    }
 
476
  else
 
477
    {
 
478
      *outdatalen = rc;
 
479
      *outdata = outbuf;
 
480
      outbuf = NULL;
 
481
      rc = 0;
 
482
    }
 
483
 
 
484
  xfree (outbuf);
 
485
  return rc;
 
486
}
 
487
 
 
488
 
 
489
 
 
490
/* Bind our operations to the card */
 
491
void
 
492
card_p15_bind (CARD card)
 
493
{
 
494
  card->fnc.enum_keypairs = p15_enum_keypairs;
 
495
  card->fnc.enum_certs    = p15_enum_certs;
 
496
  card->fnc.read_cert     = p15_read_cert;
 
497
  card->fnc.sign          = p15_sign;
 
498
  card->fnc.decipher      = p15_decipher;
 
499
}
 
500
#endif /*HAVE_OPENSC*/