OpenDNSSEC-libhsm  2.1.12
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  /* OPENDNSSEC-955: This procedure is mutexed to prevent a C_Login or
1643  * C_OpenSession happening at the same * time as looking up a key with
1644  * C_FindObject. Some HSMs like SoftHSM in database backend mode don't
1645  * like this.
1646  */
1647  pthread_mutex_lock(&_hsm_ctx_mutex);
1648  for (i = 0; i < ctx->session_count; i++) {
1649  key = hsm_find_key_by_id_session(ctx, ctx->session[i], id, len);
1650  if (key) {
1651  pthread_mutex_unlock(&_hsm_ctx_mutex);
1652  return key;
1653  }
1654  }
1655  pthread_mutex_unlock(&_hsm_ctx_mutex);
1656  return NULL;
1657 }
1658 
1659 
1665 static hsm_session_t *
1666 hsm_find_repository_session(hsm_ctx_t *ctx, const char *repository)
1667 {
1668  unsigned int i;
1669  if (!repository) {
1670  for (i = 0; i < ctx->session_count; i++) {
1671  if (ctx->session[i]) {
1672  return ctx->session[i];
1673  }
1674  }
1675  } else {
1676  for (i = 0; i < ctx->session_count; i++) {
1677  if (ctx->session[i] &&
1678  strcmp(repository, ctx->session[i]->module->name) == 0)
1679  {
1680  return ctx->session[i];
1681  }
1682  }
1683  }
1684 
1686  "hsm_find_repository_session()",
1687  "Can't find repository: %s", repository);
1688 
1689  return NULL;
1690 }
1691 
1692 static ldns_rdf *
1693 hsm_get_key_rdata_rsa(hsm_ctx_t *ctx, hsm_session_t *session,
1694  const libhsm_key_t *key)
1695 {
1696  CK_RV rv;
1697  CK_BYTE_PTR public_exponent = NULL;
1698  CK_ULONG public_exponent_len = 0;
1699  CK_BYTE_PTR modulus = NULL;
1700  CK_ULONG modulus_len = 0;
1701  unsigned long hKey = 0;
1702  unsigned char *data = NULL;
1703  size_t data_size = 0;
1704 
1705  CK_ATTRIBUTE template[] = {
1706  {CKA_PUBLIC_EXPONENT, NULL, 0},
1707  {CKA_MODULUS, NULL, 0},
1708  };
1709  ldns_rdf *rdf;
1710 
1711  if (!session || !session->module) {
1712  return NULL;
1713  }
1714 
1715  if (key->public_key) {
1716  hKey = key->public_key;
1717  } else {
1718  hKey = key->private_key;
1719  }
1720 
1721  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GetAttributeValue(
1722  session->session,
1723  hKey,
1724  template,
1725  2);
1726  if (hsm_pkcs11_check_error(ctx, rv, "C_GetAttributeValue")) {
1727  return NULL;
1728  }
1729  public_exponent_len = template[0].ulValueLen;
1730  modulus_len = template[1].ulValueLen;
1731 
1732  public_exponent = template[0].pValue = malloc(public_exponent_len);
1733  if (!public_exponent) {
1734  hsm_ctx_set_error(ctx, -1, "hsm_get_key_rdata_rsa()",
1735  "Error allocating memory for public exponent");
1736  return NULL;
1737  }
1738 
1739  modulus = template[1].pValue = malloc(modulus_len);
1740  if (!modulus) {
1741  hsm_ctx_set_error(ctx, -1, "hsm_get_key_rdata_rsa()",
1742  "Error allocating memory for modulus");
1743  free(public_exponent);
1744  return NULL;
1745  }
1746 
1747  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GetAttributeValue(
1748  session->session,
1749  hKey,
1750  template,
1751  2);
1752  if (hsm_pkcs11_check_error(ctx, rv, "get attribute value")) {
1753  free(template[0].pValue);
1754  free(template[1].pValue);
1755  return NULL;
1756  }
1757 
1758  // Remove leading zeroes
1759  hsm_remove_leading_zeroes(public_exponent, &public_exponent_len);
1760  hsm_remove_leading_zeroes(modulus, &modulus_len);
1761 
1762  data_size = public_exponent_len + modulus_len + 1;
1763  if (public_exponent_len <= 255) {
1764  data = malloc(data_size);
1765  if (!data) {
1766  hsm_ctx_set_error(ctx, -1, "hsm_get_key_rdata_rsa()",
1767  "Error allocating memory for pub key rr data");
1768  free(public_exponent);
1769  free(modulus);
1770  return NULL;
1771  }
1772  data[0] = public_exponent_len;
1773  memcpy(&data[1], public_exponent, public_exponent_len);
1774  memcpy(&data[1 + public_exponent_len], modulus, modulus_len);
1775  } else if (public_exponent_len <= 65535) {
1776  data_size += 2;
1777  data = malloc(data_size);
1778  if (!data) {
1779  hsm_ctx_set_error(ctx, -1, "hsm_get_key_rdata_rsa()",
1780  "Error allocating memory for pub key rr data");
1781  free(public_exponent);
1782  free(modulus);
1783  return NULL;
1784  }
1785  data[0] = 0;
1786  ldns_write_uint16(&data[1], (uint16_t) public_exponent_len);
1787  memcpy(&data[3], public_exponent, public_exponent_len);
1788  memcpy(&data[3 + public_exponent_len], modulus, modulus_len);
1789  } else {
1790  hsm_ctx_set_error(ctx, -1, "hsm_get_key_rdata_rsa()",
1791  "Public exponent too big");
1792  free(public_exponent);
1793  free(modulus);
1794  return NULL;
1795  }
1796  rdf = ldns_rdf_new(LDNS_RDF_TYPE_B64, data_size, data);
1797  free(public_exponent);
1798  free(modulus);
1799 
1800  return rdf;
1801 }
1802 
1803 static ldns_rdf *
1804 hsm_get_key_rdata_dsa(hsm_ctx_t *ctx, hsm_session_t *session,
1805  const libhsm_key_t *key)
1806 {
1807  CK_RV rv;
1808  CK_BYTE_PTR prime = NULL;
1809  CK_ULONG prime_len = 0;
1810  CK_BYTE_PTR subprime = NULL;
1811  CK_ULONG subprime_len = 0;
1812  CK_BYTE_PTR base = NULL;
1813  CK_ULONG base_len = 0;
1814  CK_BYTE_PTR value = NULL;
1815  CK_ULONG value_len = 0;
1816  unsigned char *data = NULL;
1817  size_t data_size = 0;
1818 
1819  CK_ATTRIBUTE template[] = {
1820  {CKA_PRIME, NULL, 0},
1821  {CKA_SUBPRIME, NULL, 0},
1822  {CKA_BASE, NULL, 0},
1823  {CKA_VALUE, NULL, 0},
1824  };
1825  ldns_rdf *rdf;
1826 
1827  if (!session || !session->module) {
1828  return NULL;
1829  }
1830 
1831  /* DSA needs the public key compared with RSA */
1832  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GetAttributeValue(
1833  session->session,
1834  key->public_key,
1835  template,
1836  4);
1837  if (hsm_pkcs11_check_error(ctx, rv, "C_GetAttributeValue")) {
1838  return NULL;
1839  }
1840  prime_len = template[0].ulValueLen;
1841  subprime_len = template[1].ulValueLen;
1842  base_len = template[2].ulValueLen;
1843  value_len = template[3].ulValueLen;
1844 
1845  prime = template[0].pValue = malloc(prime_len);
1846  if (!prime) {
1847  hsm_ctx_set_error(ctx, -1, "hsm_get_key_rdata_dsa()",
1848  "Error allocating memory for prime");
1849  return NULL;
1850  }
1851 
1852  subprime = template[1].pValue = malloc(subprime_len);
1853  if (!subprime) {
1854  hsm_ctx_set_error(ctx, -1, "hsm_get_key_rdata_dsa()",
1855  "Error allocating memory for subprime");
1856  free(prime);
1857  return NULL;
1858  }
1859 
1860  base = template[2].pValue = malloc(base_len);
1861  if (!base) {
1862  hsm_ctx_set_error(ctx, -1, "hsm_get_key_rdata_dsa()",
1863  "Error allocating memory for base");
1864  free(prime);
1865  free(subprime);
1866  return NULL;
1867  }
1868 
1869  value = template[3].pValue = malloc(value_len);
1870  if (!value) {
1871  hsm_ctx_set_error(ctx, -1, "hsm_get_key_rdata_dsa()",
1872  "Error allocating memory for value");
1873  free(prime);
1874  free(subprime);
1875  free(base);
1876  return NULL;
1877  }
1878 
1879  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GetAttributeValue(
1880  session->session,
1881  key->public_key,
1882  template,
1883  4);
1884  if (hsm_pkcs11_check_error(ctx, rv, "get attribute value")) {
1885  free(prime);
1886  free(subprime);
1887  free(base);
1888  free(value);
1889  return NULL;
1890  }
1891 
1892  data_size = prime_len + subprime_len + base_len + value_len + 1;
1893  data = malloc(data_size);
1894  if (!data) {
1895  hsm_ctx_set_error(ctx, -1, "hsm_get_key_rdata_dsa()",
1896  "Error allocating memory for pub key rr data");
1897  free(prime);
1898  free(subprime);
1899  free(base);
1900  free(value);
1901  return NULL;
1902  }
1903  data[0] = (prime_len - 64) / 8;
1904  memcpy(&data[1], subprime, subprime_len);
1905  memcpy(&data[1 + subprime_len], prime, prime_len);
1906  memcpy(&data[1 + subprime_len + prime_len], base, base_len);
1907  memcpy(&data[1 + subprime_len + prime_len + base_len], value, value_len);
1908 
1909  rdf = ldns_rdf_new(LDNS_RDF_TYPE_B64, data_size, data);
1910  free(prime);
1911  free(subprime);
1912  free(base);
1913  free(value);
1914 
1915  return rdf;
1916 }
1917 
1918 static ldns_rdf *
1919 hsm_get_key_rdata_gost(hsm_ctx_t *ctx, hsm_session_t *session,
1920  const libhsm_key_t *key)
1921 {
1922  CK_RV rv;
1923  CK_BYTE_PTR value = NULL;
1924  CK_ULONG value_len = 0;
1925 
1926  CK_ATTRIBUTE template[] = {
1927  {CKA_VALUE, NULL, 0},
1928  };
1929  ldns_rdf *rdf;
1930 
1931  if (!session || !session->module) {
1932  return NULL;
1933  }
1934 
1935  /* GOST needs the public key compared with RSA */
1936  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GetAttributeValue(
1937  session->session,
1938  key->public_key,
1939  template,
1940  1);
1941  if (hsm_pkcs11_check_error(ctx, rv, "C_GetAttributeValue")) {
1942  return NULL;
1943  }
1944  value_len = template[0].ulValueLen;
1945 
1946  value = template[0].pValue = malloc(value_len);
1947  if (!value) {
1948  hsm_ctx_set_error(ctx, -1, "hsm_get_key_rdata_gost()",
1949  "Error allocating memory for value");
1950  return NULL;
1951  }
1952 
1953  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GetAttributeValue(
1954  session->session,
1955  key->public_key,
1956  template,
1957  1);
1958  if (hsm_pkcs11_check_error(ctx, rv, "get attribute value")) {
1959  free(value);
1960  return NULL;
1961  }
1962 
1963  rdf = ldns_rdf_new(LDNS_RDF_TYPE_B64, value_len, value);
1964  return rdf;
1965 }
1966 
1967 static ldns_rdf *
1968 hsm_get_key_rdata_ecdsa(hsm_ctx_t *ctx, hsm_session_t *session,
1969  const libhsm_key_t *key)
1970 {
1972  unsigned char* value = hsm_get_key_ecdsa_value(ctx, session, key, &value_len);
1973 
1974  if (value == NULL) return NULL;
1975 
1976  ldns_rdf *rdf = ldns_rdf_new(LDNS_RDF_TYPE_B64, value_len, value);
1977 
1978  return rdf;
1979 }
1980 
1981 static ldns_rdf *
1982 hsm_get_key_rdata_eddsa(hsm_ctx_t *ctx, hsm_session_t *session,
1983  const libhsm_key_t *key)
1984 {
1986  unsigned char* value = hsm_get_key_eddsa_value(ctx, session, key, &value_len);
1987 
1988  if (value == NULL) return NULL;
1989 
1990  ldns_rdf *rdf = ldns_rdf_new(LDNS_RDF_TYPE_B64, value_len, value);
1991 
1992  return rdf;
1993 }
1994 
1995 static ldns_rdf *
1996 hsm_get_key_rdata(hsm_ctx_t *ctx, hsm_session_t *session,
1997  const libhsm_key_t *key)
1998 {
1999  switch (hsm_get_key_algorithm(ctx, session, key)) {
2000  case CKK_RSA:
2001  return hsm_get_key_rdata_rsa(ctx, session, key);
2002  break;
2003  case CKK_DSA:
2004  return hsm_get_key_rdata_dsa(ctx, session, key);
2005  break;
2006  case CKK_GOSTR3410:
2007  return hsm_get_key_rdata_gost(ctx, session, key);
2008  break;
2009  case CKK_EC:
2010  return hsm_get_key_rdata_ecdsa(ctx, session, key);
2011  case CKK_EC_EDWARDS:
2012  return hsm_get_key_rdata_eddsa(ctx, session, key);
2013  default:
2014  return 0;
2015  }
2016 }
2017 
2018 /* this function allocates memory for the mechanism ID and enough room
2019  * to leave the upcoming digest data. It fills in the mechanism id
2020  * use with care. The returned data must be free'd by the caller.
2021  * Only used by RSA PKCS. */
2022 static CK_BYTE *
2023 hsm_create_prefix(CK_ULONG digest_len,
2024  ldns_algorithm algorithm,
2025  CK_ULONG *data_size)
2026 {
2027  CK_BYTE *data;
2028  const CK_BYTE RSA_MD5_ID[] = { 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 };
2029  const CK_BYTE RSA_SHA1_ID[] = { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14 };
2030  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 };
2031  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 };
2032 
2033  switch((ldns_signing_algorithm)algorithm) {
2034  case LDNS_SIGN_RSAMD5:
2035  *data_size = sizeof(RSA_MD5_ID) + digest_len;
2036  data = malloc(*data_size);
2037  memcpy(data, RSA_MD5_ID, sizeof(RSA_MD5_ID));
2038  break;
2039  case LDNS_SIGN_RSASHA1:
2040  case LDNS_SIGN_RSASHA1_NSEC3:
2041  *data_size = sizeof(RSA_SHA1_ID) + digest_len;
2042  data = malloc(*data_size);
2043  memcpy(data, RSA_SHA1_ID, sizeof(RSA_SHA1_ID));
2044  break;
2045  case LDNS_SIGN_RSASHA256:
2046  *data_size = sizeof(RSA_SHA256_ID) + digest_len;
2047  data = malloc(*data_size);
2048  memcpy(data, RSA_SHA256_ID, sizeof(RSA_SHA256_ID));
2049  break;
2050  case LDNS_SIGN_RSASHA512:
2051  *data_size = sizeof(RSA_SHA512_ID) + digest_len;
2052  data = malloc(*data_size);
2053  memcpy(data, RSA_SHA512_ID, sizeof(RSA_SHA512_ID));
2054  break;
2055  case LDNS_SIGN_DSA:
2056  case LDNS_SIGN_DSA_NSEC3:
2057  case LDNS_SIGN_ECC_GOST:
2058  case LDNS_SIGN_ECDSAP256SHA256:
2059  case LDNS_SIGN_ECDSAP384SHA384:
2060  *data_size = digest_len;
2061  data = malloc(*data_size);
2062  break;
2063  default:
2064  return NULL;
2065  }
2066  return data;
2067 }
2068 
2069 static CK_BYTE *
2070 hsm_digest_through_hsm(hsm_ctx_t *ctx,
2071  hsm_session_t *session,
2072  CK_MECHANISM_TYPE mechanism_type,
2073  CK_ULONG digest_len,
2074  ldns_buffer *sign_buf)
2075 {
2076  CK_MECHANISM digest_mechanism;
2077  CK_BYTE *digest;
2078  CK_RV rv;
2079 
2080  digest_mechanism.pParameter = NULL;
2081  digest_mechanism.ulParameterLen = 0;
2082  digest_mechanism.mechanism = mechanism_type;
2083  digest = malloc(digest_len);
2084  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_DigestInit(session->session,
2085  &digest_mechanism);
2086  if (hsm_pkcs11_check_error(ctx, rv, "HSM digest init")) {
2087  free(digest);
2088  return NULL;
2089  }
2090 
2091  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_Digest(session->session,
2092  ldns_buffer_begin(sign_buf),
2093  ldns_buffer_position(sign_buf),
2094  digest,
2095  &digest_len);
2096  if (hsm_pkcs11_check_error(ctx, rv, "HSM digest")) {
2097  free(digest);
2098  return NULL;
2099  }
2100  return digest;
2101 }
2102 
2103 static ldns_rdf *
2104 hsm_sign_buffer(hsm_ctx_t *ctx,
2105  ldns_buffer *sign_buf,
2106  const libhsm_key_t *key,
2107  ldns_algorithm algorithm)
2108 {
2109  CK_RV rv;
2110  CK_ULONG signatureLen = HSM_MAX_SIGNATURE_LENGTH;
2111  CK_BYTE signature[HSM_MAX_SIGNATURE_LENGTH];
2112  CK_MECHANISM sign_mechanism;
2113 
2114  int data_direct = 0; // don't pre-create digest, use data directly
2115 
2116  ldns_rdf *sig_rdf;
2117  CK_BYTE *digest = NULL;
2118  CK_ULONG digest_len = 0;
2119 
2120  CK_BYTE *data = NULL;
2121  CK_ULONG data_len = 0;
2122 
2123  hsm_session_t *session;
2124 
2125  session = hsm_find_key_session(ctx, key);
2126  if (!session) return NULL;
2127 
2128  /* some HSMs don't really handle CKM_SHA1_RSA_PKCS well, so
2129  * we'll do the hashing manually */
2130  /* When adding algorithms, remember there is another switch below */
2131  switch ((ldns_signing_algorithm)algorithm) {
2132  case LDNS_SIGN_RSAMD5:
2133  digest_len = 16;
2134  digest = hsm_digest_through_hsm(ctx, session,
2135  CKM_MD5, digest_len,
2136  sign_buf);
2137  break;
2138  case LDNS_SIGN_RSASHA1:
2139  case LDNS_SIGN_RSASHA1_NSEC3:
2140  case LDNS_SIGN_DSA:
2141  case LDNS_SIGN_DSA_NSEC3:
2142  digest_len = LDNS_SHA1_DIGEST_LENGTH;
2143  digest = malloc(digest_len);
2144  digest = ldns_sha1(ldns_buffer_begin(sign_buf),
2145  ldns_buffer_position(sign_buf),
2146  digest);
2147  break;
2148 
2149  case LDNS_SIGN_RSASHA256:
2150  case LDNS_SIGN_ECDSAP256SHA256:
2151  digest_len = LDNS_SHA256_DIGEST_LENGTH;
2152  digest = malloc(digest_len);
2153  digest = ldns_sha256(ldns_buffer_begin(sign_buf),
2154  ldns_buffer_position(sign_buf),
2155  digest);
2156  break;
2157  case LDNS_SIGN_ECDSAP384SHA384:
2158  digest_len = LDNS_SHA384_DIGEST_LENGTH;
2159  digest = malloc(digest_len);
2160  digest = ldns_sha384(ldns_buffer_begin(sign_buf),
2161  ldns_buffer_position(sign_buf),
2162  digest);
2163  break;
2164  case LDNS_SIGN_RSASHA512:
2165  digest_len = LDNS_SHA512_DIGEST_LENGTH;
2166  digest = malloc(digest_len);
2167  digest = ldns_sha512(ldns_buffer_begin(sign_buf),
2168  ldns_buffer_position(sign_buf),
2169  digest);
2170  break;
2171  case LDNS_SIGN_ECC_GOST:
2172  digest_len = 32;
2173  digest = hsm_digest_through_hsm(ctx, session,
2174  CKM_GOSTR3411, digest_len,
2175  sign_buf);
2176  break;
2177 #if (LDNS_REVISION >= ((1<<16)|(7<<8)|(0)))
2178  case LDNS_SIGN_ED25519:
2179  data_direct = 1;
2180  break;
2181  case LDNS_SIGN_ED448:
2182  data_direct = 1;
2183  break;
2184 #endif
2185  default:
2186  /* log error? or should we not even get here for
2187  * unsupported algorithms? */
2188  return NULL;
2189  }
2190 
2191  if (!data_direct && !digest) {
2192  return NULL;
2193  }
2194 
2195  if (data_direct) {
2196  data = ldns_buffer_begin(sign_buf);
2197  data_len = ldns_buffer_position(sign_buf);
2198  } else {
2199  /* CKM_RSA_PKCS does the padding, but cannot know the identifier
2200  * prefix, so we need to add that ourselves.
2201  * The other algorithms will just get the digest buffer returned. */
2202  data = hsm_create_prefix(digest_len, algorithm, &data_len);
2203  memcpy(data + data_len - digest_len, digest, digest_len);
2204  }
2205 
2206  sign_mechanism.pParameter = NULL;
2207  sign_mechanism.ulParameterLen = 0;
2208  switch((ldns_signing_algorithm)algorithm) {
2209  case LDNS_SIGN_RSAMD5:
2210  case LDNS_SIGN_RSASHA1:
2211  case LDNS_SIGN_RSASHA1_NSEC3:
2212  case LDNS_SIGN_RSASHA256:
2213  case LDNS_SIGN_RSASHA512:
2214  sign_mechanism.mechanism = CKM_RSA_PKCS;
2215  break;
2216  case LDNS_SIGN_DSA:
2217  case LDNS_SIGN_DSA_NSEC3:
2218  sign_mechanism.mechanism = CKM_DSA;
2219  break;
2220  case LDNS_SIGN_ECC_GOST:
2221  sign_mechanism.mechanism = CKM_GOSTR3410;
2222  break;
2223  case LDNS_SIGN_ECDSAP256SHA256:
2224  case LDNS_SIGN_ECDSAP384SHA384:
2225  sign_mechanism.mechanism = CKM_ECDSA;
2226  break;
2227 #if (LDNS_REVISION >= ((1<<16)|(7<<8)|(0)))
2228  case LDNS_SIGN_ED25519:
2229  sign_mechanism.mechanism = CKM_EDDSA;
2230  break;
2231  case LDNS_SIGN_ED448:
2232  sign_mechanism.mechanism = CKM_EDDSA;
2233  break;
2234 #endif
2235  default:
2236  /* log error? or should we not even get here for
2237  * unsupported algorithms? */
2238  free(data);
2239  free(digest);
2240  return NULL;
2241  }
2242 
2243  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_SignInit(
2244  session->session,
2245  &sign_mechanism,
2246  key->private_key);
2247  if (hsm_pkcs11_check_error(ctx, rv, "sign init")) {
2248  if (!data_direct) {
2249  free(data);
2250  free(digest);
2251  }
2252  return NULL;
2253  }
2254 
2255  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_Sign(session->session, data, data_len,
2256  signature,
2257  &signatureLen);
2258  if (hsm_pkcs11_check_error(ctx, rv, "sign final")) {
2259  if (!data_direct) {
2260  free(data);
2261  free(digest);
2262  }
2263  return NULL;
2264  }
2265 
2266  sig_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64,
2267  signatureLen,
2268  signature);
2269 
2270  if (!data_direct) {
2271  free(data);
2272  free(digest);
2273  }
2274 
2275  return sig_rdf;
2276 
2277 }
2278 
2279 static int
2280 hsm_dname_is_wildcard(const ldns_rdf* dname)
2281 {
2282  return ( ldns_dname_label_count(dname) > 0 &&
2283  ldns_rdf_data(dname)[0] == 1 &&
2284  ldns_rdf_data(dname)[1] == '*');
2285 }
2286 
2287 static ldns_rr *
2288 hsm_create_empty_rrsig(const ldns_rr_list *rrset,
2289  const hsm_sign_params_t *sign_params)
2290 {
2291  ldns_rr *rrsig;
2292  uint32_t orig_ttl;
2293  uint32_t orig_class;
2294  time_t now;
2295  uint8_t label_count;
2296 
2297  label_count = ldns_dname_label_count(
2298  ldns_rr_owner(ldns_rr_list_rr(rrset, 0)));
2299  /* RFC 4035 section 2.2: dnssec label length and wildcards */
2300  if (hsm_dname_is_wildcard(ldns_rr_owner(ldns_rr_list_rr(rrset, 0)))) {
2301  label_count--;
2302  }
2303 
2304  rrsig = ldns_rr_new_frm_type(LDNS_RR_TYPE_RRSIG);
2305 
2306  /* set the type on the new signature */
2307  orig_ttl = ldns_rr_ttl(ldns_rr_list_rr(rrset, 0));
2308  orig_class = ldns_rr_get_class(ldns_rr_list_rr(rrset, 0));
2309 
2310  ldns_rr_set_class(rrsig, orig_class);
2311  ldns_rr_set_ttl(rrsig, orig_ttl);
2312  ldns_rr_set_owner(rrsig,
2313  ldns_rdf_clone(
2314  ldns_rr_owner(
2315  ldns_rr_list_rr(rrset,
2316  0))));
2317 
2318  /* fill in what we know of the signature */
2319 
2320  /* set the orig_ttl */
2321  (void)ldns_rr_rrsig_set_origttl(
2322  rrsig,
2323  ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32,
2324  orig_ttl));
2325  /* the signers name */
2326  (void)ldns_rr_rrsig_set_signame(
2327  rrsig,
2328  ldns_rdf_clone(sign_params->owner));
2329  /* label count - get it from the first rr in the rr_list */
2330  (void)ldns_rr_rrsig_set_labels(
2331  rrsig,
2332  ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8,
2333  label_count));
2334  /* inception, expiration */
2335  now = time_now();
2336  if (sign_params->inception != 0) {
2337  (void)ldns_rr_rrsig_set_inception(
2338  rrsig,
2339  ldns_native2rdf_int32(
2340  LDNS_RDF_TYPE_TIME,
2341  sign_params->inception));
2342  } else {
2343  (void)ldns_rr_rrsig_set_inception(
2344  rrsig,
2345  ldns_native2rdf_int32(LDNS_RDF_TYPE_TIME, now));
2346  }
2347  if (sign_params->expiration != 0) {
2348  (void)ldns_rr_rrsig_set_expiration(
2349  rrsig,
2350  ldns_native2rdf_int32(
2351  LDNS_RDF_TYPE_TIME,
2352  sign_params->expiration));
2353  } else {
2354  (void)ldns_rr_rrsig_set_expiration(
2355  rrsig,
2356  ldns_native2rdf_int32(
2357  LDNS_RDF_TYPE_TIME,
2358  now + LDNS_DEFAULT_EXP_TIME));
2359  }
2360 
2361  (void)ldns_rr_rrsig_set_keytag(
2362  rrsig,
2363  ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16,
2364  sign_params->keytag));
2365 
2366  (void)ldns_rr_rrsig_set_algorithm(
2367  rrsig,
2368  ldns_native2rdf_int8(
2369  LDNS_RDF_TYPE_ALG,
2370  sign_params->algorithm));
2371 
2372  (void)ldns_rr_rrsig_set_typecovered(
2373  rrsig,
2374  ldns_native2rdf_int16(
2375  LDNS_RDF_TYPE_TYPE,
2376  ldns_rr_get_type(ldns_rr_list_rr(rrset,
2377  0))));
2378 
2379  return rrsig;
2380 }
2381 
2382 
2383 /*
2384  * API functions
2385  */
2386 
2387 int
2389  char *(pin_callback)(unsigned int, const char *, unsigned int))
2390 {
2391  hsm_config_t module_config;
2392  hsm_repository_t* repo = NULL;
2393  char* module_pin = NULL;
2394  int result = HSM_OK;
2395  int tries;
2396  int repositories = 0;
2397 
2398  pthread_mutex_lock(&_hsm_ctx_mutex);
2399  /* create an internal context with an attached session for each
2400  * configured HSM. */
2401  if ((_hsm_ctx = hsm_ctx_new())) {
2403  }
2404 
2405  repo = rlist;
2406  while (repo) {
2407  hsm_config_default(&module_config);
2408  module_config.use_pubkey = repo->use_pubkey;
2409  module_config.allow_extract = repo->allow_extract;
2410  if (repo->name && repo->module && repo->tokenlabel) {
2411  if (repo->pin) {
2412  result = hsm_attach(repo->name, repo->tokenlabel,
2413  repo->module, repo->pin, &module_config);
2414  } else {
2415  if (pin_callback) {
2416  result = HSM_PIN_INCORRECT;
2417  tries = 0;
2418  while (result == HSM_PIN_INCORRECT && tries < 3) {
2419  module_pin = pin_callback(_hsm_ctx->session_count,
2420  repo->name, tries?HSM_PIN_RETRY:HSM_PIN_FIRST);
2421  if (module_pin == NULL) break;
2422  result = hsm_attach(repo->name, repo->tokenlabel,
2423  repo->module, module_pin, &module_config);
2424  if (result == HSM_OK) {
2425  pin_callback(_hsm_ctx->session_count - 1,
2426  repo->name, HSM_PIN_SAVE);
2427  }
2428  memset(module_pin, 0, strlen(module_pin));
2429  tries++;
2430  }
2431  } else {
2432  /* no pin, no callback */
2433  hsm_ctx_set_error(_hsm_ctx, HSM_ERROR, "hsm_open2()",
2434  "No pin or callback function");
2435  result = HSM_ERROR;
2436  }
2437  }
2438  if (result != HSM_OK) {
2439  break;
2440  }
2441  repositories++;
2442  }
2443  repo = repo->next;
2444  }
2445  if (result == HSM_OK && repositories == 0) {
2447  "No repositories found");
2448  result = HSM_NO_REPOSITORIES;
2449  }
2450  pthread_mutex_unlock(&_hsm_ctx_mutex);
2451  return result;
2452 }
2453 
2454 void
2456 {
2457  pthread_mutex_lock(&_hsm_ctx_mutex);
2459  hsm_ctx_close(_hsm_ctx, 1);
2460  _hsm_ctx = NULL;
2461  pthread_mutex_unlock(&_hsm_ctx_mutex);
2462 }
2463 
2464 hsm_ctx_t *
2466 {
2467  hsm_ctx_t* newctx;
2468  pthread_mutex_lock(&_hsm_ctx_mutex);
2469  newctx = hsm_ctx_clone(_hsm_ctx);
2470  pthread_mutex_unlock(&_hsm_ctx_mutex);
2471  return newctx;
2472 }
2473 
2474 int
2476 {
2477  unsigned int i;
2478  hsm_session_t *session;
2479  CK_SESSION_INFO info;
2480  CK_RV rv;
2481  CK_SESSION_HANDLE session_handle;
2482  hsm_ctx_t *ctx;
2483 
2484  pthread_mutex_lock(&_hsm_ctx_mutex);
2485  ctx = _hsm_ctx;
2486 
2487  for (i = 0; i < ctx->session_count; i++) {
2488  session = ctx->session[i];
2489  if (session == NULL) continue;
2490 
2491  /* Get session info */
2492  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GetSessionInfo(
2493  session->session,
2494  &info);
2495  if (hsm_pkcs11_check_error(ctx, rv, "get session info")) {
2496  pthread_mutex_unlock(&_hsm_ctx_mutex);
2497  return HSM_ERROR;
2498  }
2499 
2500  /* Check session info */
2501  if (info.state != CKS_RW_USER_FUNCTIONS) {
2502  hsm_ctx_set_error(ctx, HSM_ERROR, "hsm_check_context()",
2503  "Session not logged in");
2504  pthread_mutex_unlock(&_hsm_ctx_mutex);
2505  return HSM_ERROR;
2506  }
2507 
2508  /* Try open and close a session with the token */
2509  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_OpenSession(info.slotID,
2511  NULL,
2512  NULL,
2513  &session_handle);
2514  if (hsm_pkcs11_check_error(ctx, rv, "test open session")) {
2515  pthread_mutex_unlock(&_hsm_ctx_mutex);
2516  return HSM_ERROR;
2517  }
2518  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_CloseSession(session_handle);
2519  if (hsm_pkcs11_check_error(ctx, rv, "test close session")) {
2520  pthread_mutex_unlock(&_hsm_ctx_mutex);
2521  return HSM_ERROR;
2522  }
2523  }
2524 
2525  pthread_mutex_unlock(&_hsm_ctx_mutex);
2526  return HSM_OK;
2527 }
2528 
2529 void
2531 {
2532  hsm_ctx_close(ctx, 0);
2533 }
2534 
2540 {
2541  hsm_sign_params_t *params;
2542  params = malloc(sizeof(hsm_sign_params_t));
2543  if (!params) {
2544  return NULL;
2545  }
2546  params->algorithm = LDNS_RSASHA256;
2547  params->flags = LDNS_KEY_ZONE_KEY;
2548  params->inception = 0;
2549  params->expiration = 0;
2550  params->keytag = 0;
2551  params->owner = NULL;
2552  return params;
2553 }
2554 
2555 void
2557 {
2558  if (params) {
2559  if (params->owner) ldns_rdf_deep_free(params->owner);
2560  free(params);
2561  }
2562 }
2563 
2564 void
2566 {
2567  free(key->modulename);
2568  free(key);
2569 }
2570 
2571 libhsm_key_t **
2572 hsm_list_keys(hsm_ctx_t *ctx, size_t *count)
2573 {
2574  libhsm_key_t **keys = NULL;
2575  size_t key_count = 0;
2576  size_t cur_key_count;
2577  libhsm_key_t **session_keys;
2578  unsigned int i, j;
2579 
2580  for (i = 0; i < ctx->session_count; i++) {
2581  session_keys = hsm_list_keys_session(ctx, ctx->session[i],
2582  &cur_key_count);
2583  keys = realloc(keys,
2584  (key_count + cur_key_count) * sizeof(libhsm_key_t *));
2585  for (j = 0; j < cur_key_count; j++) {
2586  keys[key_count + j] = session_keys[j];
2587  }
2588  key_count += cur_key_count;
2589  free(session_keys);
2590  }
2591  if (count) {
2592  *count = key_count;
2593  }
2594  return keys;
2595 }
2596 
2597 libhsm_key_t **
2599  size_t *count,
2600  const char *repository)
2601 {
2602  hsm_session_t *session;
2603 
2604  if (!repository) return NULL;
2605 
2606  session = hsm_find_repository_session(ctx, repository);
2607  if (!session) {
2608  *count = 0;
2609  return NULL;
2610  }
2611  return hsm_list_keys_session(ctx, session, count);
2612 }
2613 
2614 libhsm_key_t *
2616 {
2617  unsigned char *id_bytes;
2618  size_t len;
2619  libhsm_key_t *key;
2620 
2621  id_bytes = hsm_hex_parse(id, &len);
2622 
2623  if (!id_bytes) return NULL;
2624 
2625  key = hsm_find_key_by_id_bin(ctx, id_bytes, len);
2626  free(id_bytes);
2627  return key;
2628 }
2629 
2630 static void
2631 generate_unique_id(hsm_ctx_t *ctx, unsigned char *buf, size_t bufsize)
2632 {
2633  libhsm_key_t *key;
2634  /* check whether this key doesn't happen to exist already */
2635  hsm_random_buffer(ctx, buf, bufsize);
2636  while ((key = hsm_find_key_by_id_bin(ctx, buf, bufsize))) {
2637  libhsm_key_free(key);
2638  hsm_random_buffer(ctx, buf, bufsize);
2639  }
2640 
2641 }
2642 
2643 libhsm_key_t *
2645  const char *repository,
2646  unsigned long keysize)
2647 {
2648  libhsm_key_t *new_key;
2649  hsm_session_t *session;
2650  /* ids we create are 16 bytes of data */
2651  unsigned char id[16];
2652  /* that's 33 bytes in string (16*2 + 1 for \0) */
2653  char id_str[33];
2654  CK_RV rv;
2655  CK_OBJECT_HANDLE publicKey, privateKey;
2656  CK_KEY_TYPE keyType = CKK_RSA;
2657  CK_MECHANISM mechanism = {
2659  };
2660  CK_BYTE publicExponent[] = { 1, 0, 1 };
2661  CK_BBOOL ctrue = CK_TRUE;
2662  CK_BBOOL cfalse = CK_FALSE;
2663  CK_BBOOL ctoken = CK_TRUE;
2664  CK_BBOOL cextractable = CK_FALSE;
2665 
2666  session = hsm_find_repository_session(ctx, repository);
2667  if (!session) return NULL;
2668  cextractable = session->module->config->allow_extract ? CK_TRUE : CK_FALSE;
2669 
2670  generate_unique_id(ctx, id, 16);
2671 
2672  /* the CKA_LABEL will contain a hexadecimal string representation
2673  * of the id */
2674  hsm_hex_unparse(id_str, id, 16);
2675 
2676  if (! session->module->config->use_pubkey) {
2677  ctoken = CK_FALSE;
2678  }
2679 
2680  CK_ATTRIBUTE publicKeyTemplate[] = {
2681  { CKA_LABEL,(CK_UTF8CHAR*) id_str, strlen(id_str) },
2682  { CKA_ID, id, 16 },
2683  { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
2684  { CKA_VERIFY, &ctrue, sizeof(ctrue) },
2685  { CKA_ENCRYPT, &cfalse, sizeof(cfalse) },
2686  { CKA_WRAP, &cfalse, sizeof(cfalse) },
2687  { CKA_TOKEN, &ctoken, sizeof(ctoken) },
2688  { CKA_MODULUS_BITS, &keysize, sizeof(keysize) },
2689  { CKA_PUBLIC_EXPONENT, &publicExponent, sizeof(publicExponent)}
2690  };
2691 
2692  CK_ATTRIBUTE privateKeyTemplate[] = {
2693  { CKA_LABEL,(CK_UTF8CHAR *) id_str, strlen (id_str) },
2694  { CKA_ID, id, 16 },
2695  { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
2696  { CKA_SIGN, &ctrue, sizeof (ctrue) },
2697  { CKA_DECRYPT, &cfalse, sizeof (cfalse) },
2698  { CKA_UNWRAP, &cfalse, sizeof (cfalse) },
2699  { CKA_SENSITIVE, &ctrue, sizeof (ctrue) },
2700  { CKA_TOKEN, &ctrue, sizeof (ctrue) },
2701  { CKA_PRIVATE, &ctrue, sizeof (ctrue) },
2702  { CKA_EXTRACTABLE, &cextractable, sizeof (cextractable) }
2703  };
2704 
2705  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GenerateKeyPair(session->session,
2706  &mechanism,
2707  publicKeyTemplate, 9,
2708  privateKeyTemplate, 10,
2709  &publicKey,
2710  &privateKey);
2711  if (hsm_pkcs11_check_error(ctx, rv, "generate key pair")) {
2712  return NULL;
2713  }
2714 
2715  new_key = libhsm_key_new();
2716  new_key->modulename = strdup(session->module->name);
2717 
2718  if (session->module->config->use_pubkey) {
2719  new_key->public_key = publicKey;
2720  } else {
2721  /* Destroy the object directly in order to optimize storage in HSM */
2722  /* Ignore return value, it is just a session object and will be destroyed later */
2723  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_DestroyObject(session->session, publicKey);
2724  new_key->public_key = 0;
2725  }
2726 
2727  new_key->private_key = privateKey;
2728  return new_key;
2729 }
2730 
2731 libhsm_key_t *
2733  const char *repository,
2734  unsigned long keysize)
2735 {
2736  CK_RV rv;
2737  libhsm_key_t *new_key;
2738  hsm_session_t *session;
2739  CK_OBJECT_HANDLE domainPar, publicKey, privateKey;
2740  CK_BBOOL ctrue = CK_TRUE;
2741  CK_BBOOL cfalse = CK_FALSE;
2742  CK_BBOOL cextractable = CK_FALSE;
2743 
2744  /* ids we create are 16 bytes of data */
2745  unsigned char id[16];
2746  /* that's 33 bytes in string (16*2 + 1 for \0) */
2747  char id_str[33];
2748 
2749  session = hsm_find_repository_session(ctx, repository);
2750  if (!session) return NULL;
2751  cextractable = session->module->config->allow_extract ? CK_TRUE : CK_FALSE;
2752 
2753  generate_unique_id(ctx, id, 16);
2754 
2755  /* the CKA_LABEL will contain a hexadecimal string representation
2756  * of the id */
2757  hsm_hex_unparse(id_str, id, 16);
2758 
2759  CK_KEY_TYPE keyType = CKK_DSA;
2760  CK_MECHANISM mechanism1 = {
2762  };
2763  CK_MECHANISM mechanism2 = {
2765  };
2766 
2767  /* The maximum size for DSA in DNSSEC */
2768  CK_BYTE dsa_p[128];
2769  CK_BYTE dsa_q[20];
2770  CK_BYTE dsa_g[128];
2771 
2772  CK_ATTRIBUTE domainTemplate[] = {
2773  { CKA_PRIME_BITS, &keysize, sizeof(keysize) }
2774  };
2775 
2776  CK_ATTRIBUTE publicKeyTemplate[] = {
2777  { CKA_PRIME, dsa_p, sizeof(dsa_p) },
2778  { CKA_SUBPRIME, dsa_q, sizeof(dsa_q) },
2779  { CKA_BASE, dsa_g, sizeof(dsa_g) },
2780  { CKA_LABEL,(CK_UTF8CHAR*) id_str, strlen(id_str) },
2781  { CKA_ID, id, 16 },
2782  { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
2783  { CKA_VERIFY, &ctrue, sizeof(ctrue) },
2784  { CKA_ENCRYPT, &cfalse, sizeof(cfalse) },
2785  { CKA_WRAP, &cfalse, sizeof(cfalse) },
2786  { CKA_TOKEN, &ctrue, sizeof(ctrue) }
2787  };
2788 
2789  CK_ATTRIBUTE privateKeyTemplate[] = {
2790  { CKA_LABEL,(CK_UTF8CHAR*) id_str, strlen (id_str) },
2791  { CKA_ID, id, 16 },
2792  { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
2793  { CKA_SIGN, &ctrue, sizeof(ctrue) },
2794  { CKA_DECRYPT, &cfalse, sizeof(cfalse) },
2795  { CKA_UNWRAP, &cfalse, sizeof(cfalse) },
2796  { CKA_SENSITIVE, &ctrue, sizeof(ctrue) },
2797  { CKA_TOKEN, &ctrue, sizeof(ctrue) },
2798  { CKA_PRIVATE, &ctrue, sizeof(ctrue) },
2799  { CKA_EXTRACTABLE, &cextractable, sizeof (cextractable) }
2800  };
2801 
2802  cextractable = session->module->config->allow_extract ? CK_TRUE : CK_FALSE;
2803 
2804  /* Generate the domain parameters */
2805 
2806  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GenerateKey(session->session,
2807  &mechanism1,
2808  domainTemplate, 1,
2809  &domainPar);
2810  if (hsm_pkcs11_check_error(ctx, rv, "generate domain parameters")) {
2811  return NULL;
2812  }
2813 
2814  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GetAttributeValue(session->session,
2815  domainPar, publicKeyTemplate, 3);
2816  if (hsm_pkcs11_check_error(ctx, rv, "get domain parameters")) {
2817  return NULL;
2818  }
2819 
2820  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_DestroyObject(session->session, domainPar);
2821  if (hsm_pkcs11_check_error(ctx, rv, "destroy domain parameters")) {
2822  return NULL;
2823  }
2824 
2825  /* Generate key pair */
2826 
2827  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GenerateKeyPair(session->session,
2828  &mechanism2,
2829  publicKeyTemplate, 10,
2830  privateKeyTemplate, 10,
2831  &publicKey,
2832  &privateKey);
2833  if (hsm_pkcs11_check_error(ctx, rv, "generate key pair")) {
2834  return NULL;
2835  }
2836 
2837  new_key = libhsm_key_new();
2838  new_key->modulename = strdup(session->module->name);
2839  new_key->public_key = publicKey;
2840  new_key->private_key = privateKey;
2841 
2842  return new_key;
2843 }
2844 
2845 libhsm_key_t *
2847  const char *repository)
2848 {
2849  CK_RV rv;
2850  libhsm_key_t *new_key;
2851  hsm_session_t *session;
2852  CK_OBJECT_HANDLE publicKey, privateKey;
2853  CK_BBOOL ctrue = CK_TRUE;
2854  CK_BBOOL cfalse = CK_FALSE;
2855  CK_BBOOL cextractable = CK_FALSE;
2856 
2857  /* ids we create are 16 bytes of data */
2858  unsigned char id[16];
2859  /* that's 33 bytes in string (16*2 + 1 for \0) */
2860  char id_str[33];
2861 
2862  session = hsm_find_repository_session(ctx, repository);
2863  if (!session) return NULL;
2864  cextractable = session->module->config->allow_extract ? CK_TRUE : CK_FALSE;
2865 
2866  generate_unique_id(ctx, id, 16);
2867 
2868  /* the CKA_LABEL will contain a hexadecimal string representation
2869  * of the id */
2870  hsm_hex_unparse(id_str, id, 16);
2871 
2872  CK_KEY_TYPE keyType = CKK_GOSTR3410;
2873  CK_MECHANISM mechanism = {
2875  };
2876 
2877  CK_BYTE oid1[] = { 0x06, 0x07, 0x2A, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01 };
2878  CK_BYTE oid2[] = { 0x06, 0x07, 0x2A, 0x85, 0x03, 0x02, 0x02, 0x1E, 0x01 };
2879 
2880  CK_ATTRIBUTE publicKeyTemplate[] = {
2881  { CKA_GOSTR3410PARAMS, oid1, sizeof(oid1) },
2882  { CKA_GOSTR3411PARAMS, oid2, sizeof(oid2) },
2883  { CKA_LABEL,(CK_UTF8CHAR*) id_str, strlen(id_str) },
2884  { CKA_ID, id, 16 },
2885  { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
2886  { CKA_VERIFY, &ctrue, sizeof(ctrue) },
2887  { CKA_ENCRYPT, &cfalse, sizeof(cfalse) },
2888  { CKA_WRAP, &cfalse, sizeof(cfalse) },
2889  { CKA_TOKEN, &ctrue, sizeof(ctrue) }
2890  };
2891 
2892  CK_ATTRIBUTE privateKeyTemplate[] = {
2893  { CKA_LABEL,(CK_UTF8CHAR*) id_str, strlen (id_str) },
2894  { CKA_ID, id, 16 },
2895  { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
2896  { CKA_SIGN, &ctrue, sizeof(ctrue) },
2897  { CKA_DECRYPT, &cfalse, sizeof(cfalse) },
2898  { CKA_UNWRAP, &cfalse, sizeof(cfalse) },
2899  { CKA_SENSITIVE, &ctrue, sizeof(ctrue) },
2900  { CKA_TOKEN, &ctrue, sizeof(ctrue) },
2901  { CKA_PRIVATE, &ctrue, sizeof(ctrue) },
2902  { CKA_EXTRACTABLE, &cextractable, sizeof (cextractable) }
2903  };
2904 
2905  /* Generate key pair */
2906 
2907  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GenerateKeyPair(session->session,
2908  &mechanism,
2909  publicKeyTemplate, 9,
2910  privateKeyTemplate, 10,
2911  &publicKey,
2912  &privateKey);
2913  if (hsm_pkcs11_check_error(ctx, rv, "generate key pair")) {
2914  return NULL;
2915  }
2916 
2917  new_key = libhsm_key_new();
2918  new_key->modulename = strdup(session->module->name);
2919  new_key->public_key = publicKey;
2920  new_key->private_key = privateKey;
2921 
2922  return new_key;
2923 }
2924 
2925 libhsm_key_t *
2927  const char *repository,
2928  const char *curve)
2929 {
2930  CK_RV rv;
2931  libhsm_key_t *new_key;
2932  hsm_session_t *session;
2933  CK_OBJECT_HANDLE publicKey, privateKey;
2934  CK_BBOOL ctrue = CK_TRUE;
2935  CK_BBOOL cfalse = CK_FALSE;
2936  CK_BBOOL cextractable = CK_FALSE;
2937 
2938  /* ids we create are 16 bytes of data */
2939  unsigned char id[16];
2940  /* that's 33 bytes in string (16*2 + 1 for \0) */
2941  char id_str[33];
2942 
2943  session = hsm_find_repository_session(ctx, repository);
2944  if (!session) return NULL;
2945  cextractable = session->module->config->allow_extract ? CK_TRUE : CK_FALSE;
2946 
2947  generate_unique_id(ctx, id, 16);
2948 
2949  /* the CKA_LABEL will contain a hexadecimal string representation
2950  * of the id */
2951  hsm_hex_unparse(id_str, id, 16);
2952 
2953  CK_KEY_TYPE keyType = CKK_EC;
2954  CK_MECHANISM mechanism = {
2956  };
2957 
2958  CK_BYTE oidP256[] = { 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07 };
2959  CK_BYTE oidP384[] = { 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22 };
2960 
2961  CK_ATTRIBUTE publicKeyTemplate[] = {
2962  { CKA_EC_PARAMS, NULL, 0 },
2963  { CKA_LABEL,(CK_UTF8CHAR*) id_str, strlen(id_str) },
2964  { CKA_ID, id, 16 },
2965  { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
2966  { CKA_VERIFY, &ctrue, sizeof(ctrue) },
2967  { CKA_ENCRYPT, &cfalse, sizeof(cfalse) },
2968  { CKA_WRAP, &cfalse, sizeof(cfalse) },
2969  { CKA_TOKEN, &ctrue, sizeof(ctrue) }
2970  };
2971 
2972  CK_ATTRIBUTE privateKeyTemplate[] = {
2973  { CKA_LABEL,(CK_UTF8CHAR*) id_str, strlen (id_str) },
2974  { CKA_ID, id, 16 },
2975  { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
2976  { CKA_SIGN, &ctrue, sizeof(ctrue) },
2977  { CKA_DECRYPT, &cfalse, sizeof(cfalse) },
2978  { CKA_UNWRAP, &cfalse, sizeof(cfalse) },
2979  { CKA_SENSITIVE, &ctrue, sizeof(ctrue) },
2980  { CKA_TOKEN, &ctrue, sizeof(ctrue) },
2981  { CKA_PRIVATE, &ctrue, sizeof(ctrue) },
2982  { CKA_EXTRACTABLE, &cextractable, sizeof (cextractable) }
2983  };
2984 
2985  /* Select the curve */
2986  if (strcmp(curve, "P-256") == 0)
2987  {
2988  publicKeyTemplate[0].pValue = oidP256;
2989  publicKeyTemplate[0].ulValueLen = sizeof(oidP256);
2990  }
2991  else if (strcmp(curve, "P-384") == 0)
2992  {
2993  publicKeyTemplate[0].pValue = oidP384;
2994  publicKeyTemplate[0].ulValueLen = sizeof(oidP384);
2995  }
2996  else
2997  {
2998  return NULL;
2999  }
3000 
3001  /* Generate key pair */
3002 
3003  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GenerateKeyPair(session->session,
3004  &mechanism,
3005  publicKeyTemplate, 8,
3006  privateKeyTemplate, 10,
3007  &publicKey,
3008  &privateKey);
3009  if (hsm_pkcs11_check_error(ctx, rv, "generate key pair")) {
3010  return NULL;
3011  }
3012 
3013  new_key = libhsm_key_new();
3014  new_key->modulename = strdup(session->module->name);
3015  new_key->public_key = publicKey;
3016  new_key->private_key = privateKey;
3017 
3018  return new_key;
3019 }
3020 
3021 libhsm_key_t *
3023  const char *repository,
3024  const char *curve)
3025 {
3026  CK_RV rv;
3027  libhsm_key_t *new_key;
3028  hsm_session_t *session;
3029  CK_OBJECT_HANDLE publicKey, privateKey;
3030  CK_BBOOL ctrue = CK_TRUE;
3031  CK_BBOOL cfalse = CK_FALSE;
3032  CK_BBOOL cextractable = CK_FALSE;
3033 
3034  /* ids we create are 16 bytes of data */
3035  unsigned char id[16];
3036  /* that's 33 bytes in string (16*2 + 1 for \0) */
3037  char id_str[33];
3038 
3039  session = hsm_find_repository_session(ctx, repository);
3040  if (!session) return NULL;
3041  cextractable = session->module->config->allow_extract ? CK_TRUE : CK_FALSE;
3042 
3043  generate_unique_id(ctx, id, 16);
3044 
3045  /* the CKA_LABEL will contain a hexadecimal string representation
3046  * of the id */
3047  hsm_hex_unparse(id_str, id, 16);
3048 
3049  CK_KEY_TYPE keyType = CKK_EC_EDWARDS;
3050  CK_MECHANISM mechanism = {
3052  };
3053 
3054  CK_BYTE oid25519[] = { 0x06, 0x03, 0x2B, 0x65, 0x70 };
3055  CK_BYTE oid448[] = { 0x06, 0x03, 0x2B, 0x65, 0x71 };
3056 
3057  CK_ATTRIBUTE publicKeyTemplate[] = {
3058  { CKA_EC_PARAMS, NULL, 0 },
3059  { CKA_LABEL,(CK_UTF8CHAR*) id_str, strlen(id_str) },
3060  { CKA_ID, id, 16 },
3061  { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
3062  { CKA_VERIFY, &ctrue, sizeof(ctrue) },
3063  { CKA_ENCRYPT, &cfalse, sizeof(cfalse) },
3064  { CKA_WRAP, &cfalse, sizeof(cfalse) },
3065  { CKA_TOKEN, &ctrue, sizeof(ctrue) }
3066  };
3067 
3068  CK_ATTRIBUTE privateKeyTemplate[] = {
3069  { CKA_LABEL,(CK_UTF8CHAR*) id_str, strlen (id_str) },
3070  { CKA_ID, id, 16 },
3071  { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
3072  { CKA_SIGN, &ctrue, sizeof(ctrue) },
3073  { CKA_DECRYPT, &cfalse, sizeof(cfalse) },
3074  { CKA_UNWRAP, &cfalse, sizeof(cfalse) },
3075  { CKA_SENSITIVE, &ctrue, sizeof(ctrue) },
3076  { CKA_TOKEN, &ctrue, sizeof(ctrue) },
3077  { CKA_PRIVATE, &ctrue, sizeof(ctrue) },
3078  { CKA_EXTRACTABLE, &cextractable, sizeof (cextractable) }
3079  };
3080 
3081  /* Select the curve */
3082  if (strcmp(curve, "edwards25519") == 0)
3083  {
3084  publicKeyTemplate[0].pValue = oid25519;
3085  publicKeyTemplate[0].ulValueLen = sizeof(oid25519);
3086  }
3087  else if (strcmp(curve, "edwards448") == 0)
3088  {
3089  publicKeyTemplate[0].pValue = oid448;
3090  publicKeyTemplate[0].ulValueLen = sizeof(oid448);
3091  }
3092  else
3093  {
3094  return NULL;
3095  }
3096 
3097  /* Generate key pair */
3098 
3099  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GenerateKeyPair(session->session,
3100  &mechanism,
3101  publicKeyTemplate, 8,
3102  privateKeyTemplate, 10,
3103  &publicKey,
3104  &privateKey);
3105  if (hsm_pkcs11_check_error(ctx, rv, "generate key pair")) {
3106  return NULL;
3107  }
3108 
3109  new_key = libhsm_key_new();
3110  new_key->modulename = strdup(session->module->name);
3111  new_key->public_key = publicKey;
3112  new_key->private_key = privateKey;
3113 
3114  return new_key;
3115 }
3116 
3117 int
3119 {
3120  CK_RV rv;
3121  hsm_session_t *session;
3122  if (!key) return -1;
3123 
3124  session = hsm_find_key_session(ctx, key);
3125  if (!session) return -2;
3126 
3127  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_DestroyObject(session->session,
3128  key->private_key);
3129  if (hsm_pkcs11_check_error(ctx, rv, "Destroy private key")) {
3130  return -3;
3131  }
3132  key->private_key = 0;
3133 
3134  if (key->public_key) {
3135  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_DestroyObject(session->session,
3136  key->public_key);
3137  if (hsm_pkcs11_check_error(ctx, rv, "Destroy public key")) {
3138  return -4;
3139  }
3140  }
3141  key->public_key = 0;
3142 
3143  return 0;
3144 }
3145 
3146 void
3147 libhsm_key_list_free(libhsm_key_t **key_list, size_t count)
3148 {
3149  size_t i;
3150  for (i = 0; i < count; i++) {
3151  libhsm_key_free(key_list[i]);
3152  }
3153  free(key_list);
3154 }
3155 
3156 char *
3158 {
3159  unsigned char *id;
3160  char *id_str;
3161  size_t len;
3162  hsm_session_t *session;
3163 
3164  if (!key) return NULL;
3165 
3166  session = hsm_find_key_session(ctx, key);
3167  if (!session) return NULL;
3168 
3169  id = hsm_get_id_for_object(ctx, session, key->private_key, &len);
3170  if (!id) return NULL;
3171 
3172  /* this is plain binary data, we need to convert it to hex */
3173  id_str = malloc(len * 2 + 1);
3174  if (!id_str) {
3175  free(id);
3176  return NULL;
3177  }
3178 
3179  hsm_hex_unparse(id_str, id, len);
3180 
3181  free(id);
3182 
3183  return id_str;
3184 }
3185 
3188  const libhsm_key_t *key)
3189 {
3190  libhsm_key_info_t *key_info;
3191  hsm_session_t *session;
3192 
3193  session = hsm_find_key_session(ctx, key);
3194  if (!session) return NULL;
3195 
3196  key_info = malloc(sizeof(libhsm_key_info_t));
3197 
3198  key_info->id = hsm_get_key_id(ctx, key);
3199  if (key_info->id == NULL) {
3200  key_info->id = strdup("");
3201  }
3202 
3203  key_info->algorithm = (unsigned long) hsm_get_key_algorithm(ctx,
3204  session,
3205  key);
3206  key_info->keysize = (unsigned long) hsm_get_key_size(ctx,
3207  session,
3208  key,
3209  key_info->algorithm);
3210 
3211  switch(key_info->algorithm) {
3212  case CKK_RSA:
3213  key_info->algorithm_name = strdup("RSA");
3214  break;
3215  case CKK_DSA:
3216  key_info->algorithm_name = strdup("DSA");
3217  break;
3218  case CKK_GOSTR3410:
3219  key_info->algorithm_name = strdup("GOST");
3220  break;
3221  case CKK_EC:
3222  key_info->algorithm_name = strdup("ECDSA");
3223  break;
3224  case CKK_EC_EDWARDS:
3225  key_info->algorithm_name = strdup("EDDSA");
3226  break;
3227  default:
3228  key_info->algorithm_name = malloc(HSM_MAX_ALGONAME);
3229  snprintf(key_info->algorithm_name, HSM_MAX_ALGONAME,
3230  "%lu", key_info->algorithm);
3231  break;
3232  }
3233 
3234  return key_info;
3235 }
3236 
3237 void
3239 {
3240  if (key_info) {
3241  if (key_info->id) {
3242  free(key_info->id);
3243  }
3244  if (key_info->algorithm_name) {
3245  free(key_info->algorithm_name);
3246  }
3247  free(key_info);
3248  }
3249 }
3250 
3251 ldns_rr*
3253  const ldns_rr_list* rrset,
3254  const libhsm_key_t *key,
3255  const hsm_sign_params_t *sign_params)
3256 {
3257  ldns_rr *signature;
3258  ldns_buffer *sign_buf;
3259  ldns_rdf *b64_rdf;
3260  size_t i;
3261 
3262  if (!key) return NULL;
3263  if (!sign_params) return NULL;
3264 
3265  signature = hsm_create_empty_rrsig((ldns_rr_list *)rrset,
3266  sign_params);
3267 
3268  /* right now, we have: a key, a semi-sig and an rrset. For
3269  * which we can create the sig and base64 encode that and
3270  * add that to the signature */
3271  sign_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
3272 
3273  if (ldns_rrsig2buffer_wire(sign_buf, signature)
3274  != LDNS_STATUS_OK) {
3275  ldns_buffer_free(sign_buf);
3276  /* ERROR */
3277  ldns_rr_free(signature);
3278  return NULL;
3279  }
3280 
3281  /* make it canonical */
3282  for(i = 0; i < ldns_rr_list_rr_count(rrset); i++) {
3283  ldns_rr2canonical(ldns_rr_list_rr(rrset, i));
3284  }
3285 
3286  /* add the rrset in sign_buf */
3287  if (ldns_rr_list2buffer_wire(sign_buf, rrset)
3288  != LDNS_STATUS_OK) {
3289  ldns_buffer_free(sign_buf);
3290  ldns_rr_free(signature);
3291  return NULL;
3292  }
3293 
3294  b64_rdf = hsm_sign_buffer(ctx, sign_buf, key, sign_params->algorithm);
3295 
3296  ldns_buffer_free(sign_buf);
3297  if (!b64_rdf) {
3298  /* signing went wrong */
3299  ldns_rr_free(signature);
3300  return NULL;
3301  }
3302 
3303  ldns_rr_rrsig_set_sig(signature, b64_rdf);
3304 
3305  return signature;
3306 }
3307 
3308 int
3309 hsm_keytag(const char* loc, int alg, int sep, uint16_t* keytag)
3310 {
3311  uint16_t tag;
3312  hsm_ctx_t *hsm_ctx;
3313  hsm_sign_params_t *sign_params;
3314  libhsm_key_t *hsmkey;
3315  ldns_rr *dnskey_rr;
3316 
3317  if (!loc) {
3318  return 1;
3319  }
3320 
3321  if (!(hsm_ctx = hsm_create_context())) {
3322  return 1;
3323  }
3324  if (!(sign_params = hsm_sign_params_new())) {
3325  hsm_destroy_context(hsm_ctx);
3326  return 1;
3327  }
3328 
3329  /* The owner name is not relevant for the keytag calculation.
3330  * However, a ldns_rdf_clone down the path will trip over it. */
3331  sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, "dummy");
3332  sign_params->algorithm = (ldns_algorithm) alg;
3333  sign_params->flags = LDNS_KEY_ZONE_KEY;
3334  if (sep)
3335  sign_params->flags |= LDNS_KEY_SEP_KEY;
3336 
3337  hsmkey = hsm_find_key_by_id(hsm_ctx, loc);
3338  if (!hsmkey) {
3339  hsm_sign_params_free(sign_params);
3340  hsm_destroy_context(hsm_ctx);
3341  return 1;
3342  }
3343 
3344  dnskey_rr = hsm_get_dnskey(hsm_ctx, hsmkey, sign_params);
3345  if (!dnskey_rr) {
3346  libhsm_key_free(hsmkey);
3347  hsm_sign_params_free(sign_params);
3348  hsm_destroy_context(hsm_ctx);
3349  return 1;
3350  }
3351 
3352  tag = ldns_calc_keytag(dnskey_rr);
3353 
3354  ldns_rr_free(dnskey_rr);
3355  libhsm_key_free(hsmkey);
3356  hsm_sign_params_free(sign_params);
3357  hsm_destroy_context(hsm_ctx);
3358 
3359  if (keytag)
3360  *keytag = tag;
3361  return 0;
3362 }
3363 
3364 ldns_rr *
3366  const libhsm_key_t *key,
3367  const hsm_sign_params_t *sign_params)
3368 {
3369  /* CK_RV rv; */
3370  ldns_rr *dnskey;
3371  hsm_session_t *session;
3372  ldns_rdf *rdata;
3373 
3374  if (!key) {
3375  hsm_ctx_set_error(ctx, -1, "hsm_get_dnskey()", "Got NULL key");
3376  return NULL;
3377  }
3378  if (!sign_params) {
3379  hsm_ctx_set_error(ctx, -1, "hsm_get_dnskey()", "Got NULL sign_params");
3380  return NULL;
3381  }
3382  session = hsm_find_key_session(ctx, key);
3383  if (!session) return NULL;
3384 
3385  dnskey = ldns_rr_new();
3386  ldns_rr_set_type(dnskey, LDNS_RR_TYPE_DNSKEY);
3387 
3388  ldns_rr_set_owner(dnskey, ldns_rdf_clone(sign_params->owner));
3389 
3390  ldns_rr_push_rdf(dnskey,
3391  ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16,
3392  sign_params->flags));
3393  ldns_rr_push_rdf(dnskey,
3394  ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8,
3395  LDNS_DNSSEC_KEYPROTO));
3396  ldns_rr_push_rdf(dnskey,
3397  ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG,
3398  sign_params->algorithm));
3399 
3400  rdata = hsm_get_key_rdata(ctx, session, key);
3401  if (rdata == NULL) {
3402  ldns_rr_free(dnskey);
3403  return NULL;
3404  }
3405  ldns_rr_push_rdf(dnskey, rdata);
3406 
3407  return dnskey;
3408 }
3409 
3410 int
3412  unsigned char *buffer,
3413  unsigned long length)
3414 {
3415  CK_RV rv;
3416  unsigned int i;
3417  hsm_session_t *session;
3418  if (!buffer) return -1;
3419 
3420  /* just try every attached token. If one errors (be it NO_RNG, or
3421  * any other error, simply try the next */
3422  for (i = 0; i < ctx->session_count; i++) {
3423  session = ctx->session[i];
3424  if (session) {
3425  rv = ((CK_FUNCTION_LIST_PTR)session->module->sym)->C_GenerateRandom(
3426  session->session,
3427  buffer,
3428  length);
3429  if (rv == CKR_OK) {
3430  return 0;
3431  }
3432  }
3433  }
3434  return 1;
3435 }
3436 
3437 uint32_t
3439 {
3440  uint32_t rnd;
3441  int result;
3442  unsigned char rnd_buf[4];
3443  result = hsm_random_buffer(ctx, rnd_buf, 4);
3444  if (result == 0) {
3445  memcpy(&rnd, rnd_buf, 4);
3446  return rnd;
3447  } else {
3448  return 0;
3449  }
3450 }
3451 
3452 uint64_t
3454 {
3455  uint64_t rnd;
3456  int result;
3457  unsigned char rnd_buf[8];
3458  result = hsm_random_buffer(ctx, rnd_buf, 8);
3459  if (result == 0) {
3460  memcpy(&rnd, rnd_buf, 8);
3461  return rnd;
3462  } else {
3463  return 0;
3464  }
3465 }
3466 
3467 
3468 /*
3469  * Additional functions
3470  */
3471 
3472 int hsm_attach(const char *repository,
3473  const char *token_label,
3474  const char *path,
3475  const char *pin,
3476  const hsm_config_t *config)
3477 {
3478  hsm_session_t *session;
3479  int result;
3480 
3481  result = hsm_session_init(_hsm_ctx,
3482  &session,
3483  repository,
3484  token_label,
3485  path,
3486  pin,
3487  config);
3488  if (result == HSM_OK) {
3489  result = hsm_ctx_add_session(_hsm_ctx, session);
3490  }
3491  return result;
3492 }
3493 
3494 int
3495 hsm_token_attached(hsm_ctx_t *ctx, const char *repository)
3496 {
3497  unsigned int i;
3498  for (i = 0; i < ctx->session_count; i++) {
3499  if (ctx->session[i] &&
3500  strcmp(ctx->session[i]->module->name, repository) == 0) {
3501  return 1;
3502  }
3503  }
3504 
3506  "hsm_token_attached()",
3507  "Can't find repository: %s", repository);
3508  return 0;
3509 }
3510 
3511 char *
3513 {
3514  hsm_ctx_t *ctx;
3515 
3516  char *message;
3517 
3518  if (!gctx) {
3519  ctx = _hsm_ctx;
3520  } else {
3521  ctx = gctx;
3522  }
3523 
3524  if (ctx->error) {
3525  ctx->error = 0;
3526  message = malloc(HSM_ERROR_MSGSIZE);
3527 
3528  if (message == NULL) {
3529  return strdup("libhsm memory allocation failed");
3530  }
3531 
3532  snprintf(message, HSM_ERROR_MSGSIZE,
3533  "%s: %s",
3534  ctx->error_action ? ctx->error_action : "unknown()",
3535  ctx->error_message[0] ? ctx->error_message : "unknown error");
3536 
3537  /* Since both message and ctx->error_message have the same length, the
3538  * snprintf statement above may be truncated. In this case the string
3539  * won't be null-terminated. */
3540  message[HSM_ERROR_MSGSIZE - 1U] = '\0';
3541  return message;
3542  };
3543 
3544  return NULL;
3545 }
3546 
3547 void
3549 {
3550  printf("\t\tmodule at %p (sym %p)\n", (void *) session->module, (void *) session->module->sym);
3551  printf("\t\tmodule path: %s\n", session->module->path);
3552  printf("\t\trepository name: %s\n", session->module->name);
3553  printf("\t\ttoken label: %s\n", session->module->token_label);
3554  printf("\t\tsess handle: %u\n", (unsigned int) session->session);
3555 }
3556 
3557 void
3559  unsigned int i;
3560  printf("CTX Sessions: %lu\n",
3561  (long unsigned int) ctx->session_count);
3562  for (i = 0; i < ctx->session_count; i++) {
3563  printf("\tSession at %p\n", (void *) ctx->session[i]);
3565  }
3566 }
3567 
3568 void
3570  libhsm_key_info_t *key_info;
3571  if (key) {
3572  key_info = hsm_get_key_info(ctx, key);
3573  if (key_info) {
3574  printf("key:\n");
3575  printf("\tprivkey handle: %u\n", (unsigned int) key->private_key);
3576  if (key->public_key) {
3577  printf("\tpubkey handle: %u\n", (unsigned int) key->public_key);
3578  } else {
3579  printf("\tpubkey handle: %s\n", "NULL");
3580  }
3581  printf("\trepository: %s\n", key->modulename);
3582  printf("\talgorithm: %s\n", key_info->algorithm_name);
3583  printf("\tsize: %lu\n", key_info->keysize);
3584  printf("\tid: %s\n", key_info->id);
3585  libhsm_key_info_free(key_info);
3586  } else {
3587  printf("key: hsm_get_key_info() returned NULL\n");
3588  }
3589  } else {
3590  printf("key: <void>\n");
3591  }
3592 }
3593 
3594 void
3596 {
3597  char *message;
3598 
3599  message = hsm_get_error(gctx);
3600 
3601  if (message) {
3602  fprintf(stderr, "%s\n", message);
3603  free(message);
3604  } else {
3605  fprintf(stderr, "Unknown error\n");
3606  }
3607 }
3608 
3609 void
3611 {
3612  CK_RV rv;
3613  CK_SLOT_ID slot_id;
3614  CK_TOKEN_INFO token_info;
3615  unsigned int i;
3616  hsm_session_t *session;
3617  int result;
3618 
3619  for (i = 0; i < ctx->session_count; i++) {
3620  session = ctx->session[i];
3621 
3622  result = hsm_get_slot_id(ctx,
3623  session->module->sym,
3624  session->module->token_label,
3625  &slot_id);
3626  if (result != HSM_OK) return;
3627 
3628  rv = ((CK_FUNCTION_LIST_PTR) session->module->sym)->C_GetTokenInfo(slot_id, &token_info);
3629  if (hsm_pkcs11_check_error(ctx, rv, "C_GetTokenInfo")) {
3630  return;
3631  }
3632 
3633  printf("Repository: %s\n",session->module->name);
3634 
3635  printf("\tModule: %s\n", session->module->path);
3636  printf("\tSlot: %lu\n", slot_id);
3637  printf("\tToken Label: %.*s\n",
3638  (int) sizeof(token_info.label), token_info.label);
3639  printf("\tManufacturer: %.*s\n",
3640  (int) sizeof(token_info.manufacturerID), token_info.manufacturerID);
3641  printf("\tModel: %.*s\n",
3642  (int) sizeof(token_info.model), token_info.model);
3643  printf("\tSerial: %.*s\n",
3644  (int) sizeof(token_info.serialNumber), token_info.serialNumber);
3645 
3646  if (i + 1 != ctx->session_count)
3647  printf("\n");
3648  }
3649 }
3650 
3651 static int
3652 keycache_cmpfunc(const void* a, const void* b)
3653 {
3654  const char* x = (const char*)a;
3655  const char* y = (const char*)b;
3656  return strcmp(x, y);
3657 }
3658 
3659 static void
3660 keycache_delfunc(ldns_rbnode_t* node, void* cargo)
3661 {
3662  (void)cargo;
3663  free((void*)node->key);
3664  free(((libhsm_key_t*)node->data)->modulename);
3665  free((void*)node->data);
3666  free((void*)node);
3667 }
3668 
3669 void
3671 {
3672  ctx->keycache = ldns_rbtree_create(keycache_cmpfunc);
3673  _hsm_ctx->keycache_lock = malloc(sizeof (pthread_mutex_t));
3674  pthread_mutex_init(_hsm_ctx->keycache_lock, NULL);
3675 }
3676 
3677 void
3679 {
3680  ldns_traverse_postorder(ctx->keycache, keycache_delfunc, NULL);
3681  ldns_rbtree_free(ctx->keycache);
3682  pthread_mutex_destroy(ctx->keycache_lock);
3683  free(ctx->keycache_lock);
3684  ctx->keycache_lock = NULL;
3685 }
3686 
3687 const libhsm_key_t*
3688 keycache_lookup(hsm_ctx_t* ctx, const char* locator)
3689 {
3690  ldns_rbnode_t* node;
3691 
3692  pthread_mutex_lock(ctx->keycache_lock);
3693  node = ldns_rbtree_search(ctx->keycache, locator);
3694  pthread_mutex_unlock(ctx->keycache_lock);
3695  if (node == LDNS_RBTREE_NULL || node == NULL) {
3696  libhsm_key_t* key;
3697  if ((key = hsm_find_key_by_id(ctx, locator)) == NULL) {
3698  node = NULL;
3699  } else {
3700  node = malloc(sizeof(ldns_rbnode_t));
3701  node->key = strdup(locator);
3702  node->data = key;
3703  pthread_mutex_lock(ctx->keycache_lock);
3704  node = ldns_rbtree_insert(ctx->keycache, node);
3705  pthread_mutex_unlock(ctx->keycache_lock);
3706  }
3707  }
3708 
3709  if (node == LDNS_RBTREE_NULL || node == NULL)
3710  return NULL;
3711  else
3712  return node->data;
3713 }
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:3512
void libhsm_key_list_free(libhsm_key_t **key_list, size_t count)
Definition: libhsm.c:3147
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:3187
libhsm_key_t * hsm_generate_gost_key(hsm_ctx_t *ctx, const char *repository)
Definition: libhsm.c:2846
uint64_t hsm_random64(hsm_ctx_t *ctx)
Definition: libhsm.c:3453
uint32_t hsm_random32(hsm_ctx_t *ctx)
Definition: libhsm.c:3438
char * hsm_get_key_id(hsm_ctx_t *ctx, const libhsm_key_t *key)
Definition: libhsm.c:3157
void hsm_print_error(hsm_ctx_t *gctx)
Definition: libhsm.c:3595
hsm_ctx_t * hsm_create_context()
Definition: libhsm.c:2465
int hsm_token_attached(hsm_ctx_t *ctx, const char *repository)
Definition: libhsm.c:3495
#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:3365
void hsm_print_key(hsm_ctx_t *ctx, libhsm_key_t *key)
Definition: libhsm.c:3569
void hsm_print_ctx(hsm_ctx_t *ctx)
Definition: libhsm.c:3558
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:3252
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:3472
libhsm_key_t * hsm_generate_rsa_key(hsm_ctx_t *ctx, const char *repository, unsigned long keysize)
Definition: libhsm.c:2644
libhsm_key_t * hsm_generate_ecdsa_key(hsm_ctx_t *ctx, const char *repository, const char *curve)
Definition: libhsm.c:2926
int hsm_check_context()
Definition: libhsm.c:2475
void libhsm_key_info_free(libhsm_key_info_t *key_info)
Definition: libhsm.c:3238
libhsm_key_t ** hsm_list_keys_repository(hsm_ctx_t *ctx, size_t *count, const char *repository)
Definition: libhsm.c:2598
const libhsm_key_t * keycache_lookup(hsm_ctx_t *ctx, const char *locator)
Definition: libhsm.c:3688
int hsm_random_buffer(hsm_ctx_t *ctx, unsigned char *buffer, unsigned long length)
Definition: libhsm.c:3411
int hsm_open2(hsm_repository_t *rlist, char *(pin_callback)(unsigned int, const char *, unsigned int))
Definition: libhsm.c:2388
libhsm_key_t ** hsm_list_keys(hsm_ctx_t *ctx, size_t *count)
Definition: libhsm.c:2572
int hsm_keytag(const char *loc, int alg, int sep, uint16_t *keytag)
Definition: libhsm.c:3309
void hsm_close()
Definition: libhsm.c:2455
void hsm_print_session(hsm_session_t *session)
Definition: libhsm.c:3548
void keycache_create(hsm_ctx_t *ctx)
Definition: libhsm.c:3670
libhsm_key_t * hsm_generate_eddsa_key(hsm_ctx_t *ctx, const char *repository, const char *curve)
Definition: libhsm.c:3022
libhsm_key_t * hsm_find_key_by_id(hsm_ctx_t *ctx, const char *id)
Definition: libhsm.c:2615
libhsm_key_t * hsm_generate_dsa_key(hsm_ctx_t *ctx, const char *repository, unsigned long keysize)
Definition: libhsm.c:2732
int hsm_remove_key(hsm_ctx_t *ctx, libhsm_key_t *key)
Definition: libhsm.c:3118
void hsm_print_tokeninfo(hsm_ctx_t *ctx)
Definition: libhsm.c:3610
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:2530
hsm_sign_params_t * hsm_sign_params_new()
Definition: libhsm.c:2539
void keycache_destroy(hsm_ctx_t *ctx)
Definition: libhsm.c:3678
void libhsm_key_free(libhsm_key_t *key)
Definition: libhsm.c:2565
void hsm_sign_params_free(hsm_sign_params_t *params)
Definition: libhsm.c:2556
#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