dnssec-revoke.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2009-2012, 2014, 2015  Internet Systems Consortium, Inc. ("ISC")
00003  *
00004  * Permission to use, copy, modify, and/or distribute this software for any
00005  * purpose with or without fee is hereby granted, provided that the above
00006  * copyright notice and this permission notice appear in all copies.
00007  *
00008  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00009  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00010  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00011  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00012  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00013  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00014  * PERFORMANCE OF THIS SOFTWARE.
00015  */
00016 
00017 /*! \file */
00018 
00019 #include <config.h>
00020 
00021 #include <stdlib.h>
00022 #include <unistd.h>
00023 
00024 #include <isc/buffer.h>
00025 #include <isc/commandline.h>
00026 #include <isc/entropy.h>
00027 #include <isc/file.h>
00028 #include <isc/hash.h>
00029 #include <isc/mem.h>
00030 #include <isc/print.h>
00031 #include <isc/string.h>
00032 #include <isc/util.h>
00033 
00034 #include <dns/keyvalues.h>
00035 #include <dns/result.h>
00036 
00037 #include <dst/dst.h>
00038 
00039 #ifdef PKCS11CRYPTO
00040 #include <pk11/result.h>
00041 #endif
00042 
00043 #include "dnssectool.h"
00044 
00045 const char *program = "dnssec-revoke";
00046 int verbose;
00047 
00048 static isc_mem_t        *mctx = NULL;
00049 
00050 ISC_PLATFORM_NORETURN_PRE static void
00051 usage(void) ISC_PLATFORM_NORETURN_POST;
00052 
00053 static void
00054 usage(void) {
00055         fprintf(stderr, "Usage:\n");
00056         fprintf(stderr, "    %s [options] keyfile\n\n", program);
00057         fprintf(stderr, "Version: %s\n", VERSION);
00058 #if defined(PKCS11CRYPTO)
00059         fprintf(stderr, "    -E engine:    specify PKCS#11 provider "
00060                                         "(default: %s)\n", PK11_LIB_LOCATION);
00061 #elif defined(USE_PKCS11)
00062         fprintf(stderr, "    -E engine:    specify OpenSSL engine "
00063                                            "(default \"pkcs11\")\n");
00064 #else
00065         fprintf(stderr, "    -E engine:    specify OpenSSL engine\n");
00066 #endif
00067         fprintf(stderr, "    -f:           force overwrite\n");
00068         fprintf(stderr, "    -K directory: use directory for key files\n");
00069         fprintf(stderr, "    -h:           help\n");
00070         fprintf(stderr, "    -r:           remove old keyfiles after "
00071                                            "creating revoked version\n");
00072         fprintf(stderr, "    -v level:     set level of verbosity\n");
00073         fprintf(stderr, "    -V: print version information\n");
00074         fprintf(stderr, "Output:\n");
00075         fprintf(stderr, "     K<name>+<alg>+<new id>.key, "
00076                              "K<name>+<alg>+<new id>.private\n");
00077 
00078         exit (-1);
00079 }
00080 
00081 int
00082 main(int argc, char **argv) {
00083         isc_result_t result;
00084 #ifdef USE_PKCS11
00085         const char *engine = PKCS11_ENGINE;
00086 #else
00087         const char *engine = NULL;
00088 #endif
00089         char *filename = NULL, *dir = NULL;
00090         char newname[1024], oldname[1024];
00091         char keystr[DST_KEY_FORMATSIZE];
00092         char *endp;
00093         int ch;
00094         isc_entropy_t *ectx = NULL;
00095         dst_key_t *key = NULL;
00096         isc_uint32_t flags;
00097         isc_buffer_t buf;
00098         isc_boolean_t force = ISC_FALSE;
00099         isc_boolean_t removefile = ISC_FALSE;
00100         isc_boolean_t id = ISC_FALSE;
00101 
00102         if (argc == 1)
00103                 usage();
00104 
00105         result = isc_mem_create(0, 0, &mctx);
00106         if (result != ISC_R_SUCCESS)
00107                 fatal("Out of memory");
00108 
00109 #ifdef PKCS11CRYPTO
00110         pk11_result_register();
00111 #endif
00112         dns_result_register();
00113 
00114         isc_commandline_errprint = ISC_FALSE;
00115 
00116         while ((ch = isc_commandline_parse(argc, argv, "E:fK:rRhv:V")) != -1) {
00117                 switch (ch) {
00118                     case 'E':
00119                         engine = isc_commandline_argument;
00120                         break;
00121                     case 'f':
00122                         force = ISC_TRUE;
00123                         break;
00124                     case 'K':
00125                         /*
00126                          * We don't have to copy it here, but do it to
00127                          * simplify cleanup later
00128                          */
00129                         dir = isc_mem_strdup(mctx, isc_commandline_argument);
00130                         if (dir == NULL) {
00131                                 fatal("Failed to allocate memory for "
00132                                       "directory");
00133                         }
00134                         break;
00135                     case 'r':
00136                         removefile = ISC_TRUE;
00137                         break;
00138                     case 'R':
00139                         id = ISC_TRUE;
00140                         break;
00141                     case 'v':
00142                         verbose = strtol(isc_commandline_argument, &endp, 0);
00143                         if (*endp != '\0')
00144                                 fatal("-v must be followed by a number");
00145                         break;
00146                     case '?':
00147                         if (isc_commandline_option != '?')
00148                                 fprintf(stderr, "%s: invalid argument -%c\n",
00149                                         program, isc_commandline_option);
00150                         /* Falls into */
00151                     case 'h':
00152                         /* Does not return. */
00153                         usage();
00154 
00155                     case 'V':
00156                         /* Does not return. */
00157                         version(program);
00158 
00159                     default:
00160                         fprintf(stderr, "%s: unhandled option -%c\n",
00161                                 program, isc_commandline_option);
00162                         exit(1);
00163                 }
00164         }
00165 
00166         if (argc < isc_commandline_index + 1 ||
00167             argv[isc_commandline_index] == NULL)
00168                 fatal("The key file name was not specified");
00169         if (argc > isc_commandline_index + 1)
00170                 fatal("Extraneous arguments");
00171 
00172         if (dir != NULL) {
00173                 filename = argv[isc_commandline_index];
00174         } else {
00175                 result = isc_file_splitpath(mctx, argv[isc_commandline_index],
00176                                             &dir, &filename);
00177                 if (result != ISC_R_SUCCESS)
00178                         fatal("cannot process filename %s: %s",
00179                               argv[isc_commandline_index],
00180                               isc_result_totext(result));
00181                 if (strcmp(dir, ".") == 0) {
00182                         isc_mem_free(mctx, dir);
00183                         dir = NULL;
00184                 }
00185         }
00186 
00187         if (ectx == NULL)
00188                 setup_entropy(mctx, NULL, &ectx);
00189         result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
00190         if (result != ISC_R_SUCCESS)
00191                 fatal("Could not initialize hash");
00192         result = dst_lib_init2(mctx, ectx, engine,
00193                                ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY);
00194         if (result != ISC_R_SUCCESS)
00195                 fatal("Could not initialize dst: %s",
00196                       isc_result_totext(result));
00197         isc_entropy_stopcallbacksources(ectx);
00198 
00199         result = dst_key_fromnamedfile(filename, dir,
00200                                        DST_TYPE_PUBLIC|DST_TYPE_PRIVATE,
00201                                        mctx, &key);
00202         if (result != ISC_R_SUCCESS)
00203                 fatal("Invalid keyfile name %s: %s",
00204                       filename, isc_result_totext(result));
00205 
00206         if (id) {
00207                 fprintf(stdout, "%u\n", dst_key_rid(key));
00208                 goto cleanup;
00209         }
00210         dst_key_format(key, keystr, sizeof(keystr));
00211 
00212         if (verbose > 2)
00213                 fprintf(stderr, "%s: %s\n", program, keystr);
00214 
00215         if (force)
00216                 set_keyversion(key);
00217         else
00218                 check_keyversion(key, keystr);
00219 
00220 
00221         flags = dst_key_flags(key);
00222         if ((flags & DNS_KEYFLAG_REVOKE) == 0) {
00223                 isc_stdtime_t now;
00224 
00225                 if ((flags & DNS_KEYFLAG_KSK) == 0)
00226                         fprintf(stderr, "%s: warning: Key is not flagged "
00227                                         "as a KSK. Revoking a ZSK is "
00228                                         "legal, but undefined.\n",
00229                                         program);
00230 
00231                 isc_stdtime_get(&now);
00232                 dst_key_settime(key, DST_TIME_REVOKE, now);
00233 
00234                 dst_key_setflags(key, flags | DNS_KEYFLAG_REVOKE);
00235 
00236                 isc_buffer_init(&buf, newname, sizeof(newname));
00237                 dst_key_buildfilename(key, DST_TYPE_PUBLIC, dir, &buf);
00238 
00239                 if (access(newname, F_OK) == 0 && !force) {
00240                         fatal("Key file %s already exists; "
00241                               "use -f to force overwrite", newname);
00242                 }
00243 
00244                 result = dst_key_tofile(key, DST_TYPE_PUBLIC|DST_TYPE_PRIVATE,
00245                                         dir);
00246                 if (result != ISC_R_SUCCESS) {
00247                         dst_key_format(key, keystr, sizeof(keystr));
00248                         fatal("Failed to write key %s: %s", keystr,
00249                               isc_result_totext(result));
00250                 }
00251 
00252                 isc_buffer_clear(&buf);
00253                 dst_key_buildfilename(key, 0, dir, &buf);
00254                 printf("%s\n", newname);
00255 
00256                 /*
00257                  * Remove old key file, if told to (and if
00258                  * it isn't the same as the new file)
00259                  */
00260                 if (removefile && dst_key_alg(key) != DST_ALG_RSAMD5) {
00261                         isc_buffer_init(&buf, oldname, sizeof(oldname));
00262                         dst_key_setflags(key, flags & ~DNS_KEYFLAG_REVOKE);
00263                         dst_key_buildfilename(key, DST_TYPE_PRIVATE, dir, &buf);
00264                         if (strcmp(oldname, newname) == 0)
00265                                 goto cleanup;
00266                         (void)unlink(oldname);
00267                         isc_buffer_clear(&buf);
00268                         dst_key_buildfilename(key, DST_TYPE_PUBLIC, dir, &buf);
00269                         (void)unlink(oldname);
00270                 }
00271         } else {
00272                 dst_key_format(key, keystr, sizeof(keystr));
00273                 fatal("Key %s is already revoked", keystr);
00274         }
00275 
00276 cleanup:
00277         dst_key_free(&key);
00278         dst_lib_destroy();
00279         isc_hash_destroy();
00280         cleanup_entropy(&ectx);
00281         if (verbose > 10)
00282                 isc_mem_stats(mctx, stdout);
00283         if (dir != NULL)
00284                 isc_mem_free(mctx, dir);
00285         isc_mem_destroy(&mctx);
00286 
00287         return (0);
00288 }

Generated on Tue Apr 28 17:40:53 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha