OpenDNSSEC-libhsm 1.2.1

/build/buildd-opendnssec_1.2.1.dfsg-1-mips-p9AT07/opendnssec-1.2.1.dfsg/libhsm/src/hsmutil.c

Go to the documentation of this file.
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 }