OpenDNSSEC-libhsm  1.4.10
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 <libhsmdns.h>
38 #include "hsmtest.h"
39 
40 extern char *optarg;
41 char *progname = NULL;
42 unsigned int verbose = 0;
44 
45 
46 void
48 {
49  fprintf(stderr, "%s (%s) version %s\n",
50  progname, PACKAGE_NAME, PACKAGE_VERSION);
51 }
52 
53 void
55 {
56  fprintf(stderr,
57  "usage: %s [-c config] [-vV] command [options]\n",
58  progname);
59 
60  fprintf(stderr," login\n");
61  fprintf(stderr," logout\n");
62  fprintf(stderr," list [repository]\n");
63  fprintf(stderr," generate <repository> rsa <keysize>\n");
64  fprintf(stderr," remove <id>\n");
65  fprintf(stderr," purge <repository>\n");
66  fprintf(stderr," dnskey <id> <name>\n");
67  fprintf(stderr," test <repository>\n");
68  fprintf(stderr," info\n");
69 #if 0
70  fprintf(stderr," debug\n");
71 #endif
72 }
73 
74 int
76 {
77  printf("The tokens are now logged in.\n");
78 
79  return 0;
80 }
81 
82 int
84 {
85  if (hsm_logout_pin() != HSM_OK) {
86  printf("Failed to erase the credentials.\n");
87  hsm_print_error(ctx);
88  return 1;
89  }
90 
91  printf("The credentials has been erased.\n");
92 
93  return 0;
94 }
95 
96 int
97 cmd_list (int argc, char *argv[])
98 {
99  size_t i;
100  char *repository = NULL;
101 
102  size_t key_count = 0;
103  size_t key_count_valid = 0;
104  hsm_key_t **keys;
105 
106  const char *key_info_format = "%-20s %-32s %-10s\n";
107 
108 
109  if (argc) {
110  repository = strdup(argv[0]);
111  argc--;
112  argv++;
113 
114  /* Check for repository before starting using it */
115  if (hsm_token_attached(ctx, repository) == 0) {
116  hsm_print_error(ctx);
117  return 1;
118  }
119 
120  fprintf(stdout, "\nListing keys in repository: %s\n", repository);
121  keys = hsm_list_keys_repository(ctx, &key_count, repository);
122  } else {
123  fprintf(stdout, "\nListing keys in all repositories.\n");
124  keys = hsm_list_keys(ctx, &key_count);
125  }
126 
127  fprintf(stdout, "%u %s found.\n\n", (unsigned int) key_count,
128  (key_count > 1 || key_count == 0 ? "keys" : "key"));
129 
130  if (!keys) {
131  return -1;
132  }
133 
134  /* print fancy header */
135  fprintf(stdout, key_info_format, "Repository", "ID", "Type");
136  fprintf(stdout, key_info_format, "----------", "--", "----");
137 
138  for (i = 0; i < key_count; i++) {
139  hsm_key_info_t *key_info;
140  hsm_key_t *key = NULL;
141  char key_type[HSM_MAX_ALGONAME + 8];
142  char *key_id = NULL;
143 
144  key = keys[i];
145  if (key == NULL) {
146  /* Skip NULL key for now */
147  continue;
148  }
149 
150  key_count_valid++;
151 
152  key_info = hsm_get_key_info(ctx, key);
153 
154  if (key_info) {
155  snprintf(key_type, sizeof(key_type), "%s/%lu",
156  key_info->algorithm_name, key_info->keysize);
157  key_id = key_info->id;
158  } else {
159  snprintf(key_type, sizeof(key_type), "UNKNOWN");
160  key_id = "UNKNOWN";
161  }
162 
163  printf(key_info_format, key->modulename, key_id, key_type);
164 
165  hsm_key_info_free(key_info);
166  }
167  hsm_key_list_free(keys, key_count);
168 
169  if (key_count != key_count_valid) {
170  size_t invalid_keys;
171  invalid_keys = key_count - key_count_valid;
172  printf("\n");
173  fprintf(stderr, "Warning: %u %s not usable by OpenDNSSEC was found.\n",
174  (unsigned int) invalid_keys, invalid_keys > 1 ? "keys" : "key");
175  }
176 
177  return 0;
178 }
179 
180 int
181 cmd_generate (int argc, char *argv[])
182 {
183  char *repository = NULL;
184  char *algorithm = NULL;
185  unsigned int keysize = 1024;
186 
187  hsm_key_t *key = NULL;
188 
189  if (argc != 3) {
190  usage();
191  return -1;
192  }
193 
194  repository = strdup(argv[0]);
195 
196  /* Check for repository before starting using it */
197  if (hsm_token_attached(ctx, repository) == 0) {
198  hsm_print_error(ctx);
199  return 1;
200  }
201 
202 
203  algorithm = argv[1];
204  keysize = atoi(argv[2]);
205 
206  if (!strcasecmp(algorithm, "rsa")) {
207  printf("Generating %d bit RSA key in repository: %s\n",
208  keysize, repository);
209 
210  key = hsm_generate_rsa_key(ctx, repository, keysize);
211 
212  if (key) {
213  hsm_key_info_t *key_info;
214 
215  key_info = hsm_get_key_info(ctx, key);
216  printf("Key generation successful: %s\n",
217  key_info ? key_info->id : "NULL");
218  hsm_key_info_free(key_info);
219  if (verbose) hsm_print_key(ctx, key);
220  hsm_key_free(key);
221  } else {
222  printf("Key generation failed.\n");
223  return -1;
224  }
225 
226  } else {
227  printf("Unknown algorithm: %s\n", algorithm);
228  return -1;
229  }
230 
231  return 0;
232 }
233 
234 int
235 cmd_remove (int argc, char *argv[])
236 {
237  char *id;
238  int result;
239 
240  hsm_key_t *key = NULL;
241 
242  if (argc != 1) {
243  usage();
244  return -1;
245  }
246 
247  id = strdup(argv[0]);
248 
249  key = hsm_find_key_by_id(ctx, id);
250 
251  if (!key) {
252  printf("Key not found: %s\n", id);
253  return -1;
254  }
255 
256  result = hsm_remove_key(ctx, key);
257 
258  if (!result) {
259  printf("Key remove successful.\n");
260  } else {
261  printf("Key remove failed.\n");
262  }
263 
264  hsm_key_free(key);
265 
266  return result;
267 }
268 
269 int
270 cmd_purge (int argc, char *argv[])
271 {
272  int result;
273  int final_result = 0;
274  char *fresult;
275 
276  size_t i;
277  char *repository = NULL;
278  char confirm[16];
279 
280  size_t key_count = 0;
281  hsm_key_t **keys;
282 
283  if (argc != 1) {
284  usage();
285  return -1;
286  }
287 
288  repository = strdup(argv[0]);
289  argc--;
290  argv++;
291 
292  /* Check for repository before starting using it */
293  if (hsm_token_attached(ctx, repository) == 0) {
294  hsm_print_error(ctx);
295  return 1;
296  }
297 
298  printf("Purging all keys from repository: %s\n", repository);
299  keys = hsm_list_keys_repository(ctx, &key_count, repository);
300 
301  printf("%u %s found.\n\n", (unsigned int) key_count,
302  (key_count > 1 || key_count == 0 ? "keys" : "key"));
303 
304  if (!keys) {
305  return -1;
306  }
307 
308  if (key_count == 0) {
309  return -1;
310  }
311 
312  printf("Are you sure you want to remove ALL keys from repository %s ? (YES/NO) ", repository);
313  fresult = fgets(confirm, sizeof(confirm) - 1, stdin);
314  if (fresult == NULL || strncasecmp(confirm, "yes", 3) != 0) {
315  printf("\nPurge cancelled.\n");
316  hsm_key_list_free(keys, key_count);
317  return -1;
318  } else {
319  printf("\nStarting purge...\n");
320  }
321 
322  for (i = 0; i < key_count; i++) {
323  hsm_key_info_t *key_info;
324  hsm_key_t *key = keys[i];
325 
326  key_info = hsm_get_key_info(ctx, key);
327  result = hsm_remove_key(ctx, key);
328 
329  if (!result) {
330  printf("Key remove successful: %s\n",
331  key_info ? key_info->id : "NULL");
332  } else {
333  printf("Key remove failed: %s\n",
334  key_info ? key_info->id : "NULL");
335  final_result++;
336  }
337 
338  hsm_key_info_free(key_info);
339  }
340  hsm_key_list_free(keys, key_count);
341 
342  printf("Purge done.\n");
343 
344  return final_result;
345 }
346 
347 int
348 cmd_dnskey (int argc, char *argv[])
349 {
350  char *id;
351  char *name;
352 
353  hsm_key_t *key = NULL;
354  ldns_rr *dnskey_rr;
355  hsm_sign_params_t *sign_params;
356 
357  if (argc != 2) {
358  usage();
359  return -1;
360  }
361 
362  id = strdup(argv[0]);
363  name = strdup(argv[1]);
364 
365  key = hsm_find_key_by_id(ctx, id);
366 
367  if (!key) {
368  printf("Key not found: %s\n", id);
369  free(name);
370  free(id);
371  return -1;
372  }
373 
374  sign_params = hsm_sign_params_new();
375  sign_params->algorithm = LDNS_RSASHA1;
376  sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, name);
377  dnskey_rr = hsm_get_dnskey(ctx, key, sign_params);
378  sign_params->keytag = ldns_calc_keytag(dnskey_rr);
379 
380  ldns_rr_print(stdout, dnskey_rr);
381 
382  hsm_sign_params_free(sign_params);
383  ldns_rr_free(dnskey_rr);
384  hsm_key_free(key);
385  free(name);
386  free(id);
387 
388  return 0;
389 }
390 
391 int
392 cmd_test (int argc, char *argv[])
393 {
394  char *repository = NULL;
395 
396  if (argc) {
397  repository = strdup(argv[0]);
398  argc--;
399  argv++;
400 
401  printf("Testing repository: %s\n\n", repository);
402  return hsm_test(ctx, repository);
403  } else {
404  usage();
405  }
406 
407  return 0;
408 }
409 
410 int
412 {
413  hsm_print_tokeninfo(ctx);
414 
415  return 0;
416 }
417 
418 int
420 {
421  hsm_print_ctx(ctx);
422 
423  return 0;
424 }
425 
426 int
427 main (int argc, char *argv[])
428 {
429  int result;
430 
431  char *config = NULL;
432 
433  int ch;
434  progname = argv[0];
435 
436  while ((ch = getopt(argc, argv, "c:vVh")) != -1) {
437  switch (ch) {
438  case 'c':
439  config = strdup(optarg);
440  break;
441  case 'v':
442  verbose++;
443  break;
444  case 'V':
445  version();
446  exit(0);
447  break;
448  case 'h':
449  usage();
450  exit(0);
451  break;
452  default:
453  usage();
454  exit(1);
455  }
456  }
457  argc -= optind;
458  argv += optind;
459 
460  if (!argc) {
461  usage();
462  exit(1);
463  }
464 
465 
466  if (!strcasecmp(argv[0], "logout")) {
467  if (config) free(config);
468  exit(cmd_logout());
469  }
470 
471  result = hsm_open(config?config:HSM_DEFAULT_CONFIG, hsm_prompt_pin);
472  if (result != HSM_OK) {
473  char* error = hsm_get_error(NULL);
474  if (error != NULL) {
475  fprintf(stderr,"%s\n", error);
476  free(error);
477  }
478  exit(-1);
479  }
480  ctx = hsm_create_context();
481 
482  openlog("hsmutil", LOG_PID, LOG_USER);
483 
484  if (!strcasecmp(argv[0], "login")) {
485  argc --;
486  argv ++;
487  result = cmd_login();
488  } else if (!strcasecmp(argv[0], "list")) {
489  argc --;
490  argv ++;
491  result = cmd_list(argc, argv);
492  } else if (!strcasecmp(argv[0], "generate")) {
493  argc --;
494  argv ++;
495  result = cmd_generate(argc, argv);
496  } else if (!strcasecmp(argv[0], "remove")) {
497  argc --;
498  argv ++;
499  result = cmd_remove(argc, argv);
500  } else if (!strcasecmp(argv[0], "purge")) {
501  argc --;
502  argv ++;
503  result = cmd_purge(argc, argv);
504  } else if (!strcasecmp(argv[0], "dnskey")) {
505  argc --;
506  argv ++;
507  result = cmd_dnskey(argc, argv);
508  } else if (!strcasecmp(argv[0], "test")) {
509  argc --;
510  argv ++;
511  result = cmd_test(argc, argv);
512  } else if (!strcasecmp(argv[0], "info")) {
513  argc --;
514  argv ++;
515  result = cmd_info(ctx);
516  } else if (!strcasecmp(argv[0], "debug")) {
517  argc --;
518  argv ++;
519  result = cmd_debug(ctx);
520  } else {
521  usage();
522  result = -1;
523  }
524 
525  hsm_destroy_context(ctx);
526  hsm_close();
527 
528  if (config) free(config);
529 
530  closelog();
531 
532  exit(result);
533 }
void hsm_key_free(hsm_key_t *key)
Definition: libhsm.c:2704
char * progname
Definition: hsmutil.c:41
int cmd_info(hsm_ctx_t *ctx)
Definition: hsmutil.c:411
int cmd_purge(int argc, char *argv[])
Definition: hsmutil.c:270
char * hsm_get_error(hsm_ctx_t *gctx)
Definition: libhsm.c:3227
hsm_key_t * hsm_find_key_by_id(hsm_ctx_t *ctx, const char *id)
Definition: libhsm.c:2340
int cmd_generate(int argc, char *argv[])
Definition: hsmutil.c:181
hsm_key_info_t * hsm_get_key_info(hsm_ctx_t *ctx, const hsm_key_t *key)
Definition: libhsm.c:2753
void hsm_sign_params_free(hsm_sign_params_t *params)
Definition: libhsm.c:2253
int cmd_list(int argc, char *argv[])
Definition: hsmutil.c:97
int main(int argc, char *argv[])
Definition: hsmutil.c:427
int hsm_test(hsm_ctx_t *ctx, const char *repository)
Definition: hsmtest.c:109
ldns_rdf * owner
Definition: libhsmdns.h:47
int cmd_remove(int argc, char *argv[])
Definition: hsmutil.c:235
void hsm_key_list_free(hsm_key_t **key_list, size_t count)
Definition: libhsm.c:2712
unsigned int verbose
Definition: hsmutil.c:42
ldns_rr * hsm_get_dnskey(hsm_ctx_t *ctx, const hsm_key_t *key, const hsm_sign_params_t *sign_params)
Definition: libhsm.c:3033
void hsm_destroy_context(hsm_ctx_t *ctx)
Definition: libhsm.c:2227
void hsm_print_tokeninfo(hsm_ctx_t *ctx)
Definition: libhsm.c:3315
int hsm_open(const char *config, char *(pin_callback)(unsigned int, const char *, unsigned int))
Definition: libhsm.c:1994
hsm_key_t ** hsm_list_keys(hsm_ctx_t *ctx, size_t *count)
Definition: libhsm.c:2262
const char * modulename
Definition: libhsm.h:101
void hsm_key_info_free(hsm_key_info_t *key_info)
Definition: libhsm.c:2799
int cmd_test(int argc, char *argv[])
Definition: hsmutil.c:392
int hsm_token_attached(hsm_ctx_t *ctx, const char *repository)
Definition: libhsm.c:3187
uint16_t keytag
Definition: libhsmdns.h:45
hsm_sign_params_t * hsm_sign_params_new()
Definition: libhsm.c:2236
void hsm_print_key(hsm_ctx_t *ctx, hsm_key_t *key)
Definition: libhsm.c:3279
ldns_algorithm algorithm
Definition: libhsmdns.h:37
int hsm_logout_pin()
Definition: pin.c:413
char * algorithm_name
Definition: libhsm.h:110
int cmd_login()
Definition: hsmutil.c:75
hsm_ctx_t * ctx
Definition: hsmutil.c:43
int cmd_dnskey(int argc, char *argv[])
Definition: hsmutil.c:348
int hsm_remove_key(hsm_ctx_t *ctx, hsm_key_t *key)
Definition: libhsm.c:2675
hsm_ctx_t * hsm_create_context()
Definition: libhsm.c:2162
int cmd_logout()
Definition: hsmutil.c:83
ldns_algorithm algorithm
Definition: hsmspeed.c:41
hsm_key_t ** hsm_list_keys_repository(hsm_ctx_t *ctx, size_t *count, const char *repository)
Definition: libhsm.c:2294
#define HSM_OK
Definition: libhsm.h:62
void hsm_print_ctx(hsm_ctx_t *ctx)
Definition: libhsm.c:3268
void hsm_close()
Definition: libhsm.c:2153
unsigned long keysize
Definition: libhsm.h:111
char * id
Definition: libhsm.h:108
void usage()
Definition: hsmutil.c:54
void version()
Definition: hsmutil.c:47
hsm_key_t * hsm_generate_rsa_key(hsm_ctx_t *ctx, const char *repository, unsigned long keysize)
Definition: libhsm.c:2356
char * hsm_prompt_pin(unsigned int id, const char *repository, unsigned int mode)
Definition: pin.c:228
#define HSM_MAX_ALGONAME
Definition: libhsm.h:44
int cmd_debug(hsm_ctx_t *ctx)
Definition: hsmutil.c:419
void hsm_print_error(hsm_ctx_t *gctx)
Definition: libhsm.c:3300
char * optarg