OpenDNSSEC-libhsm  2.0.2
hsmutil.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 <stdlib.h>
33 #include <syslog.h>
34 #include <unistd.h>
35 
36 #include "libhsm.h"
37 #include "hsmtest.h"
38 
39 #include <libhsmdns.h>
40 
41 extern hsm_repository_t* parse_conf_repositories(const char* cfgfile);
42 
43 extern char *optarg;
44 char *progname = NULL;
45 unsigned int verbose = 0;
46 hsm_ctx_t *ctx = NULL;
47 
48 
49 static void
50 version ()
51 {
52  fprintf(stderr, "%s (%s) version %s\n",
53  progname, PACKAGE_NAME, PACKAGE_VERSION);
54 }
55 
56 static void
57 usage ()
58 {
59  fprintf(stderr,
60  "usage: %s [-c config] [-vVfh] [command [options]]\n",
61  progname);
62 
63  fprintf(stderr," -h Print this usage information.\n");
64  fprintf(stderr," -v Increase verbosity.\n");
65  fprintf(stderr," -V Print version and exit.\n");
66  fprintf(stderr," -f Force, Assume yes on all questions.\n");
67  fprintf(stderr," -c <cfg> Use alternative conf.xml.\n");
68 
69  fprintf(stderr,"commands\n");
70 
71  fprintf(stderr," login\n");
72  fprintf(stderr," logout\n");
73  fprintf(stderr," list [repository]\n");
74  fprintf(stderr," generate <repository> rsa|dsa|gost|ecdsa [keysize]\n");
75  fprintf(stderr," remove <id>\n");
76  fprintf(stderr," purge <repository>\n");
77  fprintf(stderr," dnskey <id> <name> <type> <algo>\n");
78  fprintf(stderr," test <repository>\n");
79  fprintf(stderr," info\n");
80 #if 0
81  fprintf(stderr," debug\n");
82 #endif
83 }
84 
85 static int
86 cmd_login ()
87 {
88  printf("The tokens are now logged in.\n");
89 
90  return 0;
91 }
92 
93 static int
94 cmd_logout ()
95 {
96  if (hsm_logout_pin() != HSM_OK) {
97  printf("Failed to erase the credentials.\n");
98  hsm_print_error(NULL);
99  return 1;
100  }
101 
102  printf("The credentials has been erased.\n");
103 
104  return 0;
105 }
106 
107 #pragma GCC diagnostic push
108 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
109 static int
110 cmd_list (int argc, char *argv[])
111 {
112  size_t i;
113  char *repository = NULL;
114 
115  size_t key_count = 0;
116  size_t key_count_valid = 0;
117  libhsm_key_t **keys;
118 
119  const char *key_info_format = "%-20s %-32s %-10s\n";
120 
121  ctx = hsm_create_context();
122 
123  if (argc) {
124  repository = argv[0];
125  argc--;
126  argv++;
127 
128  /* Check for repository before starting using it */
129  if (hsm_token_attached(ctx, repository) == 0) {
130  hsm_print_error(ctx);
131  return 1;
132  }
133 
134  fprintf(stdout, "\nListing keys in repository: %s\n", repository);
135  keys = hsm_list_keys_repository(ctx, &key_count, repository);
136  } else {
137  fprintf(stdout, "\nListing keys in all repositories.\n");
138  keys = hsm_list_keys(ctx, &key_count);
139  }
140 
141  fprintf(stdout, "%u %s found.\n\n", (unsigned int) key_count,
142  (key_count > 1 || key_count == 0 ? "keys" : "key"));
143 
144  if (!keys) {
145  return -1;
146  }
147 
148  /* print fancy header */
149  fprintf(stdout, key_info_format, "Repository", "ID", "Type");
150  fprintf(stdout, key_info_format, "----------", "--", "----");
151 
152  for (i = 0; i < key_count; i++) {
153  libhsm_key_info_t *key_info;
154  libhsm_key_t *key = NULL;
155  char key_type[HSM_MAX_ALGONAME + 8];
156  char const * key_id = NULL;
157 
158  key = keys[i];
159  if (key == NULL) {
160  /* Skip NULL key for now */
161  continue;
162  }
163 
164  key_count_valid++;
165 
166  key_info = hsm_get_key_info(ctx, key);
167 
168  if (key_info) {
169  snprintf(key_type, sizeof(key_type), "%s/%lu",
170  key_info->algorithm_name, key_info->keysize);
171  key_id = key_info->id;
172  } else {
173  snprintf(key_type, sizeof(key_type), "UNKNOWN");
174  key_id = "UNKNOWN";
175  }
176 
177  printf(key_info_format, key->modulename, key_id, key_type);
178 
179  libhsm_key_info_free(key_info);
180  }
181  libhsm_key_list_free(keys, key_count);
182 
183  if (key_count != key_count_valid) {
184  size_t invalid_keys;
185  invalid_keys = key_count - key_count_valid;
186  printf("\n");
187  fprintf(stderr, "Warning: %u %s not usable by OpenDNSSEC was found.\n",
188  (unsigned int) invalid_keys, invalid_keys > 1 ? "keys" : "key");
189  }
190 
191  return 0;
192 }
193 #pragma GCC diagnostic pop
194 
195 static int
196 cmd_generate (int argc, char *argv[])
197 {
198  const char *repository = NULL;
199  const char *algorithm = NULL;
200  unsigned int keysize = 1024;
201 
202  libhsm_key_t *key = NULL;
203 
204  if (argc < 2 || argc > 3) {
205  usage();
206  return -1;
207  }
208 
209  repository = argv[0];
210 
211  /* Check for repository before starting using it */
212  if (hsm_token_attached(ctx, repository) == 0) {
213  hsm_print_error(ctx);
214  return 1;
215  }
216 
217  algorithm = argv[1];
218  if (argc == 3) {
219  keysize = atoi(argv[2]);
220  }
221 
222  if (!strcasecmp(algorithm, "rsa")) {
223  printf("Generating %d bit RSA key in repository: %s\n",
224  keysize, repository);
225 
226  key = hsm_generate_rsa_key(ctx, repository, keysize);
227  } else if (!strcasecmp(algorithm, "dsa")) {
228  printf("Generating %d bit DSA key in repository: %s\n",
229  keysize, repository);
230 
231  key = hsm_generate_dsa_key(ctx, repository, keysize);
232  } else if (!strcasecmp(algorithm, "gost")) {
233  printf("Generating 512 bit GOST key in repository: %s\n",
234  repository);
235 
236  key = hsm_generate_gost_key(ctx, repository);
237  } else if (!strcasecmp(algorithm, "ecdsa")) {
238  if (keysize == 256) {
239  printf("Generating a P-256 ECDSA key in repository: %s\n",
240  repository);
241 
242  key = hsm_generate_ecdsa_key(ctx, repository, "P-256");
243  } else if (keysize == 384) {
244  printf("Generating a P-384 ECDSA key in repository: %s\n",
245  repository);
246 
247  key = hsm_generate_ecdsa_key(ctx, repository, "P-384");
248  } else {
249  printf("Invalid ECDSA key size: %d\n", keysize);
250  printf("Expecting 256 or 384.\n");
251  return -1;
252  }
253  } else {
254  printf("Unknown algorithm: %s\n", algorithm);
255  return -1;
256  }
257 
258  if (key) {
259  libhsm_key_info_t *key_info;
260 
261  key_info = hsm_get_key_info(ctx, key);
262  printf("Key generation successful: %s\n",
263  key_info ? key_info->id : "NULL");
264  libhsm_key_info_free(key_info);
265  if (verbose) hsm_print_key(ctx, key);
266  free(key);
267  } else {
268  printf("Key generation failed.\n");
269  return -1;
270  }
271 
272  return 0;
273 }
274 
275 static int
276 cmd_remove (int argc, char *argv[])
277 {
278  char *id;
279  int result;
280 
281  libhsm_key_t *key = NULL;
282 
283  if (argc != 1) {
284  usage();
285  return -1;
286  }
287 
288  id = argv[0];
289 
290  key = hsm_find_key_by_id(ctx, id);
291 
292  if (!key) {
293  printf("Key not found: %s\n", id);
294  return -1;
295  }
296 
297  result = hsm_remove_key(ctx, key);
298 
299  if (!result) {
300  printf("Key remove successful.\n");
301  } else {
302  printf("Key remove failed.\n");
303  }
304 
305  free(key);
306 
307  return result;
308 }
309 
310 static int
311 cmd_purge (int argc, char *argv[], int force)
312 {
313  int result;
314  int final_result = 0;
315  char *fresult;
316 
317  size_t i;
318  char *repository = NULL;
319  char confirm[16];
320 
321  size_t key_count = 0;
322  libhsm_key_t **keys;
323 
324  if (argc != 1) {
325  usage();
326  return -1;
327  }
328 
329  repository = argv[0];
330  argc--;
331  argv++;
332 
333  /* Check for repository before starting using it */
334  if (hsm_token_attached(ctx, repository) == 0) {
335  hsm_print_error(ctx);
336  return 1;
337  }
338 
339  printf("Purging all keys from repository: %s\n", repository);
340  keys = hsm_list_keys_repository(ctx, &key_count, repository);
341 
342  printf("%u %s found.\n\n", (unsigned int) key_count,
343  (key_count > 1 || key_count == 0 ? "keys" : "key"));
344 
345  if (!keys) {
346  return -1;
347  }
348 
349  if (key_count == 0) {
350  libhsm_key_list_free(keys, key_count);
351  return -1;
352  }
353 
354  if (!force) {
355  printf("Are you sure you want to remove ALL keys from repository %s ? (YES/NO) ", repository);
356  fresult = fgets(confirm, sizeof(confirm) - 1, stdin);
357  if (fresult == NULL || strncasecmp(confirm, "yes", 3) != 0) {
358  printf("\npurge cancelled.\n");
359  libhsm_key_list_free(keys, key_count);
360  return -1;
361  }
362  }
363  printf("\nStarting purge...\n");
364 
365  for (i = 0; i < key_count; i++) {
366  libhsm_key_info_t *key_info;
367  libhsm_key_t *key = keys[i];
368 
369  key_info = hsm_get_key_info(ctx, key);
370  result = hsm_remove_key(ctx, key);
371 
372  if (!result) {
373  printf("Key remove successful: %s\n",
374  key_info ? key_info->id : "NULL");
375  } else {
376  printf("Key remove failed: %s\n",
377  key_info ? key_info->id : "NULL");
378  final_result++;
379  }
380 
381  libhsm_key_info_free(key_info);
382  }
383  libhsm_key_list_free(keys, key_count);
384 
385  printf("Purge done.\n");
386 
387  return final_result;
388 }
389 
390 static int
391 cmd_dnskey (int argc, char *argv[])
392 {
393  char *id;
394  char *name;
395  int type;
396  int algo;
397 
398  libhsm_key_t *key = NULL;
399  ldns_rr *dnskey_rr;
400  hsm_sign_params_t *sign_params;
401 
402  if (argc != 4) {
403  usage();
404  return -1;
405  }
406 
407  id = strdup(argv[0]);
408  name = strdup(argv[1]);
409  type = atoi(argv[2]);
410  algo = atoi(argv[3]);
411 
412  key = hsm_find_key_by_id(ctx, id);
413 
414  if (!key) {
415  printf("Key not found: %s\n", id);
416  free(name);
417  free(id);
418  return -1;
419  }
420 
421  if (type != LDNS_KEY_ZONE_KEY && type != LDNS_KEY_ZONE_KEY + LDNS_KEY_SEP_KEY) {
422  printf("Invalid key type: %i\n", type);
423  printf("Please use: %i or %i\n", LDNS_KEY_ZONE_KEY, LDNS_KEY_ZONE_KEY + LDNS_KEY_SEP_KEY);
424  free(name);
425  free(id);
426  free(key);
427  return -1;
428  }
429 
430  libhsm_key_info_t *key_info = hsm_get_key_info(ctx, key);
431  switch (algo) {
432  case LDNS_SIGN_RSAMD5:
433  case LDNS_SIGN_RSASHA1:
434  case LDNS_SIGN_RSASHA1_NSEC3:
435  case LDNS_SIGN_RSASHA256:
436  case LDNS_SIGN_RSASHA512:
437  if (strcmp(key_info->algorithm_name, "RSA") != 0) {
438  printf("Not an RSA key, the key is of algorithm %s.\n", key_info->algorithm_name);
439  libhsm_key_info_free(key_info);
440  free(key);
441  free(name);
442  free(id);
443  return -1;
444  }
445  break;
446  case LDNS_SIGN_DSA:
447  case LDNS_SIGN_DSA_NSEC3:
448  if (strcmp(key_info->algorithm_name, "DSA") != 0) {
449  printf("Not a DSA key, the key is of algorithm %s.\n", key_info->algorithm_name);
450  libhsm_key_info_free(key_info);
451  free(key);
452  free(name);
453  free(id);
454  return -1;
455  }
456  break;
457  case LDNS_SIGN_ECC_GOST:
458  if (strcmp(key_info->algorithm_name, "GOST") != 0) {
459  printf("Not a GOST key, the key is of algorithm %s.\n", key_info->algorithm_name);
460  libhsm_key_info_free(key_info);
461  free(key);
462  free(name);
463  free(id);
464  return -1;
465  }
466  break;
467 /* TODO: We can remove the directive if we require LDNS >= 1.6.13 */
468 #if !defined LDNS_BUILD_CONFIG_USE_ECDSA || LDNS_BUILD_CONFIG_USE_ECDSA
469  case LDNS_SIGN_ECDSAP256SHA256:
470  if (strcmp(key_info->algorithm_name, "ECDSA") != 0) {
471  printf("Not an ECDSA key, the key is of algorithm %s.\n", key_info->algorithm_name);
472  libhsm_key_info_free(key_info);
473  free(key);
474  free(name);
475  free(id);
476  return -1;
477  }
478  if (key_info->keysize != 256) {
479  printf("The key is a ECDSA/%lu, expecting ECDSA/256 for this algorithm.\n", key_info->keysize);
480  libhsm_key_info_free(key_info);
481  free(key);
482  free(name);
483  free(id);
484  return -1;
485  }
486  break;
487  case LDNS_SIGN_ECDSAP384SHA384:
488  if (strcmp(key_info->algorithm_name, "ECDSA") != 0) {
489  printf("Not an ECDSA key, the key is of algorithm %s.\n", key_info->algorithm_name);
490  libhsm_key_info_free(key_info);
491  free(key);
492  free(name);
493  free(id);
494  return -1;
495  }
496  if (key_info->keysize != 384) {
497  printf("The key is a ECDSA/%lu, expecting ECDSA/384 for this algorithm.\n", key_info->keysize);
498  libhsm_key_info_free(key_info);
499  free(key);
500  free(name);
501  free(id);
502  return -1;
503  }
504  break;
505 #endif
506  default:
507  printf("Invalid algorithm: %i\n", algo);
508  libhsm_key_info_free(key_info);
509  free(name);
510  free(id);
511  return -1;
512  }
513  libhsm_key_info_free(key_info);
514 
515  sign_params = hsm_sign_params_new();
516  sign_params->algorithm = algo;
517  sign_params->flags = type;
518  sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, name);
519  dnskey_rr = hsm_get_dnskey(ctx, key, sign_params);
520  sign_params->keytag = ldns_calc_keytag(dnskey_rr);
521 
522  ldns_rr_print(stdout, dnskey_rr);
523 
524  hsm_sign_params_free(sign_params);
525  ldns_rr_free(dnskey_rr);
526  free(key);
527  free(name);
528  free(id);
529 
530  return 0;
531 }
532 
533 static int
534 cmd_test (int argc, char *argv[], hsm_ctx_t* ctx)
535 {
536  char *repository = NULL;
537 
538  if (argc) {
539  repository = strdup(argv[0]);
540  argc--;
541  argv++;
542 
543  printf("Testing repository: %s\n\n", repository);
544  int rv = hsm_test(repository, ctx);
545  if (repository) free(repository);
546  return rv;
547  } else {
548  usage();
549  }
550 
551  return 0;
552 }
553 
554 static int
555 cmd_info (hsm_ctx_t* ctx)
556 {
557  hsm_print_tokeninfo(ctx);
558 
559  return 0;
560 }
561 
562 static int
563 cmd_debug (hsm_ctx_t* ctx)
564 {
565  hsm_print_ctx(ctx);
566 
567  return 0;
568 }
569 
570 int
571 main (int argc, char *argv[])
572 {
573  int result;
574 
575  char *config = NULL;
576 
577  int ch;
578  int force = 0;
579  progname = argv[0];
580 
581  while ((ch = getopt(argc, argv, "c:vVhf")) != -1) {
582  switch (ch) {
583  case 'c':
584  config = strdup(optarg);
585  break;
586  case 'f':
587  force = 1;
588  break;
589  case 'v':
590  verbose++;
591  break;
592  case 'V':
593  version();
594  exit(0);
595  break;
596  case 'h':
597  usage();
598  exit(0);
599  break;
600  default:
601  usage();
602  exit(1);
603  }
604  }
605  argc -= optind;
606  argv += optind;
607 
608  if (!argc) {
609  usage();
610  exit(1);
611  }
612 
613 
614  if (!strcasecmp(argv[0], "logout")) {
615  if (config) free(config);
616  exit(cmd_logout());
617  }
618 
619  result = hsm_open2(parse_conf_repositories(config?config:HSM_DEFAULT_CONFIG), hsm_prompt_pin);
620  if (result != HSM_OK) {
621  char* error = hsm_get_error(NULL);
622  if (error != NULL) {
623  fprintf(stderr,"%s\n", error);
624  free(error);
625  }
626  exit(-1);
627  }
628  ctx = hsm_create_context();
629 
630  openlog("hsmutil", LOG_PID, LOG_USER);
631 
632  if (!strcasecmp(argv[0], "login")) {
633  argc --;
634  argv ++;
635  result = cmd_login();
636  } else if (!strcasecmp(argv[0], "list")) {
637  argc --;
638  argv ++;
639  result = cmd_list(argc, argv);
640  } else if (!strcasecmp(argv[0], "generate")) {
641  argc --;
642  argv ++;
643  result = cmd_generate(argc, argv);
644  } else if (!strcasecmp(argv[0], "remove")) {
645  argc --;
646  argv ++;
647  result = cmd_remove(argc, argv);
648  } else if (!strcasecmp(argv[0], "purge")) {
649  argc --;
650  argv ++;
651  result = cmd_purge(argc, argv, force);
652  } else if (!strcasecmp(argv[0], "dnskey")) {
653  argc --;
654  argv ++;
655  result = cmd_dnskey(argc, argv);
656  } else if (!strcasecmp(argv[0], "test")) {
657  argc --;
658  argv ++;
659  result = cmd_test(argc, argv, ctx);
660  } else if (!strcasecmp(argv[0], "info")) {
661  argc --;
662  argv ++;
663  result = cmd_info(ctx);
664  } else if (!strcasecmp(argv[0], "debug")) {
665  argc --;
666  argv ++;
667  result = cmd_debug(ctx);
668  } else {
669  usage();
670  result = -1;
671  }
672 
673  hsm_destroy_context(ctx);
674  hsm_close();
675  if (config) free(config);
676 
677  closelog();
678 
679  exit(result);
680 }
char * progname
Definition: hsmutil.c:44
char * hsm_get_error(hsm_ctx_t *gctx)
Definition: libhsm.c:3188
const char * modulename
Definition: libhsm.h:102
void hsm_sign_params_free(hsm_sign_params_t *params)
Definition: libhsm.c:2347
int main(int argc, char *argv[])
Definition: hsmutil.c:571
ldns_rdf * owner
Definition: libhsmdns.h:46
int hsm_logout_pin(void)
Definition: pin.c:413
libhsm_key_t * hsm_find_key_by_id(hsm_ctx_t *ctx, const char *id)
Definition: libhsm.c:2399
unsigned int verbose
Definition: hsmutil.c:45
libhsm_key_t * hsm_generate_rsa_key(hsm_ctx_t *ctx, const char *repository, unsigned long keysize)
Definition: libhsm.c:2428
void hsm_destroy_context(hsm_ctx_t *ctx)
Definition: libhsm.c:2321
void hsm_print_tokeninfo(hsm_ctx_t *ctx)
Definition: libhsm.c:3281
libhsm_key_t ** hsm_list_keys_repository(hsm_ctx_t *ctx, size_t *count, const char *repository)
Definition: libhsm.c:2382
ldns_rr * hsm_get_dnskey(hsm_ctx_t *ctx, const libhsm_key_t *key, const hsm_sign_params_t *sign_params)
Definition: libhsm.c:3041
unsigned long keysize
Definition: libhsm.h:112
libhsm_key_t * hsm_generate_ecdsa_key(hsm_ctx_t *ctx, const char *repository, const char *curve)
Definition: libhsm.c:2702
int hsm_open2(hsm_repository_t *rlist, char *(pin_callback)(unsigned int, const char *, unsigned int))
Definition: libhsm.c:2184
int hsm_token_attached(hsm_ctx_t *ctx, const char *repository)
Definition: libhsm.c:3171
uint16_t flags
Definition: libhsmdns.h:38
int hsm_test(const char *repository, hsm_ctx_t *ctx)
Definition: hsmtest.c:107
uint16_t keytag
Definition: libhsmdns.h:44
hsm_sign_params_t * hsm_sign_params_new()
Definition: libhsm.c:2330
void libhsm_key_info_free(libhsm_key_info_t *key_info)
Definition: libhsm.c:2914
void hsm_print_key(hsm_ctx_t *ctx, libhsm_key_t *key)
Definition: libhsm.c:3240
ldns_algorithm algorithm
Definition: libhsmdns.h:36
libhsm_key_t * hsm_generate_gost_key(hsm_ctx_t *ctx, const char *repository)
Definition: libhsm.c:2624
libhsm_key_t ** hsm_list_keys(hsm_ctx_t *ctx, size_t *count)
Definition: libhsm.c:2356
int hsm_remove_key(hsm_ctx_t *ctx, libhsm_key_t *key)
Definition: libhsm.c:2796
hsm_ctx_t * ctx
Definition: hsmutil.c:46
hsm_repository_t * parse_conf_repositories(const char *cfgfile)
Definition: confparser.c:51
libhsm_key_t * hsm_generate_dsa_key(hsm_ctx_t *ctx, const char *repository, unsigned long keysize)
Definition: libhsm.c:2514
hsm_ctx_t * hsm_create_context()
Definition: libhsm.c:2256
ldns_algorithm algorithm
Definition: hsmspeed.c:43
#define HSM_OK
Definition: libhsm.h:64
void hsm_print_ctx(hsm_ctx_t *ctx)
Definition: libhsm.c:3229
void hsm_close()
Definition: libhsm.c:2247
char * hsm_prompt_pin(unsigned int id, const char *repository, unsigned int mode)
Definition: pin.c:228
void libhsm_key_list_free(libhsm_key_t **key_list, size_t count)
Definition: libhsm.c:2825
#define HSM_MAX_ALGONAME
Definition: libhsm.h:46
libhsm_key_info_t * hsm_get_key_info(hsm_ctx_t *ctx, const libhsm_key_t *key)
Definition: libhsm.c:2866
void hsm_print_error(hsm_ctx_t *gctx)
Definition: libhsm.c:3266
char * optarg
char * algorithm_name
Definition: libhsm.h:111