OpenDNSSEC-libhsm  2.1.6
libhsm.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009 .SE (The Internet Infrastructure Foundation).
3  * Copyright (c) 2009 NLNet Labs.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
25  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include "config.h"
29 
30 #include <stdio.h>
31 #include <string.h>
32 #include <strings.h>
33 #include <stdlib.h>
34 #include <unistd.h>
35 #include <dlfcn.h>
36 #include <ldns/ldns.h>
37 
38 #include <libxml/tree.h>
39 #include <libxml/parser.h>
40 #include <libxml/xpath.h>
41 #include <libxml/xpathInternals.h>
42 #include <libxml/relaxng.h>
43 
44 #include "libhsm.h"
45 #include "libhsmdns.h"
46 #include "compat.h"
47 #include "duration.h"
48 
49 #include <pkcs11.h>
50 #include <pthread.h>
51 
53 #define HSM_TOKEN_LABEL_LENGTH 32
54 
57 pthread_mutex_t _hsm_ctx_mutex = PTHREAD_MUTEX_INITIALIZER;
58 
60 static char const *
61 ldns_pkcs11_rv_str(CK_RV rv)
62 {
63  switch (rv)
64  {
65  case CKR_OK:
66  return "CKR_OK";
67  case CKR_CANCEL:
68  return "CKR_CANCEL";
69  case CKR_HOST_MEMORY:
70  return "CKR_HOST_MEMORY";
71  case CKR_GENERAL_ERROR:
72  return "CKR_GENERAL_ERROR";
74  return "CKR_FUNCTION_FAILED";
76  return "CKR_SLOT_ID_INVALID";
78  return "CKR_ATTRIBUTE_READ_ONLY";
80  return "CKR_ATTRIBUTE_SENSITIVE";
82  return "CKR_ATTRIBUTE_TYPE_INVALID";
84  return "CKR_ATTRIBUTE_VALUE_INVALID";
85  case CKR_DATA_INVALID:
86  return "CKR_DATA_INVALID";
87  case CKR_DATA_LEN_RANGE:
88  return "CKR_DATA_LEN_RANGE";
89  case CKR_DEVICE_ERROR:
90  return "CKR_DEVICE_ERROR";
91  case CKR_DEVICE_MEMORY:
92  return "CKR_DEVICE_MEMORY";
93  case CKR_DEVICE_REMOVED:
94  return "CKR_DEVICE_REMOVED";
96  return "CKR_ENCRYPTED_DATA_INVALID";
98  return "CKR_ENCRYPTED_DATA_LEN_RANGE";
100  return "CKR_FUNCTION_CANCELED";
102  return "CKR_FUNCTION_NOT_PARALLEL";
104  return "CKR_FUNCTION_NOT_SUPPORTED";
106  return "CKR_KEY_HANDLE_INVALID";
107  case CKR_KEY_SIZE_RANGE:
108  return "CKR_KEY_SIZE_RANGE";
110  return "CKR_KEY_TYPE_INCONSISTENT";
112  return "CKR_MECHANISM_INVALID";
114  return "CKR_MECHANISM_PARAM_INVALID";
116  return "CKR_OBJECT_HANDLE_INVALID";
118  return "CKR_OPERATION_ACTIVE";
120  return "CKR_OPERATION_NOT_INITIALIZED";
121  case CKR_PIN_INCORRECT:
122  return "CKR_PIN_INCORRECT";
123  case CKR_PIN_INVALID:
124  return "CKR_PIN_INVALID";
125  case CKR_PIN_LEN_RANGE:
126  return "CKR_PIN_LEN_RANGE";
127  case CKR_SESSION_CLOSED:
128  return "CKR_SESSION_CLOSED";
129  case CKR_SESSION_COUNT:
130  return "CKR_SESSION_COUNT";
132  return "CKR_SESSION_HANDLE_INVALID";
134  return "CKR_SESSION_PARALLEL_NOT_SUPPORTED";
136  return "CKR_SESSION_READ_ONLY";
137  case CKR_SESSION_EXISTS:
138  return "CKR_SESSION_EXISTS";
140  return "CKR_SIGNATURE_INVALID";
142  return "CKR_SIGNATURE_LEN_RANGE";
144  return "CKR_TEMPLATE_INCOMPLETE";
146  return "CKR_TEMPLATE_INCONSISTENT";
148  return "CKR_TOKEN_NOT_PRESENT";
150  return "CKR_TOKEN_NOT_RECOGNIZED";
152  return "CKR_TOKEN_WRITE_PROTECTED";
154  return "CKR_UNWRAPPING_KEY_HANDLE_INVALID";
156  return "CKR_UNWRAPPING_KEY_SIZE_RANGE";
158  return "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT";
160  return "CKR_USER_ALREADY_LOGGED_IN";
162  return "CKR_USER_NOT_LOGGED_IN";
164  return "CKR_USER_PIN_NOT_INITIALIZED";
166  return "CKR_USER_TYPE_INVALID";
168  return "CKR_WRAPPED_KEY_INVALID";
170  return "CKR_WRAPPED_KEY_LEN_RANGE";
172  return "CKR_WRAPPING_KEY_HANDLE_INVALID";
174  return "CKR_WRAPPING_KEY_SIZE_RANGE";
176  return "CKR_WRAPPING_KEY_TYPE_INCONSISTENT";
178  return "CKR_RANDOM_SEED_NOT_SUPPORTED";
179  /*CKR_VENDOR_DEFINED is not a constant but a macro which expands in to an */
180  /*expression. Which we are not allowed to use in a switch.*/
181  /*case CKR_VENDOR_DEFINED:*/
182  case 0x80000000:
183  return "CKR_VENDOR_DEFINED";
185  return "CKR_BUFFER_TOO_SMALL";
187  return "CKR_SAVED_STATE_INVALID";
189  return "CKR_INFORMATION_SENSITIVE";
191  return "CKR_STATE_UNSAVEABLE";
193  return "CKR_CRYPTOKI_NOT_INITIALIZED";
195  return "CKR_CRYPTOKI_ALREADY_INITIALIZED";
196  case CKR_MUTEX_BAD:
197  return "CKR_MUTEX_BAD";
199  return "CKR_MUTEX_NOT_LOCKED";
200  default:
201  return "Unknown error";
202  }
203 }
204 
205 void
206 hsm_ctx_set_error(hsm_ctx_t *ctx, int error, const char *action,
207  const char *message, ...)
208 {
209  va_list args;
210 
211  if (ctx && ctx->error == 0) {
212  ctx->error = error;
213  ctx->error_action = action;
214 
215  va_start(args, message);
216  vsnprintf(ctx->error_message, sizeof(ctx->error_message),
217  message, args);
218  va_end(args);
219  }
220 }
221 
233 static int
234 hsm_pkcs11_check_error(hsm_ctx_t *ctx, CK_RV rv, const char *action)
235 {
236  if (rv != CKR_OK) {
237  if (ctx && ctx->error == 0) {
238  ctx->error = (int) rv;
239  ctx->error_action = action;
240  strlcpy(ctx->error_message, ldns_pkcs11_rv_str(rv), sizeof(ctx->error_message));
241  }
242  return 1;
243  }
244  return 0;
245 }
246 
248 static void
249 hsm_pkcs11_unload_functions(void *handle)
250 {
251  if (handle) {
252 #if defined(HAVE_LOADLIBRARY)
253  /* no idea */
254 #elif defined(HAVE_DLOPEN)
255  (void) dlclose(handle);
256 #endif
257  }
258 }
259 
261 static CK_RV
262 hsm_pkcs11_load_functions(hsm_module_t *module)
263 {
264  CK_C_GetFunctionList pGetFunctionList = NULL;
265 
266  if (module && module->path) {
267  /* library provided by application or user */
268 
269 #if defined(HAVE_LOADLIBRARY)
270  /* Load PKCS #11 library */
271  HINSTANCE hDLL = LoadLibrary(_T(module->path));
272 
273  if (hDLL == NULL) {
274  /* Failed to load the PKCS #11 library */
275  return CKR_FUNCTION_FAILED;
276  }
277 
278  /* Retrieve the entry point for C_GetFunctionList */
279  pGetFunctionList = (CK_C_GetFunctionList)
280  GetProcAddress(hDLL, _T("C_GetFunctionList"));
281 
282 #elif defined(HAVE_DLOPEN)
283  /* Load PKCS #11 library */
284  void* pDynLib = dlopen(module->path, RTLD_NOW | RTLD_LOCAL);
285 
286  if (pDynLib == NULL) {
287  /* Failed to load the PKCS #11 library */
288  return CKR_FUNCTION_FAILED;
289  }
290 
291  /* Retrieve the entry point for C_GetFunctionList */
292  pGetFunctionList = (CK_C_GetFunctionList) dlsym(pDynLib, "C_GetFunctionList");
293  /* Store the handle so we can dlclose it later */
294  module->handle = pDynLib;
295 
296 #else
297  return CKR_FUNCTION_FAILED;
298 #endif
299  } else {
300  /* No library provided, use the statically compiled softHSM */
301 #ifdef HAVE_PKCS11_MODULE
302  return C_GetFunctionList(pkcs11_functions);
303 #else
304  return CKR_FUNCTION_FAILED;
305 #endif
306  }
307 
308  if (pGetFunctionList == NULL) {
309  /* Failed to load the PKCS #11 library */
310  return CKR_FUNCTION_FAILED;
311  }
312 
313  /* Retrieve the function list */
314  (pGetFunctionList)((CK_FUNCTION_LIST_PTR_PTR)(&module->sym));
315  return CKR_OK;
316 }
317 
318 static void
319 hsm_remove_leading_zeroes(CK_BYTE_PTR data, CK_ULONG *len)
320 {
321  CK_BYTE_PTR p = data;
322  CK_ULONG l;
323 
324  if (data == NULL || len == NULL) return;
325 
326  l = *len;
327 
328  while ((unsigned short int)(*p) == 0 && l > 1) {
329  p++;
330  l--;
331  }
332 
333  if (p != data) {
334  memmove(data, p, l);
335  *len = l;
336  }
337 }
338 
339 static int
340 hsm_pkcs11_check_token_name(hsm_ctx_t *ctx,
341  CK_FUNCTION_LIST_PTR pkcs11_functions,
342  CK_SLOT_ID slotId,
343  const char *token_name)
344 {
345  /* token label is always 32 bytes */
346  char token_name_bytes[HSM_TOKEN_LABEL_LENGTH];
347  int result = 0;
348  CK_RV rv;
349  CK_TOKEN_INFO token_info;
350 
351  rv = pkcs11_functions->C_GetTokenInfo(slotId, &token_info);
352  if (hsm_pkcs11_check_error(ctx, rv, "C_GetTokenInfo")) {
353  return 0;
354  }
355 
356  memset(token_name_bytes, ' ', HSM_TOKEN_LABEL_LENGTH);
357  if (strlen(token_name) < HSM_TOKEN_LABEL_LENGTH) {
358  memcpy(token_name_bytes, token_name, strlen(token_name));
359  } else {
360  memcpy(token_name_bytes, token_name, HSM_TOKEN_LABEL_LENGTH);
361  }
362 
363  result = memcmp(token_info.label,
364  token_name_bytes,
366 
367  return result;
368 }
369 
371 hsm_repository_new(char* name, char* module, char* tokenlabel, char* pin,
372  uint8_t use_pubkey, uint8_t allowextract, uint8_t require_backup)
373 {
374  hsm_repository_t* r;
375 
376  if (!name || !module || !tokenlabel) return NULL;
377 
378  r = malloc(sizeof(hsm_repository_t));
379  if (!r) return NULL;
380 
381  r->next = NULL;
382  r->pin = NULL;
383  r->name = strdup(name);
384  r->module = strdup(module);
385  r->tokenlabel = strdup(tokenlabel);
386  if (!r->name || !r->module || !r->tokenlabel) {
388  return NULL;
389  }
390  if (pin) {
391  r->pin = strdup(pin);
392  if (!r->pin) {
394  return NULL;
395  }
396  }
397  r->use_pubkey = use_pubkey;
398  r->allow_extract = allowextract;
399  r->require_backup = require_backup;
400  return r;
401 }
402 
403 void
405 {
406  if (r) {
407  if (r->next) hsm_repository_free(r->next);
408  if (r->name) free(r->name);
409  if (r->module) free(r->module);
410  if (r->tokenlabel) free(r->tokenlabel);
411  if (r->pin) free(r->pin);
412  }
413  free(r);
414 }
415 
416 static int
417 hsm_get_slot_id(hsm_ctx_t *ctx,
418  CK_FUNCTION_LIST_PTR pkcs11_functions,
419  const char *token_name, CK_SLOT_ID *slotId)
420 {
421  CK_RV rv;
422  CK_ULONG slotCount;
423  CK_SLOT_ID cur_slot;
424  CK_SLOT_ID *slotIds;
425  int found = 0;
426 
427  if (token_name == NULL || slotId == NULL) return HSM_ERROR;
428 
429  rv = pkcs11_functions->C_GetSlotList(CK_TRUE, NULL_PTR, &slotCount);
430  if (hsm_pkcs11_check_error(ctx, rv, "get slot list")) {
431  return HSM_ERROR;
432  }
433 
434  if (slotCount < 1) {
435  hsm_ctx_set_error(ctx, HSM_ERROR, "hsm_get_slot_id()",
436  "No slots found in HSM");
437  return HSM_ERROR;
438  } else if (slotCount > (SIZE_MAX / sizeof(CK_SLOT_ID))) {
439  hsm_ctx_set_error(ctx, HSM_ERROR, "hsm_get_slot_id()",
440  "Too many slots found in HSM");
441  return HSM_ERROR;
442  }
443 
444  slotIds = malloc(sizeof(CK_SLOT_ID) * slotCount);
445  if(slotIds == NULL) {
446  hsm_ctx_set_error(ctx, HSM_ERROR, "hsm_get_slot_id()",
447  "Could not allocate slot ID table");
448  return HSM_ERROR;
449  }
450 
451  rv = pkcs11_functions->C_GetSlotList(CK_TRUE, slotIds, &slotCount);
452  if (hsm_pkcs11_check_error(ctx, rv, "get slot list")) {
453  return HSM_ERROR;
454  }
455 
456  for (cur_slot = 0; cur_slot < slotCount; cur_slot++) {
457  if (hsm_pkcs11_check_token_name(ctx,
458  pkcs11_functions,
459  slotIds[cur_slot],
460  token_name)) {
461  *slotId = slotIds[cur_slot];
462  found = 1;
463  break;
464  }
465  }
466  free(slotIds);
467  if (!found) {
468  hsm_ctx_set_error(ctx, -1, "hsm_get_slot_id()",
469  "could not find token with the name %s", token_name);
470  return HSM_ERROR;
471  }
472 
473  return HSM_OK;
474 }
475 
476 /* internal functions */
477 static hsm_module_t *
478 hsm_module_new(const char *repository,
479  const char *token_label,
480  const char *path,
481  const hsm_config_t *config)
482 {
483  hsm_module_t *module;
484 
485  if (!repository || !path) return NULL;
486 
487 
488  module = malloc(sizeof(hsm_module_t));
489  if (!module) return NULL;
490 
491  if (config) {
492  module->config = malloc(sizeof(hsm_config_t));
493  if (!module->config) {
494  free(module);
495  return NULL;
496  }
497  memcpy(module->config, config, sizeof(hsm_config_t));
498  } else {
499  module->config = NULL;
500  }
501 
502  module->id = 0; /*TODO i think we can remove this*/
503  module->name = strdup(repository);
504  module->token_label = strdup(token_label);
505  module->path = strdup(path);
506  module->handle = NULL;
507  module->sym = NULL;
508 
509  return module;
510 }
511 
512 static void
513 hsm_module_free(hsm_module_t *module)
514 {
515  if (module) {
516  if (module->name) free(module->name);
517  if (module->token_label) free(module->token_label);
518  if (module->path) free(module->path);
519  if (module->config) free(module->config);
520 
521  free(module);
522  }
523 }
524 
525 static hsm_session_t *
526 hsm_session_new(hsm_module_t *module, CK_SESSION_HANDLE session_handle)
527 {
528  hsm_session_t *session;
529  session = malloc(sizeof(hsm_session_t));
530  session->module = module;
531  session->session = session_handle;
532  return session;
533 }
534 
535 static void
536 hsm_session_free(hsm_session_t *session) {
537  if (session) {
538  free(session);
539  }
540 }
541 
543 static void
544 hsm_config_default(hsm_config_t *config)
545 {
546  config->use_pubkey = 1;
547  config->allow_extract = 0;
548 }
549 
550 /* creates a session_t structure, and automatically adds and initializes
551  * a module_t struct for it
552  */
553 static int
554 hsm_session_init(hsm_ctx_t *ctx, hsm_session_t **session,
555  const char *repository, const char *token_label,
556  const char *module_path, const char *pin,
557  const hsm_config_t *config)
558 {
559  CK_RV rv;
560  CK_RV rv_login;
561  hsm_module_t *module;
562  CK_SLOT_ID slot_id;
563  CK_SESSION_HANDLE session_handle;
564  int first = 1, result;
565 
566  CK_C_INITIALIZE_ARGS InitArgs = {NULL, NULL, NULL, NULL,
567  CKF_OS_LOCKING_OK, NULL };
568 
569  if (pin == NULL) return HSM_ERROR;
570 
571  module = hsm_module_new(repository, token_label, module_path, config);
572  if (!module) return HSM_ERROR;
573  rv = hsm_pkcs11_load_functions(module);
574  if (rv != CKR_OK) {
576  "hsm_session_init()",
577  "PKCS#11 module load failed: %s", module_path);
578  hsm_module_free(module);
579  return HSM_MODULE_NOT_FOUND;
580  }
581  rv = ((CK_FUNCTION_LIST_PTR) module->sym)->C_Initialize((CK_VOID_PTR) &InitArgs);
582  /* ALREADY_INITIALIZED is ok, apparently we are using a second
583  * device with the same library */
585  if (hsm_pkcs11_check_error(ctx, rv, "Initialization")) {
586  hsm_module_free(module);
587  return HSM_ERROR;
588  }
589  } else {
590  first = 0;
591  }
592  result = hsm_get_slot_id(ctx, module->sym, token_label, &slot_id);
593  if (result != HSM_OK) {
594  hsm_module_free(module);
595  return HSM_ERROR;
596  }
597  rv = ((CK_FUNCTION_LIST_PTR) module->sym)->C_OpenSession(slot_id,
599  NULL,
600  NULL,
601  &session_handle);
602  if (hsm_pkcs11_check_error(ctx, rv, "Open first session")) {
603  hsm_module_free(module);
604  return HSM_ERROR;
605  }
606  rv_login = ((CK_FUNCTION_LIST_PTR) module->sym)->C_Login(session_handle,
607  CKU_USER,
608  (unsigned char *) pin,
609  strlen((char *)pin));
610 
611  if (rv_login == CKR_OK) {
612  *session = hsm_session_new(module, session_handle);
613  return HSM_OK;
614  } else {
615  /* uninitialize the session again */
616  if (session_handle) {
617  rv = ((CK_FUNCTION_LIST_PTR) module->sym)->
618  C_CloseSession(session_handle);
619  if (hsm_pkcs11_check_error(ctx, rv,
620  "finalize after failed login")) {
621  hsm_module_free(module);
622  return HSM_ERROR;
623  }
624  }
625  /* if this was not the first, don't close the library for
626  * the rest of us */
627  if (first) {
628  rv = ((CK_FUNCTION_LIST_PTR) module->sym)->C_Finalize(NULL);
629  if (hsm_pkcs11_check_error(ctx, rv, "finalize after failed login")) {
630  hsm_module_free(module);
631  return HSM_ERROR;
632  }
633  }
634  hsm_module_free(module);
635  *session = NULL;
636  switch(rv_login) {
637  case CKR_PIN_INCORRECT:
639  "hsm_session_init()",
640  "Incorrect PIN for repository %s", repository);
641  return HSM_PIN_INCORRECT;
642  default:
643  return HSM_ERROR;
644  }
645  }
646 }
647 
648 /* open a second session from the given one */
649 static hsm_session_t *
650 hsm_session_clone(hsm_ctx_t *ctx, hsm_session_t *session)
651 {
652  CK_RV rv;
653  CK_SLOT_ID slot_id;
654  CK_SESSION_HANDLE session_handle;
655  hsm_session_t *new_session;
656  int result;
657 
658  result = hsm_get_slot_id(ctx,
659  session->module->sym,
660  session->module->token_label,
661  &slot_id);
662  if (result != HSM_OK) return NULL;
663  rv = ((CK_FUNCTION_LIST_PTR) session->module->sym)->C_OpenSession(slot_id,
665  NULL,
666  NULL,
667  &session_handle);
668 
669  if (hsm_pkcs11_check_error(ctx, rv, "Clone session")) {
670  return NULL;
671  }
672  new_session = hsm_session_new(session->module, session_handle);
673 
674  return new_session;
675 }
676 
677 static hsm_ctx_t *
678 hsm_ctx_new()
679 {
680  hsm_ctx_t *ctx;
681  ctx = malloc(sizeof(hsm_ctx_t));
682  if (ctx) {
683  memset(ctx->session, 0, HSM_MAX_SESSIONS * sizeof(hsm_ctx_t*));
684  ctx->session_count = 0;
685  ctx->error = 0;
686  }
687  return ctx;
688 }
689 
690 /* ctx_free frees the structure */
691 static void
692 hsm_ctx_free(hsm_ctx_t *ctx)
693 {
694  unsigned int i;
695 
696  if (ctx) {
697  for (i = 0; i < ctx->session_count; i++) {
698  hsm_session_free(ctx->session[i]);
699  }
700  free(ctx);
701  }
702 }
703 
704 /* close the session, and free the allocated data
705  *
706  * if unload is non-zero, C_Logout() is called,
707  * the dlopen()d module is closed and unloaded
708  * (only call this on the last session for each
709  * module, ie. the one in the global ctx)
710  */
711 static void
712 hsm_session_close(hsm_ctx_t *ctx, hsm_session_t *session, int unload)
713 {
714  /* If we loaded this library more than once, we may have
715  * already finalized it before, so we can safely ignore
716  * NOT_INITIALIZED */
717  CK_RV rv;
718  if (unload) {
719  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_Logout(session->session);
720  if (rv != CKR_CRYPTOKI_NOT_INITIALIZED) {
721  (void) hsm_pkcs11_check_error(ctx, rv, "Logout");
722  }
723  }
724  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_CloseSession(session->session);
725  if (rv != CKR_CRYPTOKI_NOT_INITIALIZED) {
726  (void) hsm_pkcs11_check_error(ctx, rv, "Close session");
727  }
728  if (unload) {
729  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_Finalize(NULL);
730  if (rv != CKR_CRYPTOKI_NOT_INITIALIZED) {
731  (void) hsm_pkcs11_check_error(ctx, rv, "Finalize");
732  hsm_pkcs11_unload_functions(session->module->handle);
733  }
734  hsm_module_free(session->module);
735  session->module = NULL;
736  }
737  hsm_session_free(session);
738 }
739 
740 /* ctx_close closes all session, and free
741  * the structures.
742  *
743  * if unload is non-zero, the associated dynamic libraries are unloaded
744  * (hence only use that on the last, global, ctx)
745  */
746 static void
747 hsm_ctx_close(hsm_ctx_t *ctx, int unload)
748 {
749  size_t i;
750 
751  if (!ctx) return;
752  for (i = 0; i < ctx->session_count; i++) {
753  hsm_session_close(ctx, ctx->session[i], unload);
754  ctx->session[i] = NULL;
755  }
756  hsm_ctx_free(ctx);
757 
758 }
759 
760 
761 /* adds a session to the context.
762  * returns 0 on success
763  * 1 if the maximum number of sessions (HSM_MAX_SESSIONS) was
764  * reached
765  * -1 if one of the arguments is NULL
766  */
767 static int
768 hsm_ctx_add_session(hsm_ctx_t *ctx, hsm_session_t *session)
769 {
770  if (!ctx || !session) return -1;
771  if (ctx->session_count >= HSM_MAX_SESSIONS) return 1;
772  ctx->session[ctx->session_count] = session;
773  ctx->session_count++;
774  return 0;
775 }
776 
777 static hsm_ctx_t *
778 hsm_ctx_clone(hsm_ctx_t *ctx)
779 {
780  unsigned int i;
781  hsm_ctx_t *new_ctx;
782  hsm_session_t *new_session;
783 
784  new_ctx = NULL;
785  if (ctx) {
786  new_ctx = hsm_ctx_new();
787  for (i = 0; i < ctx->session_count; i++) {
788  new_session = hsm_session_clone(ctx, ctx->session[i]);
789  if (!new_session) {
790  /* one of the sessions failed to clone. Clear the
791  * new ctx and return NULL */
792  hsm_ctx_close(new_ctx, 0);
793  return NULL;
794  }
795  hsm_ctx_add_session(new_ctx, new_session);
796  }
797  new_ctx->keycache = ctx->keycache;
798  new_ctx->keycache_lock = ctx->keycache_lock;
799  }
800  return new_ctx;
801 }
802 
803 static libhsm_key_t *
804 libhsm_key_new()
805 {
806  libhsm_key_t *key;
807  key = malloc(sizeof(libhsm_key_t));
808  key->modulename = NULL;
809  key->private_key = 0;
810  key->public_key = 0;
811  return key;
812 }
813 
814 /* find the session belonging to a key, by iterating over the modules
815  * in the context */
816 static hsm_session_t *
817 hsm_find_key_session(hsm_ctx_t *ctx, const libhsm_key_t *key)
818 {
819  unsigned int i;
820  if (!key || !key->modulename) return NULL;
821  for (i = 0; i < ctx->session_count; i++) {
822  if (ctx->session[i] && !strcmp(ctx->session[i]->module->name, key->modulename)) {
823  return ctx->session[i];
824  }
825  }
826  return NULL;
827 }
828 
829 /* Returns the key type (algorithm) of the given key */
830 static CK_KEY_TYPE
831 hsm_get_key_algorithm(hsm_ctx_t *ctx, const hsm_session_t *session,
832  const libhsm_key_t *key)
833 {
834  CK_RV rv;
835  CK_KEY_TYPE key_type;
836 
837  CK_ATTRIBUTE template[] = {
838  {CKA_KEY_TYPE, &key_type, sizeof(CK_KEY_TYPE)}
839  };
840 
841  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GetAttributeValue(
842  session->session,
843  key->private_key,
844  template,
845  1);
846  if (hsm_pkcs11_check_error(ctx, rv,
847  "Get attr value algorithm type")) {
848  /* this is actually not a good return value;
849  * CKK_RSA is also 0. But we can't return a negative
850  * value. Should we #define a specific 'key type' that
851  * indicates an error? (TODO) */
852  return 0;
853  }
854 
855  if ((CK_LONG)template[0].ulValueLen < 1) {
856  /* this is actually not a good return value;
857  * CKK_RSA is also 0. But we can't return a negative
858  * value. Should we #define a specific 'key type' that
859  * indicates an error? (TODO) */
860  return 0;
861  }
862 
863  return key_type;
864 }
865 
866 /* returns a CK_ULONG with the key size of the given RSA key. The
867  * key is not checked for type. For RSA, the number of bits in the
868  * modulus is the key size (CKA_MODULUS_BITS)
869  */
870 static CK_ULONG
871 hsm_get_key_size_rsa(hsm_ctx_t *ctx, const hsm_session_t *session,
872  const libhsm_key_t *key)
873 {
874  CK_RV rv;
875  CK_ULONG modulus_bits;
876 
877  /* Template for public keys */
878  CK_ATTRIBUTE template[] = {
879  {CKA_MODULUS_BITS, &modulus_bits, sizeof(CK_KEY_TYPE)}
880  };
881 
882  /* Template for private keys */
883  CK_BYTE_PTR modulus = NULL;
884  int mask;
885  CK_ATTRIBUTE template2[] = {
886  {CKA_MODULUS, NULL, 0}
887  };
888 
889  if (key->public_key) {
890  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GetAttributeValue(
891  session->session,
892  key->public_key,
893  template,
894  1);
895  if (hsm_pkcs11_check_error(ctx, rv,
896  "Get attr value algorithm type")) {
897  return 0;
898  }
899 
900  if ((CK_ULONG)template[0].ulValueLen < 1) {
901  return 0;
902  }
903  } else {
904  // Get buffer size
905  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GetAttributeValue(
906  session->session,
907  key->private_key,
908  template2,
909  1);
910  if (hsm_pkcs11_check_error(ctx, rv, "Could not get the size of the modulus of the private key")) {
911  return 0;
912  }
913 
914  // Allocate memory
915  modulus = (CK_BYTE_PTR)malloc(template2[0].ulValueLen);
916  template2[0].pValue = modulus;
917  if (modulus == NULL) {
918  hsm_ctx_set_error(ctx, -1, "hsm_get_key_size_rsa()",
919  "Error allocating memory for modulus");
920  return 0;
921  }
922 
923  // Get attribute
924  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GetAttributeValue(
925  session->session,
926  key->private_key,
927  template2,
928  1);
929  if (hsm_pkcs11_check_error(ctx, rv, "Could not get the modulus of the private key")) {
930  free(modulus);
931  return 0;
932  }
933 
934  // Calculate size
935  modulus_bits = template2[0].ulValueLen * 8;
936  mask = 0x80;
937  for (int i = 0; modulus_bits && (modulus[i] & mask) == 0; modulus_bits--) {
938  mask >>= 1;
939  if (mask == 0) {
940  i++;
941  mask = 0x80;
942  }
943  }
944  free(modulus);
945  }
946 
947  return modulus_bits;
948 }
949 
950 /* returns a CK_ULONG with the key size of the given DSA key. The
951  * key is not checked for type. For DSA, the number of bits in the
952  * prime is the key size (CKA_PRIME)
953  */
954 static CK_ULONG
955 hsm_get_key_size_dsa(hsm_ctx_t *ctx, const hsm_session_t *session,
956  const libhsm_key_t *key)
957 {
958  CK_RV rv;
959 
960  /* Template */
961  CK_ATTRIBUTE template2[] = {
962  {CKA_PRIME, NULL, 0}
963  };
964 
965  // Get buffer size
966  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GetAttributeValue(
967  session->session,
968  key->private_key,
969  template2,
970  1);
971  if (hsm_pkcs11_check_error(ctx, rv, "Could not get the size of the prime of the private key")) {
972  return 0;
973  }
974 
975  return template2[0].ulValueLen * 8;
976 }
977 
978 /* Returns the DER decoded value of Q for ECDSA key
979  * Byte string with uncompressed form of a curve point, "x | y"
980  */
981 static unsigned char *
982 hsm_get_key_ecdsa_value(hsm_ctx_t *ctx, const hsm_session_t *session,
983  const libhsm_key_t *key, CK_ULONG *data_len)
984 {
985  CK_RV rv;
986  CK_BYTE_PTR value = NULL;
987  CK_BYTE_PTR data = NULL;
988  CK_ULONG value_len = 0;
989  CK_ULONG header_len = 0;
990 
991  CK_ATTRIBUTE template[] = {
992  {CKA_EC_POINT, NULL, 0},
993  };
994 
995  if (!session || !session->module || !key || !data_len) {
996  return NULL;
997  }
998 
999  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GetAttributeValue(
1000  session->session,
1001  key->public_key,
1002  template,
1003  1);
1004  if (hsm_pkcs11_check_error(ctx, rv, "C_GetAttributeValue")) {
1005  return NULL;
1006  }
1007  value_len = template[0].ulValueLen;
1008 
1009  value = template[0].pValue = malloc(value_len);
1010  if (!value) {
1011  hsm_ctx_set_error(ctx, -1, "hsm_get_key_ecdsa_value()",
1012  "Error allocating memory for value");
1013  return NULL;
1014  }
1015  memset(value, 0, value_len);
1016 
1017  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GetAttributeValue(
1018  session->session,
1019  key->public_key,
1020  template,
1021  1);
1022  if (hsm_pkcs11_check_error(ctx, rv, "get attribute value")) {
1023  free(value);
1024  return NULL;
1025  }
1026 
1027  if(value_len != template[0].ulValueLen) {
1028  hsm_ctx_set_error(ctx, -1, "hsm_get_key_ecdsa_value()",
1029  "HSM returned two different length for a same CKA_EC_POINT. " \
1030  "Abnormal behaviour detected.");
1031  free(value);
1032  return NULL;
1033  }
1034 
1035  /* Check that we have the first two octets */
1036  if (value_len < 2) {
1037  hsm_ctx_set_error(ctx, -1, "hsm_get_key_ecdsa_value()",
1038  "The DER value is too short");
1039  free(value);
1040  return NULL;
1041  }
1042 
1043  /* Check the identifier octet, PKCS#11 requires octet string */
1044  if (value[0] != 0x04) {
1045  hsm_ctx_set_error(ctx, -1, "hsm_get_key_ecdsa_value()",
1046  "Invalid identifier octet in the DER value");
1047  free(value);
1048  return NULL;
1049  }
1050  header_len++;
1051 
1052  /* Check the length octets, but we do not validate the length */
1053  if (value[1] <= 0x7F) {
1054  header_len++;
1055  } else if (value[1] == 0x80) {
1056  hsm_ctx_set_error(ctx, -1, "hsm_get_key_ecdsa_value()",
1057  "Indefinite length is not supported in DER values");
1058  free(value);
1059  return NULL;
1060  } else {
1061  header_len++;
1062  header_len += value[1] & 0x80;
1063  }
1064 
1065  /* Check that we have more data than the header */
1066  if (value_len - header_len < 2) {
1067  hsm_ctx_set_error(ctx, -1, "hsm_get_key_ecdsa_value()",
1068  "The value is too short");
1069  free(value);
1070  return NULL;
1071  }
1072 
1073  /* Check that we have uncompressed data */
1074  /* TODO: Not supporting compressed data */
1075  if (value[header_len] != 0x04) {
1076  hsm_ctx_set_error(ctx, -1, "hsm_get_key_ecdsa_value()",
1077  "The value is not uncompressed");
1078  free(value);
1079  return NULL;
1080  }
1081  header_len++;
1082 
1083  *data_len = value_len - header_len;
1084  data = malloc(*data_len);
1085  if (data == NULL) {
1086  hsm_ctx_set_error(ctx, -1, "hsm_get_key_ecdsa_value()",
1087  "Error allocating memory for data");
1088  free(value);
1089  return NULL;
1090  }
1091 
1092  memcpy(data, value + header_len, *data_len);
1093  free(value);
1094 
1095  return data;
1096 }
1097 
1098 /* returns a CK_ULONG with the key size of the given ECDSA key. The
1099  * key is not checked for type. For ECDSA, the number of bits in the
1100  * value X is the key size
1101  */
1102 static CK_ULONG
1103 hsm_get_key_size_ecdsa(hsm_ctx_t *ctx, const hsm_session_t *session,
1104  const libhsm_key_t *key)
1105 {
1107  unsigned char* value = hsm_get_key_ecdsa_value(ctx, session, key, &value_len);
1108  CK_ULONG bits = 0;
1109 
1110  if (value == NULL) return 0;
1111 
1112  if( ((CK_ULONG) - 1) / (8/2) < value_len) {
1113  free(value);
1114  return 0;
1115  }
1116 
1117  /* value = x | y */
1118  bits = value_len * 8 / 2;
1119  free(value);
1120 
1121  return bits;
1122 }
1123 
1124 /* Wrapper for specific key size functions */
1125 static CK_ULONG
1126 hsm_get_key_size(hsm_ctx_t *ctx, const hsm_session_t *session,
1127  const libhsm_key_t *key, const unsigned long algorithm)
1128 {
1129  switch (algorithm) {
1130  case CKK_RSA:
1131  return hsm_get_key_size_rsa(ctx, session, key);
1132  break;
1133  case CKK_DSA:
1134  return hsm_get_key_size_dsa(ctx, session, key);
1135  break;
1136  case CKK_GOSTR3410:
1137  /* GOST public keys always have a size of 512 bits */
1138  return 512;
1139  case CKK_EC:
1140  return hsm_get_key_size_ecdsa(ctx, session, key);
1141  default:
1142  return 0;
1143  }
1144 }
1145 
1146 static CK_OBJECT_HANDLE
1147 hsm_find_object_handle_for_id(hsm_ctx_t *ctx,
1148  const hsm_session_t *session,
1149  CK_OBJECT_CLASS key_class,
1150  CK_BYTE *id,
1151  CK_ULONG id_len)
1152 {
1153  CK_ULONG objectCount;
1154  CK_OBJECT_HANDLE object;
1155  CK_RV rv;
1156 
1157  CK_ATTRIBUTE template[] = {
1158  { CKA_CLASS, &key_class, sizeof(key_class) },
1159  { CKA_ID, id, id_len },
1160  };
1161 
1162  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_FindObjectsInit(session->session,
1163  template, 2);
1164  if (hsm_pkcs11_check_error(ctx, rv, "Find objects init")) {
1165  return 0;
1166  }
1167 
1168  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_FindObjects(session->session,
1169  &object,
1170  1,
1171  &objectCount);
1172  if (hsm_pkcs11_check_error(ctx, rv, "Find object")) {
1173  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_FindObjectsFinal(session->session);
1174  hsm_pkcs11_check_error(ctx, rv, "Find objects cleanup");
1175  return 0;
1176  }
1177 
1178  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_FindObjectsFinal(session->session);
1179  if (hsm_pkcs11_check_error(ctx, rv, "Find object final")) {
1180  return 0;
1181  }
1182 
1183  if (objectCount > 0) {
1184  return object;
1185  } else {
1186  return 0;
1187  }
1188 }
1189 
1190 /*
1191  * Parses the null-terminated string hex as hex values,
1192  * Returns allocated data that needs to be freed (or NULL on error)
1193  * len will contain the number of bytes allocated, or 0 on error
1194  */
1195 static unsigned char *
1196 hsm_hex_parse(const char *hex, size_t *len)
1197 {
1198  unsigned char *bytes;
1199  /* length of the hex input */
1200  size_t hex_len;
1201  size_t i;
1202 
1203  if (!len) return NULL;
1204  *len = 0;
1205 
1206  if (!hex) return NULL;
1207  hex_len = strlen(hex);
1208  if (hex_len % 2 != 0) {
1209  return NULL;
1210  }
1211 
1212  *len = hex_len / 2;
1213  bytes = malloc(*len);
1214  for (i = 0; i < *len; i++) {
1215  bytes[i] = ldns_hexdigit_to_int(hex[2*i]) * 16 +
1216  ldns_hexdigit_to_int(hex[2*i+1]);
1217  }
1218  return bytes;
1219 }
1220 
1221 /* put a hexadecimal representation of the data from src into dst
1222  * len is the number of bytes to read from src
1223  * dst must have allocated enough space (len*2 + 1)
1224  */
1225 static void
1226 hsm_hex_unparse(char *dst, const unsigned char *src, size_t len)
1227 {
1228  size_t dst_len = len*2 + 1;
1229  size_t i;
1230 
1231  for (i = 0; i < len; i++) {
1232  snprintf(dst + (2*i), dst_len, "%02x", src[i]);
1233  }
1234  dst[len*2] = '\0';
1235 }
1236 
1237 /* returns an allocated byte array with the CKA_ID for the given object
1238  * len will contain the result size
1239  * returns NULL and size zero if not found in this session
1240  */
1241 static CK_BYTE *
1242 hsm_get_id_for_object(hsm_ctx_t *ctx,
1243  const hsm_session_t *session,
1244  CK_OBJECT_HANDLE object,
1245  size_t *len)
1246 {
1247  CK_RV rv;
1248  CK_BYTE *id = NULL;
1249 
1250  CK_ATTRIBUTE template[] = {
1251  {CKA_ID, id, 0}
1252  };
1253 
1254  /* find out the size of the id first */
1255  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GetAttributeValue(
1256  session->session,
1257  object,
1258  template,
1259  1);
1260  if (hsm_pkcs11_check_error(ctx, rv, "Get attr value")) {
1261  *len = 0;
1262  return NULL;
1263  }
1264 
1265  if ((CK_LONG)template[0].ulValueLen < 1) {
1266  /* No CKA_ID found, return NULL */
1267  *len = 0;
1268  return NULL;
1269  }
1270 
1271  template[0].pValue = malloc(template[0].ulValueLen);
1272  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GetAttributeValue(
1273  session->session,
1274  object,
1275  template,
1276  1);
1277  if (hsm_pkcs11_check_error(ctx, rv, "Get attr value 2")) {
1278  *len = 0;
1279  free(template[0].pValue);
1280  return NULL;
1281  }
1282 
1283  *len = template[0].ulValueLen;
1284  return template[0].pValue;
1285 }
1286 
1287 /* returns an libhsm_key_t object for the given *private key* object handle
1288  * the module, private key, and public key handle are set
1289  * The session needs to be free to perform a search for the public key
1290  */
1291 static libhsm_key_t *
1292 libhsm_key_new_privkey_object_handle(hsm_ctx_t *ctx,
1293  const hsm_session_t *session,
1294  CK_OBJECT_HANDLE object)
1295 {
1296  libhsm_key_t *key;
1297  CK_BYTE *id;
1298  size_t len;
1299 
1300  id = hsm_get_id_for_object(ctx, session, object, &len);
1301 
1302  if (!id) return NULL;
1303 
1304  key = libhsm_key_new();
1305  key->modulename = strdup(session->module->name);
1306  key->private_key = object;
1307 
1308  key->public_key = hsm_find_object_handle_for_id(
1309  ctx,
1310  session,
1312  id,
1313  len);
1314 
1315  free(id);
1316  return key;
1317 }
1318 
1319 /* helper function to find both key counts or the keys themselves
1320  * if the argument store is 0, results are not returned; the
1321  * function will only set the count and return NULL
1322  * Otherwise, a newly allocated key array will be returned
1323  * (on error, the count will also be zero and NULL returned)
1324  */
1325 static libhsm_key_t **
1326 hsm_list_keys_session_internal(hsm_ctx_t *ctx,
1327  const hsm_session_t *session,
1328  size_t *count,
1329  int store)
1330 {
1331  libhsm_key_t **keys = NULL;
1332  libhsm_key_t *key;
1333  CK_RV rv;
1334  CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY;
1335  CK_ATTRIBUTE template[] = {
1336  { CKA_CLASS, &key_class, sizeof(key_class) },
1337  };
1338  CK_ULONG total_count = 0;
1339  CK_ULONG objectCount = 1;
1340  /* find 100 keys at a time (and loop until there are none left) */
1341  CK_ULONG max_object_count = 100;
1342  CK_ULONG i, j;
1343  CK_OBJECT_HANDLE object[max_object_count];
1344  CK_OBJECT_HANDLE *key_handles = NULL, *new_key_handles = NULL;
1345 
1346 
1347  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_FindObjectsInit(session->session,
1348  template, 1);
1349  if (hsm_pkcs11_check_error(ctx, rv, "Find objects init")) {
1350  goto err;
1351  }
1352 
1353  j = 0;
1354  while (objectCount > 0) {
1355  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_FindObjects(session->session,
1356  object,
1357  max_object_count,
1358  &objectCount);
1359  if (hsm_pkcs11_check_error(ctx, rv, "Find first object")) {
1360  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_FindObjectsFinal(session->session);
1361  hsm_pkcs11_check_error(ctx, rv, "Find objects cleanup");
1362  goto err;
1363  }
1364 
1365  total_count += objectCount;
1366  if (objectCount > 0 && store) {
1367  if (SIZE_MAX / sizeof(CK_OBJECT_HANDLE) < total_count) {
1368  hsm_ctx_set_error(ctx, -1, "hsm_list_keys_session_internal",
1369  "Too much object handle returned by HSM to allocate key_handles");
1370  goto err;
1371  }
1372 
1373  new_key_handles = realloc(key_handles, total_count * sizeof(CK_OBJECT_HANDLE));
1374  if (new_key_handles != NULL) {
1375  key_handles = new_key_handles;
1376  } else {
1377  hsm_ctx_set_error(ctx, -1, "hsm_list_keys_session_internal",
1378  "Error allocating memory for object handle (OOM)");
1379  goto err;
1380  }
1381 
1382  for (i = 0; i < objectCount; i++) {
1383  key_handles[j] = object[i];
1384  j++;
1385  }
1386  }
1387  }
1388 
1389  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_FindObjectsFinal(session->session);
1390  if (hsm_pkcs11_check_error(ctx, rv, "Find objects final")) {
1391  goto err;
1392  }
1393 
1394  if (store) {
1395  if(SIZE_MAX / sizeof(libhsm_key_t *) < total_count) {
1396  hsm_ctx_set_error(ctx, -1, "hsm_list_keys_session_internal",
1397  "Too much object handle returned by HSM to allocate keys");
1398  goto err;
1399  }
1400 
1401  keys = malloc(total_count * sizeof(libhsm_key_t *));
1402  if(keys == NULL) {
1403  hsm_ctx_set_error(ctx, -1, "hsm_list_keys_session_internal",
1404  "Error allocating memory for keys table (OOM)");
1405  goto err;
1406  }
1407 
1408  for (i = 0; i < total_count; i++) {
1409  key = libhsm_key_new_privkey_object_handle(ctx, session,
1410  key_handles[i]);
1411  if(!key) {
1412  libhsm_key_list_free(keys, i);
1413  goto err;
1414  }
1415  keys[i] = key;
1416  }
1417  }
1418  free(key_handles);
1419 
1420  *count = total_count;
1421  return keys;
1422 
1423 err:
1424  free(key_handles);
1425  *count = 0;
1426  return NULL;
1427 }
1428 
1429 
1430 /* returns an array of all keys available to the given session
1431  *
1432  * \param session the session to find the keys in
1433  * \param count this value will contain the number of keys found
1434  *
1435  * \return the list of keys
1436  */
1437 static libhsm_key_t **
1438 hsm_list_keys_session(hsm_ctx_t *ctx, const hsm_session_t *session,
1439  size_t *count)
1440 {
1441  return hsm_list_keys_session_internal(ctx, session, count, 1);
1442 }
1443 
1444 /* returns a newly allocated key structure containing the key data
1445  * for the given CKA_ID available in the session. Returns NULL if not
1446  * found
1447  */
1448 static libhsm_key_t *
1449 hsm_find_key_by_id_session(hsm_ctx_t *ctx, const hsm_session_t *session,
1450  const unsigned char *id, size_t len)
1451 {
1452  libhsm_key_t *key;
1453  CK_OBJECT_HANDLE private_key_handle;
1454 
1455  private_key_handle = hsm_find_object_handle_for_id(
1456  ctx,
1457  session,
1459  (CK_BYTE *) id,
1460  (CK_ULONG) len);
1461  if (private_key_handle != 0) {
1462  key = libhsm_key_new_privkey_object_handle(ctx, session,
1463  private_key_handle);
1464  return key;
1465  } else {
1466  return NULL;
1467  }
1468 }
1469 
1470 /* Find a key pair by CKA_ID (as byte array)
1471 
1472 The returned key structure can be freed with free()
1473 
1474 \param context HSM context
1475 \param id CKA_ID of key to find (array of bytes)
1476 \param len number of bytes in the id
1477 \return key identifier or NULL if not found
1478 */
1479 static libhsm_key_t *
1480 hsm_find_key_by_id_bin(hsm_ctx_t *ctx,
1481  const unsigned char *id,
1482  size_t len)
1483 {
1484  libhsm_key_t *key;
1485  unsigned int i;
1486 
1487  if (!id) return NULL;
1488 
1489  for (i = 0; i < ctx->session_count; i++) {
1490  key = hsm_find_key_by_id_session(ctx, ctx->session[i], id, len);
1491  if (key) return key;
1492  }
1493  return NULL;
1494 }
1495 
1496 
1502 static hsm_session_t *
1503 hsm_find_repository_session(hsm_ctx_t *ctx, const char *repository)
1504 {
1505  unsigned int i;
1506  if (!repository) {
1507  for (i = 0; i < ctx->session_count; i++) {
1508  if (ctx->session[i]) {
1509  return ctx->session[i];
1510  }
1511  }
1512  } else {
1513  for (i = 0; i < ctx->session_count; i++) {
1514  if (ctx->session[i] &&
1515  strcmp(repository, ctx->session[i]->module->name) == 0)
1516  {
1517  return ctx->session[i];
1518  }
1519  }
1520  }
1521 
1523  "hsm_find_repository_session()",
1524  "Can't find repository: %s", repository);
1525 
1526  return NULL;
1527 }
1528 
1529 static ldns_rdf *
1530 hsm_get_key_rdata_rsa(hsm_ctx_t *ctx, hsm_session_t *session,
1531  const libhsm_key_t *key)
1532 {
1533  CK_RV rv;
1534  CK_BYTE_PTR public_exponent = NULL;
1535  CK_ULONG public_exponent_len = 0;
1536  CK_BYTE_PTR modulus = NULL;
1537  CK_ULONG modulus_len = 0;
1538  unsigned long hKey = 0;
1539  unsigned char *data = NULL;
1540  size_t data_size = 0;
1541 
1542  CK_ATTRIBUTE template[] = {
1543  {CKA_PUBLIC_EXPONENT, NULL, 0},
1544  {CKA_MODULUS, NULL, 0},
1545  };
1546  ldns_rdf *rdf;
1547 
1548  if (!session || !session->module) {
1549  return NULL;
1550  }
1551 
1552  if (key->public_key) {
1553  hKey = key->public_key;
1554  } else {
1555  hKey = key->private_key;
1556  }
1557 
1558  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GetAttributeValue(
1559  session->session,
1560  hKey,
1561  template,
1562  2);
1563  if (hsm_pkcs11_check_error(ctx, rv, "C_GetAttributeValue")) {
1564  return NULL;
1565  }
1566  public_exponent_len = template[0].ulValueLen;
1567  modulus_len = template[1].ulValueLen;
1568 
1569  public_exponent = template[0].pValue = malloc(public_exponent_len);
1570  if (!public_exponent) {
1571  hsm_ctx_set_error(ctx, -1, "hsm_get_key_rdata_rsa()",
1572  "Error allocating memory for public exponent");
1573  return NULL;
1574  }
1575 
1576  modulus = template[1].pValue = malloc(modulus_len);
1577  if (!modulus) {
1578  hsm_ctx_set_error(ctx, -1, "hsm_get_key_rdata_rsa()",
1579  "Error allocating memory for modulus");
1580  free(public_exponent);
1581  return NULL;
1582  }
1583 
1584  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GetAttributeValue(
1585  session->session,
1586  hKey,
1587  template,
1588  2);
1589  if (hsm_pkcs11_check_error(ctx, rv, "get attribute value")) {
1590  free(template[0].pValue);
1591  free(template[1].pValue);
1592  return NULL;
1593  }
1594 
1595  // Remove leading zeroes
1596  hsm_remove_leading_zeroes(public_exponent, &public_exponent_len);
1597  hsm_remove_leading_zeroes(modulus, &modulus_len);
1598 
1599  data_size = public_exponent_len + modulus_len + 1;
1600  if (public_exponent_len <= 255) {
1601  data = malloc(data_size);
1602  if (!data) {
1603  hsm_ctx_set_error(ctx, -1, "hsm_get_key_rdata_rsa()",
1604  "Error allocating memory for pub key rr data");
1605  free(public_exponent);
1606  free(modulus);
1607  return NULL;
1608  }
1609  data[0] = public_exponent_len;
1610  memcpy(&data[1], public_exponent, public_exponent_len);
1611  memcpy(&data[1 + public_exponent_len], modulus, modulus_len);
1612  } else if (public_exponent_len <= 65535) {
1613  data_size += 2;
1614  data = malloc(data_size);
1615  if (!data) {
1616  hsm_ctx_set_error(ctx, -1, "hsm_get_key_rdata_rsa()",
1617  "Error allocating memory for pub key rr data");
1618  free(public_exponent);
1619  free(modulus);
1620  return NULL;
1621  }
1622  data[0] = 0;
1623  ldns_write_uint16(&data[1], (uint16_t) public_exponent_len);
1624  memcpy(&data[3], public_exponent, public_exponent_len);
1625  memcpy(&data[3 + public_exponent_len], modulus, modulus_len);
1626  } else {
1627  hsm_ctx_set_error(ctx, -1, "hsm_get_key_rdata_rsa()",
1628  "Public exponent too big");
1629  free(public_exponent);
1630  free(modulus);
1631  return NULL;
1632  }
1633  rdf = ldns_rdf_new(LDNS_RDF_TYPE_B64, data_size, data);
1634  free(public_exponent);
1635  free(modulus);
1636 
1637  return rdf;
1638 }
1639 
1640 static ldns_rdf *
1641 hsm_get_key_rdata_dsa(hsm_ctx_t *ctx, hsm_session_t *session,
1642  const libhsm_key_t *key)
1643 {
1644  CK_RV rv;
1645  CK_BYTE_PTR prime = NULL;
1646  CK_ULONG prime_len = 0;
1647  CK_BYTE_PTR subprime = NULL;
1648  CK_ULONG subprime_len = 0;
1649  CK_BYTE_PTR base = NULL;
1650  CK_ULONG base_len = 0;
1651  CK_BYTE_PTR value = NULL;
1652  CK_ULONG value_len = 0;
1653  unsigned char *data = NULL;
1654  size_t data_size = 0;
1655 
1656  CK_ATTRIBUTE template[] = {
1657  {CKA_PRIME, NULL, 0},
1658  {CKA_SUBPRIME, NULL, 0},
1659  {CKA_BASE, NULL, 0},
1660  {CKA_VALUE, NULL, 0},
1661  };
1662  ldns_rdf *rdf;
1663 
1664  if (!session || !session->module) {
1665  return NULL;
1666  }
1667 
1668  /* DSA needs the public key compared with RSA */
1669  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GetAttributeValue(
1670  session->session,
1671  key->public_key,
1672  template,
1673  4);
1674  if (hsm_pkcs11_check_error(ctx, rv, "C_GetAttributeValue")) {
1675  return NULL;
1676  }
1677  prime_len = template[0].ulValueLen;
1678  subprime_len = template[1].ulValueLen;
1679  base_len = template[2].ulValueLen;
1680  value_len = template[3].ulValueLen;
1681 
1682  prime = template[0].pValue = malloc(prime_len);
1683  if (!prime) {
1684  hsm_ctx_set_error(ctx, -1, "hsm_get_key_rdata_dsa()",
1685  "Error allocating memory for prime");
1686  return NULL;
1687  }
1688 
1689  subprime = template[1].pValue = malloc(subprime_len);
1690  if (!subprime) {
1691  hsm_ctx_set_error(ctx, -1, "hsm_get_key_rdata_dsa()",
1692  "Error allocating memory for subprime");
1693  free(prime);
1694  return NULL;
1695  }
1696 
1697  base = template[2].pValue = malloc(base_len);
1698  if (!base) {
1699  hsm_ctx_set_error(ctx, -1, "hsm_get_key_rdata_dsa()",
1700  "Error allocating memory for base");
1701  free(prime);
1702  free(subprime);
1703  return NULL;
1704  }
1705 
1706  value = template[3].pValue = malloc(value_len);
1707  if (!value) {
1708  hsm_ctx_set_error(ctx, -1, "hsm_get_key_rdata_dsa()",
1709  "Error allocating memory for value");
1710  free(prime);
1711  free(subprime);
1712  free(base);
1713  return NULL;
1714  }
1715 
1716  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GetAttributeValue(
1717  session->session,
1718  key->public_key,
1719  template,
1720  4);
1721  if (hsm_pkcs11_check_error(ctx, rv, "get attribute value")) {
1722  free(prime);
1723  free(subprime);
1724  free(base);
1725  free(value);
1726  return NULL;
1727  }
1728 
1729  data_size = prime_len + subprime_len + base_len + value_len + 1;
1730  data = malloc(data_size);
1731  if (!data) {
1732  hsm_ctx_set_error(ctx, -1, "hsm_get_key_rdata_dsa()",
1733  "Error allocating memory for pub key rr data");
1734  free(prime);
1735  free(subprime);
1736  free(base);
1737  free(value);
1738  return NULL;
1739  }
1740  data[0] = (prime_len - 64) / 8;
1741  memcpy(&data[1], subprime, subprime_len);
1742  memcpy(&data[1 + subprime_len], prime, prime_len);
1743  memcpy(&data[1 + subprime_len + prime_len], base, base_len);
1744  memcpy(&data[1 + subprime_len + prime_len + base_len], value, value_len);
1745 
1746  rdf = ldns_rdf_new(LDNS_RDF_TYPE_B64, data_size, data);
1747  free(prime);
1748  free(subprime);
1749  free(base);
1750  free(value);
1751 
1752  return rdf;
1753 }
1754 
1755 static ldns_rdf *
1756 hsm_get_key_rdata_gost(hsm_ctx_t *ctx, hsm_session_t *session,
1757  const libhsm_key_t *key)
1758 {
1759  CK_RV rv;
1760  CK_BYTE_PTR value = NULL;
1761  CK_ULONG value_len = 0;
1762 
1763  CK_ATTRIBUTE template[] = {
1764  {CKA_VALUE, NULL, 0},
1765  };
1766  ldns_rdf *rdf;
1767 
1768  if (!session || !session->module) {
1769  return NULL;
1770  }
1771 
1772  /* GOST needs the public key compared with RSA */
1773  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GetAttributeValue(
1774  session->session,
1775  key->public_key,
1776  template,
1777  1);
1778  if (hsm_pkcs11_check_error(ctx, rv, "C_GetAttributeValue")) {
1779  return NULL;
1780  }
1781  value_len = template[0].ulValueLen;
1782 
1783  value = template[0].pValue = malloc(value_len);
1784  if (!value) {
1785  hsm_ctx_set_error(ctx, -1, "hsm_get_key_rdata_gost()",
1786  "Error allocating memory for value");
1787  return NULL;
1788  }
1789 
1790  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GetAttributeValue(
1791  session->session,
1792  key->public_key,
1793  template,
1794  1);
1795  if (hsm_pkcs11_check_error(ctx, rv, "get attribute value")) {
1796  free(value);
1797  return NULL;
1798  }
1799 
1800  rdf = ldns_rdf_new(LDNS_RDF_TYPE_B64, value_len, value);
1801  return rdf;
1802 }
1803 
1804 static ldns_rdf *
1805 hsm_get_key_rdata_ecdsa(hsm_ctx_t *ctx, hsm_session_t *session,
1806  const libhsm_key_t *key)
1807 {
1809  unsigned char* value = hsm_get_key_ecdsa_value(ctx, session, key, &value_len);
1810 
1811  if (value == NULL) return NULL;
1812 
1813  ldns_rdf *rdf = ldns_rdf_new(LDNS_RDF_TYPE_B64, value_len, value);
1814 
1815  return rdf;
1816 }
1817 
1818 static ldns_rdf *
1819 hsm_get_key_rdata(hsm_ctx_t *ctx, hsm_session_t *session,
1820  const libhsm_key_t *key)
1821 {
1822  switch (hsm_get_key_algorithm(ctx, session, key)) {
1823  case CKK_RSA:
1824  return hsm_get_key_rdata_rsa(ctx, session, key);
1825  break;
1826  case CKK_DSA:
1827  return hsm_get_key_rdata_dsa(ctx, session, key);
1828  break;
1829  case CKK_GOSTR3410:
1830  return hsm_get_key_rdata_gost(ctx, session, key);
1831  break;
1832  case CKK_EC:
1833  return hsm_get_key_rdata_ecdsa(ctx, session, key);
1834  default:
1835  return 0;
1836  }
1837 }
1838 
1839 /* this function allocates memory for the mechanism ID and enough room
1840  * to leave the upcoming digest data. It fills in the mechanism id
1841  * use with care. The returned data must be free'd by the caller.
1842  * Only used by RSA PKCS. */
1843 static CK_BYTE *
1844 hsm_create_prefix(CK_ULONG digest_len,
1845  ldns_algorithm algorithm,
1846  CK_ULONG *data_size)
1847 {
1848  CK_BYTE *data;
1849  const CK_BYTE RSA_MD5_ID[] = { 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 };
1850  const CK_BYTE RSA_SHA1_ID[] = { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14 };
1851  const CK_BYTE RSA_SHA256_ID[] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 };
1852  const CK_BYTE RSA_SHA512_ID[] = { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40 };
1853 
1854  switch((ldns_signing_algorithm)algorithm) {
1855  case LDNS_SIGN_RSAMD5:
1856  *data_size = sizeof(RSA_MD5_ID) + digest_len;
1857  data = malloc(*data_size);
1858  memcpy(data, RSA_MD5_ID, sizeof(RSA_MD5_ID));
1859  break;
1860  case LDNS_SIGN_RSASHA1:
1861  case LDNS_SIGN_RSASHA1_NSEC3:
1862  *data_size = sizeof(RSA_SHA1_ID) + digest_len;
1863  data = malloc(*data_size);
1864  memcpy(data, RSA_SHA1_ID, sizeof(RSA_SHA1_ID));
1865  break;
1866  case LDNS_SIGN_RSASHA256:
1867  *data_size = sizeof(RSA_SHA256_ID) + digest_len;
1868  data = malloc(*data_size);
1869  memcpy(data, RSA_SHA256_ID, sizeof(RSA_SHA256_ID));
1870  break;
1871  case LDNS_SIGN_RSASHA512:
1872  *data_size = sizeof(RSA_SHA512_ID) + digest_len;
1873  data = malloc(*data_size);
1874  memcpy(data, RSA_SHA512_ID, sizeof(RSA_SHA512_ID));
1875  break;
1876  case LDNS_SIGN_DSA:
1877  case LDNS_SIGN_DSA_NSEC3:
1878  case LDNS_SIGN_ECC_GOST:
1879 /* TODO: We can remove the directive if we require LDNS >= 1.6.13 */
1880 #if !defined LDNS_BUILD_CONFIG_USE_ECDSA || LDNS_BUILD_CONFIG_USE_ECDSA
1881  case LDNS_SIGN_ECDSAP256SHA256:
1882  case LDNS_SIGN_ECDSAP384SHA384:
1883 #endif
1884  *data_size = digest_len;
1885  data = malloc(*data_size);
1886  break;
1887  default:
1888  return NULL;
1889  }
1890  return data;
1891 }
1892 
1893 static CK_BYTE *
1894 hsm_digest_through_hsm(hsm_ctx_t *ctx,
1895  hsm_session_t *session,
1896  CK_MECHANISM_TYPE mechanism_type,
1897  CK_ULONG digest_len,
1898  ldns_buffer *sign_buf)
1899 {
1900  CK_MECHANISM digest_mechanism;
1901  CK_BYTE *digest;
1902  CK_RV rv;
1903 
1904  digest_mechanism.pParameter = NULL;
1905  digest_mechanism.ulParameterLen = 0;
1906  digest_mechanism.mechanism = mechanism_type;
1907  digest = malloc(digest_len);
1908  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_DigestInit(session->session,
1909  &digest_mechanism);
1910  if (hsm_pkcs11_check_error(ctx, rv, "HSM digest init")) {
1911  free(digest);
1912  return NULL;
1913  }
1914 
1915  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_Digest(session->session,
1916  ldns_buffer_begin(sign_buf),
1917  ldns_buffer_position(sign_buf),
1918  digest,
1919  &digest_len);
1920  if (hsm_pkcs11_check_error(ctx, rv, "HSM digest")) {
1921  free(digest);
1922  return NULL;
1923  }
1924  return digest;
1925 }
1926 
1927 static ldns_rdf *
1928 hsm_sign_buffer(hsm_ctx_t *ctx,
1929  ldns_buffer *sign_buf,
1930  const libhsm_key_t *key,
1931  ldns_algorithm algorithm)
1932 {
1933  CK_RV rv;
1934  CK_ULONG signatureLen = HSM_MAX_SIGNATURE_LENGTH;
1935  CK_BYTE signature[HSM_MAX_SIGNATURE_LENGTH];
1936  CK_MECHANISM sign_mechanism;
1937 
1938  ldns_rdf *sig_rdf;
1939  CK_BYTE *digest = NULL;
1940  CK_ULONG digest_len;
1941 
1942  CK_BYTE *data = NULL;
1943  CK_ULONG data_len = 0;
1944 
1945  hsm_session_t *session;
1946 
1947  session = hsm_find_key_session(ctx, key);
1948  if (!session) return NULL;
1949 
1950  /* some HSMs don't really handle CKM_SHA1_RSA_PKCS well, so
1951  * we'll do the hashing manually */
1952  /* When adding algorithms, remember there is another switch below */
1953  switch ((ldns_signing_algorithm)algorithm) {
1954  case LDNS_SIGN_RSAMD5:
1955  digest_len = 16;
1956  digest = hsm_digest_through_hsm(ctx, session,
1957  CKM_MD5, digest_len,
1958  sign_buf);
1959  break;
1960  case LDNS_SIGN_RSASHA1:
1961  case LDNS_SIGN_RSASHA1_NSEC3:
1962  case LDNS_SIGN_DSA:
1963  case LDNS_SIGN_DSA_NSEC3:
1964  digest_len = LDNS_SHA1_DIGEST_LENGTH;
1965  digest = malloc(digest_len);
1966  digest = ldns_sha1(ldns_buffer_begin(sign_buf),
1967  ldns_buffer_position(sign_buf),
1968  digest);
1969  break;
1970 
1971  case LDNS_SIGN_RSASHA256:
1972 /* TODO: We can remove the directive if we require LDNS >= 1.6.13 */
1973 #if !defined LDNS_BUILD_CONFIG_USE_ECDSA || LDNS_BUILD_CONFIG_USE_ECDSA
1974  case LDNS_SIGN_ECDSAP256SHA256:
1975 #endif
1976  digest_len = LDNS_SHA256_DIGEST_LENGTH;
1977  digest = malloc(digest_len);
1978  digest = ldns_sha256(ldns_buffer_begin(sign_buf),
1979  ldns_buffer_position(sign_buf),
1980  digest);
1981  break;
1982 /* TODO: We can remove the directive if we require LDNS >= 1.6.13 */
1983 #if !defined LDNS_BUILD_CONFIG_USE_ECDSA || LDNS_BUILD_CONFIG_USE_ECDSA
1984  case LDNS_SIGN_ECDSAP384SHA384:
1985  digest_len = LDNS_SHA384_DIGEST_LENGTH;
1986  digest = malloc(digest_len);
1987  digest = ldns_sha384(ldns_buffer_begin(sign_buf),
1988  ldns_buffer_position(sign_buf),
1989  digest);
1990  break;
1991 #endif
1992  case LDNS_SIGN_RSASHA512:
1993  digest_len = LDNS_SHA512_DIGEST_LENGTH;
1994  digest = malloc(digest_len);
1995  digest = ldns_sha512(ldns_buffer_begin(sign_buf),
1996  ldns_buffer_position(sign_buf),
1997  digest);
1998  break;
1999  case LDNS_SIGN_ECC_GOST:
2000  digest_len = 32;
2001  digest = hsm_digest_through_hsm(ctx, session,
2002  CKM_GOSTR3411, digest_len,
2003  sign_buf);
2004  break;
2005  default:
2006  /* log error? or should we not even get here for
2007  * unsupported algorithms? */
2008  return NULL;
2009  }
2010 
2011  if (!digest) {
2012  return NULL;
2013  }
2014 
2015  /* CKM_RSA_PKCS does the padding, but cannot know the identifier
2016  * prefix, so we need to add that ourselves.
2017  * The other algorithms will just get the digest buffer returned. */
2018  data = hsm_create_prefix(digest_len, algorithm, &data_len);
2019  memcpy(data + data_len - digest_len, digest, digest_len);
2020 
2021  sign_mechanism.pParameter = NULL;
2022  sign_mechanism.ulParameterLen = 0;
2023  switch((ldns_signing_algorithm)algorithm) {
2024  case LDNS_SIGN_RSAMD5:
2025  case LDNS_SIGN_RSASHA1:
2026  case LDNS_SIGN_RSASHA1_NSEC3:
2027  case LDNS_SIGN_RSASHA256:
2028  case LDNS_SIGN_RSASHA512:
2029  sign_mechanism.mechanism = CKM_RSA_PKCS;
2030  break;
2031  case LDNS_SIGN_DSA:
2032  case LDNS_SIGN_DSA_NSEC3:
2033  sign_mechanism.mechanism = CKM_DSA;
2034  break;
2035  case LDNS_SIGN_ECC_GOST:
2036  sign_mechanism.mechanism = CKM_GOSTR3410;
2037  break;
2038 /* TODO: We can remove the directive if we require LDNS >= 1.6.13 */
2039 #if !defined LDNS_BUILD_CONFIG_USE_ECDSA || LDNS_BUILD_CONFIG_USE_ECDSA
2040  case LDNS_SIGN_ECDSAP256SHA256:
2041  case LDNS_SIGN_ECDSAP384SHA384:
2042  sign_mechanism.mechanism = CKM_ECDSA;
2043  break;
2044 #endif
2045  default:
2046  /* log error? or should we not even get here for
2047  * unsupported algorithms? */
2048  free(data);
2049  free(digest);
2050  return NULL;
2051  }
2052 
2053  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_SignInit(
2054  session->session,
2055  &sign_mechanism,
2056  key->private_key);
2057  if (hsm_pkcs11_check_error(ctx, rv, "sign init")) {
2058  free(data);
2059  free(digest);
2060  return NULL;
2061  }
2062 
2063  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_Sign(session->session, data, data_len,
2064  signature,
2065  &signatureLen);
2066  if (hsm_pkcs11_check_error(ctx, rv, "sign final")) {
2067  free(data);
2068  free(digest);
2069  return NULL;
2070  }
2071 
2072  sig_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64,
2073  signatureLen,
2074  signature);
2075 
2076  free(data);
2077  free(digest);
2078 
2079  return sig_rdf;
2080 
2081 }
2082 
2083 static int
2084 hsm_dname_is_wildcard(const ldns_rdf* dname)
2085 {
2086  return ( ldns_dname_label_count(dname) > 0 &&
2087  ldns_rdf_data(dname)[0] == 1 &&
2088  ldns_rdf_data(dname)[1] == '*');
2089 }
2090 
2091 static ldns_rr *
2092 hsm_create_empty_rrsig(const ldns_rr_list *rrset,
2093  const hsm_sign_params_t *sign_params)
2094 {
2095  ldns_rr *rrsig;
2096  uint32_t orig_ttl;
2097  uint32_t orig_class;
2098  time_t now;
2099  uint8_t label_count;
2100 
2101  label_count = ldns_dname_label_count(
2102  ldns_rr_owner(ldns_rr_list_rr(rrset, 0)));
2103  /* RFC 4035 section 2.2: dnssec label length and wildcards */
2104  if (hsm_dname_is_wildcard(ldns_rr_owner(ldns_rr_list_rr(rrset, 0)))) {
2105  label_count--;
2106  }
2107 
2108  rrsig = ldns_rr_new_frm_type(LDNS_RR_TYPE_RRSIG);
2109 
2110  /* set the type on the new signature */
2111  orig_ttl = ldns_rr_ttl(ldns_rr_list_rr(rrset, 0));
2112  orig_class = ldns_rr_get_class(ldns_rr_list_rr(rrset, 0));
2113 
2114  ldns_rr_set_class(rrsig, orig_class);
2115  ldns_rr_set_ttl(rrsig, orig_ttl);
2116  ldns_rr_set_owner(rrsig,
2117  ldns_rdf_clone(
2118  ldns_rr_owner(
2119  ldns_rr_list_rr(rrset,
2120  0))));
2121 
2122  /* fill in what we know of the signature */
2123 
2124  /* set the orig_ttl */
2125  (void)ldns_rr_rrsig_set_origttl(
2126  rrsig,
2127  ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32,
2128  orig_ttl));
2129  /* the signers name */
2130  (void)ldns_rr_rrsig_set_signame(
2131  rrsig,
2132  ldns_rdf_clone(sign_params->owner));
2133  /* label count - get it from the first rr in the rr_list */
2134  (void)ldns_rr_rrsig_set_labels(
2135  rrsig,
2136  ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8,
2137  label_count));
2138  /* inception, expiration */
2139  now = time_now();
2140  if (sign_params->inception != 0) {
2141  (void)ldns_rr_rrsig_set_inception(
2142  rrsig,
2143  ldns_native2rdf_int32(
2144  LDNS_RDF_TYPE_TIME,
2145  sign_params->inception));
2146  } else {
2147  (void)ldns_rr_rrsig_set_inception(
2148  rrsig,
2149  ldns_native2rdf_int32(LDNS_RDF_TYPE_TIME, now));
2150  }
2151  if (sign_params->expiration != 0) {
2152  (void)ldns_rr_rrsig_set_expiration(
2153  rrsig,
2154  ldns_native2rdf_int32(
2155  LDNS_RDF_TYPE_TIME,
2156  sign_params->expiration));
2157  } else {
2158  (void)ldns_rr_rrsig_set_expiration(
2159  rrsig,
2160  ldns_native2rdf_int32(
2161  LDNS_RDF_TYPE_TIME,
2162  now + LDNS_DEFAULT_EXP_TIME));
2163  }
2164 
2165  (void)ldns_rr_rrsig_set_keytag(
2166  rrsig,
2167  ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16,
2168  sign_params->keytag));
2169 
2170  (void)ldns_rr_rrsig_set_algorithm(
2171  rrsig,
2172  ldns_native2rdf_int8(
2173  LDNS_RDF_TYPE_ALG,
2174  sign_params->algorithm));
2175 
2176  (void)ldns_rr_rrsig_set_typecovered(
2177  rrsig,
2178  ldns_native2rdf_int16(
2179  LDNS_RDF_TYPE_TYPE,
2180  ldns_rr_get_type(ldns_rr_list_rr(rrset,
2181  0))));
2182 
2183  return rrsig;
2184 }
2185 
2186 
2187 /*
2188  * API functions
2189  */
2190 
2191 int
2193  char *(pin_callback)(unsigned int, const char *, unsigned int))
2194 {
2195  hsm_config_t module_config;
2196  hsm_repository_t* repo = NULL;
2197  char* module_pin = NULL;
2198  int result = HSM_OK;
2199  int tries;
2200  int repositories = 0;
2201 
2202  pthread_mutex_lock(&_hsm_ctx_mutex);
2203  /* create an internal context with an attached session for each
2204  * configured HSM. */
2205  if ((_hsm_ctx = hsm_ctx_new())) {
2207  }
2208 
2209  repo = rlist;
2210  while (repo) {
2211  hsm_config_default(&module_config);
2212  module_config.use_pubkey = repo->use_pubkey;
2213  module_config.allow_extract = repo->allow_extract;
2214  if (repo->name && repo->module && repo->tokenlabel) {
2215  if (repo->pin) {
2216  result = hsm_attach(repo->name, repo->tokenlabel,
2217  repo->module, repo->pin, &module_config);
2218  } else {
2219  if (pin_callback) {
2220  result = HSM_PIN_INCORRECT;
2221  tries = 0;
2222  while (result == HSM_PIN_INCORRECT && tries < 3) {
2223  module_pin = pin_callback(_hsm_ctx->session_count,
2224  repo->name, tries?HSM_PIN_RETRY:HSM_PIN_FIRST);
2225  if (module_pin == NULL) break;
2226  result = hsm_attach(repo->name, repo->tokenlabel,
2227  repo->module, module_pin, &module_config);
2228  if (result == HSM_OK) {
2229  pin_callback(_hsm_ctx->session_count - 1,
2230  repo->name, HSM_PIN_SAVE);
2231  }
2232  memset(module_pin, 0, strlen(module_pin));
2233  tries++;
2234  }
2235  } else {
2236  /* no pin, no callback */
2237  hsm_ctx_set_error(_hsm_ctx, HSM_ERROR, "hsm_open2()",
2238  "No pin or callback function");
2239  result = HSM_ERROR;
2240  }
2241  }
2242  if (result != HSM_OK) {
2243  break;
2244  }
2245  repositories++;
2246  }
2247  repo = repo->next;
2248  }
2249  if (result == HSM_OK && repositories == 0) {
2251  "No repositories found");
2252  result = HSM_NO_REPOSITORIES;
2253  }
2254  pthread_mutex_unlock(&_hsm_ctx_mutex);
2255  return result;
2256 }
2257 
2258 void
2260 {
2261  pthread_mutex_lock(&_hsm_ctx_mutex);
2263  hsm_ctx_close(_hsm_ctx, 1);
2264  _hsm_ctx = NULL;
2265  pthread_mutex_unlock(&_hsm_ctx_mutex);
2266 }
2267 
2268 hsm_ctx_t *
2270 {
2271  hsm_ctx_t* newctx;
2272  pthread_mutex_lock(&_hsm_ctx_mutex);
2273  newctx = hsm_ctx_clone(_hsm_ctx);
2274  pthread_mutex_unlock(&_hsm_ctx_mutex);
2275  return newctx;
2276 }
2277 
2278 int
2280 {
2281  unsigned int i;
2282  hsm_session_t *session;
2283  CK_SESSION_INFO info;
2284  CK_RV rv;
2285  CK_SESSION_HANDLE session_handle;
2286  hsm_ctx_t *ctx;
2287 
2288  pthread_mutex_lock(&_hsm_ctx_mutex);
2289  ctx = _hsm_ctx;
2290 
2291  for (i = 0; i < ctx->session_count; i++) {
2292  session = ctx->session[i];
2293  if (session == NULL) continue;
2294 
2295  /* Get session info */
2296  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GetSessionInfo(
2297  session->session,
2298  &info);
2299  if (hsm_pkcs11_check_error(ctx, rv, "get session info")) {
2300  pthread_mutex_unlock(&_hsm_ctx_mutex);
2301  return HSM_ERROR;
2302  }
2303 
2304  /* Check session info */
2305  if (info.state != CKS_RW_USER_FUNCTIONS) {
2306  hsm_ctx_set_error(ctx, HSM_ERROR, "hsm_check_context()",
2307  "Session not logged in");
2308  pthread_mutex_unlock(&_hsm_ctx_mutex);
2309  return HSM_ERROR;
2310  }
2311 
2312  /* Try open and close a session with the token */
2313  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_OpenSession(info.slotID,
2315  NULL,
2316  NULL,
2317  &session_handle);
2318  if (hsm_pkcs11_check_error(ctx, rv, "test open session")) {
2319  pthread_mutex_unlock(&_hsm_ctx_mutex);
2320  return HSM_ERROR;
2321  }
2322  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_CloseSession(session_handle);
2323  if (hsm_pkcs11_check_error(ctx, rv, "test close session")) {
2324  pthread_mutex_unlock(&_hsm_ctx_mutex);
2325  return HSM_ERROR;
2326  }
2327  }
2328 
2329  pthread_mutex_unlock(&_hsm_ctx_mutex);
2330  return HSM_OK;
2331 }
2332 
2333 void
2335 {
2336  hsm_ctx_close(ctx, 0);
2337 }
2338 
2344 {
2345  hsm_sign_params_t *params;
2346  params = malloc(sizeof(hsm_sign_params_t));
2347  if (!params) {
2348  return NULL;
2349  }
2350  params->algorithm = LDNS_RSASHA256;
2351  params->flags = LDNS_KEY_ZONE_KEY;
2352  params->inception = 0;
2353  params->expiration = 0;
2354  params->keytag = 0;
2355  params->owner = NULL;
2356  return params;
2357 }
2358 
2359 void
2361 {
2362  if (params) {
2363  if (params->owner) ldns_rdf_deep_free(params->owner);
2364  free(params);
2365  }
2366 }
2367 
2368 void
2370 {
2371  free(key->modulename);
2372  free(key);
2373 }
2374 
2375 libhsm_key_t **
2376 hsm_list_keys(hsm_ctx_t *ctx, size_t *count)
2377 {
2378  libhsm_key_t **keys = NULL;
2379  size_t key_count = 0;
2380  size_t cur_key_count;
2381  libhsm_key_t **session_keys;
2382  unsigned int i, j;
2383 
2384  for (i = 0; i < ctx->session_count; i++) {
2385  session_keys = hsm_list_keys_session(ctx, ctx->session[i],
2386  &cur_key_count);
2387  keys = realloc(keys,
2388  (key_count + cur_key_count) * sizeof(libhsm_key_t *));
2389  for (j = 0; j < cur_key_count; j++) {
2390  keys[key_count + j] = session_keys[j];
2391  }
2392  key_count += cur_key_count;
2393  free(session_keys);
2394  }
2395  if (count) {
2396  *count = key_count;
2397  }
2398  return keys;
2399 }
2400 
2401 libhsm_key_t **
2403  size_t *count,
2404  const char *repository)
2405 {
2406  hsm_session_t *session;
2407 
2408  if (!repository) return NULL;
2409 
2410  session = hsm_find_repository_session(ctx, repository);
2411  if (!session) {
2412  *count = 0;
2413  return NULL;
2414  }
2415  return hsm_list_keys_session(ctx, session, count);
2416 }
2417 
2418 libhsm_key_t *
2420 {
2421  unsigned char *id_bytes;
2422  size_t len;
2423  libhsm_key_t *key;
2424 
2425  id_bytes = hsm_hex_parse(id, &len);
2426 
2427  if (!id_bytes) return NULL;
2428 
2429  key = hsm_find_key_by_id_bin(ctx, id_bytes, len);
2430  free(id_bytes);
2431  return key;
2432 }
2433 
2434 static void
2435 generate_unique_id(hsm_ctx_t *ctx, unsigned char *buf, size_t bufsize)
2436 {
2437  libhsm_key_t *key;
2438  /* check whether this key doesn't happen to exist already */
2439  hsm_random_buffer(ctx, buf, bufsize);
2440  while ((key = hsm_find_key_by_id_bin(ctx, buf, bufsize))) {
2441  libhsm_key_free(key);
2442  hsm_random_buffer(ctx, buf, bufsize);
2443  }
2444 
2445 }
2446 
2447 libhsm_key_t *
2449  const char *repository,
2450  unsigned long keysize)
2451 {
2452  libhsm_key_t *new_key;
2453  hsm_session_t *session;
2454  /* ids we create are 16 bytes of data */
2455  unsigned char id[16];
2456  /* that's 33 bytes in string (16*2 + 1 for \0) */
2457  char id_str[33];
2458  CK_RV rv;
2459  CK_OBJECT_HANDLE publicKey, privateKey;
2460  CK_KEY_TYPE keyType = CKK_RSA;
2461  CK_MECHANISM mechanism = {
2463  };
2464  CK_BYTE publicExponent[] = { 1, 0, 1 };
2465  CK_BBOOL ctrue = CK_TRUE;
2466  CK_BBOOL cfalse = CK_FALSE;
2467  CK_BBOOL ctoken = CK_TRUE;
2468  CK_BBOOL cextractable = CK_FALSE;
2469 
2470  session = hsm_find_repository_session(ctx, repository);
2471  if (!session) return NULL;
2472  cextractable = session->module->config->allow_extract ? CK_TRUE : CK_FALSE;
2473 
2474  generate_unique_id(ctx, id, 16);
2475 
2476  /* the CKA_LABEL will contain a hexadecimal string representation
2477  * of the id */
2478  hsm_hex_unparse(id_str, id, 16);
2479 
2480  if (! session->module->config->use_pubkey) {
2481  ctoken = CK_FALSE;
2482  }
2483 
2484  CK_ATTRIBUTE publicKeyTemplate[] = {
2485  { CKA_LABEL,(CK_UTF8CHAR*) id_str, strlen(id_str) },
2486  { CKA_ID, id, 16 },
2487  { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
2488  { CKA_VERIFY, &ctrue, sizeof(ctrue) },
2489  { CKA_ENCRYPT, &cfalse, sizeof(cfalse) },
2490  { CKA_WRAP, &cfalse, sizeof(cfalse) },
2491  { CKA_TOKEN, &ctoken, sizeof(ctoken) },
2492  { CKA_MODULUS_BITS, &keysize, sizeof(keysize) },
2493  { CKA_PUBLIC_EXPONENT, &publicExponent, sizeof(publicExponent)}
2494  };
2495 
2496  CK_ATTRIBUTE privateKeyTemplate[] = {
2497  { CKA_LABEL,(CK_UTF8CHAR *) id_str, strlen (id_str) },
2498  { CKA_ID, id, 16 },
2499  { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
2500  { CKA_SIGN, &ctrue, sizeof (ctrue) },
2501  { CKA_DECRYPT, &cfalse, sizeof (cfalse) },
2502  { CKA_UNWRAP, &cfalse, sizeof (cfalse) },
2503  { CKA_SENSITIVE, &ctrue, sizeof (ctrue) },
2504  { CKA_TOKEN, &ctrue, sizeof (ctrue) },
2505  { CKA_PRIVATE, &ctrue, sizeof (ctrue) },
2506  { CKA_EXTRACTABLE, &cextractable, sizeof (cextractable) }
2507  };
2508 
2509  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GenerateKeyPair(session->session,
2510  &mechanism,
2511  publicKeyTemplate, 9,
2512  privateKeyTemplate, 10,
2513  &publicKey,
2514  &privateKey);
2515  if (hsm_pkcs11_check_error(ctx, rv, "generate key pair")) {
2516  return NULL;
2517  }
2518 
2519  new_key = libhsm_key_new();
2520  new_key->modulename = strdup(session->module->name);
2521 
2522  if (session->module->config->use_pubkey) {
2523  new_key->public_key = publicKey;
2524  } else {
2525  /* Destroy the object directly in order to optimize storage in HSM */
2526  /* Ignore return value, it is just a session object and will be destroyed later */
2527  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_DestroyObject(session->session, publicKey);
2528  new_key->public_key = 0;
2529  }
2530 
2531  new_key->private_key = privateKey;
2532  return new_key;
2533 }
2534 
2535 libhsm_key_t *
2537  const char *repository,
2538  unsigned long keysize)
2539 {
2540  CK_RV rv;
2541  libhsm_key_t *new_key;
2542  hsm_session_t *session;
2543  CK_OBJECT_HANDLE domainPar, publicKey, privateKey;
2544  CK_BBOOL ctrue = CK_TRUE;
2545  CK_BBOOL cfalse = CK_FALSE;
2546  CK_BBOOL cextractable = CK_FALSE;
2547 
2548  /* ids we create are 16 bytes of data */
2549  unsigned char id[16];
2550  /* that's 33 bytes in string (16*2 + 1 for \0) */
2551  char id_str[33];
2552 
2553  session = hsm_find_repository_session(ctx, repository);
2554  if (!session) return NULL;
2555  cextractable = session->module->config->allow_extract ? CK_TRUE : CK_FALSE;
2556 
2557  generate_unique_id(ctx, id, 16);
2558 
2559  /* the CKA_LABEL will contain a hexadecimal string representation
2560  * of the id */
2561  hsm_hex_unparse(id_str, id, 16);
2562 
2563  CK_KEY_TYPE keyType = CKK_DSA;
2564  CK_MECHANISM mechanism1 = {
2566  };
2567  CK_MECHANISM mechanism2 = {
2569  };
2570 
2571  /* The maximum size for DSA in DNSSEC */
2572  CK_BYTE dsa_p[128];
2573  CK_BYTE dsa_q[20];
2574  CK_BYTE dsa_g[128];
2575 
2576  CK_ATTRIBUTE domainTemplate[] = {
2577  { CKA_PRIME_BITS, &keysize, sizeof(keysize) }
2578  };
2579 
2580  CK_ATTRIBUTE publicKeyTemplate[] = {
2581  { CKA_PRIME, dsa_p, sizeof(dsa_p) },
2582  { CKA_SUBPRIME, dsa_q, sizeof(dsa_q) },
2583  { CKA_BASE, dsa_g, sizeof(dsa_g) },
2584  { CKA_LABEL,(CK_UTF8CHAR*) id_str, strlen(id_str) },
2585  { CKA_ID, id, 16 },
2586  { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
2587  { CKA_VERIFY, &ctrue, sizeof(ctrue) },
2588  { CKA_ENCRYPT, &cfalse, sizeof(cfalse) },
2589  { CKA_WRAP, &cfalse, sizeof(cfalse) },
2590  { CKA_TOKEN, &ctrue, sizeof(ctrue) }
2591  };
2592 
2593  CK_ATTRIBUTE privateKeyTemplate[] = {
2594  { CKA_LABEL,(CK_UTF8CHAR*) id_str, strlen (id_str) },
2595  { CKA_ID, id, 16 },
2596  { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
2597  { CKA_SIGN, &ctrue, sizeof(ctrue) },
2598  { CKA_DECRYPT, &cfalse, sizeof(cfalse) },
2599  { CKA_UNWRAP, &cfalse, sizeof(cfalse) },
2600  { CKA_SENSITIVE, &ctrue, sizeof(ctrue) },
2601  { CKA_TOKEN, &ctrue, sizeof(ctrue) },
2602  { CKA_PRIVATE, &ctrue, sizeof(ctrue) },
2603  { CKA_EXTRACTABLE, &cextractable, sizeof (cextractable) }
2604  };
2605 
2606  cextractable = session->module->config->allow_extract ? CK_TRUE : CK_FALSE;
2607 
2608  /* Generate the domain parameters */
2609 
2610  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GenerateKey(session->session,
2611  &mechanism1,
2612  domainTemplate, 1,
2613  &domainPar);
2614  if (hsm_pkcs11_check_error(ctx, rv, "generate domain parameters")) {
2615  return NULL;
2616  }
2617 
2618  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GetAttributeValue(session->session,
2619  domainPar, publicKeyTemplate, 3);
2620  if (hsm_pkcs11_check_error(ctx, rv, "get domain parameters")) {
2621  return NULL;
2622  }
2623 
2624  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_DestroyObject(session->session, domainPar);
2625  if (hsm_pkcs11_check_error(ctx, rv, "destroy domain parameters")) {
2626  return NULL;
2627  }
2628 
2629  /* Generate key pair */
2630 
2631  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GenerateKeyPair(session->session,
2632  &mechanism2,
2633  publicKeyTemplate, 10,
2634  privateKeyTemplate, 10,
2635  &publicKey,
2636  &privateKey);
2637  if (hsm_pkcs11_check_error(ctx, rv, "generate key pair")) {
2638  return NULL;
2639  }
2640 
2641  new_key = libhsm_key_new();
2642  new_key->modulename = strdup(session->module->name);
2643  new_key->public_key = publicKey;
2644  new_key->private_key = privateKey;
2645 
2646  return new_key;
2647 }
2648 
2649 libhsm_key_t *
2651  const char *repository)
2652 {
2653  CK_RV rv;
2654  libhsm_key_t *new_key;
2655  hsm_session_t *session;
2656  CK_OBJECT_HANDLE publicKey, privateKey;
2657  CK_BBOOL ctrue = CK_TRUE;
2658  CK_BBOOL cfalse = CK_FALSE;
2659  CK_BBOOL cextractable = CK_FALSE;
2660 
2661  /* ids we create are 16 bytes of data */
2662  unsigned char id[16];
2663  /* that's 33 bytes in string (16*2 + 1 for \0) */
2664  char id_str[33];
2665 
2666  session = hsm_find_repository_session(ctx, repository);
2667  if (!session) return NULL;
2668  cextractable = session->module->config->allow_extract ? CK_TRUE : CK_FALSE;
2669 
2670  generate_unique_id(ctx, id, 16);
2671 
2672  /* the CKA_LABEL will contain a hexadecimal string representation
2673  * of the id */
2674  hsm_hex_unparse(id_str, id, 16);
2675 
2676  CK_KEY_TYPE keyType = CKK_GOSTR3410;
2677  CK_MECHANISM mechanism = {
2679  };
2680 
2681  CK_BYTE oid1[] = { 0x06, 0x07, 0x2A, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01 };
2682  CK_BYTE oid2[] = { 0x06, 0x07, 0x2A, 0x85, 0x03, 0x02, 0x02, 0x1E, 0x01 };
2683 
2684  CK_ATTRIBUTE publicKeyTemplate[] = {
2685  { CKA_GOSTR3410PARAMS, oid1, sizeof(oid1) },
2686  { CKA_GOSTR3411PARAMS, oid2, sizeof(oid2) },
2687  { CKA_LABEL,(CK_UTF8CHAR*) id_str, strlen(id_str) },
2688  { CKA_ID, id, 16 },
2689  { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
2690  { CKA_VERIFY, &ctrue, sizeof(ctrue) },
2691  { CKA_ENCRYPT, &cfalse, sizeof(cfalse) },
2692  { CKA_WRAP, &cfalse, sizeof(cfalse) },
2693  { CKA_TOKEN, &ctrue, sizeof(ctrue) }
2694  };
2695 
2696  CK_ATTRIBUTE privateKeyTemplate[] = {
2697  { CKA_LABEL,(CK_UTF8CHAR*) id_str, strlen (id_str) },
2698  { CKA_ID, id, 16 },
2699  { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
2700  { CKA_SIGN, &ctrue, sizeof(ctrue) },
2701  { CKA_DECRYPT, &cfalse, sizeof(cfalse) },
2702  { CKA_UNWRAP, &cfalse, sizeof(cfalse) },
2703  { CKA_SENSITIVE, &ctrue, sizeof(ctrue) },
2704  { CKA_TOKEN, &ctrue, sizeof(ctrue) },
2705  { CKA_PRIVATE, &ctrue, sizeof(ctrue) },
2706  { CKA_EXTRACTABLE, &cextractable, sizeof (cextractable) }
2707  };
2708 
2709  /* Generate key pair */
2710 
2711  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GenerateKeyPair(session->session,
2712  &mechanism,
2713  publicKeyTemplate, 9,
2714  privateKeyTemplate, 10,
2715  &publicKey,
2716  &privateKey);
2717  if (hsm_pkcs11_check_error(ctx, rv, "generate key pair")) {
2718  return NULL;
2719  }
2720 
2721  new_key = libhsm_key_new();
2722  new_key->modulename = strdup(session->module->name);
2723  new_key->public_key = publicKey;
2724  new_key->private_key = privateKey;
2725 
2726  return new_key;
2727 }
2728 
2729 libhsm_key_t *
2731  const char *repository,
2732  const char *curve)
2733 {
2734  CK_RV rv;
2735  libhsm_key_t *new_key;
2736  hsm_session_t *session;
2737  CK_OBJECT_HANDLE publicKey, privateKey;
2738  CK_BBOOL ctrue = CK_TRUE;
2739  CK_BBOOL cfalse = CK_FALSE;
2740  CK_BBOOL cextractable = CK_FALSE;
2741 
2742  /* ids we create are 16 bytes of data */
2743  unsigned char id[16];
2744  /* that's 33 bytes in string (16*2 + 1 for \0) */
2745  char id_str[33];
2746 
2747  session = hsm_find_repository_session(ctx, repository);
2748  if (!session) return NULL;
2749  cextractable = session->module->config->allow_extract ? CK_TRUE : CK_FALSE;
2750 
2751  generate_unique_id(ctx, id, 16);
2752 
2753  /* the CKA_LABEL will contain a hexadecimal string representation
2754  * of the id */
2755  hsm_hex_unparse(id_str, id, 16);
2756 
2757  CK_KEY_TYPE keyType = CKK_EC;
2758  CK_MECHANISM mechanism = {
2760  };
2761 
2762  CK_BYTE oidP256[] = { 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07 };
2763  CK_BYTE oidP384[] = { 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22 };
2764 
2765  CK_ATTRIBUTE publicKeyTemplate[] = {
2766  { CKA_EC_PARAMS, NULL, 0 },
2767  { CKA_LABEL,(CK_UTF8CHAR*) id_str, strlen(id_str) },
2768  { CKA_ID, id, 16 },
2769  { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
2770  { CKA_VERIFY, &ctrue, sizeof(ctrue) },
2771  { CKA_ENCRYPT, &cfalse, sizeof(cfalse) },
2772  { CKA_WRAP, &cfalse, sizeof(cfalse) },
2773  { CKA_TOKEN, &ctrue, sizeof(ctrue) }
2774  };
2775 
2776  CK_ATTRIBUTE privateKeyTemplate[] = {
2777  { CKA_LABEL,(CK_UTF8CHAR*) id_str, strlen (id_str) },
2778  { CKA_ID, id, 16 },
2779  { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
2780  { CKA_SIGN, &ctrue, sizeof(ctrue) },
2781  { CKA_DECRYPT, &cfalse, sizeof(cfalse) },
2782  { CKA_UNWRAP, &cfalse, sizeof(cfalse) },
2783  { CKA_SENSITIVE, &ctrue, sizeof(ctrue) },
2784  { CKA_TOKEN, &ctrue, sizeof(ctrue) },
2785  { CKA_PRIVATE, &ctrue, sizeof(ctrue) },
2786  { CKA_EXTRACTABLE, &cextractable, sizeof (cextractable) }
2787  };
2788 
2789  /* Select the curve */
2790  if (strcmp(curve, "P-256") == 0)
2791  {
2792  publicKeyTemplate[0].pValue = oidP256;
2793  publicKeyTemplate[0].ulValueLen = sizeof(oidP256);
2794  }
2795  else if (strcmp(curve, "P-384") == 0)
2796  {
2797  publicKeyTemplate[0].pValue = oidP384;
2798  publicKeyTemplate[0].ulValueLen = sizeof(oidP384);
2799  }
2800  else
2801  {
2802  return NULL;
2803  }
2804 
2805  /* Generate key pair */
2806 
2807  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GenerateKeyPair(session->session,
2808  &mechanism,
2809  publicKeyTemplate, 8,
2810  privateKeyTemplate, 10,
2811  &publicKey,
2812  &privateKey);
2813  if (hsm_pkcs11_check_error(ctx, rv, "generate key pair")) {
2814  return NULL;
2815  }
2816 
2817  new_key = libhsm_key_new();
2818  new_key->modulename = strdup(session->module->name);
2819  new_key->public_key = publicKey;
2820  new_key->private_key = privateKey;
2821 
2822  return new_key;
2823 }
2824 
2825 int
2827 {
2828  CK_RV rv;
2829  hsm_session_t *session;
2830  if (!key) return -1;
2831 
2832  session = hsm_find_key_session(ctx, key);
2833  if (!session) return -2;
2834 
2835  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_DestroyObject(session->session,
2836  key->private_key);
2837  if (hsm_pkcs11_check_error(ctx, rv, "Destroy private key")) {
2838  return -3;
2839  }
2840  key->private_key = 0;
2841 
2842  if (key->public_key) {
2843  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_DestroyObject(session->session,
2844  key->public_key);
2845  if (hsm_pkcs11_check_error(ctx, rv, "Destroy public key")) {
2846  return -4;
2847  }
2848  }
2849  key->public_key = 0;
2850 
2851  return 0;
2852 }
2853 
2854 void
2855 libhsm_key_list_free(libhsm_key_t **key_list, size_t count)
2856 {
2857  size_t i;
2858  for (i = 0; i < count; i++) {
2859  libhsm_key_free(key_list[i]);
2860  }
2861  free(key_list);
2862 }
2863 
2864 char *
2866 {
2867  unsigned char *id;
2868  char *id_str;
2869  size_t len;
2870  hsm_session_t *session;
2871 
2872  if (!key) return NULL;
2873 
2874  session = hsm_find_key_session(ctx, key);
2875  if (!session) return NULL;
2876 
2877  id = hsm_get_id_for_object(ctx, session, key->private_key, &len);
2878  if (!id) return NULL;
2879 
2880  /* this is plain binary data, we need to convert it to hex */
2881  id_str = malloc(len * 2 + 1);
2882  if (!id_str) {
2883  free(id);
2884  return NULL;
2885  }
2886 
2887  hsm_hex_unparse(id_str, id, len);
2888 
2889  free(id);
2890 
2891  return id_str;
2892 }
2893 
2896  const libhsm_key_t *key)
2897 {
2898  libhsm_key_info_t *key_info;
2899  hsm_session_t *session;
2900 
2901  session = hsm_find_key_session(ctx, key);
2902  if (!session) return NULL;
2903 
2904  key_info = malloc(sizeof(libhsm_key_info_t));
2905 
2906  key_info->id = hsm_get_key_id(ctx, key);
2907  if (key_info->id == NULL) {
2908  key_info->id = strdup("");
2909  }
2910 
2911  key_info->algorithm = (unsigned long) hsm_get_key_algorithm(ctx,
2912  session,
2913  key);
2914  key_info->keysize = (unsigned long) hsm_get_key_size(ctx,
2915  session,
2916  key,
2917  key_info->algorithm);
2918 
2919  switch(key_info->algorithm) {
2920  case CKK_RSA:
2921  key_info->algorithm_name = strdup("RSA");
2922  break;
2923  case CKK_DSA:
2924  key_info->algorithm_name = strdup("DSA");
2925  break;
2926  case CKK_GOSTR3410:
2927  key_info->algorithm_name = strdup("GOST");
2928  break;
2929  case CKK_EC:
2930  key_info->algorithm_name = strdup("ECDSA");
2931  break;
2932  default:
2933  key_info->algorithm_name = malloc(HSM_MAX_ALGONAME);
2934  snprintf(key_info->algorithm_name, HSM_MAX_ALGONAME,
2935  "%lu", key_info->algorithm);
2936  break;
2937  }
2938 
2939  return key_info;
2940 }
2941 
2942 void
2944 {
2945  if (key_info) {
2946  if (key_info->id) {
2947  free(key_info->id);
2948  }
2949  if (key_info->algorithm_name) {
2950  free(key_info->algorithm_name);
2951  }
2952  free(key_info);
2953  }
2954 }
2955 
2956 ldns_rr*
2958  const ldns_rr_list* rrset,
2959  const libhsm_key_t *key,
2960  const hsm_sign_params_t *sign_params)
2961 {
2962  ldns_rr *signature;
2963  ldns_buffer *sign_buf;
2964  ldns_rdf *b64_rdf;
2965  size_t i;
2966 
2967  if (!key) return NULL;
2968  if (!sign_params) return NULL;
2969 
2970  signature = hsm_create_empty_rrsig((ldns_rr_list *)rrset,
2971  sign_params);
2972 
2973  /* right now, we have: a key, a semi-sig and an rrset. For
2974  * which we can create the sig and base64 encode that and
2975  * add that to the signature */
2976  sign_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2977 
2978  if (ldns_rrsig2buffer_wire(sign_buf, signature)
2979  != LDNS_STATUS_OK) {
2980  ldns_buffer_free(sign_buf);
2981  /* ERROR */
2982  ldns_rr_free(signature);
2983  return NULL;
2984  }
2985 
2986  /* make it canonical */
2987  for(i = 0; i < ldns_rr_list_rr_count(rrset); i++) {
2988  ldns_rr2canonical(ldns_rr_list_rr(rrset, i));
2989  }
2990 
2991  /* add the rrset in sign_buf */
2992  if (ldns_rr_list2buffer_wire(sign_buf, rrset)
2993  != LDNS_STATUS_OK) {
2994  ldns_buffer_free(sign_buf);
2995  ldns_rr_free(signature);
2996  return NULL;
2997  }
2998 
2999  b64_rdf = hsm_sign_buffer(ctx, sign_buf, key, sign_params->algorithm);
3000 
3001  ldns_buffer_free(sign_buf);
3002  if (!b64_rdf) {
3003  /* signing went wrong */
3004  ldns_rr_free(signature);
3005  return NULL;
3006  }
3007 
3008  ldns_rr_rrsig_set_sig(signature, b64_rdf);
3009 
3010  return signature;
3011 }
3012 
3013 int
3014 hsm_keytag(const char* loc, int alg, int ksk, uint16_t* keytag)
3015 {
3016  uint16_t tag;
3017  hsm_ctx_t *hsm_ctx;
3018  hsm_sign_params_t *sign_params;
3019  libhsm_key_t *hsmkey;
3020  ldns_rr *dnskey_rr;
3021 
3022  if (!loc) {
3023  return 1;
3024  }
3025 
3026  if (!(hsm_ctx = hsm_create_context())) {
3027  return 1;
3028  }
3029  if (!(sign_params = hsm_sign_params_new())) {
3030  hsm_destroy_context(hsm_ctx);
3031  return 1;
3032  }
3033 
3034  /* The owner name is not relevant for the keytag calculation.
3035  * However, a ldns_rdf_clone down the path will trip over it. */
3036  sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, "dummy");
3037  sign_params->algorithm = (ldns_algorithm) alg;
3038  sign_params->flags = LDNS_KEY_ZONE_KEY;
3039  if (ksk)
3040  sign_params->flags |= LDNS_KEY_SEP_KEY;
3041 
3042  hsmkey = hsm_find_key_by_id(hsm_ctx, loc);
3043  if (!hsmkey) {
3044  hsm_sign_params_free(sign_params);
3045  hsm_destroy_context(hsm_ctx);
3046  return 1;
3047  }
3048 
3049  dnskey_rr = hsm_get_dnskey(hsm_ctx, hsmkey, sign_params);
3050  if (!dnskey_rr) {
3051  libhsm_key_free(hsmkey);
3052  hsm_sign_params_free(sign_params);
3053  hsm_destroy_context(hsm_ctx);
3054  return 1;
3055  }
3056 
3057  tag = ldns_calc_keytag(dnskey_rr);
3058 
3059  ldns_rr_free(dnskey_rr);
3060  libhsm_key_free(hsmkey);
3061  hsm_sign_params_free(sign_params);
3062  hsm_destroy_context(hsm_ctx);
3063 
3064  if (keytag)
3065  *keytag = tag;
3066  return 0;
3067 }
3068 
3069 ldns_rr *
3071  const libhsm_key_t *key,
3072  const hsm_sign_params_t *sign_params)
3073 {
3074  /* CK_RV rv; */
3075  ldns_rr *dnskey;
3076  hsm_session_t *session;
3077  ldns_rdf *rdata;
3078 
3079  if (!key) {
3080  hsm_ctx_set_error(ctx, -1, "hsm_get_dnskey()", "Got NULL key");
3081  return NULL;
3082  }
3083  if (!sign_params) {
3084  hsm_ctx_set_error(ctx, -1, "hsm_get_dnskey()", "Got NULL sign_params");
3085  return NULL;
3086  }
3087  session = hsm_find_key_session(ctx, key);
3088  if (!session) return NULL;
3089 
3090  dnskey = ldns_rr_new();
3091  ldns_rr_set_type(dnskey, LDNS_RR_TYPE_DNSKEY);
3092 
3093  ldns_rr_set_owner(dnskey, ldns_rdf_clone(sign_params->owner));
3094 
3095  ldns_rr_push_rdf(dnskey,
3096  ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16,
3097  sign_params->flags));
3098  ldns_rr_push_rdf(dnskey,
3099  ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8,
3100  LDNS_DNSSEC_KEYPROTO));
3101  ldns_rr_push_rdf(dnskey,
3102  ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG,
3103  sign_params->algorithm));
3104 
3105  rdata = hsm_get_key_rdata(ctx, session, key);
3106  if (rdata == NULL) {
3107  ldns_rr_free(dnskey);
3108  return NULL;
3109  }
3110  ldns_rr_push_rdf(dnskey, rdata);
3111 
3112  return dnskey;
3113 }
3114 
3115 int
3117  unsigned char *buffer,
3118  unsigned long length)
3119 {
3120  CK_RV rv;
3121  unsigned int i;
3122  hsm_session_t *session;
3123  if (!buffer) return -1;
3124 
3125  /* just try every attached token. If one errors (be it NO_RNG, or
3126  * any other error, simply try the next */
3127  for (i = 0; i < ctx->session_count; i++) {
3128  session = ctx->session[i];
3129  if (session) {
3130  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GenerateRandom(
3131  session->session,
3132  buffer,
3133  length);
3134  if (rv == CKR_OK) {
3135  return 0;
3136  }
3137  }
3138  }
3139  return 1;
3140 }
3141 
3142 uint32_t
3144 {
3145  uint32_t rnd;
3146  int result;
3147  unsigned char rnd_buf[4];
3148  result = hsm_random_buffer(ctx, rnd_buf, 4);
3149  if (result == 0) {
3150  memcpy(&rnd, rnd_buf, 4);
3151  return rnd;
3152  } else {
3153  return 0;
3154  }
3155 }
3156 
3157 uint64_t
3159 {
3160  uint64_t rnd;
3161  int result;
3162  unsigned char rnd_buf[8];
3163  result = hsm_random_buffer(ctx, rnd_buf, 8);
3164  if (result == 0) {
3165  memcpy(&rnd, rnd_buf, 8);
3166  return rnd;
3167  } else {
3168  return 0;
3169  }
3170 }
3171 
3172 
3173 /*
3174  * Additional functions
3175  */
3176 
3177 int hsm_attach(const char *repository,
3178  const char *token_label,
3179  const char *path,
3180  const char *pin,
3181  const hsm_config_t *config)
3182 {
3183  hsm_session_t *session;
3184  int result;
3185 
3186  result = hsm_session_init(_hsm_ctx,
3187  &session,
3188  repository,
3189  token_label,
3190  path,
3191  pin,
3192  config);
3193  if (result == HSM_OK) {
3194  result = hsm_ctx_add_session(_hsm_ctx, session);
3195  }
3196  return result;
3197 }
3198 
3199 int
3200 hsm_token_attached(hsm_ctx_t *ctx, const char *repository)
3201 {
3202  unsigned int i;
3203  for (i = 0; i < ctx->session_count; i++) {
3204  if (ctx->session[i] &&
3205  strcmp(ctx->session[i]->module->name, repository) == 0) {
3206  return 1;
3207  }
3208  }
3209 
3211  "hsm_token_attached()",
3212  "Can't find repository: %s", repository);
3213  return 0;
3214 }
3215 
3216 char *
3218 {
3219  hsm_ctx_t *ctx;
3220 
3221  char *message;
3222 
3223  if (!gctx) {
3224  ctx = _hsm_ctx;
3225  } else {
3226  ctx = gctx;
3227  }
3228 
3229  if (ctx->error) {
3230  ctx->error = 0;
3231  message = malloc(HSM_ERROR_MSGSIZE);
3232 
3233  if (message == NULL) {
3234  return strdup("libhsm memory allocation failed");
3235  }
3236 
3237  snprintf(message, HSM_ERROR_MSGSIZE,
3238  "%s: %s",
3239  ctx->error_action ? ctx->error_action : "unknown()",
3240  ctx->error_message[0] ? ctx->error_message : "unknown error");
3241 
3242  /* Since both message and ctx->error_message have the same length, the
3243  * snprintf statement above may be truncated. In this case the string
3244  * won't be null-terminated. */
3245  message[HSM_ERROR_MSGSIZE - 1U] = '\0';
3246  return message;
3247  };
3248 
3249  return NULL;
3250 }
3251 
3252 void
3254 {
3255  printf("\t\tmodule at %p (sym %p)\n", (void *) session->module, (void *) session->module->sym);
3256  printf("\t\tmodule path: %s\n", session->module->path);
3257  printf("\t\trepository name: %s\n", session->module->name);
3258  printf("\t\ttoken label: %s\n", session->module->token_label);
3259  printf("\t\tsess handle: %u\n", (unsigned int) session->session);
3260 }
3261 
3262 void
3264  unsigned int i;
3265  printf("CTX Sessions: %lu\n",
3266  (long unsigned int) ctx->session_count);
3267  for (i = 0; i < ctx->session_count; i++) {
3268  printf("\tSession at %p\n", (void *) ctx->session[i]);
3270  }
3271 }
3272 
3273 void
3275  libhsm_key_info_t *key_info;
3276  if (key) {
3277  key_info = hsm_get_key_info(ctx, key);
3278  if (key_info) {
3279  printf("key:\n");
3280  printf("\tprivkey handle: %u\n", (unsigned int) key->private_key);
3281  if (key->public_key) {
3282  printf("\tpubkey handle: %u\n", (unsigned int) key->public_key);
3283  } else {
3284  printf("\tpubkey handle: %s\n", "NULL");
3285  }
3286  printf("\trepository: %s\n", key->modulename);
3287  printf("\talgorithm: %s\n", key_info->algorithm_name);
3288  printf("\tsize: %lu\n", key_info->keysize);
3289  printf("\tid: %s\n", key_info->id);
3290  libhsm_key_info_free(key_info);
3291  } else {
3292  printf("key: hsm_get_key_info() returned NULL\n");
3293  }
3294  } else {
3295  printf("key: <void>\n");
3296  }
3297 }
3298 
3299 void
3301 {
3302  char *message;
3303 
3304  message = hsm_get_error(gctx);
3305 
3306  if (message) {
3307  fprintf(stderr, "%s\n", message);
3308  free(message);
3309  } else {
3310  fprintf(stderr, "Unknown error\n");
3311  }
3312 }
3313 
3314 void
3316 {
3317  CK_RV rv;
3318  CK_SLOT_ID slot_id;
3319  CK_TOKEN_INFO token_info;
3320  unsigned int i;
3321  hsm_session_t *session;
3322  int result;
3323 
3324  for (i = 0; i < ctx->session_count; i++) {
3325  session = ctx->session[i];
3326 
3327  result = hsm_get_slot_id(ctx,
3328  session->module->sym,
3329  session->module->token_label,
3330  &slot_id);
3331  if (result != HSM_OK) return;
3332 
3333  rv = ((CK_FUNCTION_LIST_PTR) session->module->sym)->C_GetTokenInfo(slot_id, &token_info);
3334  if (hsm_pkcs11_check_error(ctx, rv, "C_GetTokenInfo")) {
3335  return;
3336  }
3337 
3338  printf("Repository: %s\n",session->module->name);
3339 
3340  printf("\tModule: %s\n", session->module->path);
3341  printf("\tSlot: %lu\n", slot_id);
3342  printf("\tToken Label: %.*s\n",
3343  (int) sizeof(token_info.label), token_info.label);
3344  printf("\tManufacturer: %.*s\n",
3345  (int) sizeof(token_info.manufacturerID), token_info.manufacturerID);
3346  printf("\tModel: %.*s\n",
3347  (int) sizeof(token_info.model), token_info.model);
3348  printf("\tSerial: %.*s\n",
3349  (int) sizeof(token_info.serialNumber), token_info.serialNumber);
3350 
3351  if (i + 1 != ctx->session_count)
3352  printf("\n");
3353  }
3354 }
3355 
3356 static int
3357 keycache_cmpfunc(const void* a, const void* b)
3358 {
3359  const char* x = (const char*)a;
3360  const char* y = (const char*)b;
3361  return strcmp(x, y);
3362 }
3363 
3364 static void
3365 keycache_delfunc(ldns_rbnode_t* node, void* cargo)
3366 {
3367  (void)cargo;
3368  free((void*)node->key);
3369  free(((libhsm_key_t*)node->data)->modulename);
3370  free((void*)node->data);
3371  free((void*)node);
3372 }
3373 
3374 void
3376 {
3377  ctx->keycache = ldns_rbtree_create(keycache_cmpfunc);
3378  _hsm_ctx->keycache_lock = malloc(sizeof (pthread_mutex_t));
3379  pthread_mutex_init(_hsm_ctx->keycache_lock, NULL);
3380 }
3381 
3382 void
3384 {
3385  ldns_traverse_postorder(ctx->keycache, keycache_delfunc, NULL);
3386  ldns_rbtree_free(ctx->keycache);
3387  pthread_mutex_destroy(ctx->keycache_lock);
3388  free(ctx->keycache_lock);
3389  ctx->keycache_lock = NULL;
3390 }
3391 
3392 const libhsm_key_t*
3393 keycache_lookup(hsm_ctx_t* ctx, const char* locator)
3394 {
3395  ldns_rbnode_t* node;
3396 
3397  pthread_mutex_lock(ctx->keycache_lock);
3398  node = ldns_rbtree_search(ctx->keycache, locator);
3399  pthread_mutex_unlock(ctx->keycache_lock);
3400  if (node == LDNS_RBTREE_NULL || node == NULL) {
3401  libhsm_key_t* key;
3402  if ((key = hsm_find_key_by_id(ctx, locator)) == NULL) {
3403  node = NULL;
3404  } else {
3405  node = malloc(sizeof(ldns_rbnode_t));
3406  node->key = strdup(locator);
3407  node->data = key;
3408  pthread_mutex_lock(ctx->keycache_lock);
3409  node = ldns_rbtree_insert(ctx->keycache, node);
3410  pthread_mutex_unlock(ctx->keycache_lock);
3411  }
3412  }
3413 
3414  if (node == LDNS_RBTREE_NULL || node == NULL)
3415  return NULL;
3416  else
3417  return node->data;
3418 }
CKR_DEVICE_ERROR
#define CKR_DEVICE_ERROR
Definition: pkcs11.h:1120
hsm_sign_params_t::flags
uint16_t flags
Definition: libhsmdns.h:38
ck_token_info
Definition: pkcs11.h:230
ck_attribute
Definition: pkcs11.h:463
libhsm_key_t::public_key
unsigned long public_key
Definition: libhsm.h:105
slot_id
#define slot_id
Definition: pkcs11.h:139
CKR_SESSION_HANDLE_INVALID
#define CKR_SESSION_HANDLE_INVALID
Definition: pkcs11.h:1150
CKR_SESSION_READ_ONLY
#define CKR_SESSION_READ_ONLY
Definition: pkcs11.h:1152
CKA_PUBLIC_EXPONENT
#define CKA_PUBLIC_EXPONENT
Definition: pkcs11.h:410
hsm_create_context
hsm_ctx_t * hsm_create_context()
Definition: libhsm.c:2269
libhsmdns.h
CKR_OPERATION_NOT_INITIALIZED
#define CKR_OPERATION_NOT_INITIALIZED
Definition: pkcs11.h:1142
CKR_MECHANISM_PARAM_INVALID
#define CKR_MECHANISM_PARAM_INVALID
Definition: pkcs11.h:1139
hsm_sign_params_t::owner
ldns_rdf * owner
Definition: libhsmdns.h:46
CKR_GENERAL_ERROR
#define CKR_GENERAL_ERROR
Definition: pkcs11.h:1108
hsm_sign_params_new
hsm_sign_params_t * hsm_sign_params_new()
Definition: libhsm.c:2343
hsm_repository_struct::tokenlabel
char * tokenlabel
Definition: libhsm.h:122
keycache_lookup
const libhsm_key_t * keycache_lookup(hsm_ctx_t *ctx, const char *locator)
Definition: libhsm.c:3393
ck_token_info::label
unsigned char label[32]
Definition: pkcs11.h:231
hsm_sign_params_t::keytag
uint16_t keytag
Definition: libhsmdns.h:44
CKA_TOKEN
#define CKA_TOKEN
Definition: pkcs11.h:374
CKA_MODULUS
#define CKA_MODULUS
Definition: pkcs11.h:408
value_len
#define value_len
Definition: pkcs11.h:151
hsm_generate_dsa_key
libhsm_key_t * hsm_generate_dsa_key(hsm_ctx_t *ctx, const char *repository, unsigned long keysize)
Definition: libhsm.c:2536
CK_BYTE_PTR
CK_BYTE * CK_BYTE_PTR
Definition: pkcs11.h:1218
hsm_module_t::sym
void * sym
Definition: libhsm.h:91
CKR_MUTEX_NOT_LOCKED
#define CKR_MUTEX_NOT_LOCKED
Definition: pkcs11.h:1187
hsm_repository_struct::use_pubkey
uint8_t use_pubkey
Definition: libhsm.h:125
CK_BYTE
unsigned char CK_BYTE
Definition: pkcs11.h:1212
CK_TRUE
#define CK_TRUE
Definition: pkcs11.h:1225
CKR_CANCEL
#define CKR_CANCEL
Definition: pkcs11.h:1105
CKM_DSA_KEY_PAIR_GEN
#define CKM_DSA_KEY_PAIR_GEN
Definition: pkcs11.h:495
hsm_module_t::handle
void * handle
Definition: libhsm.h:90
CKM_ECDSA
#define CKM_ECDSA
Definition: pkcs11.h:657
CKR_PIN_INCORRECT
#define CKR_PIN_INCORRECT
Definition: pkcs11.h:1143
hsm_generate_ecdsa_key
libhsm_key_t * hsm_generate_ecdsa_key(hsm_ctx_t *ctx, const char *repository, const char *curve)
Definition: libhsm.c:2730
hsm_config_t::use_pubkey
unsigned int use_pubkey
Definition: libhsm.h:80
CKR_SIGNATURE_INVALID
#define CKR_SIGNATURE_INVALID
Definition: pkcs11.h:1156
CKR_ATTRIBUTE_SENSITIVE
#define CKR_ATTRIBUTE_SENSITIVE
Definition: pkcs11.h:1115
hsm_print_tokeninfo
void hsm_print_tokeninfo(hsm_ctx_t *ctx)
Definition: libhsm.c:3315
hsm_config_t
Definition: libhsm.h:79
CKR_OPERATION_ACTIVE
#define CKR_OPERATION_ACTIVE
Definition: pkcs11.h:1141
ck_function_list::C_GetTokenInfo
CK_C_GetTokenInfo C_GetTokenInfo
Definition: pkcs11.h:1019
CKR_PIN_LEN_RANGE
#define CKR_PIN_LEN_RANGE
Definition: pkcs11.h:1145
hsm_get_key_info
libhsm_key_info_t * hsm_get_key_info(hsm_ctx_t *ctx, const libhsm_key_t *key)
Definition: libhsm.c:2895
hsm_repository_struct::next
hsm_repository_t * next
Definition: libhsm.h:119
hsm_random64
uint64_t hsm_random64(hsm_ctx_t *ctx)
Definition: libhsm.c:3158
libhsm_key_t
Definition: libhsm.h:102
CKM_GOSTR3410
#define CKM_GOSTR3410
Definition: pkcs11.h:676
CKR_WRAPPING_KEY_HANDLE_INVALID
#define CKR_WRAPPING_KEY_HANDLE_INVALID
Definition: pkcs11.h:1174
libhsm_key_info_t::id
char * id
Definition: libhsm.h:110
hsm_config_t::allow_extract
unsigned int allow_extract
Definition: libhsm.h:81
CKR_DEVICE_REMOVED
#define CKR_DEVICE_REMOVED
Definition: pkcs11.h:1122
CKS_RW_USER_FUNCTIONS
#define CKS_RW_USER_FUNCTIONS
Definition: pkcs11.h:292
keycache_create
void keycache_create(hsm_ctx_t *ctx)
Definition: libhsm.c:3375
CKM_GOSTR3411
#define CKM_GOSTR3411
Definition: pkcs11.h:678
ck_mechanism
Definition: pkcs11.h:686
CKR_ENCRYPTED_DATA_INVALID
#define CKR_ENCRYPTED_DATA_INVALID
Definition: pkcs11.h:1123
CKR_FUNCTION_CANCELED
#define CKR_FUNCTION_CANCELED
Definition: pkcs11.h:1125
CKA_EC_PARAMS
#define CKA_EC_PARAMS
Definition: pkcs11.h:431
_hsm_ctx_mutex
pthread_mutex_t _hsm_ctx_mutex
Definition: libhsm.c:57
hsm_sign_params_t::inception
uint32_t inception
Definition: libhsmdns.h:40
hsm_ctx_t::session
hsm_session_t * session[HSM_MAX_SESSIONS]
Definition: libhsm.h:131
CKR_STATE_UNSAVEABLE
#define CKR_STATE_UNSAVEABLE
Definition: pkcs11.h:1183
CKF_OS_LOCKING_OK
#define CKF_OS_LOCKING_OK
Definition: pkcs11.h:1102
CKF_SERIAL_SESSION
#define CKF_SERIAL_SESSION
Definition: pkcs11.h:305
CKM_RSA_PKCS
#define CKM_RSA_PKCS
Definition: pkcs11.h:481
CKR_DATA_LEN_RANGE
#define CKR_DATA_LEN_RANGE
Definition: pkcs11.h:1119
CKR_DEVICE_MEMORY
#define CKR_DEVICE_MEMORY
Definition: pkcs11.h:1121
ck_function_list
Definition: pkcs11.h:1011
ck_function_list::C_GetSlotList
CK_C_GetSlotList C_GetSlotList
Definition: pkcs11.h:1017
CKA_DECRYPT
#define CKA_DECRYPT
Definition: pkcs11.h:398
CKR_WRAPPING_KEY_SIZE_RANGE
#define CKR_WRAPPING_KEY_SIZE_RANGE
Definition: pkcs11.h:1175
CKA_GOSTR3410PARAMS
#define CKA_GOSTR3410PARAMS
Definition: pkcs11.h:437
HSM_PIN_FIRST
#define HSM_PIN_FIRST
Definition: libhsm.h:74
CKA_EC_POINT
#define CKA_EC_POINT
Definition: pkcs11.h:432
CKR_TEMPLATE_INCOMPLETE
#define CKR_TEMPLATE_INCOMPLETE
Definition: pkcs11.h:1158
CKA_SIGN
#define CKA_SIGN
Definition: pkcs11.h:401
hsm_sign_rrset
ldns_rr * hsm_sign_rrset(hsm_ctx_t *ctx, const ldns_rr_list *rrset, const libhsm_key_t *key, const hsm_sign_params_t *sign_params)
Definition: libhsm.c:2957
libhsm_key_info_free
void libhsm_key_info_free(libhsm_key_info_t *key_info)
Definition: libhsm.c:2943
HSM_NO_REPOSITORIES
#define HSM_NO_REPOSITORIES
Definition: libhsm.h:70
ck_session_info::state
ck_state_t state
Definition: pkcs11.h:299
CKR_SESSION_EXISTS
#define CKR_SESSION_EXISTS
Definition: pkcs11.h:1153
CKA_EXTRACTABLE
#define CKA_EXTRACTABLE
Definition: pkcs11.h:424
hsm_ctx_t::session_count
size_t session_count
Definition: libhsm.h:132
ck_token_info::model
unsigned char model[16]
Definition: pkcs11.h:233
hsm_keytag
int hsm_keytag(const char *loc, int alg, int ksk, uint16_t *keytag)
Definition: libhsm.c:3014
hsm_repository_struct::module
char * module
Definition: libhsm.h:121
CKR_USER_NOT_LOGGED_IN
#define CKR_USER_NOT_LOGGED_IN
Definition: pkcs11.h:1167
algorithm
ldns_algorithm algorithm
Definition: hsmspeed.c:43
CKR_UNWRAPPING_KEY_HANDLE_INVALID
#define CKR_UNWRAPPING_KEY_HANDLE_INVALID
Definition: pkcs11.h:1163
CKR_FUNCTION_FAILED
#define CKR_FUNCTION_FAILED
Definition: pkcs11.h:1109
hsm_sign_params_free
void hsm_sign_params_free(hsm_sign_params_t *params)
Definition: libhsm.c:2360
_hsm_ctx
hsm_ctx_t * _hsm_ctx
Definition: libhsm.c:56
CKA_VALUE
#define CKA_VALUE
Definition: pkcs11.h:378
CKR_MUTEX_BAD
#define CKR_MUTEX_BAD
Definition: pkcs11.h:1186
libhsm_key_info_t::algorithm_name
char * algorithm_name
Definition: libhsm.h:112
CKA_PRIVATE
#define CKA_PRIVATE
Definition: pkcs11.h:375
hsm_random_buffer
int hsm_random_buffer(hsm_ctx_t *ctx, unsigned char *buffer, unsigned long length)
Definition: libhsm.c:3116
HSM_PIN_RETRY
#define HSM_PIN_RETRY
Definition: libhsm.h:75
CK_LONG
long int CK_LONG
Definition: pkcs11.h:1217
HSM_ERROR_MSGSIZE
#define HSM_ERROR_MSGSIZE
Definition: libhsm.h:49
hsm_module_t::id
unsigned int id
Definition: libhsm.h:86
CK_UTF8CHAR
unsigned char CK_UTF8CHAR
Definition: pkcs11.h:1214
libhsm.h
CKM_GOSTR3410_KEY_PAIR_GEN
#define CKM_GOSTR3410_KEY_PAIR_GEN
Definition: pkcs11.h:675
CKK_EC
#define CKK_EC
Definition: pkcs11.h:338
hsm_list_keys
libhsm_key_t ** hsm_list_keys(hsm_ctx_t *ctx, size_t *count)
Definition: libhsm.c:2376
CKM_RSA_PKCS_KEY_PAIR_GEN
#define CKM_RSA_PKCS_KEY_PAIR_GEN
Definition: pkcs11.h:480
CKR_FUNCTION_NOT_PARALLEL
#define CKR_FUNCTION_NOT_PARALLEL
Definition: pkcs11.h:1126
libhsm_key_t::private_key
unsigned long private_key
Definition: libhsm.h:104
HSM_REPOSITORY_NOT_FOUND
#define HSM_REPOSITORY_NOT_FOUND
Definition: libhsm.h:69
hsm_repository_new
hsm_repository_t * hsm_repository_new(char *name, char *module, char *tokenlabel, char *pin, uint8_t use_pubkey, uint8_t allowextract, uint8_t require_backup)
Definition: libhsm.c:371
CKA_WRAP
#define CKA_WRAP
Definition: pkcs11.h:399
hsm_generate_rsa_key
libhsm_key_t * hsm_generate_rsa_key(hsm_ctx_t *ctx, const char *repository, unsigned long keysize)
Definition: libhsm.c:2448
CKA_LABEL
#define CKA_LABEL
Definition: pkcs11.h:376
libhsm_key_info_t::algorithm
unsigned long algorithm
Definition: libhsm.h:111
CKA_KEY_TYPE
#define CKA_KEY_TYPE
Definition: pkcs11.h:393
hsm_module_t::token_label
char * token_label
Definition: libhsm.h:88
CKR_WRAPPING_KEY_TYPE_INCONSISTENT
#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT
Definition: pkcs11.h:1176
CKR_CRYPTOKI_ALREADY_INITIALIZED
#define CKR_CRYPTOKI_ALREADY_INITIALIZED
Definition: pkcs11.h:1185
CKR_RANDOM_SEED_NOT_SUPPORTED
#define CKR_RANDOM_SEED_NOT_SUPPORTED
Definition: pkcs11.h:1177
CKR_ATTRIBUTE_READ_ONLY
#define CKR_ATTRIBUTE_READ_ONLY
Definition: pkcs11.h:1114
CK_BBOOL
unsigned char CK_BBOOL
Definition: pkcs11.h:1215
HSM_TOKEN_LABEL_LENGTH
#define HSM_TOKEN_LABEL_LENGTH
Definition: libhsm.c:53
hsm_remove_key
int hsm_remove_key(hsm_ctx_t *ctx, libhsm_key_t *key)
Definition: libhsm.c:2826
libhsm_key_free
void libhsm_key_free(libhsm_key_t *key)
Definition: libhsm.c:2369
CKR_PIN_INVALID
#define CKR_PIN_INVALID
Definition: pkcs11.h:1144
CKR_SLOT_ID_INVALID
#define CKR_SLOT_ID_INVALID
Definition: pkcs11.h:1107
hsm_module_t::path
char * path
Definition: libhsm.h:89
CKA_SENSITIVE
#define CKA_SENSITIVE
Definition: pkcs11.h:396
CKR_KEY_TYPE_INCONSISTENT
#define CKR_KEY_TYPE_INCONSISTENT
Definition: pkcs11.h:1130
CKR_KEY_SIZE_RANGE
#define CKR_KEY_SIZE_RANGE
Definition: pkcs11.h:1129
CKO_PUBLIC_KEY
#define CKO_PUBLIC_KEY
Definition: pkcs11.h:315
HSM_OK
#define HSM_OK
Definition: libhsm.h:65
CKR_SIGNATURE_LEN_RANGE
#define CKR_SIGNATURE_LEN_RANGE
Definition: pkcs11.h:1157
hsm_print_key
void hsm_print_key(hsm_ctx_t *ctx, libhsm_key_t *key)
Definition: libhsm.c:3274
hsm_attach
int hsm_attach(const char *repository, const char *token_label, const char *path, const char *pin, const hsm_config_t *config)
Definition: libhsm.c:3177
value
#define value
Definition: pkcs11.h:150
hsm_list_keys_repository
libhsm_key_t ** hsm_list_keys_repository(hsm_ctx_t *ctx, size_t *count, const char *repository)
Definition: libhsm.c:2402
CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT
#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT
Definition: pkcs11.h:1165
HSM_MAX_SIGNATURE_LENGTH
#define HSM_MAX_SIGNATURE_LENGTH
Definition: libhsm.h:53
hsm_module_t::config
hsm_config_t * config
Definition: libhsm.h:92
CKR_FUNCTION_NOT_SUPPORTED
#define CKR_FUNCTION_NOT_SUPPORTED
Definition: pkcs11.h:1127
hsm_ctx_t::keycache
ldns_rbtree_t * keycache
Definition: libhsm.h:144
CKO_PRIVATE_KEY
#define CKO_PRIVATE_KEY
Definition: pkcs11.h:316
hsm_print_session
void hsm_print_session(hsm_session_t *session)
Definition: libhsm.c:3253
CKR_HOST_MEMORY
#define CKR_HOST_MEMORY
Definition: pkcs11.h:1106
HSM_MODULE_NOT_FOUND
#define HSM_MODULE_NOT_FOUND
Definition: libhsm.h:71
CKR_DATA_INVALID
#define CKR_DATA_INVALID
Definition: pkcs11.h:1118
CKA_PRIME
#define CKA_PRIME
Definition: pkcs11.h:417
CKA_ENCRYPT
#define CKA_ENCRYPT
Definition: pkcs11.h:397
CKA_SUBPRIME
#define CKA_SUBPRIME
Definition: pkcs11.h:418
CKR_OK
#define CKR_OK
Definition: pkcs11.h:1104
CKM_DSA_PARAMETER_GEN
#define CKM_DSA_PARAMETER_GEN
Definition: pkcs11.h:679
hsm_repository_struct::pin
char * pin
Definition: libhsm.h:123
keycache_destroy
void keycache_destroy(hsm_ctx_t *ctx)
Definition: libhsm.c:3383
libhsm_key_info_t::keysize
unsigned long keysize
Definition: libhsm.h:113
hsm_module_t
Definition: libhsm.h:85
CKR_SESSION_COUNT
#define CKR_SESSION_COUNT
Definition: pkcs11.h:1149
CKR_MECHANISM_INVALID
#define CKR_MECHANISM_INVALID
Definition: pkcs11.h:1138
CKR_UNWRAPPING_KEY_SIZE_RANGE
#define CKR_UNWRAPPING_KEY_SIZE_RANGE
Definition: pkcs11.h:1164
CKK_GOSTR3410
#define CKK_GOSTR3410
Definition: pkcs11.h:359
CKA_ID
#define CKA_ID
Definition: pkcs11.h:395
hsm_print_ctx
void hsm_print_ctx(hsm_ctx_t *ctx)
Definition: libhsm.c:3263
CKK_DSA
#define CKK_DSA
Definition: pkcs11.h:335
CKA_VERIFY
#define CKA_VERIFY
Definition: pkcs11.h:403
CKR_SESSION_PARALLEL_NOT_SUPPORTED
#define CKR_SESSION_PARALLEL_NOT_SUPPORTED
Definition: pkcs11.h:1151
CKA_GOSTR3411PARAMS
#define CKA_GOSTR3411PARAMS
Definition: pkcs11.h:438
libhsm_key_t::modulename
char * modulename
Definition: libhsm.h:103
pkcs11.h
hsm_ctx_t::error
int error
Definition: libhsm.h:135
ctx
hsm_ctx_t * ctx
Definition: hsmutil.c:46
CK_FUNCTION_LIST_PTR
struct ck_function_list * CK_FUNCTION_LIST_PTR
Definition: pkcs11.h:1273
CKR_SESSION_CLOSED
#define CKR_SESSION_CLOSED
Definition: pkcs11.h:1148
hsm_repository_struct::allow_extract
unsigned int allow_extract
Definition: libhsm.h:126
ck_c_initialize_args
Definition: pkcs11.h:1091
CKM_DSA
#define CKM_DSA
Definition: pkcs11.h:496
HSM_MAX_SESSIONS
#define HSM_MAX_SESSIONS
Definition: libhsm.h:45
hsm_get_key_id
char * hsm_get_key_id(hsm_ctx_t *ctx, const libhsm_key_t *key)
Definition: libhsm.c:2865
hsm_module_t::name
char * name
Definition: libhsm.h:87
CKR_TEMPLATE_INCONSISTENT
#define CKR_TEMPLATE_INCONSISTENT
Definition: pkcs11.h:1159
hsm_find_key_by_id
libhsm_key_t * hsm_find_key_by_id(hsm_ctx_t *ctx, const char *id)
Definition: libhsm.c:2419
hsm_sign_params_t::algorithm
ldns_algorithm algorithm
Definition: libhsmdns.h:36
CKR_USER_ALREADY_LOGGED_IN
#define CKR_USER_ALREADY_LOGGED_IN
Definition: pkcs11.h:1166
hsm_sign_params_t
Definition: libhsmdns.h:34
CKR_INFORMATION_SENSITIVE
#define CKR_INFORMATION_SENSITIVE
Definition: pkcs11.h:1182
CKR_ATTRIBUTE_VALUE_INVALID
#define CKR_ATTRIBUTE_VALUE_INVALID
Definition: pkcs11.h:1117
CKR_ATTRIBUTE_TYPE_INVALID
#define CKR_ATTRIBUTE_TYPE_INVALID
Definition: pkcs11.h:1116
CKR_CRYPTOKI_NOT_INITIALIZED
#define CKR_CRYPTOKI_NOT_INITIALIZED
Definition: pkcs11.h:1184
hsm_repository_struct::name
char * name
Definition: libhsm.h:120
CK_ULONG
unsigned long int CK_ULONG
Definition: pkcs11.h:1216
hsm_ctx_t::error_action
const char * error_action
Definition: libhsm.h:139
CKR_KEY_HANDLE_INVALID
#define CKR_KEY_HANDLE_INVALID
Definition: pkcs11.h:1128
libhsm_key_info_t
Definition: libhsm.h:109
CKR_WRAPPED_KEY_LEN_RANGE
#define CKR_WRAPPED_KEY_LEN_RANGE
Definition: pkcs11.h:1173
CKM_MD5
#define CKM_MD5
Definition: pkcs11.h:540
hsm_get_dnskey
ldns_rr * hsm_get_dnskey(hsm_ctx_t *ctx, const libhsm_key_t *key, const hsm_sign_params_t *sign_params)
Definition: libhsm.c:3070
hsm_check_context
int hsm_check_context()
Definition: libhsm.c:2279
CK_FALSE
#define CK_FALSE
Definition: pkcs11.h:1224
CKF_RW_SESSION
#define CKF_RW_SESSION
Definition: pkcs11.h:304
CKA_BASE
#define CKA_BASE
Definition: pkcs11.h:419
HSM_PIN_INCORRECT
#define HSM_PIN_INCORRECT
Definition: libhsm.h:67
CKR_TOKEN_NOT_RECOGNIZED
#define CKR_TOKEN_NOT_RECOGNIZED
Definition: pkcs11.h:1161
hsm_ctx_t::error_message
char error_message[HSM_ERROR_MSGSIZE]
Definition: libhsm.h:142
hsm_ctx_t
Definition: libhsm.h:130
hsm_sign_params_t::expiration
uint32_t expiration
Definition: libhsmdns.h:42
hsm_open2
int hsm_open2(hsm_repository_t *rlist, char *(pin_callback)(unsigned int, const char *, unsigned int))
Definition: libhsm.c:2192
ck_session_info
Definition: pkcs11.h:297
hsm_session_t::module
hsm_module_t * module
Definition: libhsm.h:97
hsm_ctx_t::keycache_lock
pthread_mutex_t * keycache_lock
Definition: libhsm.h:145
CK_VOID_PTR
void * CK_VOID_PTR
Definition: pkcs11.h:1222
CKR_SAVED_STATE_INVALID
#define CKR_SAVED_STATE_INVALID
Definition: pkcs11.h:1181
HSM_MAX_ALGONAME
#define HSM_MAX_ALGONAME
Definition: libhsm.h:47
CKR_USER_TYPE_INVALID
#define CKR_USER_TYPE_INVALID
Definition: pkcs11.h:1169
CKR_TOKEN_WRITE_PROTECTED
#define CKR_TOKEN_WRITE_PROTECTED
Definition: pkcs11.h:1162
libhsm_key_list_free
void libhsm_key_list_free(libhsm_key_t **key_list, size_t count)
Definition: libhsm.c:2855
hsm_random32
uint32_t hsm_random32(hsm_ctx_t *ctx)
Definition: libhsm.c:3143
CKR_ENCRYPTED_DATA_LEN_RANGE
#define CKR_ENCRYPTED_DATA_LEN_RANGE
Definition: pkcs11.h:1124
CKA_CLASS
#define CKA_CLASS
Definition: pkcs11.h:373
NULL_PTR
#define NULL_PTR
Definition: pkcs11.h:1279
CKR_OBJECT_HANDLE_INVALID
#define CKR_OBJECT_HANDLE_INVALID
Definition: pkcs11.h:1140
CKA_MODULUS_BITS
#define CKA_MODULUS_BITS
Definition: pkcs11.h:409
HSM_PIN_SAVE
#define HSM_PIN_SAVE
Definition: libhsm.h:76
hsm_session_t
Definition: libhsm.h:96
hsm_generate_gost_key
libhsm_key_t * hsm_generate_gost_key(hsm_ctx_t *ctx, const char *repository)
Definition: libhsm.c:2650
CKM_EC_KEY_PAIR_GEN
#define CKM_EC_KEY_PAIR_GEN
Definition: pkcs11.h:656
CKR_WRAPPED_KEY_INVALID
#define CKR_WRAPPED_KEY_INVALID
Definition: pkcs11.h:1172
hsm_print_error
void hsm_print_error(hsm_ctx_t *gctx)
Definition: libhsm.c:3300
CKR_BUFFER_TOO_SMALL
#define CKR_BUFFER_TOO_SMALL
Definition: pkcs11.h:1180
hsm_session_t::session
unsigned long session
Definition: libhsm.h:98
hsm_close
void hsm_close()
Definition: libhsm.c:2259
ck_mechanism::mechanism
ck_mechanism_type_t mechanism
Definition: pkcs11.h:687
hsm_repository_free
void hsm_repository_free(hsm_repository_t *r)
Definition: libhsm.c:404
CKR_USER_PIN_NOT_INITIALIZED
#define CKR_USER_PIN_NOT_INITIALIZED
Definition: pkcs11.h:1168
CKA_UNWRAP
#define CKA_UNWRAP
Definition: pkcs11.h:400
hsm_destroy_context
void hsm_destroy_context(hsm_ctx_t *ctx)
Definition: libhsm.c:2334
hsm_get_error
char * hsm_get_error(hsm_ctx_t *gctx)
Definition: libhsm.c:3217
CKA_PRIME_BITS
#define CKA_PRIME_BITS
Definition: pkcs11.h:420
hsm_token_attached
int hsm_token_attached(hsm_ctx_t *ctx, const char *repository)
Definition: libhsm.c:3200
CKU_USER
#define CKU_USER
Definition: pkcs11.h:283
hsm_ctx_set_error
void hsm_ctx_set_error(hsm_ctx_t *ctx, int error, const char *action, const char *message,...)
Definition: libhsm.c:206
CKK_RSA
#define CKK_RSA
Definition: pkcs11.h:334
HSM_ERROR
#define HSM_ERROR
Definition: libhsm.h:66
CKR_TOKEN_NOT_PRESENT
#define CKR_TOKEN_NOT_PRESENT
Definition: pkcs11.h:1160
hsm_repository_struct::require_backup
uint8_t require_backup
Definition: libhsm.h:124
hsm_repository_struct
Definition: libhsm.h:118