From ff8d15be4e6096329fe6ae8217d0adcabd08c94b Mon Sep 17 00:00:00 2001 From: Olafur Gudmundsson Date: Wed, 10 May 2000 17:57:53 +0000 Subject: [PATCH] Fixed 3 bugs in keygen, it overwrote old keys if new key key-id conflicted It was generating non null-keys with id==0 It was not able to generate DSA null keys. I changed size of maximum RSA key to 2048. --- CHANGES | 6 +++ bin/dnssec/dnssec-keygen.c | 95 ++++++++++++++++++++++++---------- bin/tests/keygen.c | 95 ++++++++++++++++++++++++---------- lib/dns/sec/dnssafe/bigmaxes.h | 2 +- 4 files changed, 145 insertions(+), 53 deletions(-) diff --git a/CHANGES b/CHANGES index 9cea757b2d..46541b65a5 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ + 166. [bug] Keygen was overwriting existing keys if key_id conflicted, + now it will retry, and non-null keys with key_id == 0 + are not generated anymore. + Key was not able to generate NOAUTHCONF DSA key, + increased RSA key size to 2048 bits. + 165. [cleanup] Silence "end-of-loop condition not reached" warnings from Solaris compiler. diff --git a/bin/dnssec/dnssec-keygen.c b/bin/dnssec/dnssec-keygen.c index 160de9bf7d..b9e9dc8c89 100644 --- a/bin/dnssec/dnssec-keygen.c +++ b/bin/dnssec/dnssec-keygen.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (c) 1995-1999 by TISLabs at Network Associates, Inc. + * Portions Copyright (c) 1995-2000 by Network Associates, Inc. * * Permission to use, copy modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THE SOFTWARE. */ -/* $Id: dnssec-keygen.c,v 1.16 2000/05/08 20:12:41 tale Exp $ */ +/* $Id: dnssec-keygen.c,v 1.17 2000/05/10 17:57:53 ogud Exp $ */ #include @@ -37,15 +37,17 @@ static void die(char *str); static void usage(char *prog); static int verbose; +#define MAX_RSA 2048 /* XXX ogud update this when rsa library is updated */ int main(int argc, char **argv) { char *algname = NULL, *nametype = NULL, *type = NULL; char *prog, *endp; - dst_key_t *key; + dst_key_t *key, *old_keyp; char *name = NULL; isc_uint16_t flags = 0; dns_secalg_t alg; + isc_boolean_t conflict = ISC_FALSE, null_key = ISC_FALSE; isc_mem_t *mctx = NULL; int ch, rsa_exp = 0, generator = 0, param = 0; int protocol = -1, size = -1, signatory = 0; @@ -146,25 +148,28 @@ main(int argc, char **argv) { if (dst_supported_algorithm(alg) == ISC_FALSE) die("Unsupported algorithm"); - if (size < 0) - die("Must specify key size (-b option)"); - if (type != NULL) { if (strcasecmp(type, "NOAUTH") == 0) flags |= DNS_KEYTYPE_NOAUTH; else if (strcasecmp(type, "NOCONF") == 0) flags |= DNS_KEYTYPE_NOCONF; - else if (strcasecmp(type, "NOAUTHCONF") == 0) + else if (strcasecmp(type, "NOAUTHCONF") == 0) { flags |= (DNS_KEYTYPE_NOAUTH | DNS_KEYTYPE_NOCONF); + if (size < 0) + size = 0; + } else if (strcasecmp(type, "AUTHCONF") == 0) /* nothing */; else die("Invalid type"); } + if (size < 0) + die("Must specify key size (-b option)"); + switch (alg) { case DNS_KEYALG_RSA: - if (size != 0 && (size < 512 || size > 1024)) + if (size != 0 && (size < 512 || size > MAX_RSA)) die("RSA key size out of range"); break; case DNS_KEYALG_DH: @@ -172,7 +177,7 @@ main(int argc, char **argv) { die("DH key size out of range"); break; case DNS_KEYALG_DSA: - if (!dsa_size_ok(size)) + if (size != 0 && !dsa_size_ok(size)) die("Invalid DSS key size"); break; case DST_ALG_HMACMD5: @@ -239,23 +244,61 @@ main(int argc, char **argv) { } dst_result_register(); - ret = dst_key_generate(name, alg, size, param, flags, protocol, mctx, - &key); + do { + conflict = ISC_FALSE; - if (ret != ISC_R_SUCCESS) { - printf("Failed to generate key: %s\n", dst_result_totext(ret)); - exit(-1); + /* generate the key */ + ret = dst_key_generate(name, alg, size, param, flags, protocol, + mctx, &key); + + if (ret != ISC_R_SUCCESS) { + printf("Failed to generate key: %s\n", + dst_result_totext(ret)); + exit(-1); + } + + /* now try to read a key with same name, alg and id from file + * if there is one we must continue generating a new one + * unless we were asked to generate a null-key. + */ + if ((dst_key_flags(key) & DNS_KEYFLAG_TYPEMASK) ==DNS_KEYTYPE_NOKEY) + null_key = ISC_TRUE; + else if (dst_key_id(key) == 0) { + /* non null key can not have id == 0 */ + conflict = ISC_TRUE; + } + else { + + ret = dst_key_fromfile( name, dst_key_id(key), alg, + DST_TYPE_PRIVATE, mctx, &old_keyp); + /* we are not allowed to overwrite an existing key */ + if (ret == ISC_R_SUCCESS) { + + printf("Detected conflict %d\n", dst_key_id(key)); + if (ret == ISC_R_SUCCESS) + dst_key_free(old_keyp); + conflict = ISC_TRUE; + } + } + if (conflict == ISC_TRUE && null_key == ISC_FALSE) + /* non-null keys can not have id == 0 */ + dst_key_free(key); + + } while ((conflict == ISC_TRUE) && (null_key == ISC_FALSE)); + + + if (conflict == ISC_FALSE) { /* write file */ + ret = dst_key_tofile(key, DST_TYPE_PUBLIC | DST_TYPE_PRIVATE); + if (ret != ISC_R_SUCCESS) { + printf("Failed to write key %s(%d)\n", name, + dst_key_id(key)); + exit(-1); + } + + printf("Generated %d bit key %s: id=%d alg=%d flags=%d\n\n", + size, name, dst_key_id(key), dst_key_alg(key), + dst_key_flags(key)); } - - ret = dst_key_tofile(key, DST_TYPE_PUBLIC | DST_TYPE_PRIVATE); - if (ret != ISC_R_SUCCESS) { - printf("Failed to write key %s(%d)\n", name, dst_key_id(key)); - exit(-1); - } - - printf("Generated %d bit key %s: id=%d alg=%d flags=%d\n\n", size, - name, dst_key_id(key), dst_key_alg(key), dst_key_flags(key)); - isc_mem_free(mctx, name); isc_mem_free(mctx, algname); isc_mem_free(mctx, nametype); @@ -286,9 +329,9 @@ usage(char *prog) { printf("Required options:\n"); printf(" -a algorithm: RSA | RSAMD5 | DH | DSA | HMAC-MD5\n"); printf(" -b key size, in bits:\n"); - printf(" RSA:\t\t[512..1024]\n"); + printf(" RSA:\t\t[512..%d]\n", MAX_RSA); printf(" DH:\t\t[128..4096]\n"); - printf(" DSA:\t\t[512..1024] and a multiple of 64\n"); + printf(" DSA:\t\t[512..1024] and dividable by 64\n"); printf(" HMAC-MD5:\t[1..512]\n"); printf(" -n nametype: ZONE | HOST | ENTITY | USER\n"); printf(" name: owner of the key\n"); diff --git a/bin/tests/keygen.c b/bin/tests/keygen.c index d570724a13..5889c0e701 100644 --- a/bin/tests/keygen.c +++ b/bin/tests/keygen.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (c) 1995-1999 by TISLabs at Network Associates, Inc. + * Portions Copyright (c) 1995-2000 by Network Associates, Inc. * * Permission to use, copy modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THE SOFTWARE. */ -/* $Id: keygen.c,v 1.16 2000/05/08 20:12:41 tale Exp $ */ +/* $Id: keygen.c,v 1.17 2000/05/10 17:57:53 ogud Exp $ */ #include @@ -37,15 +37,17 @@ static void die(char *str); static void usage(char *prog); static int verbose; +#define MAX_RSA 2048 /* XXX ogud update this when rsa library is updated */ int main(int argc, char **argv) { char *algname = NULL, *nametype = NULL, *type = NULL; char *prog, *endp; - dst_key_t *key; + dst_key_t *key, *old_keyp; char *name = NULL; isc_uint16_t flags = 0; dns_secalg_t alg; + isc_boolean_t conflict = ISC_FALSE, null_key = ISC_FALSE; isc_mem_t *mctx = NULL; int ch, rsa_exp = 0, generator = 0, param = 0; int protocol = -1, size = -1, signatory = 0; @@ -146,25 +148,28 @@ main(int argc, char **argv) { if (dst_supported_algorithm(alg) == ISC_FALSE) die("Unsupported algorithm"); - if (size < 0) - die("Must specify key size (-b option)"); - if (type != NULL) { if (strcasecmp(type, "NOAUTH") == 0) flags |= DNS_KEYTYPE_NOAUTH; else if (strcasecmp(type, "NOCONF") == 0) flags |= DNS_KEYTYPE_NOCONF; - else if (strcasecmp(type, "NOAUTHCONF") == 0) + else if (strcasecmp(type, "NOAUTHCONF") == 0) { flags |= (DNS_KEYTYPE_NOAUTH | DNS_KEYTYPE_NOCONF); + if (size < 0) + size = 0; + } else if (strcasecmp(type, "AUTHCONF") == 0) /* nothing */; else die("Invalid type"); } + if (size < 0) + die("Must specify key size (-b option)"); + switch (alg) { case DNS_KEYALG_RSA: - if (size != 0 && (size < 512 || size > 1024)) + if (size != 0 && (size < 512 || size > MAX_RSA)) die("RSA key size out of range"); break; case DNS_KEYALG_DH: @@ -172,7 +177,7 @@ main(int argc, char **argv) { die("DH key size out of range"); break; case DNS_KEYALG_DSA: - if (!dsa_size_ok(size)) + if (size != 0 && !dsa_size_ok(size)) die("Invalid DSS key size"); break; case DST_ALG_HMACMD5: @@ -239,23 +244,61 @@ main(int argc, char **argv) { } dst_result_register(); - ret = dst_key_generate(name, alg, size, param, flags, protocol, mctx, - &key); + do { + conflict = ISC_FALSE; - if (ret != ISC_R_SUCCESS) { - printf("Failed to generate key: %s\n", dst_result_totext(ret)); - exit(-1); + /* generate the key */ + ret = dst_key_generate(name, alg, size, param, flags, protocol, + mctx, &key); + + if (ret != ISC_R_SUCCESS) { + printf("Failed to generate key: %s\n", + dst_result_totext(ret)); + exit(-1); + } + + /* now try to read a key with same name, alg and id from file + * if there is one we must continue generating a new one + * unless we were asked to generate a null-key. + */ + if ((dst_key_flags(key) & DNS_KEYFLAG_TYPEMASK) ==DNS_KEYTYPE_NOKEY) + null_key = ISC_TRUE; + else if (dst_key_id(key) == 0) { + /* non null key can not have id == 0 */ + conflict = ISC_TRUE; + } + else { + + ret = dst_key_fromfile( name, dst_key_id(key), alg, + DST_TYPE_PRIVATE, mctx, &old_keyp); + /* we are not allowed to overwrite an existing key */ + if (ret == ISC_R_SUCCESS) { + + printf("Detected conflict %d\n", dst_key_id(key)); + if (ret == ISC_R_SUCCESS) + dst_key_free(old_keyp); + conflict = ISC_TRUE; + } + } + if (conflict == ISC_TRUE && null_key == ISC_FALSE) + /* non-null keys can not have id == 0 */ + dst_key_free(key); + + } while ((conflict == ISC_TRUE) && (null_key == ISC_FALSE)); + + + if (conflict == ISC_FALSE) { /* write file */ + ret = dst_key_tofile(key, DST_TYPE_PUBLIC | DST_TYPE_PRIVATE); + if (ret != ISC_R_SUCCESS) { + printf("Failed to write key %s(%d)\n", name, + dst_key_id(key)); + exit(-1); + } + + printf("Generated %d bit key %s: id=%d alg=%d flags=%d\n\n", + size, name, dst_key_id(key), dst_key_alg(key), + dst_key_flags(key)); } - - ret = dst_key_tofile(key, DST_TYPE_PUBLIC | DST_TYPE_PRIVATE); - if (ret != ISC_R_SUCCESS) { - printf("Failed to write key %s(%d)\n", name, dst_key_id(key)); - exit(-1); - } - - printf("Generated %d bit key %s: id=%d alg=%d flags=%d\n\n", size, - name, dst_key_id(key), dst_key_alg(key), dst_key_flags(key)); - isc_mem_free(mctx, name); isc_mem_free(mctx, algname); isc_mem_free(mctx, nametype); @@ -286,9 +329,9 @@ usage(char *prog) { printf("Required options:\n"); printf(" -a algorithm: RSA | RSAMD5 | DH | DSA | HMAC-MD5\n"); printf(" -b key size, in bits:\n"); - printf(" RSA:\t\t[512..1024]\n"); + printf(" RSA:\t\t[512..%d]\n", MAX_RSA); printf(" DH:\t\t[128..4096]\n"); - printf(" DSA:\t\t[512..1024] and a multiple of 64\n"); + printf(" DSA:\t\t[512..1024] and dividable by 64\n"); printf(" HMAC-MD5:\t[1..512]\n"); printf(" -n nametype: ZONE | HOST | ENTITY | USER\n"); printf(" name: owner of the key\n"); diff --git a/lib/dns/sec/dnssafe/bigmaxes.h b/lib/dns/sec/dnssafe/bigmaxes.h index 9dbb3aed41..9f5ba820f7 100644 --- a/lib/dns/sec/dnssafe/bigmaxes.h +++ b/lib/dns/sec/dnssafe/bigmaxes.h @@ -13,7 +13,7 @@ extern "C" { #endif -#define MAX_RSA_MODULUS_BITS 1024 +#define MAX_RSA_MODULUS_BITS 2028 #define BITS_TO_LEN(modulusBits) (((modulusBits) + 7) / 8) #define RSA_PRIME_BITS(modulusBits) (((modulusBits) + 1) / 2)