~ubuntu-branches/ubuntu/trusty/gnutls26/trusty

« back to all changes in this revision

Viewing changes to lib/pkcs11.c

  • Committer: Package Import Robot
  • Author(s): Andreas Metzler
  • Date: 2011-10-01 15:28:13 UTC
  • mfrom: (12.1.20 sid)
  • Revision ID: package-import@ubuntu.com-20111001152813-yygm1c4cxonfxhzy
* New upstream version.
  + Allow CA importing of 0 certificates to succeed. Closes: #640639
* Add libp11-kit-dev to libgnutls-dev dependencies. (see #643811)
* [20_guiledocstring.diff] guile: Fix docstring extraction with CPP 4.5+.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * GnuTLS PKCS#11 support
 
3
 * Copyright (C) 2010 Free Software Foundation
 
4
 * Copyright (C) 2008, Joe Orton <joe@manyfish.co.uk>
 
5
 * 
 
6
 * Author: Nikos Mavrogiannopoulos
 
7
 *
 
8
 * Inspired and some parts (pkcs11_login) based on neon PKCS #11 support 
 
9
 * by Joe Orton. More ideas came from the pkcs11-helper library by 
 
10
 * Alon Bar-Lev.
 
11
 *
 
12
 * This library is free software; you can redistribute it and/or
 
13
 * modify it under the terms of the GNU Library General Public
 
14
 * License as published by the Free Software Foundation; either
 
15
 * version 2 of the License, or (at your option) any later version.
 
16
 *
 
17
 * This library is distributed in the hope that it will be useful,
 
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
20
 * Library General Public License for more details.
 
21
 *
 
22
 * You should have received a copy of the GNU Library General Public
 
23
 * License along with this library; if not, write to the Free
 
24
 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 
25
 * MA 02111-1307, USA
 
26
*/
 
27
 
 
28
#include <gnutls_int.h>
 
29
#include <gnutls/pkcs11.h>
 
30
#include <stdio.h>
 
31
#include <string.h>
 
32
#include <gnutls_errors.h>
 
33
#include <gnutls_datum.h>
 
34
#include <pkcs11_int.h>
 
35
#include <p11-kit/p11-kit.h>
 
36
#include <p11-kit/pin.h>
 
37
#include <errno.h>
 
38
 
 
39
#define MAX_PROVIDERS 16
 
40
 
 
41
/* XXX: try to eliminate this */
 
42
#define MAX_CERT_SIZE 8*1024
 
43
 
 
44
struct gnutls_pkcs11_provider_s
 
45
{
 
46
  struct ck_function_list *module;
 
47
  unsigned long nslots;
 
48
  ck_slot_id_t *slots;
 
49
  struct ck_info info;
 
50
  int initialized;
 
51
};
 
52
 
 
53
struct flags_find_data_st
 
54
{
 
55
  struct p11_kit_uri *info;
 
56
  unsigned int slot_flags;
 
57
};
 
58
 
 
59
struct url_find_data_st
 
60
{
 
61
  gnutls_pkcs11_obj_t crt;
 
62
};
 
63
 
 
64
struct crt_find_data_st
 
65
{
 
66
  gnutls_pkcs11_obj_t *p_list;
 
67
  unsigned int *n_list;
 
68
  unsigned int current;
 
69
  gnutls_pkcs11_obj_attr_t flags;
 
70
  struct p11_kit_uri *info;
 
71
};
 
72
 
 
73
 
 
74
static struct gnutls_pkcs11_provider_s providers[MAX_PROVIDERS];
 
75
static int active_providers = 0;
 
76
static int initialized_registered = 0;
 
77
 
 
78
static gnutls_pkcs11_pin_callback_t pin_func;
 
79
static void *pin_data;
 
80
 
 
81
gnutls_pkcs11_token_callback_t token_func;
 
82
void *token_data;
 
83
 
 
84
int
 
85
pkcs11_rv_to_err (ck_rv_t rv)
 
86
{
 
87
  switch (rv)
 
88
    {
 
89
    case CKR_OK:
 
90
      return 0;
 
91
    case CKR_HOST_MEMORY:
 
92
      return GNUTLS_E_MEMORY_ERROR;
 
93
    case CKR_SLOT_ID_INVALID:
 
94
      return GNUTLS_E_PKCS11_SLOT_ERROR;
 
95
    case CKR_ARGUMENTS_BAD:
 
96
    case CKR_MECHANISM_PARAM_INVALID:
 
97
      return GNUTLS_E_INVALID_REQUEST;
 
98
    case CKR_NEED_TO_CREATE_THREADS:
 
99
    case CKR_CANT_LOCK:
 
100
    case CKR_FUNCTION_NOT_PARALLEL:
 
101
    case CKR_MUTEX_BAD:
 
102
    case CKR_MUTEX_NOT_LOCKED:
 
103
      return GNUTLS_E_LOCKING_ERROR;
 
104
    case CKR_ATTRIBUTE_READ_ONLY:
 
105
    case CKR_ATTRIBUTE_SENSITIVE:
 
106
    case CKR_ATTRIBUTE_TYPE_INVALID:
 
107
    case CKR_ATTRIBUTE_VALUE_INVALID:
 
108
      return GNUTLS_E_PKCS11_ATTRIBUTE_ERROR;
 
109
    case CKR_DEVICE_ERROR:
 
110
    case CKR_DEVICE_MEMORY:
 
111
    case CKR_DEVICE_REMOVED:
 
112
      return GNUTLS_E_PKCS11_DEVICE_ERROR;
 
113
    case CKR_DATA_INVALID:
 
114
    case CKR_DATA_LEN_RANGE:
 
115
    case CKR_ENCRYPTED_DATA_INVALID:
 
116
    case CKR_ENCRYPTED_DATA_LEN_RANGE:
 
117
    case CKR_OBJECT_HANDLE_INVALID:
 
118
      return GNUTLS_E_PKCS11_DATA_ERROR;
 
119
    case CKR_FUNCTION_NOT_SUPPORTED:
 
120
    case CKR_MECHANISM_INVALID:
 
121
      return GNUTLS_E_PKCS11_UNSUPPORTED_FEATURE_ERROR;
 
122
    case CKR_KEY_HANDLE_INVALID:
 
123
    case CKR_KEY_SIZE_RANGE:
 
124
    case CKR_KEY_TYPE_INCONSISTENT:
 
125
    case CKR_KEY_NOT_NEEDED:
 
126
    case CKR_KEY_CHANGED:
 
127
    case CKR_KEY_NEEDED:
 
128
    case CKR_KEY_INDIGESTIBLE:
 
129
    case CKR_KEY_FUNCTION_NOT_PERMITTED:
 
130
    case CKR_KEY_NOT_WRAPPABLE:
 
131
    case CKR_KEY_UNEXTRACTABLE:
 
132
      return GNUTLS_E_PKCS11_KEY_ERROR;
 
133
    case CKR_PIN_INCORRECT:
 
134
    case CKR_PIN_INVALID:
 
135
    case CKR_PIN_LEN_RANGE:
 
136
      return GNUTLS_E_PKCS11_PIN_ERROR;
 
137
    case CKR_PIN_EXPIRED:
 
138
      return GNUTLS_E_PKCS11_PIN_EXPIRED;
 
139
    case CKR_PIN_LOCKED:
 
140
      return GNUTLS_E_PKCS11_PIN_LOCKED;
 
141
    case CKR_SESSION_CLOSED:
 
142
    case CKR_SESSION_COUNT:
 
143
    case CKR_SESSION_HANDLE_INVALID:
 
144
    case CKR_SESSION_PARALLEL_NOT_SUPPORTED:
 
145
    case CKR_SESSION_READ_ONLY:
 
146
    case CKR_SESSION_EXISTS:
 
147
    case CKR_SESSION_READ_ONLY_EXISTS:
 
148
    case CKR_SESSION_READ_WRITE_SO_EXISTS:
 
149
      return GNUTLS_E_PKCS11_SESSION_ERROR;
 
150
    case CKR_SIGNATURE_INVALID:
 
151
    case CKR_SIGNATURE_LEN_RANGE:
 
152
      return GNUTLS_E_PKCS11_SIGNATURE_ERROR;
 
153
    case CKR_TOKEN_NOT_PRESENT:
 
154
    case CKR_TOKEN_NOT_RECOGNIZED:
 
155
    case CKR_TOKEN_WRITE_PROTECTED:
 
156
      return GNUTLS_E_PKCS11_TOKEN_ERROR;
 
157
    case CKR_USER_ALREADY_LOGGED_IN:
 
158
    case CKR_USER_NOT_LOGGED_IN:
 
159
    case CKR_USER_PIN_NOT_INITIALIZED:
 
160
    case CKR_USER_TYPE_INVALID:
 
161
    case CKR_USER_ANOTHER_ALREADY_LOGGED_IN:
 
162
    case CKR_USER_TOO_MANY_TYPES:
 
163
      return GNUTLS_E_PKCS11_USER_ERROR;
 
164
    case CKR_BUFFER_TOO_SMALL:
 
165
      return GNUTLS_E_SHORT_MEMORY_BUFFER;
 
166
    default:
 
167
      return GNUTLS_E_PKCS11_ERROR;
 
168
    }
 
169
}
 
170
 
 
171
/* Fake scan */
 
172
void
 
173
pkcs11_rescan_slots (void)
 
174
{
 
175
  unsigned long slots;
 
176
 
 
177
  pkcs11_get_slot_list (providers[active_providers - 1].module, 0,
 
178
                          NULL, &slots);
 
179
}
 
180
 
 
181
static int
 
182
pkcs11_add_module (const char *name, struct ck_function_list *module)
 
183
{
 
184
  struct ck_info info;
 
185
  int i;
 
186
 
 
187
  if (active_providers >= MAX_PROVIDERS)
 
188
    {
 
189
      gnutls_assert ();
 
190
      return GNUTLS_E_CONSTRAINT_ERROR;
 
191
    }
 
192
 
 
193
  /* initially check if this module is a duplicate */
 
194
  memset(&info, 0, sizeof(info));
 
195
  pkcs11_get_module_info (module, &info);
 
196
  for (i=0;i<active_providers;i++)
 
197
    {
 
198
      /* already loaded, skip the rest */
 
199
      if (memcmp(&info, &providers[i].info, sizeof(info)) == 0)
 
200
        {
 
201
          _gnutls_debug_log("%s is already loaded.\n", name);
 
202
          return 0;
 
203
        }
 
204
    }
 
205
 
 
206
  active_providers++;
 
207
  providers[active_providers - 1].module = module;
 
208
 
 
209
  /* cache the number of slots in this module */
 
210
  if (pkcs11_get_slot_list
 
211
      (providers[active_providers - 1].module, 0, NULL,
 
212
       &providers[active_providers - 1].nslots) != CKR_OK)
 
213
    {
 
214
      gnutls_assert ();
 
215
      goto fail;
 
216
    }
 
217
 
 
218
  providers[active_providers - 1].slots =
 
219
    gnutls_malloc (sizeof (*providers[active_providers - 1].slots) *
 
220
                   providers[active_providers - 1].nslots);
 
221
  if (providers[active_providers - 1].slots == NULL)
 
222
    {
 
223
      gnutls_assert ();
 
224
      goto fail;
 
225
    }
 
226
 
 
227
  if (pkcs11_get_slot_list
 
228
      (providers[active_providers - 1].module, 0,
 
229
       providers[active_providers - 1].slots,
 
230
       &providers[active_providers - 1].nslots) != CKR_OK)
 
231
    {
 
232
      gnutls_assert ();
 
233
      gnutls_free (providers[active_providers - 1].slots);
 
234
      goto fail;
 
235
    }
 
236
 
 
237
  memcpy (&providers[active_providers - 1].info, &info, sizeof(info));
 
238
 
 
239
  _gnutls_debug_log ("p11: loaded provider '%s' with %d slots\n",
 
240
                     name, (int) providers[active_providers - 1].nslots);
 
241
 
 
242
  return 0;
 
243
 
 
244
fail:
 
245
  active_providers--;
 
246
  return GNUTLS_E_PKCS11_LOAD_ERROR;
 
247
}
 
248
 
 
249
 
 
250
/**
 
251
 * gnutls_pkcs11_add_provider:
 
252
 * @name: The filename of the module
 
253
 * @params: should be NULL
 
254
 *
 
255
 * This function will load and add a PKCS 11 module to the module
 
256
 * list used in gnutls. After this function is called the module will
 
257
 * be used for PKCS 11 operations.
 
258
 *
 
259
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
 
260
 *   negative error value.
 
261
 **/
 
262
int
 
263
gnutls_pkcs11_add_provider (const char *name, const char *params)
 
264
{
 
265
  struct ck_function_list *module;
 
266
  int ret;
 
267
 
 
268
  active_providers++;
 
269
  if (p11_kit_load_initialize_module (name, &module) != CKR_OK)
 
270
    {
 
271
      gnutls_assert ();
 
272
      _gnutls_debug_log ("p11: Cannot load provider %s\n", name);
 
273
      active_providers--;
 
274
      return GNUTLS_E_PKCS11_LOAD_ERROR;
 
275
    }
 
276
 
 
277
  ret = pkcs11_add_module (name, module);
 
278
  if (ret == 0)
 
279
    {
 
280
      /* Mark this one as having been separately initialized */
 
281
      providers[active_providers - 1].initialized = 1;
 
282
    }
 
283
  else
 
284
    {
 
285
      p11_kit_finalize_module (module);
 
286
      gnutls_assert ();
 
287
    }
 
288
 
 
289
  return ret;
 
290
}
 
291
 
 
292
 
 
293
/**
 
294
 * gnutls_pkcs11_obj_get_info:
 
295
 * @crt: should contain a #gnutls_pkcs11_obj_t structure
 
296
 * @itype: Denotes the type of information requested
 
297
 * @output: where output will be stored
 
298
 * @output_size: contains the maximum size of the output and will be overwritten with actual
 
299
 *
 
300
 * This function will return information about the PKCS 11 certificatesuch
 
301
 * as the label, id as well as token information where the key is stored. When
 
302
 * output is text it returns null terminated string although %output_size contains
 
303
 * the size of the actual data only.
 
304
 *
 
305
 * Returns: zero on success or a negative value on error.
 
306
 **/
 
307
int
 
308
gnutls_pkcs11_obj_get_info (gnutls_pkcs11_obj_t crt,
 
309
                            gnutls_pkcs11_obj_info_t itype,
 
310
                            void *output, size_t * output_size)
 
311
{
 
312
  return pkcs11_get_info (crt->info, itype, output, output_size);
 
313
}
 
314
 
 
315
int
 
316
pkcs11_get_info (struct p11_kit_uri *info,
 
317
                 gnutls_pkcs11_obj_info_t itype, void *output,
 
318
                 size_t * output_size)
 
319
{
 
320
  struct ck_attribute *attr = NULL;
 
321
  struct ck_version *version = NULL;
 
322
  const char *str = NULL;
 
323
  size_t str_max = 0;
 
324
  int terminate = 0;
 
325
  int hexify = 0;
 
326
  size_t length = 0;
 
327
  const char *data = NULL;
 
328
  char buf[32];
 
329
 
 
330
  /*
 
331
   * Either attr, str or version is valid by the time switch
 
332
   * finishes
 
333
   */
 
334
 
 
335
  switch (itype)
 
336
    {
 
337
    case GNUTLS_PKCS11_OBJ_ID:
 
338
      attr = p11_kit_uri_get_attribute (info, CKA_ID);
 
339
      break;
 
340
    case GNUTLS_PKCS11_OBJ_ID_HEX:
 
341
      attr = p11_kit_uri_get_attribute (info, CKA_ID);
 
342
      hexify = 1;
 
343
      terminate = 1;
 
344
      break;
 
345
    case GNUTLS_PKCS11_OBJ_LABEL:
 
346
      attr = p11_kit_uri_get_attribute (info, CKA_LABEL);
 
347
      terminate = 1;
 
348
      break;
 
349
    case GNUTLS_PKCS11_OBJ_TOKEN_LABEL:
 
350
      str = p11_kit_uri_get_token_info (info)->label;
 
351
      str_max = 32;
 
352
      break;
 
353
    case GNUTLS_PKCS11_OBJ_TOKEN_SERIAL:
 
354
      str = p11_kit_uri_get_token_info (info)->serial_number;
 
355
      str_max = 16;
 
356
      break;
 
357
    case GNUTLS_PKCS11_OBJ_TOKEN_MANUFACTURER:
 
358
      str = p11_kit_uri_get_token_info (info)->manufacturer_id;
 
359
      str_max = 32;
 
360
      break;
 
361
    case GNUTLS_PKCS11_OBJ_TOKEN_MODEL:
 
362
      str = p11_kit_uri_get_token_info (info)->model;
 
363
      str_max = 16;
 
364
      break;
 
365
    case GNUTLS_PKCS11_OBJ_LIBRARY_DESCRIPTION:
 
366
      str = p11_kit_uri_get_module_info (info)->library_description;
 
367
      str_max = 32;
 
368
      break;
 
369
    case GNUTLS_PKCS11_OBJ_LIBRARY_VERSION:
 
370
      version = &p11_kit_uri_get_module_info (info)->library_version;
 
371
      break;
 
372
    case GNUTLS_PKCS11_OBJ_LIBRARY_MANUFACTURER:
 
373
      str = p11_kit_uri_get_module_info (info)->manufacturer_id;
 
374
      str_max = 32;
 
375
      break;
 
376
    default:
 
377
      gnutls_assert ();
 
378
      return GNUTLS_E_INVALID_REQUEST;
 
379
    }
 
380
 
 
381
  if (attr != NULL)
 
382
    {
 
383
      data = attr->value;
 
384
      length = attr->value_len;
 
385
    }
 
386
  else if (str != NULL)
 
387
    {
 
388
      data = str;
 
389
      length = p11_kit_space_strlen (str, str_max);
 
390
      terminate = 1;
 
391
    }
 
392
  else if (version != NULL)
 
393
    {
 
394
      data = buf;
 
395
      length = snprintf (buf, sizeof (buf), "%d.%d", (int)version->major,
 
396
                         (int)version->minor);
 
397
      terminate = 1;
 
398
    }
 
399
 
 
400
  if (hexify)
 
401
    {
 
402
      /* terminate is assumed with hexify */
 
403
      if (*output_size < length * 3)
 
404
        {
 
405
          *output_size = length * 3;
 
406
          return GNUTLS_E_SHORT_MEMORY_BUFFER;
 
407
        }
 
408
      if (output)
 
409
        _gnutls_bin2hex (data, length, output, *output_size, ":");
 
410
      *output_size = length * 3;
 
411
      return 0;
 
412
    }
 
413
  else
 
414
    {
 
415
      if (*output_size < length + terminate)
 
416
        {
 
417
          *output_size = length + terminate;
 
418
          return GNUTLS_E_SHORT_MEMORY_BUFFER;
 
419
        }
 
420
      if (output)
 
421
        {
 
422
          memcpy (output, data, length);
 
423
          if (terminate)
 
424
            ((unsigned char*)output)[length] = '\0';
 
425
        }
 
426
      *output_size = length + terminate;
 
427
    }
 
428
 
 
429
  return 0;
 
430
}
 
431
 
 
432
static int init = 0;
 
433
 
 
434
static int
 
435
initialize_automatic_p11_kit (void)
 
436
{
 
437
  struct ck_function_list **modules;
 
438
  const char *name;
 
439
  ck_rv_t rv;
 
440
  int i, ret;
 
441
 
 
442
  rv = p11_kit_initialize_registered ();
 
443
  if (rv != CKR_OK)
 
444
    {
 
445
      gnutls_assert ();
 
446
      _gnutls_debug_log ("Cannot initialize registered module: %s\n",
 
447
                         p11_kit_strerror (rv));
 
448
      return GNUTLS_E_INTERNAL_ERROR;
 
449
    }
 
450
 
 
451
  initialized_registered = 1;
 
452
 
 
453
  modules = p11_kit_registered_modules ();
 
454
  for (i = 0; modules[i] != NULL; i++)
 
455
    {
 
456
      name = p11_kit_registered_module_to_name (modules[i]);
 
457
      ret = pkcs11_add_module (name, modules[i]);
 
458
      if (ret != 0)
 
459
        {
 
460
          gnutls_assert ();
 
461
          _gnutls_debug_log ("Cannot add registered module: %s\n", name);
 
462
        }
 
463
    }
 
464
 
 
465
  free (modules);
 
466
  return 0;
 
467
}
 
468
 
 
469
static int
 
470
initialize_automatic_legacy (const char *configfile)
 
471
{
 
472
  FILE *fp;
 
473
  char line[512];
 
474
  const char *library;
 
475
  int ret;
 
476
 
 
477
  if (configfile == NULL)
 
478
    configfile = "/etc/gnutls/pkcs11.conf";
 
479
 
 
480
  fp = fopen (configfile, "r");
 
481
  if (fp == NULL)
 
482
    {
 
483
      if (errno == ENOENT)
 
484
        return 0;
 
485
      gnutls_assert ();
 
486
      _gnutls_debug_log ("Cannot load %s\n", configfile);
 
487
      return GNUTLS_E_FILE_ERROR;
 
488
    }
 
489
 
 
490
  while (fgets (line, sizeof (line), fp) != NULL)
 
491
    {
 
492
      if (strncmp (line, "load", sizeof ("load") - 1) == 0)
 
493
        {
 
494
          char *p;
 
495
          p = strchr (line, '=');
 
496
          if (p == NULL)
 
497
            continue;
 
498
 
 
499
          library = ++p;
 
500
 
 
501
          p = strchr (line, '\n');
 
502
          if (p != NULL)
 
503
            {
 
504
              *p = 0;
 
505
            }
 
506
 
 
507
          ret = gnutls_pkcs11_add_provider (library, NULL);
 
508
          if (ret < 0)
 
509
            {
 
510
              gnutls_assert ();
 
511
              _gnutls_debug_log ("Cannot load provider: %s\n", library);
 
512
              continue;
 
513
            }
 
514
        }
 
515
    }
 
516
 
 
517
  fclose(fp);
 
518
  return 0;
 
519
}
 
520
 
 
521
/**
 
522
 * gnutls_pkcs11_init:
 
523
 * @flags: %GNUTLS_PKCS11_FLAG_MANUAL or %GNUTLS_PKCS11_FLAG_AUTO
 
524
 * @deprecated_config_file: either NULL or the location of a deprecated
 
525
 *     configuration file
 
526
 *
 
527
 * This function will initialize the PKCS 11 subsystem in gnutls. It will
 
528
 * read configuration files if %GNUTLS_PKCS11_FLAG_AUTO is used or allow
 
529
 * you to independently load PKCS 11 modules using gnutls_pkcs11_add_provider()
 
530
 * if %GNUTLS_PKCS11_FLAG_MANUAL is specified.
 
531
 *
 
532
 * Using a custom configfile is deprecated and will not be supported in future
 
533
 * versions of gnutls.
 
534
 *
 
535
 * Normally you don't need to call this function since it is being called
 
536
 * by gnutls_global_init() using the %GNUTLS_PKCS11_FLAG_AUTO. If you need to
 
537
 * call this function, you must call it before gnutls_global_init().
 
538
 *
 
539
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
 
540
 *   negative error value.
 
541
 **/
 
542
int
 
543
gnutls_pkcs11_init (unsigned int flags, const char *deprecated_config_file)
 
544
{
 
545
  int ret = 0;
 
546
 
 
547
  if (init != 0)
 
548
    {
 
549
      init++;
 
550
      return 0;
 
551
    }
 
552
  init++;
 
553
 
 
554
  if (flags == GNUTLS_PKCS11_FLAG_AUTO)
 
555
    {
 
556
      if (deprecated_config_file == NULL)
 
557
        ret = initialize_automatic_p11_kit ();
 
558
 
 
559
      if (ret == 0)
 
560
        ret = initialize_automatic_legacy (deprecated_config_file);
 
561
    }
 
562
 
 
563
  return ret;
 
564
}
 
565
 
 
566
/**
 
567
 * gnutls_pkcs11_deinit:
 
568
 *
 
569
 * This function will deinitialize the PKCS 11 subsystem in gnutls.
 
570
 *
 
571
 **/
 
572
void
 
573
gnutls_pkcs11_deinit (void)
 
574
{
 
575
  int i;
 
576
 
 
577
  init--;
 
578
  if (init > 0)
 
579
    return;
 
580
  if (init < 0)
 
581
    {
 
582
      init = 0;
 
583
      return;
 
584
    }
 
585
 
 
586
  for (i = 0; i < active_providers; i++)
 
587
    {
 
588
      if (providers[i].initialized)
 
589
        p11_kit_finalize_module (providers[i].module);
 
590
    }
 
591
  active_providers = 0;
 
592
 
 
593
  if (initialized_registered != 0)
 
594
    p11_kit_finalize_registered ();
 
595
  initialized_registered = 0;
 
596
}
 
597
 
 
598
/**
 
599
 * gnutls_pkcs11_set_pin_function:
 
600
 * @fn: The PIN callback
 
601
 * @userdata: data to be supplied to callback
 
602
 *
 
603
 * This function will set a callback function to be used when a PIN
 
604
 * is required for PKCS 11 operations.
 
605
 *
 
606
 * Callback for PKCS#11 PIN entry.  The callback provides the PIN code
 
607
 * to unlock the token with label 'token_label', specified by the URL 
 
608
 * 'token_url'.
 
609
 *
 
610
 * The PIN code, as a NUL-terminated ASCII string, should be copied
 
611
 * into the 'pin' buffer (of maximum size pin_max), and
 
612
 * return 0 to indicate success. Alternatively, the callback may
 
613
 * return a negative gnutls error code to indicate failure and cancel
 
614
 * PIN entry (in which case, the contents of the 'pin' parameter are ignored).
 
615
 *
 
616
 * When a PIN is required, the callback will be invoked repeatedly
 
617
 * (and indefinitely) until either the returned PIN code is correct,
 
618
 * the callback returns failure, or the token refuses login (e.g. when
 
619
 * the token is locked due to too many incorrect PINs!).  For the
 
620
 * first such invocation, the 'attempt' counter will have value zero;
 
621
 * it will increase by one for each subsequent attempt.
 
622
 *
 
623
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
 
624
 *   negative error value.
 
625
 **/
 
626
void
 
627
gnutls_pkcs11_set_pin_function (gnutls_pkcs11_pin_callback_t fn,
 
628
                                void *userdata)
 
629
{
 
630
  pin_func = fn;
 
631
  pin_data = userdata;
 
632
}
 
633
 
 
634
/**
 
635
 * gnutls_pkcs11_set_token_function:
 
636
 * @fn: The token callback
 
637
 * @userdata: data to be supplied to callback
 
638
 *
 
639
 * This function will set a callback function to be used when a token
 
640
 * needs to be inserted to continue PKCS 11 operations.
 
641
 *
 
642
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
 
643
 *   negative error value.
 
644
 **/
 
645
void
 
646
gnutls_pkcs11_set_token_function (gnutls_pkcs11_token_callback_t fn,
 
647
                                  void *userdata)
 
648
{
 
649
  token_func = fn;
 
650
  token_data = userdata;
 
651
}
 
652
 
 
653
int
 
654
pkcs11_url_to_info (const char *url, struct p11_kit_uri **info)
 
655
{
 
656
  int allocated = 0;
 
657
  int ret;
 
658
 
 
659
  if (*info == NULL)
 
660
    {
 
661
      *info = p11_kit_uri_new ();
 
662
      if (*info == NULL)
 
663
        {
 
664
          gnutls_assert ();
 
665
          return GNUTLS_E_MEMORY_ERROR;
 
666
        }
 
667
      allocated = 1;
 
668
    }
 
669
 
 
670
  ret = p11_kit_uri_parse (url, P11_KIT_URI_FOR_ANY, *info);
 
671
  if (ret < 0)
 
672
    {
 
673
      if (allocated)
 
674
        {
 
675
          p11_kit_uri_free (*info);
 
676
          *info = NULL;
 
677
        }
 
678
      gnutls_assert ();
 
679
      return ret == P11_KIT_URI_NO_MEMORY ?
 
680
          GNUTLS_E_MEMORY_ERROR : GNUTLS_E_PARSING_ERROR;
 
681
    }
 
682
 
 
683
  return 0;
 
684
}
 
685
 
 
686
int
 
687
pkcs11_info_to_url (struct p11_kit_uri *info,
 
688
                    gnutls_pkcs11_url_type_t detailed, char **url)
 
689
{
 
690
  p11_kit_uri_type_t type = 0;
 
691
  int ret;
 
692
 
 
693
  switch (detailed)
 
694
    {
 
695
      case GNUTLS_PKCS11_URL_GENERIC:
 
696
        type = P11_KIT_URI_FOR_OBJECT_ON_TOKEN;
 
697
        break;
 
698
      case GNUTLS_PKCS11_URL_LIB:
 
699
        type = P11_KIT_URI_FOR_OBJECT_ON_TOKEN_AND_MODULE;
 
700
        break;
 
701
      case GNUTLS_PKCS11_URL_LIB_VERSION:
 
702
        type = P11_KIT_URI_FOR_OBJECT_ON_TOKEN_AND_MODULE | P11_KIT_URI_FOR_MODULE_WITH_VERSION;
 
703
        break;
 
704
    }
 
705
 
 
706
  ret = p11_kit_uri_format (info, type, url);
 
707
  if (ret < 0)
 
708
    {
 
709
      gnutls_assert ();
 
710
      return ret == P11_KIT_URI_NO_MEMORY ?
 
711
          GNUTLS_E_MEMORY_ERROR : GNUTLS_E_INTERNAL_ERROR;
 
712
    }
 
713
 
 
714
  return 0;
 
715
}
 
716
 
 
717
/**
 
718
 * gnutls_pkcs11_obj_init:
 
719
 * @obj: The structure to be initialized
 
720
 *
 
721
 * This function will initialize a pkcs11 certificate structure.
 
722
 *
 
723
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
 
724
 *   negative error value.
 
725
 **/
 
726
int
 
727
gnutls_pkcs11_obj_init (gnutls_pkcs11_obj_t * obj)
 
728
{
 
729
  *obj = gnutls_calloc (1, sizeof (struct gnutls_pkcs11_obj_st));
 
730
  if (*obj == NULL)
 
731
    {
 
732
      gnutls_assert ();
 
733
      return GNUTLS_E_MEMORY_ERROR;
 
734
    }
 
735
 
 
736
  (*obj)->info = p11_kit_uri_new ();
 
737
  if ((*obj)->info == NULL)
 
738
    {
 
739
      free (*obj);
 
740
      gnutls_assert ();
 
741
      return GNUTLS_E_MEMORY_ERROR;
 
742
    }
 
743
 
 
744
  return 0;
 
745
}
 
746
 
 
747
/**
 
748
 * gnutls_pkcs11_obj_deinit:
 
749
 * @obj: The structure to be initialized
 
750
 *
 
751
 * This function will deinitialize a certificate structure.
 
752
 **/
 
753
void
 
754
gnutls_pkcs11_obj_deinit (gnutls_pkcs11_obj_t obj)
 
755
{
 
756
  _gnutls_free_datum (&obj->raw);
 
757
  p11_kit_uri_free (obj->info);
 
758
  free (obj);
 
759
}
 
760
 
 
761
/**
 
762
 * gnutls_pkcs11_obj_export:
 
763
 * @obj: Holds the object
 
764
 * @output_data: will contain a certificate PEM or DER encoded
 
765
 * @output_data_size: holds the size of output_data (and will be
 
766
 *   replaced by the actual size of parameters)
 
767
 *
 
768
 * This function will export the pkcs11 object data. It is normal
 
769
 * for PKCS #11 data to be inaccesible and in that case %GNUTLS_E_INVALID_REQUEST
 
770
 * will be returned.
 
771
 *
 
772
 * If the buffer provided is not long enough to hold the output, then
 
773
 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
 
774
 * be returned.
 
775
 *
 
776
 * If the structure is PEM encoded, it will have a header
 
777
 * of "BEGIN CERTIFICATE".
 
778
 *
 
779
 * Return value: In case of failure a negative value will be
 
780
 *   returned, and 0 on success.
 
781
 **/
 
782
int
 
783
gnutls_pkcs11_obj_export (gnutls_pkcs11_obj_t obj,
 
784
                          void *output_data, size_t * output_data_size)
 
785
{
 
786
  if (obj == NULL || obj->raw.data == NULL)
 
787
    {
 
788
      gnutls_assert ();
 
789
      return GNUTLS_E_INVALID_REQUEST;
 
790
    }
 
791
 
 
792
  if (output_data == NULL || *output_data_size < obj->raw.size)
 
793
    {
 
794
      *output_data_size = obj->raw.size;
 
795
      gnutls_assert ();
 
796
      return GNUTLS_E_SHORT_MEMORY_BUFFER;
 
797
    }
 
798
  *output_data_size = obj->raw.size;
 
799
 
 
800
  memcpy (output_data, obj->raw.data, obj->raw.size);
 
801
  return 0;
 
802
}
 
803
 
 
804
int
 
805
pkcs11_find_object (struct ck_function_list ** _module,
 
806
                    ck_session_handle_t * _pks,
 
807
                    ck_object_handle_t * _obj,
 
808
                    struct p11_kit_uri *info, unsigned int flags)
 
809
{
 
810
  int ret;
 
811
  struct ck_function_list *module;
 
812
  ck_session_handle_t pks;
 
813
  ck_object_handle_t obj;
 
814
  struct ck_attribute *attrs;
 
815
  unsigned long attr_count;
 
816
  unsigned long count;
 
817
  ck_rv_t rv;
 
818
 
 
819
  ret = pkcs11_open_session (&module, &pks, info, flags & SESSION_LOGIN);
 
820
  if (ret < 0)
 
821
    {
 
822
      gnutls_assert ();
 
823
      return ret;
 
824
    }
 
825
 
 
826
  attrs = p11_kit_uri_get_attributes (info, &attr_count);
 
827
  rv = pkcs11_find_objects_init (module, pks, attrs, attr_count);
 
828
  if (rv != CKR_OK)
 
829
    {
 
830
      gnutls_assert ();
 
831
      _gnutls_debug_log ("pk11: FindObjectsInit failed.\n");
 
832
      ret = pkcs11_rv_to_err (rv);
 
833
      goto fail;
 
834
    }
 
835
 
 
836
  if (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK && count == 1)
 
837
    {
 
838
      *_obj = obj;
 
839
      *_pks = pks;
 
840
      *_module = module;
 
841
      pkcs11_find_objects_final (module, pks);
 
842
      return 0;
 
843
    }
 
844
 
 
845
  ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
 
846
  pkcs11_find_objects_final (module, pks);
 
847
fail:
 
848
  pkcs11_close_session (module, pks);
 
849
 
 
850
  return ret;
 
851
}
 
852
 
 
853
int
 
854
pkcs11_find_slot (struct ck_function_list ** module, ck_slot_id_t * slot,
 
855
                  struct p11_kit_uri *info, struct token_info *_tinfo)
 
856
{
 
857
  int x, z;
 
858
 
 
859
  for (x = 0; x < active_providers; x++)
 
860
    {
 
861
      for (z = 0; z < providers[x].nslots; z++)
 
862
        {
 
863
          struct token_info tinfo;
 
864
 
 
865
          if (pkcs11_get_token_info
 
866
              (providers[x].module, providers[x].slots[z],
 
867
               &tinfo.tinfo) != CKR_OK)
 
868
            {
 
869
              continue;
 
870
            }
 
871
          tinfo.sid = providers[x].slots[z];
 
872
          tinfo.prov = &providers[x];
 
873
 
 
874
          if (pkcs11_get_slot_info
 
875
              (providers[x].module, providers[x].slots[z],
 
876
               &tinfo.sinfo) != CKR_OK)
 
877
            {
 
878
              continue;
 
879
            }
 
880
 
 
881
          if (!p11_kit_uri_match_token_info (info, &tinfo.tinfo) ||
 
882
              !p11_kit_uri_match_module_info (info, &providers[x].info))
 
883
            {
 
884
              continue;
 
885
            }
 
886
 
 
887
          /* ok found */
 
888
          *module = providers[x].module;
 
889
          *slot = providers[x].slots[z];
 
890
 
 
891
          if (_tinfo != NULL)
 
892
            memcpy (_tinfo, &tinfo, sizeof (tinfo));
 
893
 
 
894
          return 0;
 
895
        }
 
896
    }
 
897
 
 
898
  gnutls_assert ();
 
899
  return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
 
900
}
 
901
 
 
902
int
 
903
pkcs11_open_session (struct ck_function_list ** _module, ck_session_handle_t * _pks,
 
904
                     struct p11_kit_uri *info, unsigned int flags)
 
905
{
 
906
  ck_rv_t rv;
 
907
  int ret;
 
908
  ck_session_handle_t pks = 0;
 
909
  struct ck_function_list *module;
 
910
  ck_slot_id_t slot;
 
911
  struct token_info tinfo;
 
912
 
 
913
  ret = pkcs11_find_slot (&module, &slot, info, &tinfo);
 
914
  if (ret < 0)
 
915
    {
 
916
      gnutls_assert ();
 
917
      return ret;
 
918
    }
 
919
 
 
920
  rv = (module)->C_OpenSession (slot,
 
921
                              ((flags & SESSION_WRITE)
 
922
                               ? CKF_RW_SESSION : 0) |
 
923
                              CKF_SERIAL_SESSION, NULL, NULL, &pks);
 
924
  if (rv != CKR_OK)
 
925
    {
 
926
      gnutls_assert ();
 
927
      return pkcs11_rv_to_err (rv);
 
928
    }
 
929
 
 
930
  if (flags & SESSION_LOGIN)
 
931
    {
 
932
      ret = pkcs11_login (module, pks, &tinfo, info, (flags & SESSION_SO) ? 1 : 0);
 
933
      if (ret < 0)
 
934
        {
 
935
          gnutls_assert ();
 
936
          pkcs11_close_session (module, pks);
 
937
          return ret;
 
938
        }
 
939
    }
 
940
 
 
941
  /* ok found */
 
942
  *_pks = pks;
 
943
  *_module = module;
 
944
  return 0;
 
945
}
 
946
 
 
947
 
 
948
int
 
949
_pkcs11_traverse_tokens (find_func_t find_func, void *input,
 
950
                         struct p11_kit_uri *info, unsigned int flags)
 
951
{
 
952
  ck_rv_t rv;
 
953
  int found = 0, x, z, ret;
 
954
  ck_session_handle_t pks = 0;
 
955
  struct ck_function_list *module = NULL;
 
956
 
 
957
  for (x = 0; x < active_providers; x++)
 
958
    {
 
959
      module = providers[x].module;
 
960
      for (z = 0; z < providers[x].nslots; z++)
 
961
        {
 
962
          struct token_info tinfo;
 
963
 
 
964
          ret = GNUTLS_E_PKCS11_ERROR;
 
965
 
 
966
          if (pkcs11_get_token_info (module, providers[x].slots[z],
 
967
               &tinfo.tinfo) != CKR_OK)
 
968
            {
 
969
              continue;
 
970
            }
 
971
          tinfo.sid = providers[x].slots[z];
 
972
          tinfo.prov = &providers[x];
 
973
 
 
974
          if (pkcs11_get_slot_info (module, providers[x].slots[z],
 
975
               &tinfo.sinfo) != CKR_OK)
 
976
            {
 
977
              continue;
 
978
            }
 
979
 
 
980
          rv = (module)->C_OpenSession (providers[x].slots[z],
 
981
                                        ((flags & SESSION_WRITE)
 
982
                                          ? CKF_RW_SESSION : 0) |
 
983
                                        CKF_SERIAL_SESSION, NULL, NULL, &pks);
 
984
          if (rv != CKR_OK)
 
985
            {
 
986
              continue;
 
987
            }
 
988
 
 
989
          if (flags & SESSION_LOGIN)
 
990
            {
 
991
              ret = pkcs11_login (module, pks, &tinfo, info, (flags & SESSION_SO) ? 1 : 0);
 
992
              if (ret < 0)
 
993
                {
 
994
                  gnutls_assert ();
 
995
                  return ret;
 
996
                }
 
997
            }
 
998
 
 
999
          ret = find_func (module, pks, &tinfo, &providers[x].info, input);
 
1000
 
 
1001
          if (ret == 0)
 
1002
            {
 
1003
              found = 1;
 
1004
              goto finish;
 
1005
            }
 
1006
          else
 
1007
            {
 
1008
              pkcs11_close_session (module, pks);
 
1009
              pks = 0;
 
1010
            }
 
1011
        }
 
1012
    }
 
1013
 
 
1014
finish:
 
1015
  /* final call */
 
1016
 
 
1017
  if (found == 0)
 
1018
    {
 
1019
      if (module)
 
1020
        ret = find_func (module, pks, NULL, NULL, input);
 
1021
      else
 
1022
        ret = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
 
1023
    }
 
1024
  else
 
1025
    {
 
1026
      ret = 0;
 
1027
    }
 
1028
 
 
1029
  if (pks != 0 && module != NULL)
 
1030
    {
 
1031
      pkcs11_close_session (module, pks);
 
1032
    }
 
1033
 
 
1034
  return ret;
 
1035
}
 
1036
 
 
1037
/* imports a raw certificate from a token to a pkcs11_obj_t structure.
 
1038
 */
 
1039
static int
 
1040
pkcs11_obj_import (ck_object_class_t class, gnutls_pkcs11_obj_t obj,
 
1041
                   const gnutls_datum_t * data,
 
1042
                   const gnutls_datum_t * id,
 
1043
                   const gnutls_datum_t * label,
 
1044
                   struct ck_token_info *tinfo, struct ck_info *lib_info)
 
1045
{
 
1046
  struct ck_attribute attr;
 
1047
  int ret;
 
1048
 
 
1049
  switch (class)
 
1050
    {
 
1051
    case CKO_CERTIFICATE:
 
1052
      obj->type = GNUTLS_PKCS11_OBJ_X509_CRT;
 
1053
      break;
 
1054
    case CKO_PUBLIC_KEY:
 
1055
      obj->type = GNUTLS_PKCS11_OBJ_PUBKEY;
 
1056
      break;
 
1057
    case CKO_PRIVATE_KEY:
 
1058
      obj->type = GNUTLS_PKCS11_OBJ_PRIVKEY;
 
1059
      break;
 
1060
    case CKO_SECRET_KEY:
 
1061
      obj->type = GNUTLS_PKCS11_OBJ_SECRET_KEY;
 
1062
      break;
 
1063
    case CKO_DATA:
 
1064
      obj->type = GNUTLS_PKCS11_OBJ_DATA;
 
1065
      break;
 
1066
    default:
 
1067
      obj->type = GNUTLS_PKCS11_OBJ_UNKNOWN;
 
1068
      break;
 
1069
    }
 
1070
 
 
1071
  attr.type = CKA_CLASS;
 
1072
  attr.value = &class;
 
1073
  attr.value_len = sizeof (class);
 
1074
  ret = p11_kit_uri_set_attribute (obj->info, &attr);
 
1075
  if (ret < 0)
 
1076
    {
 
1077
      gnutls_assert ();
 
1078
      return GNUTLS_E_MEMORY_ERROR;
 
1079
    }
 
1080
 
 
1081
  if (data && data->data)
 
1082
    {
 
1083
      ret = _gnutls_set_datum (&obj->raw, data->data, data->size);
 
1084
      if (ret < 0)
 
1085
        {
 
1086
          gnutls_assert ();
 
1087
          return ret;
 
1088
        }
 
1089
    }
 
1090
 
 
1091
  /* copy the token and library info into the uri */
 
1092
  memcpy (p11_kit_uri_get_token_info (obj->info), tinfo, sizeof (struct ck_token_info));
 
1093
  memcpy (p11_kit_uri_get_module_info (obj->info), lib_info, sizeof (struct ck_info));
 
1094
 
 
1095
  if (label && label->data)
 
1096
    {
 
1097
      attr.type = CKA_LABEL;
 
1098
      attr.value = label->data;
 
1099
      attr.value_len = label->size;
 
1100
      ret = p11_kit_uri_set_attribute (obj->info, &attr);
 
1101
      if (ret < 0)
 
1102
        {
 
1103
          gnutls_assert ();
 
1104
          return GNUTLS_E_MEMORY_ERROR;
 
1105
        }
 
1106
    }
 
1107
 
 
1108
  if (id && id->data)
 
1109
    {
 
1110
      attr.type = CKA_ID;
 
1111
      attr.value = id->data;
 
1112
      attr.value_len = id->size;
 
1113
      ret = p11_kit_uri_set_attribute (obj->info, &attr);
 
1114
      if (ret < 0)
 
1115
        {
 
1116
          gnutls_assert ();
 
1117
          return GNUTLS_E_MEMORY_ERROR;
 
1118
        }
 
1119
    }
 
1120
 
 
1121
  return 0;
 
1122
}
 
1123
 
 
1124
static int
 
1125
pkcs11_obj_import_pubkey (struct ck_function_list *module,
 
1126
                          ck_session_handle_t pks,
 
1127
                          ck_object_handle_t obj,
 
1128
                          gnutls_pkcs11_obj_t crt,
 
1129
                          const gnutls_datum_t * id,
 
1130
                          const gnutls_datum_t * label,
 
1131
                          struct ck_token_info *tinfo,
 
1132
                          struct ck_info *lib_info)
 
1133
{
 
1134
 
 
1135
  struct ck_attribute a[4];
 
1136
  ck_key_type_t key_type;
 
1137
  opaque tmp1[2048];
 
1138
  opaque tmp2[2048];
 
1139
  int ret;
 
1140
  ck_bool_t tval;
 
1141
 
 
1142
  a[0].type = CKA_KEY_TYPE;
 
1143
  a[0].value = &key_type;
 
1144
  a[0].value_len = sizeof (key_type);
 
1145
 
 
1146
  if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
 
1147
    {
 
1148
      switch (key_type)
 
1149
        {
 
1150
        case CKK_RSA:
 
1151
          a[0].type = CKA_MODULUS;
 
1152
          a[0].value = tmp1;
 
1153
          a[0].value_len = sizeof (tmp1);
 
1154
          a[1].type = CKA_PUBLIC_EXPONENT;
 
1155
          a[1].value = tmp2;
 
1156
          a[1].value_len = sizeof (tmp2);
 
1157
 
 
1158
          if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
 
1159
            {
 
1160
 
 
1161
              ret =
 
1162
                _gnutls_set_datum (&crt->pubkey[0],
 
1163
                                   a[0].value, a[0].value_len);
 
1164
 
 
1165
              if (ret >= 0)
 
1166
                ret =
 
1167
                  _gnutls_set_datum (&crt->pubkey
 
1168
                                     [1], a[1].value, a[1].value_len);
 
1169
 
 
1170
              if (ret < 0)
 
1171
                {
 
1172
                  gnutls_assert ();
 
1173
                  _gnutls_free_datum (&crt->pubkey[1]);
 
1174
                  _gnutls_free_datum (&crt->pubkey[0]);
 
1175
                  return GNUTLS_E_MEMORY_ERROR;
 
1176
                }
 
1177
            }
 
1178
          else
 
1179
            {
 
1180
              gnutls_assert ();
 
1181
              return GNUTLS_E_PKCS11_ERROR;
 
1182
            }
 
1183
          crt->pk_algorithm = GNUTLS_PK_RSA;
 
1184
          break;
 
1185
        case CKK_DSA:
 
1186
          a[0].type = CKA_PRIME;
 
1187
          a[0].value = tmp1;
 
1188
          a[0].value_len = sizeof (tmp1);
 
1189
          a[1].type = CKA_SUBPRIME;
 
1190
          a[1].value = tmp2;
 
1191
          a[1].value_len = sizeof (tmp2);
 
1192
 
 
1193
          if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
 
1194
            {
 
1195
              ret =
 
1196
                _gnutls_set_datum (&crt->pubkey[0],
 
1197
                                   a[0].value, a[0].value_len);
 
1198
 
 
1199
              if (ret >= 0)
 
1200
                ret =
 
1201
                  _gnutls_set_datum (&crt->pubkey
 
1202
                                     [1], a[1].value, a[1].value_len);
 
1203
 
 
1204
              if (ret < 0)
 
1205
                {
 
1206
                  gnutls_assert ();
 
1207
                  _gnutls_free_datum (&crt->pubkey[1]);
 
1208
                  _gnutls_free_datum (&crt->pubkey[0]);
 
1209
                  return GNUTLS_E_MEMORY_ERROR;
 
1210
                }
 
1211
            }
 
1212
          else
 
1213
            {
 
1214
              gnutls_assert ();
 
1215
              return GNUTLS_E_PKCS11_ERROR;
 
1216
            }
 
1217
 
 
1218
          a[0].type = CKA_BASE;
 
1219
          a[0].value = tmp1;
 
1220
          a[0].value_len = sizeof (tmp1);
 
1221
          a[1].type = CKA_VALUE;
 
1222
          a[1].value = tmp2;
 
1223
          a[1].value_len = sizeof (tmp2);
 
1224
 
 
1225
          if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
 
1226
            {
 
1227
              ret =
 
1228
                _gnutls_set_datum (&crt->pubkey[2],
 
1229
                                   a[0].value, a[0].value_len);
 
1230
 
 
1231
              if (ret >= 0)
 
1232
                ret =
 
1233
                  _gnutls_set_datum (&crt->pubkey
 
1234
                                     [3], a[1].value, a[1].value_len);
 
1235
 
 
1236
              if (ret < 0)
 
1237
                {
 
1238
                  gnutls_assert ();
 
1239
                  _gnutls_free_datum (&crt->pubkey[0]);
 
1240
                  _gnutls_free_datum (&crt->pubkey[1]);
 
1241
                  _gnutls_free_datum (&crt->pubkey[2]);
 
1242
                  _gnutls_free_datum (&crt->pubkey[3]);
 
1243
                  return GNUTLS_E_MEMORY_ERROR;
 
1244
                }
 
1245
            }
 
1246
          else
 
1247
            {
 
1248
              gnutls_assert ();
 
1249
              return GNUTLS_E_PKCS11_ERROR;
 
1250
            }
 
1251
          crt->pk_algorithm = GNUTLS_PK_RSA;
 
1252
          break;
 
1253
        default:
 
1254
          gnutls_assert ();
 
1255
          return GNUTLS_E_UNIMPLEMENTED_FEATURE;
 
1256
        }
 
1257
    }
 
1258
 
 
1259
  /* read key usage flags */
 
1260
  a[0].type = CKA_ENCRYPT;
 
1261
  a[0].value = &tval;
 
1262
  a[0].value_len = sizeof (tval);
 
1263
 
 
1264
  if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
 
1265
    {
 
1266
      if (tval != 0)
 
1267
        {
 
1268
          crt->key_usage |= GNUTLS_KEY_DATA_ENCIPHERMENT;
 
1269
        }
 
1270
    }
 
1271
 
 
1272
  a[0].type = CKA_VERIFY;
 
1273
  a[0].value = &tval;
 
1274
  a[0].value_len = sizeof (tval);
 
1275
 
 
1276
  if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
 
1277
    {
 
1278
      if (tval != 0)
 
1279
        {
 
1280
          crt->key_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE |
 
1281
            GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN
 
1282
            | GNUTLS_KEY_NON_REPUDIATION;
 
1283
        }
 
1284
    }
 
1285
 
 
1286
  a[0].type = CKA_VERIFY_RECOVER;
 
1287
  a[0].value = &tval;
 
1288
  a[0].value_len = sizeof (tval);
 
1289
 
 
1290
  if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
 
1291
    {
 
1292
      if (tval != 0)
 
1293
        {
 
1294
          crt->key_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE |
 
1295
            GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN
 
1296
            | GNUTLS_KEY_NON_REPUDIATION;
 
1297
        }
 
1298
    }
 
1299
 
 
1300
  a[0].type = CKA_DERIVE;
 
1301
  a[0].value = &tval;
 
1302
  a[0].value_len = sizeof (tval);
 
1303
 
 
1304
  if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
 
1305
    {
 
1306
      if (tval != 0)
 
1307
        {
 
1308
          crt->key_usage |= GNUTLS_KEY_KEY_AGREEMENT;
 
1309
        }
 
1310
    }
 
1311
 
 
1312
  a[0].type = CKA_WRAP;
 
1313
  a[0].value = &tval;
 
1314
  a[0].value_len = sizeof (tval);
 
1315
 
 
1316
  if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
 
1317
    {
 
1318
      if (tval != 0)
 
1319
        {
 
1320
          crt->key_usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
 
1321
        }
 
1322
    }
 
1323
 
 
1324
  return pkcs11_obj_import (CKO_PUBLIC_KEY, crt, NULL, id, label,
 
1325
                            tinfo, lib_info);
 
1326
}
 
1327
 
 
1328
static int
 
1329
find_obj_url (struct ck_function_list *module, ck_session_handle_t pks,
 
1330
              struct token_info *info, struct ck_info *lib_info, void *input)
 
1331
{
 
1332
  struct url_find_data_st *find_data = input;
 
1333
  struct ck_attribute a[4];
 
1334
  struct ck_attribute *attr;
 
1335
  ck_object_class_t class = -1;
 
1336
  ck_certificate_type_t type = -1;
 
1337
  ck_rv_t rv;
 
1338
  ck_object_handle_t obj;
 
1339
  unsigned long count, a_vals;
 
1340
  int found = 0, ret;
 
1341
  opaque *cert_data = NULL;
 
1342
  char label_tmp[PKCS11_LABEL_SIZE];
 
1343
 
 
1344
  if (info == NULL)
 
1345
    {                           /* we don't support multiple calls */
 
1346
      gnutls_assert ();
 
1347
      return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
 
1348
    }
 
1349
 
 
1350
  /* do not bother reading the token if basic fields do not match
 
1351
   */
 
1352
  if (!p11_kit_uri_match_token_info (find_data->crt->info, &info->tinfo) ||
 
1353
      !p11_kit_uri_match_module_info (find_data->crt->info, lib_info))
 
1354
    {
 
1355
      gnutls_assert ();
 
1356
      return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
 
1357
    }
 
1358
 
 
1359
  attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_ID);
 
1360
  if (attr == NULL)
 
1361
    {
 
1362
      gnutls_assert ();
 
1363
      return GNUTLS_E_INVALID_REQUEST;
 
1364
    }
 
1365
 
 
1366
  /* search the token for the id */
 
1367
 
 
1368
  cert_data = gnutls_malloc (MAX_CERT_SIZE);
 
1369
  if (cert_data == NULL)
 
1370
    {
 
1371
      gnutls_assert ();
 
1372
      return GNUTLS_E_MEMORY_ERROR;
 
1373
    }
 
1374
 
 
1375
  /* Find objects with given class and type */
 
1376
  memcpy (a, attr, sizeof (struct ck_attribute));
 
1377
  a_vals = 1;
 
1378
 
 
1379
  attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_CLASS);
 
1380
  if (attr)
 
1381
    {
 
1382
      if(attr->value && attr->value_len == sizeof (ck_object_class_t))
 
1383
        class = *((ck_object_class_t*)attr->value);
 
1384
      if (class == CKO_CERTIFICATE)
 
1385
        type = CKC_X_509;
 
1386
      memcpy (a + a_vals, attr, sizeof (struct ck_attribute));
 
1387
      a_vals++;
 
1388
    }
 
1389
 
 
1390
  if (type != -1)
 
1391
    {
 
1392
      a[a_vals].type = CKA_CERTIFICATE_TYPE;
 
1393
      a[a_vals].value = &type;
 
1394
      a[a_vals].value_len = sizeof type;
 
1395
      a_vals++;
 
1396
    }
 
1397
 
 
1398
  rv = pkcs11_find_objects_init (module, pks, a, a_vals);
 
1399
  if (rv != CKR_OK)
 
1400
    {
 
1401
      gnutls_assert ();
 
1402
      _gnutls_debug_log ("pk11: FindObjectsInit failed.\n");
 
1403
      ret = pkcs11_rv_to_err (rv);
 
1404
      goto cleanup;
 
1405
    }
 
1406
 
 
1407
  while (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK && count == 1)
 
1408
    {
 
1409
 
 
1410
      a[0].type = CKA_VALUE;
 
1411
      a[0].value = cert_data;
 
1412
      a[0].value_len = MAX_CERT_SIZE;
 
1413
      a[1].type = CKA_LABEL;
 
1414
      a[1].value = label_tmp;
 
1415
      a[1].value_len = sizeof (label_tmp);
 
1416
 
 
1417
      if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
 
1418
        {
 
1419
          gnutls_datum_t id;
 
1420
          gnutls_datum_t data = { a[0].value, a[0].value_len };
 
1421
          gnutls_datum_t label = { a[1].value, a[1].value_len };
 
1422
 
 
1423
          attr = p11_kit_uri_get_attribute (find_data->crt->info, CKA_ID);
 
1424
          id.data = attr->value;
 
1425
          id.size = attr->value_len;
 
1426
 
 
1427
          if (class == CKO_PUBLIC_KEY)
 
1428
            {
 
1429
              ret =
 
1430
                pkcs11_obj_import_pubkey (module, pks, obj,
 
1431
                                          find_data->crt,
 
1432
                                          &id, &label,
 
1433
                                          &info->tinfo, lib_info);
 
1434
            }
 
1435
          else
 
1436
            {
 
1437
              ret =
 
1438
                pkcs11_obj_import (class,
 
1439
                                   find_data->crt,
 
1440
                                   &data, &id, &label,
 
1441
                                   &info->tinfo, lib_info);
 
1442
            }
 
1443
          if (ret < 0)
 
1444
            {
 
1445
              gnutls_assert ();
 
1446
              goto cleanup;
 
1447
            }
 
1448
 
 
1449
          found = 1;
 
1450
          break;
 
1451
        }
 
1452
      else
 
1453
        {
 
1454
          _gnutls_debug_log ("pk11: Skipped cert, missing attrs.\n");
 
1455
        }
 
1456
    }
 
1457
 
 
1458
  if (found == 0)
 
1459
    {
 
1460
      gnutls_assert ();
 
1461
      ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
 
1462
    }
 
1463
  else
 
1464
    {
 
1465
      ret = 0;
 
1466
    }
 
1467
 
 
1468
cleanup:
 
1469
  gnutls_free (cert_data);
 
1470
  pkcs11_find_objects_final (module, pks);
 
1471
 
 
1472
  return ret;
 
1473
}
 
1474
 
 
1475
unsigned int
 
1476
pkcs11_obj_flags_to_int (unsigned int flags)
 
1477
{
 
1478
  unsigned int ret_flags = 0;
 
1479
 
 
1480
  if (flags & GNUTLS_PKCS11_OBJ_FLAG_LOGIN)
 
1481
    ret_flags |= SESSION_LOGIN;
 
1482
  if (flags & GNUTLS_PKCS11_OBJ_FLAG_LOGIN_SO)
 
1483
    ret_flags |= SESSION_LOGIN|SESSION_SO;
 
1484
 
 
1485
  return ret_flags;
 
1486
}
 
1487
 
 
1488
/**
 
1489
 * gnutls_pkcs11_privkey_import_url:
 
1490
 * @cert: The structure to store the parsed certificate
 
1491
 * @url: a PKCS 11 url identifying the key
 
1492
 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
 
1493
 *
 
1494
 * This function will "import" a PKCS 11 URL identifying a certificate
 
1495
 * key to the #gnutls_pkcs11_obj_t structure. This does not involve any
 
1496
 * parsing (such as X.509 or OpenPGP) since the #gnutls_pkcs11_obj_t is
 
1497
 * format agnostic. Only data are transferred.
 
1498
 *
 
1499
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
 
1500
 *   negative error value.
 
1501
 **/
 
1502
int
 
1503
gnutls_pkcs11_obj_import_url (gnutls_pkcs11_obj_t cert, const char *url,
 
1504
                              unsigned int flags)
 
1505
{
 
1506
  int ret;
 
1507
  struct url_find_data_st find_data;
 
1508
 
 
1509
  /* fill in the find data structure */
 
1510
  find_data.crt = cert;
 
1511
 
 
1512
  ret = pkcs11_url_to_info (url, &cert->info);
 
1513
  if (ret < 0)
 
1514
    {
 
1515
      gnutls_assert ();
 
1516
      return ret;
 
1517
    }
 
1518
 
 
1519
  ret =
 
1520
    _pkcs11_traverse_tokens (find_obj_url, &find_data, cert->info,
 
1521
                             pkcs11_obj_flags_to_int (flags));
 
1522
 
 
1523
  if (ret < 0)
 
1524
    {
 
1525
      gnutls_assert ();
 
1526
      return ret;
 
1527
    }
 
1528
 
 
1529
  return 0;
 
1530
}
 
1531
 
 
1532
struct token_num
 
1533
{
 
1534
  struct p11_kit_uri *info;
 
1535
  unsigned int seq;             /* which one we are looking for */
 
1536
  unsigned int current;         /* which one are we now */
 
1537
};
 
1538
 
 
1539
static int
 
1540
find_token_num (struct ck_function_list *module,
 
1541
                ck_session_handle_t pks,
 
1542
                struct token_info *tinfo,
 
1543
                struct ck_info *lib_info, void *input)
 
1544
{
 
1545
  struct token_num *find_data = input;
 
1546
 
 
1547
  if (tinfo == NULL)
 
1548
    {                           /* we don't support multiple calls */
 
1549
      gnutls_assert ();
 
1550
      return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
 
1551
    }
 
1552
 
 
1553
  if (find_data->current == find_data->seq)
 
1554
    {
 
1555
      memcpy (p11_kit_uri_get_token_info (find_data->info), &tinfo->tinfo, sizeof (struct ck_token_info));
 
1556
      memcpy (p11_kit_uri_get_module_info (find_data->info), lib_info, sizeof (struct ck_info));
 
1557
      return 0;
 
1558
    }
 
1559
 
 
1560
  find_data->current++;
 
1561
  /* search the token for the id */
 
1562
 
 
1563
 
 
1564
  return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; /* non zero is enough */
 
1565
}
 
1566
 
 
1567
/**
 
1568
 * gnutls_pkcs11_token_get_url:
 
1569
 * @seq: sequence number starting from 0
 
1570
 * @detailed: non zero if a detailed URL is required
 
1571
 * @url: will contain an allocated url
 
1572
 *
 
1573
 * This function will return the URL for each token available
 
1574
 * in system. The url has to be released using gnutls_free()
 
1575
 *
 
1576
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
 
1577
 * if the sequence number exceeds the available tokens, otherwise a negative error value.
 
1578
 **/
 
1579
 
 
1580
int
 
1581
gnutls_pkcs11_token_get_url (unsigned int seq,
 
1582
                             gnutls_pkcs11_url_type_t detailed, char **url)
 
1583
{
 
1584
  int ret;
 
1585
  struct token_num tn;
 
1586
 
 
1587
  memset (&tn, 0, sizeof (tn));
 
1588
  tn.seq = seq;
 
1589
  tn.info = p11_kit_uri_new ();
 
1590
 
 
1591
  ret = _pkcs11_traverse_tokens (find_token_num, &tn, NULL, 0);
 
1592
  if (ret < 0)
 
1593
    {
 
1594
      p11_kit_uri_free (tn.info);
 
1595
      gnutls_assert ();
 
1596
      return ret;
 
1597
    }
 
1598
 
 
1599
  ret = pkcs11_info_to_url (tn.info, detailed, url);
 
1600
  p11_kit_uri_free (tn.info);
 
1601
 
 
1602
  if (ret < 0)
 
1603
    {
 
1604
      gnutls_assert ();
 
1605
      return ret;
 
1606
    }
 
1607
 
 
1608
  return 0;
 
1609
 
 
1610
}
 
1611
 
 
1612
/**
 
1613
 * gnutls_pkcs11_token_get_info:
 
1614
 * @url: should contain a PKCS 11 URL
 
1615
 * @ttype: Denotes the type of information requested
 
1616
 * @output: where output will be stored
 
1617
 * @output_size: contains the maximum size of the output and will be overwritten with actual
 
1618
 *
 
1619
 * This function will return information about the PKCS 11 token such
 
1620
 * as the label, id as well as token information where the key is stored.
 
1621
 *
 
1622
 * Returns: zero on success or a negative value on error.
 
1623
 **/
 
1624
int
 
1625
gnutls_pkcs11_token_get_info (const char *url,
 
1626
                              gnutls_pkcs11_token_info_t ttype,
 
1627
                              void *output, size_t * output_size)
 
1628
{
 
1629
  struct p11_kit_uri *info = NULL;
 
1630
  const char *str;
 
1631
  size_t str_max;
 
1632
  size_t len;
 
1633
  int ret;
 
1634
 
 
1635
  ret = pkcs11_url_to_info (url, &info);
 
1636
  if (ret < 0)
 
1637
    {
 
1638
      gnutls_assert ();
 
1639
      return ret;
 
1640
    }
 
1641
 
 
1642
  switch (ttype)
 
1643
    {
 
1644
    case GNUTLS_PKCS11_TOKEN_LABEL:
 
1645
      str = p11_kit_uri_get_token_info (info)->label;
 
1646
      str_max = 32;
 
1647
      break;
 
1648
    case GNUTLS_PKCS11_TOKEN_SERIAL:
 
1649
      str = p11_kit_uri_get_token_info (info)->serial_number;
 
1650
      str_max = 16;
 
1651
      break;
 
1652
    case GNUTLS_PKCS11_TOKEN_MANUFACTURER:
 
1653
      str = p11_kit_uri_get_token_info (info)->manufacturer_id;
 
1654
      str_max = 32;
 
1655
      break;
 
1656
    case GNUTLS_PKCS11_TOKEN_MODEL:
 
1657
      str = p11_kit_uri_get_token_info (info)->model;
 
1658
      str_max = 16;
 
1659
      break;
 
1660
    default:
 
1661
      p11_kit_uri_free (info);
 
1662
      gnutls_assert ();
 
1663
      return GNUTLS_E_INVALID_REQUEST;
 
1664
    }
 
1665
 
 
1666
  len = p11_kit_space_strlen (str, str_max);
 
1667
 
 
1668
  if (len + 1 > *output_size)
 
1669
    {
 
1670
      *output_size = len + 1;
 
1671
      return GNUTLS_E_SHORT_MEMORY_BUFFER;
 
1672
    }
 
1673
 
 
1674
  memcpy (output, str, len);
 
1675
  ((char*)output)[len] = '\0';
 
1676
 
 
1677
  *output_size = len;
 
1678
 
 
1679
  p11_kit_uri_free (info);
 
1680
  return 0;
 
1681
}
 
1682
 
 
1683
/**
 
1684
 * gnutls_pkcs11_obj_export_url:
 
1685
 * @obj: Holds the PKCS 11 certificate
 
1686
 * @detailed: non zero if a detailed URL is required
 
1687
 * @url: will contain an allocated url
 
1688
 *
 
1689
 * This function will export a URL identifying the given certificate.
 
1690
 *
 
1691
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
 
1692
 *   negative error value.
 
1693
 **/
 
1694
int
 
1695
gnutls_pkcs11_obj_export_url (gnutls_pkcs11_obj_t obj,
 
1696
                              gnutls_pkcs11_url_type_t detailed, char **url)
 
1697
{
 
1698
  int ret;
 
1699
 
 
1700
  ret = pkcs11_info_to_url (obj->info, detailed, url);
 
1701
  if (ret < 0)
 
1702
    {
 
1703
      gnutls_assert ();
 
1704
      return ret;
 
1705
    }
 
1706
 
 
1707
  return 0;
 
1708
}
 
1709
 
 
1710
/**
 
1711
 * gnutls_pkcs11_obj_get_type:
 
1712
 * @certificate: Holds the PKCS 11 certificate
 
1713
 *
 
1714
 * This function will return the type of the certificate being
 
1715
 * stored in the structure.
 
1716
 *
 
1717
 * Returns: The type of the certificate.
 
1718
 **/
 
1719
gnutls_pkcs11_obj_type_t
 
1720
gnutls_pkcs11_obj_get_type (gnutls_pkcs11_obj_t obj)
 
1721
{
 
1722
  return obj->type;
 
1723
}
 
1724
 
 
1725
struct pkey_list
 
1726
{
 
1727
  gnutls_buffer_st *key_ids;
 
1728
  size_t key_ids_size;
 
1729
};
 
1730
 
 
1731
 
 
1732
static int
 
1733
retrieve_pin_for_pinfile (const char *pinfile, struct ck_token_info *token_info,
 
1734
                          int attempts, ck_user_type_t user_type, struct p11_kit_pin **pin)
 
1735
{
 
1736
  unsigned int flags = 0;
 
1737
  struct p11_kit_uri *token_uri;
 
1738
  struct p11_kit_pin *result;
 
1739
  char *label;
 
1740
 
 
1741
  label = p11_kit_space_strdup (token_info->label, sizeof (token_info->label));
 
1742
  if (label == NULL)
 
1743
    {
 
1744
      gnutls_assert ();
 
1745
      return GNUTLS_E_MEMORY_ERROR;
 
1746
    }
 
1747
 
 
1748
  token_uri = p11_kit_uri_new ();
 
1749
  if (token_uri == NULL)
 
1750
    {
 
1751
      free (label);
 
1752
      gnutls_assert ();
 
1753
      return GNUTLS_E_MEMORY_ERROR;
 
1754
    }
 
1755
 
 
1756
  memcpy (p11_kit_uri_get_token_info (token_uri), token_info,
 
1757
          sizeof (struct ck_token_info));
 
1758
 
 
1759
  if (attempts)
 
1760
    flags |= P11_KIT_PIN_FLAGS_RETRY;
 
1761
  if (user_type == CKU_USER)
 
1762
    {
 
1763
      flags |= P11_KIT_PIN_FLAGS_USER_LOGIN;
 
1764
      if (token_info->flags & CKF_USER_PIN_COUNT_LOW)
 
1765
        flags |= P11_KIT_PIN_FLAGS_MANY_TRIES;
 
1766
      if (token_info->flags & CKF_USER_PIN_FINAL_TRY)
 
1767
        flags |= P11_KIT_PIN_FLAGS_FINAL_TRY;
 
1768
    }
 
1769
  else if (user_type == CKU_SO)
 
1770
    {
 
1771
      flags |= P11_KIT_PIN_FLAGS_SO_LOGIN;
 
1772
      if (token_info->flags & CKF_SO_PIN_COUNT_LOW)
 
1773
        flags |= P11_KIT_PIN_FLAGS_MANY_TRIES;
 
1774
      if (token_info->flags & CKF_SO_PIN_FINAL_TRY)
 
1775
        flags |= P11_KIT_PIN_FLAGS_FINAL_TRY;
 
1776
    }
 
1777
  else if (user_type == CKU_CONTEXT_SPECIFIC)
 
1778
    {
 
1779
      flags |= P11_KIT_PIN_FLAGS_CONTEXT_LOGIN;
 
1780
    }
 
1781
 
 
1782
  result = p11_kit_pin_request (pinfile, token_uri, label, flags);
 
1783
  p11_kit_uri_free (token_uri);
 
1784
  free (label);
 
1785
 
 
1786
  if (result == NULL)
 
1787
    {
 
1788
      gnutls_assert ();
 
1789
      return GNUTLS_E_PKCS11_PIN_ERROR;
 
1790
    }
 
1791
 
 
1792
  *pin = result;
 
1793
  return 0;
 
1794
}
 
1795
 
 
1796
static int
 
1797
retrieve_pin_for_callback (struct ck_token_info *token_info, int attempts,
 
1798
                           ck_user_type_t user_type, struct p11_kit_pin **pin)
 
1799
{
 
1800
  char pin_value[GNUTLS_PKCS11_MAX_PIN_LEN];
 
1801
  unsigned int flags = 0;
 
1802
  char *token_str;
 
1803
  char *label;
 
1804
  struct p11_kit_uri *token_uri;
 
1805
  int ret = 0;
 
1806
 
 
1807
  label = p11_kit_space_strdup (token_info->label, sizeof (token_info->label));
 
1808
  if (label == NULL)
 
1809
    {
 
1810
      gnutls_assert ();
 
1811
      return GNUTLS_E_MEMORY_ERROR;
 
1812
    }
 
1813
 
 
1814
  token_uri = p11_kit_uri_new ();
 
1815
  if (token_uri == NULL)
 
1816
    {
 
1817
      free (label);
 
1818
      gnutls_assert ();
 
1819
      return GNUTLS_E_MEMORY_ERROR;
 
1820
    }
 
1821
 
 
1822
  memcpy (p11_kit_uri_get_token_info (token_uri), token_info,
 
1823
          sizeof (struct ck_token_info));
 
1824
  ret = pkcs11_info_to_url (token_uri, 1, &token_str);
 
1825
  p11_kit_uri_free (token_uri);
 
1826
 
 
1827
  if (ret < 0)
 
1828
    {
 
1829
      free (label);
 
1830
      gnutls_assert ();
 
1831
      return GNUTLS_E_MEMORY_ERROR;
 
1832
    }
 
1833
 
 
1834
  if (user_type == CKU_USER)
 
1835
    {
 
1836
      flags |= GNUTLS_PKCS11_PIN_USER;
 
1837
      if (token_info->flags & CKF_USER_PIN_COUNT_LOW)
 
1838
        flags |= GNUTLS_PKCS11_PIN_COUNT_LOW;
 
1839
      if (token_info->flags & CKF_USER_PIN_FINAL_TRY)
 
1840
        flags |= GNUTLS_PKCS11_PIN_FINAL_TRY;
 
1841
    }
 
1842
  else if (user_type == CKU_SO)
 
1843
    {
 
1844
      flags |= GNUTLS_PKCS11_PIN_SO;
 
1845
      if (token_info->flags & CKF_SO_PIN_COUNT_LOW)
 
1846
        flags |= GNUTLS_PKCS11_PIN_COUNT_LOW;
 
1847
      if (token_info->flags & CKF_SO_PIN_FINAL_TRY)
 
1848
        flags |= GNUTLS_PKCS11_PIN_FINAL_TRY;
 
1849
    }
 
1850
 
 
1851
  if (attempts > 0)
 
1852
    flags |= GNUTLS_PKCS11_PIN_WRONG;
 
1853
 
 
1854
  ret = pin_func (pin_data, attempts, (char*)token_str, label,
 
1855
                  flags, pin_value, GNUTLS_PKCS11_MAX_PIN_LEN);
 
1856
  free (token_str);
 
1857
  free (label);
 
1858
 
 
1859
  if (ret < 0)
 
1860
    return gnutls_assert_val(GNUTLS_E_PKCS11_PIN_ERROR);
 
1861
 
 
1862
  *pin = p11_kit_pin_new_for_string (pin_value);
 
1863
  
 
1864
  if (*pin == NULL)
 
1865
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
 
1866
 
 
1867
  return 0;
 
1868
}
 
1869
 
 
1870
static int
 
1871
retrieve_pin (struct p11_kit_uri *info, struct ck_token_info *token_info,
 
1872
              int attempts, ck_user_type_t user_type, struct p11_kit_pin **pin)
 
1873
{
 
1874
  const char *pinfile;
 
1875
 
 
1876
  *pin = NULL;
 
1877
 
 
1878
  /* Check if a pinfile is specified, and use that if possible */
 
1879
  pinfile = p11_kit_uri_get_pinfile (info);
 
1880
  if (pinfile != NULL)
 
1881
    {
 
1882
      _gnutls_debug_log("pk11: Using pinfile to retrieve PIN\n");
 
1883
      return retrieve_pin_for_pinfile (pinfile, token_info, attempts, user_type, pin);
 
1884
    }
 
1885
 
 
1886
  /* The global gnutls pin callback */
 
1887
  else if (pin_func)
 
1888
    return retrieve_pin_for_callback (token_info, attempts, user_type, pin);
 
1889
 
 
1890
  /* Otherwise, PIN entry is necessary for login, so fail if there's
 
1891
   * no callback. */
 
1892
  else
 
1893
    {
 
1894
      gnutls_assert ();
 
1895
      _gnutls_debug_log ("pk11: No pin callback but login required.\n");
 
1896
      return GNUTLS_E_PKCS11_ERROR;
 
1897
    }
 
1898
}
 
1899
 
 
1900
int
 
1901
pkcs11_login (struct ck_function_list * module, ck_session_handle_t pks,
 
1902
              const struct token_info *tokinfo, struct p11_kit_uri *info, int so)
 
1903
{
 
1904
  struct ck_session_info session_info;
 
1905
  int attempt = 0, ret;
 
1906
  ck_user_type_t user_type;
 
1907
  ck_rv_t rv;
 
1908
 
 
1909
  user_type = (so == 0) ? CKU_USER : CKU_SO;
 
1910
  if (so == 0 && (tokinfo->tinfo.flags & CKF_LOGIN_REQUIRED) == 0)
 
1911
    {
 
1912
      gnutls_assert ();
 
1913
      _gnutls_debug_log ("pk11: No login required.\n");
 
1914
      return 0;
 
1915
    }
 
1916
 
 
1917
  /* For a token with a "protected" (out-of-band) authentication
 
1918
   * path, calling login with a NULL username is all that is
 
1919
   * required. */
 
1920
  if (tokinfo->tinfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
 
1921
    {
 
1922
      rv = (module)->C_Login (pks, (so == 0) ? CKU_USER : CKU_SO, NULL, 0);
 
1923
      if (rv == CKR_OK || rv == CKR_USER_ALREADY_LOGGED_IN)
 
1924
        {
 
1925
          return 0;
 
1926
        }
 
1927
      else
 
1928
        {
 
1929
          gnutls_assert ();
 
1930
          _gnutls_debug_log ("pk11: Protected login failed.\n");
 
1931
          ret = GNUTLS_E_PKCS11_ERROR;
 
1932
          goto cleanup;
 
1933
        }
 
1934
    }
 
1935
 
 
1936
  do
 
1937
    {
 
1938
      struct p11_kit_pin *pin;
 
1939
      struct ck_token_info tinfo;
 
1940
 
 
1941
      memcpy (&tinfo, &tokinfo->tinfo, sizeof(tinfo));
 
1942
 
 
1943
      /* Check whether the session is already logged in, and if so, just skip */
 
1944
      rv = (module)->C_GetSessionInfo (pks, &session_info);
 
1945
      if (rv == CKR_OK && (session_info.state == CKS_RO_USER_FUNCTIONS ||
 
1946
                           session_info.state == CKS_RW_USER_FUNCTIONS))
 
1947
        {
 
1948
          ret = 0;
 
1949
          goto cleanup;
 
1950
        }
 
1951
 
 
1952
      /* If login has been attempted once already, check the token
 
1953
       * status again, the flags might change. */
 
1954
      if (attempt)
 
1955
        {
 
1956
          if (pkcs11_get_token_info
 
1957
              (tokinfo->prov->module, tokinfo->sid, &tinfo) != CKR_OK)
 
1958
            {
 
1959
              gnutls_assert ();
 
1960
              _gnutls_debug_log ("pk11: GetTokenInfo failed\n");
 
1961
              ret = GNUTLS_E_PKCS11_ERROR;
 
1962
              goto cleanup;
 
1963
            }
 
1964
        }
 
1965
 
 
1966
      ret = retrieve_pin (info, &tinfo, attempt++, user_type, &pin);
 
1967
      if (ret < 0)
 
1968
        {
 
1969
          gnutls_assert ();
 
1970
          goto cleanup;
 
1971
        }
 
1972
 
 
1973
      rv = (module)->C_Login (pks, user_type,
 
1974
                              (unsigned char *)p11_kit_pin_get_value (pin, NULL),
 
1975
                              p11_kit_pin_get_length (pin));
 
1976
 
 
1977
      p11_kit_pin_unref (pin);
 
1978
    }
 
1979
  while (rv == CKR_PIN_INCORRECT);
 
1980
 
 
1981
  _gnutls_debug_log ("pk11: Login result = %lu\n", rv);
 
1982
 
 
1983
 
 
1984
  ret = (rv == CKR_OK
 
1985
         || rv == CKR_USER_ALREADY_LOGGED_IN) ? 0 : pkcs11_rv_to_err (rv);
 
1986
 
 
1987
cleanup:
 
1988
  return ret;
 
1989
}
 
1990
 
 
1991
int
 
1992
pkcs11_call_token_func (struct p11_kit_uri *info, const unsigned retry)
 
1993
{
 
1994
  struct ck_token_info *tinfo;
 
1995
  char *label;
 
1996
  int ret = 0;
 
1997
 
 
1998
  tinfo = p11_kit_uri_get_token_info (info);
 
1999
  label = p11_kit_space_strdup (tinfo->label, sizeof (tinfo->label));
 
2000
  ret = (token_func) (token_data, label, retry);
 
2001
  free (label);
 
2002
 
 
2003
  return ret;
 
2004
}
 
2005
 
 
2006
 
 
2007
static int
 
2008
find_privkeys (struct ck_function_list *module, ck_session_handle_t pks,
 
2009
               struct token_info *info, struct pkey_list *list)
 
2010
{
 
2011
  struct ck_attribute a[3];
 
2012
  ck_object_class_t class;
 
2013
  ck_rv_t rv;
 
2014
  ck_object_handle_t obj;
 
2015
  unsigned long count, current;
 
2016
  char certid_tmp[PKCS11_ID_SIZE];
 
2017
 
 
2018
  class = CKO_PRIVATE_KEY;
 
2019
 
 
2020
  /* Find an object with private key class and a certificate ID
 
2021
   * which matches the certificate. */
 
2022
  /* FIXME: also match the cert subject. */
 
2023
  a[0].type = CKA_CLASS;
 
2024
  a[0].value = &class;
 
2025
  a[0].value_len = sizeof class;
 
2026
 
 
2027
  rv = pkcs11_find_objects_init (module, pks, a, 1);
 
2028
  if (rv != CKR_OK)
 
2029
    {
 
2030
      gnutls_assert ();
 
2031
      return pkcs11_rv_to_err (rv);
 
2032
    }
 
2033
 
 
2034
  list->key_ids_size = 0;
 
2035
  while (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK && count == 1)
 
2036
    {
 
2037
      list->key_ids_size++;
 
2038
    }
 
2039
 
 
2040
  pkcs11_find_objects_final (module, pks);
 
2041
 
 
2042
  if (list->key_ids_size == 0)
 
2043
    {
 
2044
      gnutls_assert ();
 
2045
      return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
 
2046
    }
 
2047
 
 
2048
  list->key_ids =
 
2049
    gnutls_malloc (sizeof (gnutls_buffer_st) * list->key_ids_size);
 
2050
  if (list->key_ids == NULL)
 
2051
    {
 
2052
      gnutls_assert ();
 
2053
      return GNUTLS_E_MEMORY_ERROR;
 
2054
    }
 
2055
 
 
2056
  /* actual search */
 
2057
  a[0].type = CKA_CLASS;
 
2058
  a[0].value = &class;
 
2059
  a[0].value_len = sizeof class;
 
2060
 
 
2061
  rv = pkcs11_find_objects_init (module, pks, a, 1);
 
2062
  if (rv != CKR_OK)
 
2063
    {
 
2064
      gnutls_assert ();
 
2065
      return pkcs11_rv_to_err (rv);
 
2066
    }
 
2067
 
 
2068
  current = 0;
 
2069
  while (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK && count == 1)
 
2070
    {
 
2071
 
 
2072
      a[0].type = CKA_ID;
 
2073
      a[0].value = certid_tmp;
 
2074
      a[0].value_len = sizeof (certid_tmp);
 
2075
 
 
2076
      _gnutls_buffer_init (&list->key_ids[current]);
 
2077
 
 
2078
      if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
 
2079
        {
 
2080
          _gnutls_buffer_append_data (&list->key_ids[current],
 
2081
                                      a[0].value, a[0].value_len);
 
2082
          current++;
 
2083
        }
 
2084
 
 
2085
      if (current > list->key_ids_size)
 
2086
        break;
 
2087
    }
 
2088
 
 
2089
  pkcs11_find_objects_final (module, pks);
 
2090
 
 
2091
  list->key_ids_size = current - 1;
 
2092
 
 
2093
  return 0;
 
2094
}
 
2095
 
 
2096
/* Recover certificate list from tokens */
 
2097
 
 
2098
 
 
2099
static int
 
2100
find_objs (struct ck_function_list * module, ck_session_handle_t pks,
 
2101
           struct token_info *info, struct ck_info *lib_info, void *input)
 
2102
{
 
2103
  struct crt_find_data_st *find_data = input;
 
2104
  struct ck_attribute a[4];
 
2105
  struct ck_attribute *attr;
 
2106
  ck_object_class_t class = -1;
 
2107
  ck_certificate_type_t type = -1;
 
2108
  unsigned int trusted;
 
2109
  ck_rv_t rv;
 
2110
  ck_object_handle_t obj;
 
2111
  unsigned long count;
 
2112
  opaque *cert_data;
 
2113
  char certid_tmp[PKCS11_ID_SIZE];
 
2114
  char label_tmp[PKCS11_LABEL_SIZE];
 
2115
  int ret, i;
 
2116
  struct pkey_list plist;       /* private key holder */
 
2117
  int tot_values = 0;
 
2118
 
 
2119
  if (info == NULL)
 
2120
    {                           /* final call */
 
2121
      if (find_data->current <= *find_data->n_list)
 
2122
        ret = 0;
 
2123
      else
 
2124
        ret = GNUTLS_E_SHORT_MEMORY_BUFFER;
 
2125
 
 
2126
      *find_data->n_list = find_data->current;
 
2127
 
 
2128
      return ret;
 
2129
    }
 
2130
 
 
2131
  /* do not bother reading the token if basic fields do not match
 
2132
   */
 
2133
  if (!p11_kit_uri_match_token_info (find_data->info, &info->tinfo) ||
 
2134
      !p11_kit_uri_match_module_info (find_data->info, lib_info))
 
2135
    {
 
2136
      gnutls_assert ();
 
2137
      return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
 
2138
    }
 
2139
 
 
2140
  memset (&plist, 0, sizeof (plist));
 
2141
 
 
2142
  if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY)
 
2143
    {
 
2144
      ret = find_privkeys (module, pks, info, &plist);
 
2145
      if (ret < 0)
 
2146
        {
 
2147
          gnutls_assert ();
 
2148
          return ret;
 
2149
        }
 
2150
 
 
2151
      if (plist.key_ids_size == 0)
 
2152
        {
 
2153
          gnutls_assert ();
 
2154
          return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
 
2155
        }
 
2156
    }
 
2157
 
 
2158
  cert_data = gnutls_malloc (MAX_CERT_SIZE);
 
2159
  if (cert_data == NULL)
 
2160
    {
 
2161
      gnutls_assert ();
 
2162
      return GNUTLS_E_MEMORY_ERROR;
 
2163
    }
 
2164
 
 
2165
  /* Find objects with cert class and X.509 cert type. */
 
2166
 
 
2167
  tot_values = 0;
 
2168
 
 
2169
  if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_ALL
 
2170
      || find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY)
 
2171
    {
 
2172
      class = CKO_CERTIFICATE;
 
2173
      type = CKC_X_509;
 
2174
      trusted = 1;
 
2175
 
 
2176
      a[tot_values].type = CKA_CLASS;
 
2177
      a[tot_values].value = &class;
 
2178
      a[tot_values].value_len = sizeof class;
 
2179
      tot_values++;
 
2180
 
 
2181
      a[tot_values].type = CKA_CERTIFICATE_TYPE;
 
2182
      a[tot_values].value = &type;
 
2183
      a[tot_values].value_len = sizeof type;
 
2184
      tot_values++;
 
2185
 
 
2186
    }
 
2187
  else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED)
 
2188
    {
 
2189
      class = CKO_CERTIFICATE;
 
2190
      type = CKC_X_509;
 
2191
      trusted = 1;
 
2192
 
 
2193
      a[tot_values].type = CKA_CLASS;
 
2194
      a[tot_values].value = &class;
 
2195
      a[tot_values].value_len = sizeof class;
 
2196
      tot_values++;
 
2197
 
 
2198
      a[tot_values].type = CKA_TRUSTED;
 
2199
      a[tot_values].value = &trusted;
 
2200
      a[tot_values].value_len = sizeof trusted;
 
2201
      tot_values++;
 
2202
 
 
2203
    }
 
2204
  else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_PUBKEY)
 
2205
    {
 
2206
      class = CKO_PUBLIC_KEY;
 
2207
 
 
2208
      a[tot_values].type = CKA_CLASS;
 
2209
      a[tot_values].value = &class;
 
2210
      a[tot_values].value_len = sizeof class;
 
2211
      tot_values++;
 
2212
    }
 
2213
  else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY)
 
2214
    {
 
2215
      class = CKO_PRIVATE_KEY;
 
2216
 
 
2217
      a[tot_values].type = CKA_CLASS;
 
2218
      a[tot_values].value = &class;
 
2219
      a[tot_values].value_len = sizeof class;
 
2220
      tot_values++;
 
2221
    }
 
2222
  else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_ALL)
 
2223
    {
 
2224
      if (class != -1)
 
2225
        {
 
2226
          a[tot_values].type = CKA_CLASS;
 
2227
          a[tot_values].value = &class;
 
2228
          a[tot_values].value_len = sizeof class;
 
2229
          tot_values++;
 
2230
        }
 
2231
      if (type != -1)
 
2232
        {
 
2233
          a[tot_values].type = CKA_CERTIFICATE_TYPE;
 
2234
          a[tot_values].value = &type;
 
2235
          a[tot_values].value_len = sizeof type;
 
2236
          tot_values++;
 
2237
        }
 
2238
    }
 
2239
  else
 
2240
    {
 
2241
      gnutls_assert ();
 
2242
      ret = GNUTLS_E_INVALID_REQUEST;
 
2243
      goto fail;
 
2244
    }
 
2245
 
 
2246
  attr = p11_kit_uri_get_attribute (find_data->info, CKA_ID);
 
2247
  if (attr != NULL)
 
2248
    {
 
2249
      memcpy (a + tot_values, attr, sizeof (struct ck_attribute));
 
2250
      tot_values++;
 
2251
    }
 
2252
 
 
2253
  rv = pkcs11_find_objects_init (module, pks, a, tot_values);
 
2254
  if (rv != CKR_OK)
 
2255
    {
 
2256
      gnutls_assert ();
 
2257
      _gnutls_debug_log ("pk11: FindObjectsInit failed.\n");
 
2258
      return pkcs11_rv_to_err (rv);
 
2259
    }
 
2260
 
 
2261
  while (pkcs11_find_objects (module, pks, &obj, 1, &count) == CKR_OK && count == 1)
 
2262
    {
 
2263
      gnutls_datum_t label, id, value;
 
2264
 
 
2265
      a[0].type = CKA_LABEL;
 
2266
      a[0].value = label_tmp;
 
2267
      a[0].value_len = sizeof label_tmp;
 
2268
 
 
2269
      if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
 
2270
        {
 
2271
          label.data = a[0].value;
 
2272
          label.size = a[0].value_len;
 
2273
        }
 
2274
      else
 
2275
        {
 
2276
          label.data = NULL;
 
2277
          label.size = 0;
 
2278
        }
 
2279
 
 
2280
      a[0].type = CKA_ID;
 
2281
      a[0].value = certid_tmp;
 
2282
      a[0].value_len = sizeof certid_tmp;
 
2283
 
 
2284
      if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
 
2285
        {
 
2286
          id.data = a[0].value;
 
2287
          id.size = a[0].value_len;
 
2288
        }
 
2289
      else
 
2290
        {
 
2291
          id.data = NULL;
 
2292
          id.size = 0;
 
2293
        }
 
2294
 
 
2295
      a[0].type = CKA_VALUE;
 
2296
      a[0].value = cert_data;
 
2297
      a[0].value_len = MAX_CERT_SIZE;
 
2298
      if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
 
2299
        {
 
2300
          value.data = a[0].value;
 
2301
          value.size = a[0].value_len;
 
2302
        }
 
2303
      else
 
2304
        {
 
2305
          value.data = NULL;
 
2306
          value.size = 0;
 
2307
        }
 
2308
 
 
2309
      if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_ALL)
 
2310
        {
 
2311
          a[0].type = CKA_CLASS;
 
2312
          a[0].value = &class;
 
2313
          a[0].value_len = sizeof class;
 
2314
 
 
2315
          pkcs11_get_attribute_value (module, pks, obj, a, 1);
 
2316
        }
 
2317
 
 
2318
      if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY)
 
2319
        {
 
2320
          for (i = 0; i < plist.key_ids_size; i++)
 
2321
            {
 
2322
              if (plist.key_ids[i].length !=
 
2323
                  a[1].value_len
 
2324
                  || memcmp (plist.key_ids[i].data,
 
2325
                             a[1].value, a[1].value_len) != 0)
 
2326
                {
 
2327
                  /* not found */
 
2328
                  continue;
 
2329
                }
 
2330
            }
 
2331
        }
 
2332
 
 
2333
      if (find_data->current < *find_data->n_list)
 
2334
        {
 
2335
          ret =
 
2336
            gnutls_pkcs11_obj_init (&find_data->p_list[find_data->current]);
 
2337
          if (ret < 0)
 
2338
            {
 
2339
              gnutls_assert ();
 
2340
              goto fail;
 
2341
            }
 
2342
 
 
2343
          if (class == CKO_PUBLIC_KEY)
 
2344
            {
 
2345
              ret =
 
2346
                pkcs11_obj_import_pubkey (module, pks, obj,
 
2347
                                          find_data->p_list
 
2348
                                          [find_data->current],
 
2349
                                          &id, &label,
 
2350
                                          &info->tinfo, lib_info);
 
2351
            }
 
2352
          else
 
2353
            {
 
2354
              ret =
 
2355
                pkcs11_obj_import (class,
 
2356
                                   find_data->p_list
 
2357
                                   [find_data->current],
 
2358
                                   &value, &id, &label,
 
2359
                                   &info->tinfo, lib_info);
 
2360
            }
 
2361
          if (ret < 0)
 
2362
            {
 
2363
              gnutls_assert ();
 
2364
              goto fail;
 
2365
            }
 
2366
        }
 
2367
 
 
2368
      find_data->current++;
 
2369
 
 
2370
    }
 
2371
 
 
2372
  gnutls_free (cert_data);
 
2373
  pkcs11_find_objects_final (module, pks);
 
2374
 
 
2375
  return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; /* continue until all tokens have been checked */
 
2376
 
 
2377
fail:
 
2378
  gnutls_free (cert_data);
 
2379
  pkcs11_find_objects_final (module, pks);
 
2380
  if (plist.key_ids != NULL)
 
2381
    {
 
2382
      for (i = 0; i < plist.key_ids_size; i++)
 
2383
        {
 
2384
          _gnutls_buffer_clear (&plist.key_ids[i]);
 
2385
        }
 
2386
      gnutls_free (plist.key_ids);
 
2387
    }
 
2388
  for (i = 0; i < find_data->current; i++)
 
2389
    {
 
2390
      gnutls_pkcs11_obj_deinit (find_data->p_list[i]);
 
2391
    }
 
2392
  find_data->current = 0;
 
2393
 
 
2394
  return ret;
 
2395
}
 
2396
 
 
2397
/**
 
2398
 * gnutls_pkcs11_obj_list_import_url:
 
2399
 * @p_list: An uninitialized object list (may be NULL)
 
2400
 * @n_list: initially should hold the maximum size of the list. Will contain the actual size.
 
2401
 * @url: A PKCS 11 url identifying a set of objects
 
2402
 * @attrs: Attributes of type #gnutls_pkcs11_obj_attr_t that can be used to limit output
 
2403
 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
 
2404
 *
 
2405
 * This function will initialize and set values to an object list
 
2406
 * by using all objects identified by a PKCS 11 URL.
 
2407
 *
 
2408
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
 
2409
 *   negative error value.
 
2410
 **/
 
2411
int
 
2412
gnutls_pkcs11_obj_list_import_url (gnutls_pkcs11_obj_t * p_list,
 
2413
                                   unsigned int *n_list,
 
2414
                                   const char *url,
 
2415
                                   gnutls_pkcs11_obj_attr_t attrs,
 
2416
                                   unsigned int flags)
 
2417
{
 
2418
  int ret;
 
2419
  struct crt_find_data_st find_data;
 
2420
 
 
2421
  memset (&find_data, 0, sizeof (find_data));
 
2422
 
 
2423
  /* fill in the find data structure */
 
2424
  find_data.p_list = p_list;
 
2425
  find_data.n_list = n_list;
 
2426
  find_data.flags = attrs;
 
2427
  find_data.current = 0;
 
2428
 
 
2429
  if (url == NULL || url[0] == 0)
 
2430
    {
 
2431
      url = "pkcs11:";
 
2432
    }
 
2433
 
 
2434
  ret = pkcs11_url_to_info (url, &find_data.info);
 
2435
  if (ret < 0)
 
2436
    {
 
2437
      gnutls_assert ();
 
2438
      return ret;
 
2439
    }
 
2440
 
 
2441
  ret =
 
2442
    _pkcs11_traverse_tokens (find_objs, &find_data, find_data.info,
 
2443
                             pkcs11_obj_flags_to_int (flags));
 
2444
  p11_kit_uri_free (find_data.info);
 
2445
 
 
2446
  if (ret < 0)
 
2447
    {
 
2448
      gnutls_assert ();
 
2449
      return ret;
 
2450
    }
 
2451
 
 
2452
  return 0;
 
2453
}
 
2454
 
 
2455
/**
 
2456
 * gnutls_x509_crt_import_pkcs11_url:
 
2457
 * @crt: A certificate of type #gnutls_x509_crt_t
 
2458
 * @url: A PKCS 11 url
 
2459
 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
 
2460
 *
 
2461
 * This function will import a PKCS 11 certificate directly from a token
 
2462
 * without involving the #gnutls_pkcs11_obj_t structure. This function will
 
2463
 * fail if the certificate stored is not of X.509 type.
 
2464
 *
 
2465
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
 
2466
 *   negative error value.
 
2467
 **/
 
2468
int
 
2469
gnutls_x509_crt_import_pkcs11_url (gnutls_x509_crt_t crt,
 
2470
                                   const char *url, unsigned int flags)
 
2471
{
 
2472
  gnutls_pkcs11_obj_t pcrt;
 
2473
  int ret;
 
2474
 
 
2475
  ret = gnutls_pkcs11_obj_init (&pcrt);
 
2476
  if (ret < 0)
 
2477
    {
 
2478
      gnutls_assert ();
 
2479
      return ret;
 
2480
    }
 
2481
 
 
2482
  ret = gnutls_pkcs11_obj_import_url (pcrt, url, flags);
 
2483
  if (ret < 0)
 
2484
    {
 
2485
      gnutls_assert ();
 
2486
      goto cleanup;
 
2487
    }
 
2488
 
 
2489
  ret = gnutls_x509_crt_import (crt, &pcrt->raw, GNUTLS_X509_FMT_DER);
 
2490
  if (ret < 0)
 
2491
    {
 
2492
      gnutls_assert ();
 
2493
      goto cleanup;
 
2494
    }
 
2495
 
 
2496
  ret = 0;
 
2497
cleanup:
 
2498
 
 
2499
  gnutls_pkcs11_obj_deinit (pcrt);
 
2500
 
 
2501
  return ret;
 
2502
}
 
2503
 
 
2504
 
 
2505
/**
 
2506
 * gnutls_x509_crt_import_pkcs11:
 
2507
 * @crt: A certificate of type #gnutls_x509_crt_t
 
2508
 * @pkcs11_crt: A PKCS 11 object that contains a certificate
 
2509
 *
 
2510
 * This function will import a PKCS 11 certificate to a #gnutls_x509_crt_t
 
2511
 * structure.
 
2512
 *
 
2513
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
 
2514
 *   negative error value.
 
2515
 **/
 
2516
int
 
2517
gnutls_x509_crt_import_pkcs11 (gnutls_x509_crt_t crt,
 
2518
                               gnutls_pkcs11_obj_t pkcs11_crt)
 
2519
{
 
2520
  return gnutls_x509_crt_import (crt, &pkcs11_crt->raw, GNUTLS_X509_FMT_DER);
 
2521
}
 
2522
 
 
2523
/**
 
2524
 * gnutls_x509_crt_list_import_pkcs11:
 
2525
 * @certs: A list of certificates of type #gnutls_x509_crt_t
 
2526
 * @cert_max: The maximum size of the list
 
2527
 * @objs: A list of PKCS 11 objects
 
2528
 * @flags: 0 for now
 
2529
 *
 
2530
 * This function will import a PKCS 11 certificate list to a list of 
 
2531
 * #gnutls_x509_crt_t structure. These must not be initialized.
 
2532
 *
 
2533
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
 
2534
 *   negative error value.
 
2535
 **/
 
2536
int
 
2537
gnutls_x509_crt_list_import_pkcs11 (gnutls_x509_crt_t * certs,
 
2538
                                    unsigned int cert_max,
 
2539
                                    gnutls_pkcs11_obj_t * const objs,
 
2540
                                    unsigned int flags)
 
2541
{
 
2542
  int i, j;
 
2543
  int ret;
 
2544
 
 
2545
  for (i = 0; i < cert_max; i++)
 
2546
    {
 
2547
      ret = gnutls_x509_crt_init (&certs[i]);
 
2548
      if (ret < 0)
 
2549
        {
 
2550
          gnutls_assert ();
 
2551
          goto cleanup;
 
2552
        }
 
2553
 
 
2554
      ret = gnutls_x509_crt_import_pkcs11 (certs[i], objs[i]);
 
2555
      if (ret < 0)
 
2556
        {
 
2557
          gnutls_assert ();
 
2558
          goto cleanup;
 
2559
        }
 
2560
    }
 
2561
 
 
2562
  return 0;
 
2563
 
 
2564
cleanup:
 
2565
  for (j = 0; j < i; j++)
 
2566
    {
 
2567
      gnutls_x509_crt_deinit (certs[j]);
 
2568
    }
 
2569
 
 
2570
  return ret;
 
2571
}
 
2572
 
 
2573
static int
 
2574
find_flags (struct ck_function_list * module, ck_session_handle_t pks,
 
2575
            struct token_info *info, struct ck_info *lib_info, void *input)
 
2576
{
 
2577
  struct flags_find_data_st *find_data = input;
 
2578
 
 
2579
  if (info == NULL)
 
2580
    {                           /* we don't support multiple calls */
 
2581
      gnutls_assert ();
 
2582
      return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
 
2583
    }
 
2584
 
 
2585
  /* do not bother reading the token if basic fields do not match
 
2586
   */
 
2587
  if (!p11_kit_uri_match_token_info (find_data->info, &info->tinfo) ||
 
2588
      !p11_kit_uri_match_module_info (find_data->info, lib_info))
 
2589
    {
 
2590
      gnutls_assert ();
 
2591
      return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
 
2592
    }
 
2593
 
 
2594
  /* found token! */
 
2595
 
 
2596
  find_data->slot_flags = info->sinfo.flags;
 
2597
 
 
2598
  return 0;
 
2599
}
 
2600
 
 
2601
/**
 
2602
 * gnutls_pkcs11_token_get_flags:
 
2603
 * @url: should contain a PKCS 11 URL
 
2604
 * @flags: The output flags (GNUTLS_PKCS11_TOKEN_*)
 
2605
 *
 
2606
 * This function will return information about the PKCS 11 token flags.
 
2607
 *
 
2608
 * Returns: zero on success or a negative value on error.
 
2609
 **/
 
2610
int
 
2611
gnutls_pkcs11_token_get_flags (const char *url, unsigned int *flags)
 
2612
{
 
2613
  struct flags_find_data_st find_data;
 
2614
  int ret;
 
2615
 
 
2616
  memset (&find_data, 0, sizeof (find_data));
 
2617
  ret = pkcs11_url_to_info (url, &find_data.info);
 
2618
  if (ret < 0)
 
2619
    {
 
2620
      gnutls_assert ();
 
2621
      return ret;
 
2622
    }
 
2623
 
 
2624
  ret = _pkcs11_traverse_tokens (find_flags, &find_data, find_data.info, 0);
 
2625
  p11_kit_uri_free (find_data.info);
 
2626
 
 
2627
  if (ret < 0)
 
2628
    {
 
2629
      gnutls_assert ();
 
2630
      return ret;
 
2631
    }
 
2632
 
 
2633
  *flags = 0;
 
2634
  if (find_data.slot_flags & CKF_HW_SLOT)
 
2635
    *flags |= GNUTLS_PKCS11_TOKEN_HW;
 
2636
 
 
2637
  return 0;
 
2638
 
 
2639
}
 
2640
 
 
2641
 
 
2642
/**
 
2643
 * gnutls_pkcs11_token_get_mechanism:
 
2644
 * @url: should contain a PKCS 11 URL
 
2645
 * @idx: The index of the mechanism
 
2646
 * @mechanism: The PKCS #11 mechanism ID
 
2647
 *
 
2648
 * This function will return the names of the supported mechanisms
 
2649
 * by the token. It should be called with an increasing index until
 
2650
 * it return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE.
 
2651
 *
 
2652
 * Returns: zero on success or a negative value on error.
 
2653
 **/
 
2654
int
 
2655
gnutls_pkcs11_token_get_mechanism (const char *url, int idx,
 
2656
                                   unsigned long *mechanism)
 
2657
{
 
2658
  int ret;
 
2659
  ck_rv_t rv;
 
2660
  struct ck_function_list *module;
 
2661
  ck_slot_id_t slot;
 
2662
  struct token_info tinfo;
 
2663
  struct p11_kit_uri *info = NULL;
 
2664
  unsigned long count;
 
2665
  ck_mechanism_type_t mlist[400];
 
2666
 
 
2667
  ret = pkcs11_url_to_info (url, &info);
 
2668
  if (ret < 0)
 
2669
    {
 
2670
      gnutls_assert ();
 
2671
      return ret;
 
2672
    }
 
2673
 
 
2674
 
 
2675
  ret = pkcs11_find_slot (&module, &slot, info, &tinfo);
 
2676
  p11_kit_uri_free (info);
 
2677
 
 
2678
  if (ret < 0)
 
2679
    {
 
2680
      gnutls_assert ();
 
2681
      return ret;
 
2682
    }
 
2683
 
 
2684
  count = sizeof (mlist) / sizeof (mlist[0]);
 
2685
  rv = pkcs11_get_mechanism_list (module, slot, mlist, &count);
 
2686
  if (rv != CKR_OK)
 
2687
    {
 
2688
      gnutls_assert ();
 
2689
      return pkcs11_rv_to_err (rv);
 
2690
    }
 
2691
 
 
2692
  if (idx >= count)
 
2693
    {
 
2694
      gnutls_assert ();
 
2695
      return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
 
2696
    }
 
2697
 
 
2698
  *mechanism = mlist[idx];
 
2699
 
 
2700
  return 0;
 
2701
 
 
2702
}
 
2703
 
 
2704
 
 
2705
const char *
 
2706
gnutls_pkcs11_type_get_name (gnutls_pkcs11_obj_type_t type)
 
2707
{
 
2708
  switch (type)
 
2709
    {
 
2710
    case GNUTLS_PKCS11_OBJ_X509_CRT:
 
2711
      return "X.509 Certificate";
 
2712
    case GNUTLS_PKCS11_OBJ_PUBKEY:
 
2713
      return "Public key";
 
2714
    case GNUTLS_PKCS11_OBJ_PRIVKEY:
 
2715
      return "Private key";
 
2716
    case GNUTLS_PKCS11_OBJ_SECRET_KEY:
 
2717
      return "Secret key";
 
2718
    case GNUTLS_PKCS11_OBJ_DATA:
 
2719
      return "Data";
 
2720
    case GNUTLS_PKCS11_OBJ_UNKNOWN:
 
2721
    default:
 
2722
      return "Unknown";
 
2723
    }
 
2724
}
 
2725
 
 
2726
ck_rv_t
 
2727
pkcs11_get_slot_list (struct ck_function_list * module, unsigned char token_present,
 
2728
                      ck_slot_id_t *slot_list, unsigned long *count)
 
2729
{
 
2730
        return (module)->C_GetSlotList (token_present, slot_list, count);
 
2731
}
 
2732
 
 
2733
ck_rv_t
 
2734
pkcs11_get_module_info (struct ck_function_list * module,
 
2735
                        struct ck_info * info)
 
2736
{
 
2737
        return (module)->C_GetInfo (info);
 
2738
}
 
2739
 
 
2740
ck_rv_t
 
2741
pkcs11_get_slot_info(struct ck_function_list * module,
 
2742
                     ck_slot_id_t slot_id,
 
2743
                     struct ck_slot_info *info)
 
2744
{
 
2745
        return (module)->C_GetSlotInfo (slot_id, info);
 
2746
}
 
2747
 
 
2748
ck_rv_t
 
2749
pkcs11_get_token_info (struct ck_function_list * module,
 
2750
                       ck_slot_id_t slot_id,
 
2751
                       struct ck_token_info *info)
 
2752
{
 
2753
        return (module)->C_GetTokenInfo (slot_id, info);
 
2754
}
 
2755
 
 
2756
ck_rv_t
 
2757
pkcs11_find_objects_init (struct ck_function_list *module,
 
2758
                          ck_session_handle_t sess,
 
2759
                          struct ck_attribute *templ,
 
2760
                          unsigned long count)
 
2761
{
 
2762
        return (module)->C_FindObjectsInit (sess, templ, count);
 
2763
}
 
2764
 
 
2765
ck_rv_t
 
2766
pkcs11_find_objects (struct ck_function_list *module,
 
2767
                       ck_session_handle_t sess,
 
2768
                       ck_object_handle_t *objects,
 
2769
                       unsigned long max_object_count,
 
2770
                       unsigned long *object_count)
 
2771
{
 
2772
        return (module)->C_FindObjects (sess, objects, max_object_count, object_count);
 
2773
}
 
2774
 
 
2775
ck_rv_t
 
2776
pkcs11_find_objects_final (struct ck_function_list *module,
 
2777
                           ck_session_handle_t sess)
 
2778
{
 
2779
        return (module)->C_FindObjectsFinal (sess);
 
2780
}
 
2781
 
 
2782
ck_rv_t
 
2783
pkcs11_close_session (struct ck_function_list *module,
 
2784
                      ck_session_handle_t sess)
 
2785
{
 
2786
        return (module)->C_CloseSession (sess);
 
2787
}
 
2788
 
 
2789
ck_rv_t
 
2790
pkcs11_get_attribute_value(struct ck_function_list *module,
 
2791
                           ck_session_handle_t sess,
 
2792
                           ck_object_handle_t object,
 
2793
                           struct ck_attribute *templ,
 
2794
                           unsigned long count)
 
2795
{
 
2796
        return (module)->C_GetAttributeValue (sess, object, templ, count);
 
2797
}
 
2798
 
 
2799
ck_rv_t
 
2800
pkcs11_get_mechanism_list (struct ck_function_list *module,
 
2801
                           ck_slot_id_t slot_id,
 
2802
                           ck_mechanism_type_t *mechanism_list,
 
2803
                           unsigned long *count)
 
2804
{
 
2805
        return (module)->C_GetMechanismList (slot_id, mechanism_list, count);
 
2806
}
 
2807
 
 
2808
ck_rv_t
 
2809
pkcs11_sign_init (struct ck_function_list *module,
 
2810
                  ck_session_handle_t sess,
 
2811
                  struct ck_mechanism *mechanism,
 
2812
                  ck_object_handle_t key)
 
2813
{
 
2814
        return (module)->C_SignInit (sess, mechanism, key);
 
2815
}
 
2816
 
 
2817
ck_rv_t
 
2818
pkcs11_sign (struct ck_function_list *module,
 
2819
             ck_session_handle_t sess,
 
2820
             unsigned char *data,
 
2821
             unsigned long data_len,
 
2822
             unsigned char *signature,
 
2823
             unsigned long *signature_len)
 
2824
{
 
2825
        return (module)->C_Sign (sess, data, data_len, signature, signature_len);
 
2826
}
 
2827
 
 
2828
ck_rv_t
 
2829
pkcs11_decrypt_init (struct ck_function_list *module,
 
2830
                     ck_session_handle_t sess,
 
2831
                     struct ck_mechanism *mechanism,
 
2832
                     ck_object_handle_t key)
 
2833
{
 
2834
        return (module)->C_DecryptInit (sess, mechanism, key);
 
2835
}
 
2836
 
 
2837
ck_rv_t
 
2838
pkcs11_decrypt (struct ck_function_list *module,
 
2839
                ck_session_handle_t sess,
 
2840
                unsigned char *encrypted_data,
 
2841
                unsigned long encrypted_data_len,
 
2842
                unsigned char *data, unsigned long *data_len)
 
2843
{
 
2844
        return (module)->C_Decrypt (sess, encrypted_data, encrypted_data_len,
 
2845
                                    data, data_len);
 
2846
}
 
2847
 
 
2848
ck_rv_t
 
2849
pkcs11_create_object (struct ck_function_list *module,
 
2850
                      ck_session_handle_t sess,
 
2851
                      struct ck_attribute *templ,
 
2852
                      unsigned long count,
 
2853
                      ck_object_handle_t *object)
 
2854
{
 
2855
        return (module)->C_CreateObject (sess, templ, count, object);
 
2856
}
 
2857
 
 
2858
ck_rv_t
 
2859
pkcs11_destroy_object (struct ck_function_list *module,
 
2860
                       ck_session_handle_t sess,
 
2861
                       ck_object_handle_t object)
 
2862
{
 
2863
        return (module)->C_DestroyObject (sess, object);
 
2864
}
 
2865
 
 
2866
ck_rv_t
 
2867
pkcs11_init_token (struct ck_function_list *module,
 
2868
                   ck_slot_id_t slot_id, unsigned char *pin,
 
2869
                   unsigned long pin_len, unsigned char *label)
 
2870
{
 
2871
        return (module)->C_InitToken (slot_id, pin, pin_len, label);
 
2872
}
 
2873
 
 
2874
ck_rv_t
 
2875
pkcs11_init_pin (struct ck_function_list *module,
 
2876
                 ck_session_handle_t sess,
 
2877
                 unsigned char *pin,
 
2878
                 unsigned long pin_len)
 
2879
{
 
2880
        return (module)->C_InitPIN (sess, pin, pin_len);
 
2881
}
 
2882
 
 
2883
ck_rv_t
 
2884
pkcs11_set_pin (struct ck_function_list *module,
 
2885
                ck_session_handle_t sess,
 
2886
                unsigned char *old_pin,
 
2887
                unsigned long old_len,
 
2888
                unsigned char *new_pin,
 
2889
                unsigned long new_len)
 
2890
{
 
2891
        return (module)->C_SetPIN (sess, old_pin, old_len, new_pin, new_len);
 
2892
}
 
2893
 
 
2894
const char *
 
2895
pkcs11_strerror (ck_rv_t rv)
 
2896
{
 
2897
        return p11_kit_strerror (rv);
 
2898
}