OpenDNSSEC-libhsm 1.2.1
|
00001 /* 00002 * $Id: hsmutil.c 4294 2011-01-13 19:58:29Z jakob $ 00003 * 00004 * Copyright (c) 2009 .SE (The Internet Infrastructure Foundation). 00005 * Copyright (c) 2009 NLNet Labs. 00006 * All rights reserved. 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions 00010 * are met: 00011 * 1. Redistributions of source code must retain the above copyright 00012 * notice, this list of conditions and the following disclaimer. 00013 * 2. Redistributions in binary form must reproduce the above copyright 00014 * notice, this list of conditions and the following disclaimer in the 00015 * documentation and/or other materials provided with the distribution. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00018 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00019 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 00021 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00022 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00023 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00024 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 00025 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 00026 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 00027 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00028 */ 00029 00030 #include "config.h" 00031 #include "hsmtest.h" 00032 00033 #include <stdio.h> 00034 #include <string.h> 00035 #include <stdlib.h> 00036 #include <syslog.h> 00037 #include <unistd.h> 00038 00039 #include <libhsm.h> 00040 #include <libhsmdns.h> 00041 00042 00043 extern char *optarg; 00044 char *progname = NULL; 00045 unsigned int verbose = 0; 00046 00047 00048 void 00049 version () 00050 { 00051 fprintf(stderr, "%s (%s) version %s\n", 00052 progname, PACKAGE_NAME, PACKAGE_VERSION); 00053 } 00054 00055 void 00056 usage () 00057 { 00058 fprintf(stderr, 00059 "usage: %s [-c config] [-vV] command [options]\n", 00060 progname); 00061 00062 fprintf(stderr," list [repository]\n"); 00063 fprintf(stderr," generate <repository> rsa <keysize>\n"); 00064 fprintf(stderr," remove <id>\n"); 00065 fprintf(stderr," purge <repository>\n"); 00066 fprintf(stderr," dnskey <id> <name>\n"); 00067 fprintf(stderr," test <repository>\n"); 00068 fprintf(stderr," info\n"); 00069 #if 0 00070 fprintf(stderr," debug\n"); 00071 #endif 00072 } 00073 00074 int 00075 cmd_list (int argc, char *argv[]) 00076 { 00077 size_t i; 00078 char *repository = NULL; 00079 00080 size_t key_count = 0; 00081 size_t key_count_valid = 0; 00082 hsm_key_t **keys; 00083 hsm_ctx_t *ctx = NULL; 00084 00085 const char *key_info_format = "%-20s %-32s %-10s\n"; 00086 00087 00088 if (argc) { 00089 repository = strdup(argv[0]); 00090 argc--; 00091 argv++; 00092 00093 /* Check for repository before starting using it */ 00094 if (hsm_token_attached(ctx, repository) == 0) { 00095 hsm_print_error(ctx); 00096 return 1; 00097 } 00098 00099 fprintf(stderr, "Listing keys in repository: %s\n", repository); 00100 keys = hsm_list_keys_repository(NULL, &key_count, repository); 00101 } else { 00102 fprintf(stderr, "Listing keys in all repositories.\n"); 00103 keys = hsm_list_keys(NULL, &key_count); 00104 } 00105 00106 fprintf(stderr, "%u %s found.\n\n", (unsigned int) key_count, 00107 (key_count > 1 || key_count == 0 ? "keys" : "key")); 00108 00109 if (!keys) { 00110 return -1; 00111 } 00112 00113 /* print fancy header */ 00114 fprintf(stderr, key_info_format, "Repository", "ID", "Type"); 00115 fprintf(stderr, key_info_format, "----------", "--", "----"); 00116 00117 for (i = 0; i < key_count; i++) { 00118 hsm_key_info_t *key_info; 00119 hsm_key_t *key = NULL; 00120 char key_type[HSM_MAX_ALGONAME + 8]; 00121 char *key_id = NULL; 00122 00123 key = keys[i]; 00124 if (key == NULL) { 00125 /* Skip NULL key for now */ 00126 continue; 00127 } 00128 00129 key_count_valid++; 00130 00131 key_info = hsm_get_key_info(NULL, key); 00132 00133 if (key_info) { 00134 snprintf(key_type, sizeof(key_type), "%s/%lu", 00135 key_info->algorithm_name, key_info->keysize); 00136 key_id = key_info->id; 00137 } else { 00138 snprintf(key_type, sizeof(key_type), "UNKNOWN"); 00139 key_id = "UNKNOWN"; 00140 } 00141 00142 printf(key_info_format, key->module->name, key_id, key_type); 00143 00144 hsm_key_info_free(key_info); 00145 } 00146 hsm_key_list_free(keys, key_count); 00147 00148 if (key_count != key_count_valid) { 00149 size_t invalid_keys; 00150 invalid_keys = key_count - key_count_valid; 00151 printf("\n"); 00152 fprintf(stderr, "Warning: %u %s not usable by OpenDNSSEC was found.\n", 00153 invalid_keys, invalid_keys > 1 ? "keys" : "key"); 00154 } 00155 00156 return 0; 00157 } 00158 00159 int 00160 cmd_generate (int argc, char *argv[]) 00161 { 00162 char *repository = NULL; 00163 char *algorithm = NULL; 00164 unsigned int keysize = 1024; 00165 00166 hsm_key_t *key = NULL; 00167 hsm_ctx_t *ctx = NULL; 00168 00169 if (argc != 3) { 00170 usage(); 00171 return -1; 00172 } 00173 00174 repository = strdup(argv[0]); 00175 00176 /* Check for repository before starting using it */ 00177 if (hsm_token_attached(ctx, repository) == 0) { 00178 hsm_print_error(ctx); 00179 return 1; 00180 } 00181 00182 00183 algorithm = strdup(argv[1]); 00184 keysize = atoi(argv[2]); 00185 00186 if (!strcasecmp(algorithm, "rsa")) { 00187 printf("Generating %d bit RSA key in repository: %s\n", 00188 keysize, repository); 00189 00190 key = hsm_generate_rsa_key(NULL, repository, keysize); 00191 00192 if (key) { 00193 hsm_key_info_t *key_info; 00194 00195 key_info = hsm_get_key_info(NULL, key); 00196 printf("Key generation successful: %s\n", 00197 key_info ? key_info->id : "NULL"); 00198 hsm_key_info_free(key_info); 00199 if (verbose) hsm_print_key(key); 00200 hsm_key_free(key); 00201 } else { 00202 printf("Key generation failed.\n"); 00203 return -1; 00204 } 00205 00206 } else { 00207 printf("Unknown algorithm: %s\n", algorithm); 00208 return -1; 00209 } 00210 00211 return 0; 00212 } 00213 00214 int 00215 cmd_remove (int argc, char *argv[]) 00216 { 00217 char *id; 00218 int result; 00219 00220 hsm_key_t *key = NULL; 00221 00222 if (argc != 1) { 00223 usage(); 00224 return -1; 00225 } 00226 00227 id = strdup(argv[0]); 00228 00229 key = hsm_find_key_by_id(NULL, id); 00230 00231 if (!key) { 00232 printf("Key not found: %s\n", id); 00233 return -1; 00234 } 00235 00236 result = hsm_remove_key(NULL, key); 00237 00238 if (!result) { 00239 printf("Key remove successful.\n"); 00240 } else { 00241 printf("Key remove failed.\n"); 00242 } 00243 00244 hsm_key_free(key); 00245 00246 return result; 00247 } 00248 00249 int 00250 cmd_purge (int argc, char *argv[]) 00251 { 00252 int result; 00253 int final_result = 0; 00254 char *fresult; 00255 00256 size_t i; 00257 char *repository = NULL; 00258 char confirm[16]; 00259 00260 size_t key_count = 0; 00261 hsm_key_t **keys; 00262 hsm_ctx_t *ctx = NULL; 00263 00264 if (argc != 1) { 00265 usage(); 00266 return -1; 00267 } 00268 00269 repository = strdup(argv[0]); 00270 argc--; 00271 argv++; 00272 00273 /* Check for repository before starting using it */ 00274 if (hsm_token_attached(ctx, repository) == 0) { 00275 hsm_print_error(ctx); 00276 return 1; 00277 } 00278 00279 printf("Purging all keys from repository: %s\n", repository); 00280 keys = hsm_list_keys_repository(NULL, &key_count, repository); 00281 00282 printf("%u %s found.\n\n", (unsigned int) key_count, 00283 (key_count > 1 || key_count == 0 ? "keys" : "key")); 00284 00285 if (!keys) { 00286 return -1; 00287 } 00288 00289 if (key_count == 0) { 00290 return -1; 00291 } 00292 00293 printf("Are you sure you want to remove ALL keys from repository %s ? (YES/NO) ", repository); 00294 fresult = fgets(confirm, sizeof(confirm) - 1, stdin); 00295 if (fresult == NULL || strncasecmp(confirm, "yes", 3) != 0) { 00296 printf("\nPurge cancelled.\n"); 00297 hsm_key_list_free(keys, key_count); 00298 return -1; 00299 } else { 00300 printf("\nStarting purge...\n"); 00301 } 00302 00303 for (i = 0; i < key_count; i++) { 00304 hsm_key_info_t *key_info; 00305 hsm_key_t *key = keys[i]; 00306 00307 key_info = hsm_get_key_info(NULL, key); 00308 result = hsm_remove_key(NULL, key); 00309 00310 if (!result) { 00311 printf("Key remove successful: %s\n", 00312 key_info ? key_info->id : "NULL"); 00313 } else { 00314 printf("Key remove failed: %s\n", 00315 key_info ? key_info->id : "NULL"); 00316 final_result++; 00317 } 00318 00319 hsm_key_info_free(key_info); 00320 } 00321 hsm_key_list_free(keys, key_count); 00322 00323 printf("Purge done.\n"); 00324 00325 return final_result; 00326 } 00327 00328 int 00329 cmd_dnskey (int argc, char *argv[]) 00330 { 00331 char *id; 00332 char *name; 00333 00334 hsm_key_t *key = NULL; 00335 ldns_rr *dnskey_rr; 00336 hsm_sign_params_t *sign_params; 00337 00338 if (argc != 2) { 00339 usage(); 00340 return -1; 00341 } 00342 00343 id = strdup(argv[0]); 00344 name = strdup(argv[1]); 00345 00346 key = hsm_find_key_by_id(NULL, id); 00347 00348 if (!key) { 00349 printf("Key not found: %s\n", id); 00350 return -1; 00351 } 00352 00353 sign_params = hsm_sign_params_new(); 00354 sign_params->algorithm = LDNS_RSASHA1; 00355 sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, name); 00356 dnskey_rr = hsm_get_dnskey(NULL, key, sign_params); 00357 sign_params->keytag = ldns_calc_keytag(dnskey_rr); 00358 00359 ldns_rr_print(stdout, dnskey_rr); 00360 00361 hsm_sign_params_free(sign_params); 00362 ldns_rr_free(dnskey_rr); 00363 hsm_key_free(key); 00364 00365 return 0; 00366 } 00367 00368 int 00369 cmd_test (int argc, char *argv[]) 00370 { 00371 char *repository = NULL; 00372 00373 if (argc) { 00374 repository = strdup(argv[0]); 00375 argc--; 00376 argv++; 00377 00378 printf("Testing repository: %s\n\n", repository); 00379 return hsm_test(repository); 00380 } else { 00381 usage(); 00382 } 00383 00384 return 0; 00385 } 00386 00387 int 00388 cmd_info () 00389 { 00390 hsm_print_tokeninfo(NULL); 00391 00392 return 0; 00393 } 00394 00395 int 00396 cmd_debug () 00397 { 00398 hsm_print_ctx(NULL); 00399 00400 return 0; 00401 } 00402 00403 int 00404 main (int argc, char *argv[]) 00405 { 00406 int result; 00407 00408 char *config = NULL; 00409 00410 int ch; 00411 progname = argv[0]; 00412 00413 while ((ch = getopt(argc, argv, "c:vVh")) != -1) { 00414 switch (ch) { 00415 case 'c': 00416 config = strdup(optarg); 00417 break; 00418 case 'v': 00419 verbose++; 00420 break; 00421 case 'V': 00422 version(); 00423 exit(0); 00424 break; 00425 case 'h': 00426 usage(); 00427 exit(0); 00428 break; 00429 default: 00430 usage(); 00431 exit(1); 00432 } 00433 } 00434 argc -= optind; 00435 argv += optind; 00436 00437 if (!argc) { 00438 usage(); 00439 exit(1); 00440 } 00441 00442 result = hsm_open(config, hsm_prompt_pin, NULL); 00443 if (result) { 00444 hsm_print_error(NULL); 00445 exit(-1); 00446 } 00447 00448 openlog("hsmutil", LOG_PID, LOG_USER); 00449 00450 if (!strcasecmp(argv[0], "list")) { 00451 argc --; 00452 argv ++; 00453 result = cmd_list(argc, argv); 00454 } else if (!strcasecmp(argv[0], "generate")) { 00455 argc --; 00456 argv ++; 00457 result = cmd_generate(argc, argv); 00458 } else if (!strcasecmp(argv[0], "remove")) { 00459 argc --; 00460 argv ++; 00461 result = cmd_remove(argc, argv); 00462 } else if (!strcasecmp(argv[0], "purge")) { 00463 argc --; 00464 argv ++; 00465 result = cmd_purge(argc, argv); 00466 } else if (!strcasecmp(argv[0], "dnskey")) { 00467 argc --; 00468 argv ++; 00469 result = cmd_dnskey(argc, argv); 00470 } else if (!strcasecmp(argv[0], "test")) { 00471 argc --; 00472 argv ++; 00473 result = cmd_test(argc, argv); 00474 } else if (!strcasecmp(argv[0], "info")) { 00475 argc --; 00476 argv ++; 00477 result = cmd_info(); 00478 } else if (!strcasecmp(argv[0], "debug")) { 00479 argc --; 00480 argv ++; 00481 result = cmd_debug(); 00482 } else { 00483 usage(); 00484 result = -1; 00485 } 00486 00487 (void) hsm_close(); 00488 if (config) free(config); 00489 00490 closelog(); 00491 00492 exit(result); 00493 }