OpenDNSSEC-libhsm  1.3.9
hsmutil.c
Go to the documentation of this file.
1 /*
2  * $Id: hsmutil.c 6190 2012-02-28 15:29:48Z 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," 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
75 cmd_list (int argc, char *argv[])
76 {
77  size_t i;
78  char *repository = NULL;
79 
80  size_t key_count = 0;
81  size_t key_count_valid = 0;
82  hsm_key_t **keys;
83  hsm_ctx_t *ctx = NULL;
84 
85  const char *key_info_format = "%-20s %-32s %-10s\n";
86 
87 
88  if (argc) {
89  repository = strdup(argv[0]);
90  argc--;
91  argv++;
92 
93  /* Check for repository before starting using it */
94  if (hsm_token_attached(ctx, repository) == 0) {
95  hsm_print_error(ctx);
96  return 1;
97  }
98 
99  fprintf(stderr, "Listing keys in repository: %s\n", repository);
100  keys = hsm_list_keys_repository(NULL, &key_count, repository);
101  } else {
102  fprintf(stderr, "Listing keys in all repositories.\n");
103  keys = hsm_list_keys(NULL, &key_count);
104  }
105 
106  fprintf(stderr, "%u %s found.\n\n", (unsigned int) key_count,
107  (key_count > 1 || key_count == 0 ? "keys" : "key"));
108 
109  if (!keys) {
110  return -1;
111  }
112 
113  /* print fancy header */
114  fprintf(stderr, key_info_format, "Repository", "ID", "Type");
115  fprintf(stderr, key_info_format, "----------", "--", "----");
116 
117  for (i = 0; i < key_count; i++) {
118  hsm_key_info_t *key_info;
119  hsm_key_t *key = NULL;
120  char key_type[HSM_MAX_ALGONAME + 8];
121  char *key_id = NULL;
122 
123  key = keys[i];
124  if (key == NULL) {
125  /* Skip NULL key for now */
126  continue;
127  }
128 
129  key_count_valid++;
130 
131  key_info = hsm_get_key_info(NULL, key);
132 
133  if (key_info) {
134  snprintf(key_type, sizeof(key_type), "%s/%lu",
135  key_info->algorithm_name, key_info->keysize);
136  key_id = key_info->id;
137  } else {
138  snprintf(key_type, sizeof(key_type), "UNKNOWN");
139  key_id = "UNKNOWN";
140  }
141 
142  printf(key_info_format, key->module->name, key_id, key_type);
143 
144  hsm_key_info_free(key_info);
145  }
146  hsm_key_list_free(keys, key_count);
147 
148  if (key_count != key_count_valid) {
149  size_t invalid_keys;
150  invalid_keys = key_count - key_count_valid;
151  printf("\n");
152  fprintf(stderr, "Warning: %lu %s not usable by OpenDNSSEC was found.\n",
153  (unsigned long)invalid_keys, invalid_keys > 1 ? "keys" : "key");
154  }
155 
156  return 0;
157 }
158 
159 int
160 cmd_generate (int argc, char *argv[])
161 {
162  char *repository = NULL;
163  char *algorithm = NULL;
164  unsigned int keysize = 1024;
165 
166  hsm_key_t *key = NULL;
167  hsm_ctx_t *ctx = NULL;
168 
169  if (argc != 3) {
170  usage();
171  return -1;
172  }
173 
174  repository = strdup(argv[0]);
175 
176  /* Check for repository before starting using it */
177  if (hsm_token_attached(ctx, repository) == 0) {
178  hsm_print_error(ctx);
179  return 1;
180  }
181 
182 
183  algorithm = strdup(argv[1]);
184  keysize = atoi(argv[2]);
185 
186  if (!strcasecmp(algorithm, "rsa")) {
187  printf("Generating %d bit RSA key in repository: %s\n",
188  keysize, repository);
189 
190  key = hsm_generate_rsa_key(NULL, repository, keysize);
191 
192  if (key) {
193  hsm_key_info_t *key_info;
194 
195  key_info = hsm_get_key_info(NULL, key);
196  printf("Key generation successful: %s\n",
197  key_info ? key_info->id : "NULL");
198  hsm_key_info_free(key_info);
199  if (verbose) hsm_print_key(key);
200  hsm_key_free(key);
201  } else {
202  printf("Key generation failed.\n");
203  return -1;
204  }
205 
206  } else {
207  printf("Unknown algorithm: %s\n", algorithm);
208  return -1;
209  }
210 
211  return 0;
212 }
213 
214 int
215 cmd_remove (int argc, char *argv[])
216 {
217  char *id;
218  int result;
219 
220  hsm_key_t *key = NULL;
221 
222  if (argc != 1) {
223  usage();
224  return -1;
225  }
226 
227  id = strdup(argv[0]);
228 
229  key = hsm_find_key_by_id(NULL, id);
230 
231  if (!key) {
232  printf("Key not found: %s\n", id);
233  return -1;
234  }
235 
236  result = hsm_remove_key(NULL, key);
237 
238  if (!result) {
239  printf("Key remove successful.\n");
240  } else {
241  printf("Key remove failed.\n");
242  }
243 
244  hsm_key_free(key);
245 
246  return result;
247 }
248 
249 int
250 cmd_purge (int argc, char *argv[])
251 {
252  int result;
253  int final_result = 0;
254  char *fresult;
255 
256  size_t i;
257  char *repository = NULL;
258  char confirm[16];
259 
260  size_t key_count = 0;
261  hsm_key_t **keys;
262  hsm_ctx_t *ctx = NULL;
263 
264  if (argc != 1) {
265  usage();
266  return -1;
267  }
268 
269  repository = strdup(argv[0]);
270  argc--;
271  argv++;
272 
273  /* Check for repository before starting using it */
274  if (hsm_token_attached(ctx, repository) == 0) {
275  hsm_print_error(ctx);
276  return 1;
277  }
278 
279  printf("Purging all keys from repository: %s\n", repository);
280  keys = hsm_list_keys_repository(NULL, &key_count, repository);
281 
282  printf("%u %s found.\n\n", (unsigned int) key_count,
283  (key_count > 1 || key_count == 0 ? "keys" : "key"));
284 
285  if (!keys) {
286  return -1;
287  }
288 
289  if (key_count == 0) {
290  return -1;
291  }
292 
293  printf("Are you sure you want to remove ALL keys from repository %s ? (YES/NO) ", repository);
294  fresult = fgets(confirm, sizeof(confirm) - 1, stdin);
295  if (fresult == NULL || strncasecmp(confirm, "yes", 3) != 0) {
296  printf("\nPurge cancelled.\n");
297  hsm_key_list_free(keys, key_count);
298  return -1;
299  } else {
300  printf("\nStarting purge...\n");
301  }
302 
303  for (i = 0; i < key_count; i++) {
304  hsm_key_info_t *key_info;
305  hsm_key_t *key = keys[i];
306 
307  key_info = hsm_get_key_info(NULL, key);
308  result = hsm_remove_key(NULL, key);
309 
310  if (!result) {
311  printf("Key remove successful: %s\n",
312  key_info ? key_info->id : "NULL");
313  } else {
314  printf("Key remove failed: %s\n",
315  key_info ? key_info->id : "NULL");
316  final_result++;
317  }
318 
319  hsm_key_info_free(key_info);
320  }
321  hsm_key_list_free(keys, key_count);
322 
323  printf("Purge done.\n");
324 
325  return final_result;
326 }
327 
328 int
329 cmd_dnskey (int argc, char *argv[])
330 {
331  char *id;
332  char *name;
333 
334  hsm_key_t *key = NULL;
335  ldns_rr *dnskey_rr;
336  hsm_sign_params_t *sign_params;
337 
338  if (argc != 2) {
339  usage();
340  return -1;
341  }
342 
343  id = strdup(argv[0]);
344  name = strdup(argv[1]);
345 
346  key = hsm_find_key_by_id(NULL, id);
347 
348  if (!key) {
349  printf("Key not found: %s\n", id);
350  free(name);
351  free(id);
352  return -1;
353  }
354 
355  sign_params = hsm_sign_params_new();
356  sign_params->algorithm = LDNS_RSASHA1;
357  sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, name);
358  dnskey_rr = hsm_get_dnskey(NULL, key, sign_params);
359  sign_params->keytag = ldns_calc_keytag(dnskey_rr);
360 
361  ldns_rr_print(stdout, dnskey_rr);
362 
363  hsm_sign_params_free(sign_params);
364  ldns_rr_free(dnskey_rr);
365  hsm_key_free(key);
366  free(name);
367  free(id);
368 
369  return 0;
370 }
371 
372 int
373 cmd_test (int argc, char *argv[])
374 {
375  char *repository = NULL;
376 
377  if (argc) {
378  repository = strdup(argv[0]);
379  argc--;
380  argv++;
381 
382  printf("Testing repository: %s\n\n", repository);
383  return hsm_test(repository);
384  } else {
385  usage();
386  }
387 
388  return 0;
389 }
390 
391 int
393 {
394  hsm_print_tokeninfo(NULL);
395 
396  return 0;
397 }
398 
399 int
401 {
402  hsm_print_ctx(NULL);
403 
404  return 0;
405 }
406 
407 int
408 main (int argc, char *argv[])
409 {
410  int result;
411 
412  char *config = NULL;
413 
414  int ch;
415  progname = argv[0];
416 
417  while ((ch = getopt(argc, argv, "c:vVh")) != -1) {
418  switch (ch) {
419  case 'c':
420  config = strdup(optarg);
421  break;
422  case 'v':
423  verbose++;
424  break;
425  case 'V':
426  version();
427  exit(0);
428  break;
429  case 'h':
430  usage();
431  exit(0);
432  break;
433  default:
434  usage();
435  exit(1);
436  }
437  }
438  argc -= optind;
439  argv += optind;
440 
441  if (!argc) {
442  usage();
443  exit(1);
444  }
445 
446  result = hsm_open(config, hsm_prompt_pin, NULL);
447  if (result) {
448  hsm_print_error(NULL);
449  exit(-1);
450  }
451 
452  openlog("hsmutil", LOG_PID, LOG_USER);
453 
454  if (!strcasecmp(argv[0], "list")) {
455  argc --;
456  argv ++;
457  result = cmd_list(argc, argv);
458  } else if (!strcasecmp(argv[0], "generate")) {
459  argc --;
460  argv ++;
461  result = cmd_generate(argc, argv);
462  } else if (!strcasecmp(argv[0], "remove")) {
463  argc --;
464  argv ++;
465  result = cmd_remove(argc, argv);
466  } else if (!strcasecmp(argv[0], "purge")) {
467  argc --;
468  argv ++;
469  result = cmd_purge(argc, argv);
470  } else if (!strcasecmp(argv[0], "dnskey")) {
471  argc --;
472  argv ++;
473  result = cmd_dnskey(argc, argv);
474  } else if (!strcasecmp(argv[0], "test")) {
475  argc --;
476  argv ++;
477  result = cmd_test(argc, argv);
478  } else if (!strcasecmp(argv[0], "info")) {
479  argc --;
480  argv ++;
481  result = cmd_info();
482  } else if (!strcasecmp(argv[0], "debug")) {
483  argc --;
484  argv ++;
485  result = cmd_debug();
486  } else {
487  usage();
488  result = -1;
489  }
490 
491  (void) hsm_close();
492  if (config) free(config);
493 
494  closelog();
495 
496  exit(result);
497 }