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