OpenDNSSEC-libhsm  1.4.1
hsmutil.c
Go to the documentation of this file.
1 /*
2  * $Id: hsmutil.c 6704 2012-09-20 10:43:19Z rb $
3  *
4  * Copyright (c) 2009 .SE (The Internet Infrastructure Foundation).
5  * Copyright (c) 2009 NLNet Labs.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in the
15  * documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include "config.h"
31 #include "hsmtest.h"
32 
33 #include <stdio.h>
34 #include <string.h>
35 #include <stdlib.h>
36 #include <syslog.h>
37 #include <unistd.h>
38 
39 #include <libhsm.h>
40 #include <libhsmdns.h>
41 
42 
43 extern char *optarg;
44 char *progname = NULL;
45 unsigned int verbose = 0;
46 
47 
48 void
50 {
51  fprintf(stderr, "%s (%s) version %s\n",
52  progname, PACKAGE_NAME, PACKAGE_VERSION);
53 }
54 
55 void
57 {
58  fprintf(stderr,
59  "usage: %s [-c config] [-vV] command [options]\n",
60  progname);
61 
62  fprintf(stderr," login\n");
63  fprintf(stderr," logout\n");
64  fprintf(stderr," list [repository]\n");
65  fprintf(stderr," generate <repository> rsa <keysize>\n");
66  fprintf(stderr," remove <id>\n");
67  fprintf(stderr," purge <repository>\n");
68  fprintf(stderr," dnskey <id> <name>\n");
69  fprintf(stderr," test <repository>\n");
70  fprintf(stderr," info\n");
71 #if 0
72  fprintf(stderr," debug\n");
73 #endif
74 }
75 
76 int
78 {
79  printf("The tokens are now logged in.\n");
80 
81  return 0;
82 }
83 
84 int
86 {
87  if (hsm_logout_pin() != HSM_OK) {
88  printf("Failed to erase the credentials.\n");
89  hsm_print_error(NULL);
90  return 1;
91  }
92 
93  printf("The credentials has been erased.\n");
94 
95  return 0;
96 }
97 
98 int
99 cmd_list (int argc, char *argv[])
100 {
101  size_t i;
102  char *repository = NULL;
103 
104  size_t key_count = 0;
105  size_t key_count_valid = 0;
106  hsm_key_t **keys;
107  hsm_ctx_t *ctx = NULL;
108 
109  const char *key_info_format = "%-20s %-32s %-10s\n";
110 
111 
112  if (argc) {
113  repository = strdup(argv[0]);
114  argc--;
115  argv++;
116 
117  /* Check for repository before starting using it */
118  if (hsm_token_attached(ctx, repository) == 0) {
119  hsm_print_error(ctx);
120  return 1;
121  }
122 
123  fprintf(stderr, "Listing keys in repository: %s\n", repository);
124  keys = hsm_list_keys_repository(NULL, &key_count, repository);
125  } else {
126  fprintf(stderr, "Listing keys in all repositories.\n");
127  keys = hsm_list_keys(NULL, &key_count);
128  }
129 
130  fprintf(stderr, "%u %s found.\n\n", (unsigned int) key_count,
131  (key_count > 1 || key_count == 0 ? "keys" : "key"));
132 
133  if (!keys) {
134  return -1;
135  }
136 
137  /* print fancy header */
138  fprintf(stderr, key_info_format, "Repository", "ID", "Type");
139  fprintf(stderr, key_info_format, "----------", "--", "----");
140 
141  for (i = 0; i < key_count; i++) {
142  hsm_key_info_t *key_info;
143  hsm_key_t *key = NULL;
144  char key_type[HSM_MAX_ALGONAME + 8];
145  char *key_id = NULL;
146 
147  key = keys[i];
148  if (key == NULL) {
149  /* Skip NULL key for now */
150  continue;
151  }
152 
153  key_count_valid++;
154 
155  key_info = hsm_get_key_info(NULL, key);
156 
157  if (key_info) {
158  snprintf(key_type, sizeof(key_type), "%s/%lu",
159  key_info->algorithm_name, key_info->keysize);
160  key_id = key_info->id;
161  } else {
162  snprintf(key_type, sizeof(key_type), "UNKNOWN");
163  key_id = "UNKNOWN";
164  }
165 
166  printf(key_info_format, key->module->name, key_id, key_type);
167 
168  hsm_key_info_free(key_info);
169  }
170  hsm_key_list_free(keys, key_count);
171 
172  if (key_count != key_count_valid) {
173  size_t invalid_keys;
174  invalid_keys = key_count - key_count_valid;
175  printf("\n");
176  fprintf(stderr, "Warning: %u %s not usable by OpenDNSSEC was found.\n",
177  (unsigned int) invalid_keys, invalid_keys > 1 ? "keys" : "key");
178  }
179 
180  return 0;
181 }
182 
183 int
184 cmd_generate (int argc, char *argv[])
185 {
186  char *repository = NULL;
187  char *algorithm = NULL;
188  unsigned int keysize = 1024;
189 
190  hsm_key_t *key = NULL;
191  hsm_ctx_t *ctx = NULL;
192 
193  if (argc != 3) {
194  usage();
195  return -1;
196  }
197 
198  repository = strdup(argv[0]);
199 
200  /* Check for repository before starting using it */
201  if (hsm_token_attached(ctx, repository) == 0) {
202  hsm_print_error(ctx);
203  return 1;
204  }
205 
206 
207  algorithm = strdup(argv[1]);
208  keysize = atoi(argv[2]);
209 
210  if (!strcasecmp(algorithm, "rsa")) {
211  printf("Generating %d bit RSA key in repository: %s\n",
212  keysize, repository);
213 
214  key = hsm_generate_rsa_key(NULL, repository, keysize);
215 
216  if (key) {
217  hsm_key_info_t *key_info;
218 
219  key_info = hsm_get_key_info(NULL, key);
220  printf("Key generation successful: %s\n",
221  key_info ? key_info->id : "NULL");
222  hsm_key_info_free(key_info);
223  if (verbose) hsm_print_key(key);
224  hsm_key_free(key);
225  } else {
226  printf("Key generation failed.\n");
227  return -1;
228  }
229 
230  } else {
231  printf("Unknown algorithm: %s\n", algorithm);
232  return -1;
233  }
234 
235  return 0;
236 }
237 
238 int
239 cmd_remove (int argc, char *argv[])
240 {
241  char *id;
242  int result;
243 
244  hsm_key_t *key = NULL;
245 
246  if (argc != 1) {
247  usage();
248  return -1;
249  }
250 
251  id = strdup(argv[0]);
252 
253  key = hsm_find_key_by_id(NULL, id);
254 
255  if (!key) {
256  printf("Key not found: %s\n", id);
257  return -1;
258  }
259 
260  result = hsm_remove_key(NULL, key);
261 
262  if (!result) {
263  printf("Key remove successful.\n");
264  } else {
265  printf("Key remove failed.\n");
266  }
267 
268  hsm_key_free(key);
269 
270  return result;
271 }
272 
273 int
274 cmd_purge (int argc, char *argv[])
275 {
276  int result;
277  int final_result = 0;
278  char *fresult;
279 
280  size_t i;
281  char *repository = NULL;
282  char confirm[16];
283 
284  size_t key_count = 0;
285  hsm_key_t **keys;
286  hsm_ctx_t *ctx = NULL;
287 
288  if (argc != 1) {
289  usage();
290  return -1;
291  }
292 
293  repository = strdup(argv[0]);
294  argc--;
295  argv++;
296 
297  /* Check for repository before starting using it */
298  if (hsm_token_attached(ctx, repository) == 0) {
299  hsm_print_error(ctx);
300  return 1;
301  }
302 
303  printf("Purging all keys from repository: %s\n", repository);
304  keys = hsm_list_keys_repository(NULL, &key_count, repository);
305 
306  printf("%u %s found.\n\n", (unsigned int) key_count,
307  (key_count > 1 || key_count == 0 ? "keys" : "key"));
308 
309  if (!keys) {
310  return -1;
311  }
312 
313  if (key_count == 0) {
314  return -1;
315  }
316 
317  printf("Are you sure you want to remove ALL keys from repository %s ? (YES/NO) ", repository);
318  fresult = fgets(confirm, sizeof(confirm) - 1, stdin);
319  if (fresult == NULL || strncasecmp(confirm, "yes", 3) != 0) {
320  printf("\nPurge cancelled.\n");
321  hsm_key_list_free(keys, key_count);
322  return -1;
323  } else {
324  printf("\nStarting purge...\n");
325  }
326 
327  for (i = 0; i < key_count; i++) {
328  hsm_key_info_t *key_info;
329  hsm_key_t *key = keys[i];
330 
331  key_info = hsm_get_key_info(NULL, key);
332  result = hsm_remove_key(NULL, key);
333 
334  if (!result) {
335  printf("Key remove successful: %s\n",
336  key_info ? key_info->id : "NULL");
337  } else {
338  printf("Key remove failed: %s\n",
339  key_info ? key_info->id : "NULL");
340  final_result++;
341  }
342 
343  hsm_key_info_free(key_info);
344  }
345  hsm_key_list_free(keys, key_count);
346 
347  printf("Purge done.\n");
348 
349  return final_result;
350 }
351 
352 int
353 cmd_dnskey (int argc, char *argv[])
354 {
355  char *id;
356  char *name;
357 
358  hsm_key_t *key = NULL;
359  ldns_rr *dnskey_rr;
360  hsm_sign_params_t *sign_params;
361 
362  if (argc != 2) {
363  usage();
364  return -1;
365  }
366 
367  id = strdup(argv[0]);
368  name = strdup(argv[1]);
369 
370  key = hsm_find_key_by_id(NULL, id);
371 
372  if (!key) {
373  printf("Key not found: %s\n", id);
374  free(name);
375  free(id);
376  return -1;
377  }
378 
379  sign_params = hsm_sign_params_new();
380  sign_params->algorithm = LDNS_RSASHA1;
381  sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, name);
382  dnskey_rr = hsm_get_dnskey(NULL, key, sign_params);
383  sign_params->keytag = ldns_calc_keytag(dnskey_rr);
384 
385  ldns_rr_print(stdout, dnskey_rr);
386 
387  hsm_sign_params_free(sign_params);
388  ldns_rr_free(dnskey_rr);
389  hsm_key_free(key);
390  free(name);
391  free(id);
392 
393  return 0;
394 }
395 
396 int
397 cmd_test (int argc, char *argv[])
398 {
399  char *repository = NULL;
400 
401  if (argc) {
402  repository = strdup(argv[0]);
403  argc--;
404  argv++;
405 
406  printf("Testing repository: %s\n\n", repository);
407  return hsm_test(repository);
408  } else {
409  usage();
410  }
411 
412  return 0;
413 }
414 
415 int
417 {
418  hsm_print_tokeninfo(NULL);
419 
420  return 0;
421 }
422 
423 int
425 {
426  hsm_print_ctx(NULL);
427 
428  return 0;
429 }
430 
431 int
432 main (int argc, char *argv[])
433 {
434  int result;
435 
436  char *config = NULL;
437 
438  int ch;
439  progname = argv[0];
440 
441  while ((ch = getopt(argc, argv, "c:vVh")) != -1) {
442  switch (ch) {
443  case 'c':
444  config = strdup(optarg);
445  break;
446  case 'v':
447  verbose++;
448  break;
449  case 'V':
450  version();
451  exit(0);
452  break;
453  case 'h':
454  usage();
455  exit(0);
456  break;
457  default:
458  usage();
459  exit(1);
460  }
461  }
462  argc -= optind;
463  argv += optind;
464 
465  if (!argc) {
466  usage();
467  exit(1);
468  }
469 
470 
471  if (!strcasecmp(argv[0], "logout")) {
472  if (config) free(config);
473  exit(cmd_logout());
474  }
475 
476  result = hsm_open(config, hsm_prompt_pin);
477  if (result) {
478  hsm_print_error(NULL);
479  exit(-1);
480  }
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();
516  } else if (!strcasecmp(argv[0], "debug")) {
517  argc --;
518  argv ++;
519  result = cmd_debug();
520  } else {
521  usage();
522  result = -1;
523  }
524 
525  (void) hsm_close();
526  if (config) free(config);
527 
528  closelog();
529 
530  exit(result);
531 }