"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.11.23/bin/confgen/keygen.c" (7 Sep 2020, 5515 Bytes) of package /linux/misc/dns/bind9/9.11.23/bind-9.11.23.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "keygen.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 9.17.1_vs_9.17.2.

    1 /*
    2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
    3  *
    4  * This Source Code Form is subject to the terms of the Mozilla Public
    5  * License, v. 2.0. If a copy of the MPL was not distributed with this
    6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
    7  *
    8  * See the COPYRIGHT file distributed with this work for additional
    9  * information regarding copyright ownership.
   10  */
   11 
   12 
   13 /*! \file */
   14 
   15 #include <config.h>
   16 
   17 #include <stdlib.h>
   18 #include <stdarg.h>
   19 
   20 #include <isc/base64.h>
   21 #include <isc/buffer.h>
   22 #include <isc/entropy.h>
   23 #include <isc/file.h>
   24 #include <isc/keyboard.h>
   25 #include <isc/mem.h>
   26 #include <isc/print.h>
   27 #include <isc/result.h>
   28 #include <isc/string.h>
   29 
   30 #include <pk11/site.h>
   31 
   32 #include <dns/keyvalues.h>
   33 #include <dns/name.h>
   34 
   35 #include <dst/dst.h>
   36 #include <confgen/os.h>
   37 
   38 #include "util.h"
   39 #include "keygen.h"
   40 
   41 /*%
   42  * Convert algorithm type to string.
   43  */
   44 const char *
   45 alg_totext(dns_secalg_t alg) {
   46     switch (alg) {
   47 #ifndef PK11_MD5_DISABLE
   48         case DST_ALG_HMACMD5:
   49         return "hmac-md5";
   50 #endif
   51         case DST_ALG_HMACSHA1:
   52         return "hmac-sha1";
   53         case DST_ALG_HMACSHA224:
   54         return "hmac-sha224";
   55         case DST_ALG_HMACSHA256:
   56         return "hmac-sha256";
   57         case DST_ALG_HMACSHA384:
   58         return "hmac-sha384";
   59         case DST_ALG_HMACSHA512:
   60         return "hmac-sha512";
   61         default:
   62         return "(unknown)";
   63     }
   64 }
   65 
   66 /*%
   67  * Convert string to algorithm type.
   68  */
   69 dns_secalg_t
   70 alg_fromtext(const char *name) {
   71     const char *p = name;
   72     if (strncasecmp(p, "hmac-", 5) == 0)
   73         p = &name[5];
   74 
   75 #ifndef PK11_MD5_DISABLE
   76     if (strcasecmp(p, "md5") == 0)
   77         return DST_ALG_HMACMD5;
   78 #endif
   79     if (strcasecmp(p, "sha1") == 0)
   80         return DST_ALG_HMACSHA1;
   81     if (strcasecmp(p, "sha224") == 0)
   82         return DST_ALG_HMACSHA224;
   83     if (strcasecmp(p, "sha256") == 0)
   84         return DST_ALG_HMACSHA256;
   85     if (strcasecmp(p, "sha384") == 0)
   86         return DST_ALG_HMACSHA384;
   87     if (strcasecmp(p, "sha512") == 0)
   88         return DST_ALG_HMACSHA512;
   89     return DST_ALG_UNKNOWN;
   90 }
   91 
   92 /*%
   93  * Return default keysize for a given algorithm type.
   94  */
   95 int
   96 alg_bits(dns_secalg_t alg) {
   97     switch (alg) {
   98         case DST_ALG_HMACMD5:
   99         return 128;
  100         case DST_ALG_HMACSHA1:
  101         return 160;
  102         case DST_ALG_HMACSHA224:
  103         return 224;
  104         case DST_ALG_HMACSHA256:
  105         return 256;
  106         case DST_ALG_HMACSHA384:
  107         return 384;
  108         case DST_ALG_HMACSHA512:
  109         return 512;
  110         default:
  111         return 0;
  112     }
  113 }
  114 
  115 /*%
  116  * Generate a key of size 'keysize' using entropy source 'randomfile',
  117  * and place it in 'key_txtbuffer'
  118  */
  119 void
  120 generate_key(isc_mem_t *mctx, const char *randomfile, dns_secalg_t alg,
  121          int keysize, isc_buffer_t *key_txtbuffer) {
  122     isc_result_t result = ISC_R_SUCCESS;
  123     isc_entropysource_t *entropy_source = NULL;
  124     int open_keyboard = ISC_ENTROPY_KEYBOARDMAYBE;
  125     int entropy_flags = 0;
  126     isc_entropy_t *ectx = NULL;
  127     isc_buffer_t key_rawbuffer;
  128     isc_region_t key_rawregion;
  129     char key_rawsecret[64];
  130     dst_key_t *key = NULL;
  131 
  132     switch (alg) {
  133 #ifndef PK11_MD5_DISABLE
  134         case DST_ALG_HMACMD5:
  135 #endif
  136         case DST_ALG_HMACSHA1:
  137         case DST_ALG_HMACSHA224:
  138         case DST_ALG_HMACSHA256:
  139         if (keysize < 1 || keysize > 512)
  140             fatal("keysize %d out of range (must be 1-512)\n",
  141                   keysize);
  142         break;
  143         case DST_ALG_HMACSHA384:
  144         case DST_ALG_HMACSHA512:
  145         if (keysize < 1 || keysize > 1024)
  146             fatal("keysize %d out of range (must be 1-1024)\n",
  147                   keysize);
  148         break;
  149         default:
  150         fatal("unsupported algorithm %d\n", alg);
  151     }
  152 
  153 
  154     DO("create entropy context", isc_entropy_create(mctx, &ectx));
  155 
  156     if (randomfile != NULL && strcmp(randomfile, "keyboard") == 0) {
  157         randomfile = NULL;
  158         open_keyboard = ISC_ENTROPY_KEYBOARDYES;
  159     }
  160     DO("start entropy source", isc_entropy_usebestsource(ectx,
  161                                  &entropy_source,
  162                                  randomfile,
  163                                  open_keyboard));
  164 
  165     entropy_flags = ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY;
  166 
  167     DO("initialize dst library", dst_lib_init(mctx, ectx, entropy_flags));
  168 
  169     DO("generate key", dst_key_generate(dns_rootname, alg,
  170                         keysize, 0, 0,
  171                         DNS_KEYPROTO_ANY,
  172                         dns_rdataclass_in, mctx, &key));
  173 
  174     isc_buffer_init(&key_rawbuffer, &key_rawsecret, sizeof(key_rawsecret));
  175 
  176     DO("dump key to buffer", dst_key_tobuffer(key, &key_rawbuffer));
  177 
  178     isc_buffer_usedregion(&key_rawbuffer, &key_rawregion);
  179 
  180     DO("bsse64 encode secret", isc_base64_totext(&key_rawregion, -1, "",
  181                              key_txtbuffer));
  182 
  183     /*
  184      * Shut down the entropy source now so the "stop typing" message
  185      * does not muck with the output.
  186      */
  187     if (entropy_source != NULL)
  188         isc_entropy_destroysource(&entropy_source);
  189 
  190     if (key != NULL)
  191         dst_key_free(&key);
  192 
  193     isc_entropy_detach(&ectx);
  194     dst_lib_destroy();
  195 }
  196 
  197 /*%
  198  * Write a key file to 'keyfile'.  If 'user' is non-NULL,
  199  * make that user the owner of the file.  The key will have
  200  * the name 'keyname' and the secret in the buffer 'secret'.
  201  */
  202 void
  203 write_key_file(const char *keyfile, const char *user,
  204            const char *keyname, isc_buffer_t *secret,
  205            dns_secalg_t alg) {
  206     isc_result_t result;
  207     const char *algname = alg_totext(alg);
  208     FILE *fd = NULL;
  209 
  210     DO("create keyfile", isc_file_safecreate(keyfile, &fd));
  211 
  212     if (user != NULL) {
  213         if (set_user(fd, user) == -1)
  214             fatal("unable to set file owner\n");
  215     }
  216 
  217     fprintf(fd, "key \"%s\" {\n\talgorithm %s;\n"
  218         "\tsecret \"%.*s\";\n};\n",
  219         keyname, algname,
  220         (int)isc_buffer_usedlength(secret),
  221         (char *)isc_buffer_base(secret));
  222     fflush(fd);
  223     if (ferror(fd))
  224         fatal("write to %s failed\n", keyfile);
  225     if (fclose(fd))
  226         fatal("fclose(%s) failed\n", keyfile);
  227     fprintf(stderr, "wrote key file \"%s\"\n", keyfile);
  228 }