diff --git a/CHANGES b/CHANGES index eb9ace7af3..159108b04d 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,10 @@ +2730. [func] Have dnssec-keygen display a progress indication + a la 'openssl genrsa' on standard error. Note + when the first '.' is followed by a long stop + one has the choice between slow generation vs. + poor random quality, i.e., '-r /dev/urandom'. + [RT #20284] + 2729. [func] When constructing a CNAME from a DNAME use the DNAME TTL. [RT #20451] diff --git a/bin/dnssec/dnssec-keygen.c b/bin/dnssec/dnssec-keygen.c index 0631af15b7..fb5782d110 100644 --- a/bin/dnssec/dnssec-keygen.c +++ b/bin/dnssec/dnssec-keygen.c @@ -29,7 +29,7 @@ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dnssec-keygen.c,v 1.103 2009/10/24 00:00:06 each Exp $ */ +/* $Id: dnssec-keygen.c,v 1.104 2009/10/24 09:46:18 fdupont Exp $ */ /*! \file */ @@ -74,6 +74,8 @@ dsa_size_ok(int size) { ISC_PLATFORM_NORETURN_PRE static void usage(void) ISC_PLATFORM_NORETURN_POST; +static void progress(int p); + static void usage(void) { fprintf(stderr, "Usage:\n"); @@ -157,6 +159,31 @@ usage(void) { exit (-1); } +static void +progress(int p) +{ + char c = '*'; + + switch (p) { + case 0: + c = '.'; + break; + case 1: + c = '+'; + break; + case 2: + c = '*'; + break; + case 3: + c = '\n'; + break; + default: + break; + } + (void) putc(c, stderr); + (void) fflush(stderr); +} + int main(int argc, char **argv) { char *algname = NULL, *nametype = NULL, *type = NULL; @@ -687,8 +714,9 @@ main(int argc, char **argv) { oldkey = NULL; /* generate the key */ - ret = dst_key_generate(name, alg, size, param, flags, protocol, - rdclass, mctx, &key); + ret = dst_key_generate2(name, alg, size, param, flags, + protocol, rdclass, mctx, &key, + &progress); isc_entropy_stopcallbacksources(ectx); if (ret != ISC_R_SUCCESS) { diff --git a/lib/dns/dst_api.c b/lib/dns/dst_api.c index 72f4fe670d..9a08ed5d79 100644 --- a/lib/dns/dst_api.c +++ b/lib/dns/dst_api.c @@ -31,7 +31,7 @@ /* * Principal Author: Brian Wellington - * $Id: dst_api.c,v 1.43 2009/10/22 02:21:30 each Exp $ + * $Id: dst_api.c,v 1.44 2009/10/24 09:46:18 fdupont Exp $ */ /*! \file */ @@ -752,6 +752,18 @@ dst_key_generate(dns_name_t *name, unsigned int alg, unsigned int flags, unsigned int protocol, dns_rdataclass_t rdclass, isc_mem_t *mctx, dst_key_t **keyp) +{ + return (dst_key_generate2(name, alg, bits, param, flags, protocol, + rdclass, mctx, keyp, NULL)); +} + +isc_result_t +dst_key_generate2(dns_name_t *name, unsigned int alg, + unsigned int bits, unsigned int param, + unsigned int flags, unsigned int protocol, + dns_rdataclass_t rdclass, + isc_mem_t *mctx, dst_key_t **keyp, + void (*callback)(int)) { dst_key_t *key; isc_result_t ret; @@ -778,7 +790,7 @@ dst_key_generate(dns_name_t *name, unsigned int alg, return (DST_R_UNSUPPORTEDALG); } - ret = key->func->generate(key, param); + ret = key->func->generate(key, param, callback); if (ret != ISC_R_SUCCESS) { dst_key_free(&key); return (ret); diff --git a/lib/dns/dst_internal.h b/lib/dns/dst_internal.h index c0c09a8aa2..19b0f8bf2c 100644 --- a/lib/dns/dst_internal.h +++ b/lib/dns/dst_internal.h @@ -29,7 +29,7 @@ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dst_internal.h,v 1.21 2009/10/22 02:21:30 each Exp $ */ +/* $Id: dst_internal.h,v 1.22 2009/10/24 09:46:19 fdupont Exp $ */ #ifndef DST_DST_INTERNAL_H #define DST_DST_INTERNAL_H 1 @@ -170,7 +170,8 @@ struct dst_func { isc_boolean_t (*compare)(const dst_key_t *key1, const dst_key_t *key2); isc_boolean_t (*paramcompare)(const dst_key_t *key1, const dst_key_t *key2); - isc_result_t (*generate)(dst_key_t *key, int parms); + isc_result_t (*generate)(dst_key_t *key, int parms, + void (*callback)(int)); isc_boolean_t (*isprivate)(const dst_key_t *key); void (*destroy)(dst_key_t *key); diff --git a/lib/dns/gssapi_link.c b/lib/dns/gssapi_link.c index 0dd27bbea3..edc2bf26ff 100644 --- a/lib/dns/gssapi_link.c +++ b/lib/dns/gssapi_link.c @@ -16,7 +16,7 @@ */ /* - * $Id: gssapi_link.c,v 1.12 2008/11/11 03:55:01 marka Exp $ + * $Id: gssapi_link.c,v 1.13 2009/10/24 09:46:19 fdupont Exp $ */ #include @@ -254,9 +254,10 @@ gssapi_compare(const dst_key_t *key1, const dst_key_t *key2) { } static isc_result_t -gssapi_generate(dst_key_t *key, int unused) { +gssapi_generate(dst_key_t *key, int unused, void (*callback)(int)) { UNUSED(key); UNUSED(unused); + UNUSED(callback); /* No idea */ return (ISC_R_FAILURE); @@ -292,7 +293,7 @@ static dst_func_t gssapi_functions = { NULL, /*%< tofile */ NULL, /*%< parse */ NULL, /*%< cleanup */ - NULL /*%< fromlabel */ + NULL, /*%< fromlabel */ }; isc_result_t diff --git a/lib/dns/hmac_link.c b/lib/dns/hmac_link.c index 24d836538c..70eb41bef9 100644 --- a/lib/dns/hmac_link.c +++ b/lib/dns/hmac_link.c @@ -31,7 +31,7 @@ /* * Principal Author: Brian Wellington - * $Id: hmac_link.c,v 1.14 2009/10/09 06:09:21 each Exp $ + * $Id: hmac_link.c,v 1.15 2009/10/24 09:46:19 fdupont Exp $ */ #include @@ -149,12 +149,14 @@ hmacmd5_compare(const dst_key_t *key1, const dst_key_t *key2) { } static isc_result_t -hmacmd5_generate(dst_key_t *key, int pseudorandom_ok) { +hmacmd5_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int)) { isc_buffer_t b; isc_result_t ret; int bytes; unsigned char data[HMAC_LEN]; + UNUSED(callback); + bytes = (key->key_size + 7) / 8; if (bytes > HMAC_LEN) { bytes = HMAC_LEN; @@ -420,12 +422,14 @@ hmacsha1_compare(const dst_key_t *key1, const dst_key_t *key2) { } static isc_result_t -hmacsha1_generate(dst_key_t *key, int pseudorandom_ok) { +hmacsha1_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int)) { isc_buffer_t b; isc_result_t ret; int bytes; unsigned char data[HMAC_LEN]; + UNUSED(callback); + bytes = (key->key_size + 7) / 8; if (bytes > HMAC_LEN) { bytes = HMAC_LEN; @@ -691,12 +695,16 @@ hmacsha224_compare(const dst_key_t *key1, const dst_key_t *key2) { } static isc_result_t -hmacsha224_generate(dst_key_t *key, int pseudorandom_ok) { +hmacsha224_generate(dst_key_t *key, int pseudorandom_ok, + void (*callback)(int)) +{ isc_buffer_t b; isc_result_t ret; int bytes; unsigned char data[HMAC_LEN]; + UNUSED(callback); + bytes = (key->key_size + 7) / 8; if (bytes > HMAC_LEN) { bytes = HMAC_LEN; @@ -962,12 +970,16 @@ hmacsha256_compare(const dst_key_t *key1, const dst_key_t *key2) { } static isc_result_t -hmacsha256_generate(dst_key_t *key, int pseudorandom_ok) { +hmacsha256_generate(dst_key_t *key, int pseudorandom_ok, + void (*callback)(int)) +{ isc_buffer_t b; isc_result_t ret; int bytes; unsigned char data[HMAC_LEN]; + UNUSED(callback); + bytes = (key->key_size + 7) / 8; if (bytes > HMAC_LEN) { bytes = HMAC_LEN; @@ -1233,12 +1245,16 @@ hmacsha384_compare(const dst_key_t *key1, const dst_key_t *key2) { } static isc_result_t -hmacsha384_generate(dst_key_t *key, int pseudorandom_ok) { +hmacsha384_generate(dst_key_t *key, int pseudorandom_ok, + void (*callback)(int)) +{ isc_buffer_t b; isc_result_t ret; int bytes; unsigned char data[HMAC_LEN]; + UNUSED(callback); + bytes = (key->key_size + 7) / 8; if (bytes > HMAC_LEN) { bytes = HMAC_LEN; @@ -1504,12 +1520,16 @@ hmacsha512_compare(const dst_key_t *key1, const dst_key_t *key2) { } static isc_result_t -hmacsha512_generate(dst_key_t *key, int pseudorandom_ok) { +hmacsha512_generate(dst_key_t *key, int pseudorandom_ok, + void (*callback)(int)) +{ isc_buffer_t b; isc_result_t ret; int bytes; unsigned char data[HMAC_LEN]; + UNUSED(callback); + bytes = (key->key_size + 7) / 8; if (bytes > HMAC_LEN) { bytes = HMAC_LEN; diff --git a/lib/dns/include/dst/dst.h b/lib/dns/include/dst/dst.h index fffd4b40d2..2217139e3d 100644 --- a/lib/dns/include/dst/dst.h +++ b/lib/dns/include/dst/dst.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dst.h,v 1.23 2009/10/22 02:21:31 each Exp $ */ +/* $Id: dst.h,v 1.24 2009/10/24 09:46:19 fdupont Exp $ */ #ifndef DST_DST_H #define DST_DST_H 1 @@ -479,6 +479,14 @@ dst_key_generate(dns_name_t *name, unsigned int alg, unsigned int flags, unsigned int protocol, dns_rdataclass_t rdclass, isc_mem_t *mctx, dst_key_t **keyp); + +isc_result_t +dst_key_generate2(dns_name_t *name, unsigned int alg, + unsigned int bits, unsigned int param, + unsigned int flags, unsigned int protocol, + dns_rdataclass_t rdclass, + isc_mem_t *mctx, dst_key_t **keyp, + void (*callback)(int)); /*%< * Generate a DST key (or keypair) with the supplied parameters. The * interpretation of the "param" field depends on the algorithm: diff --git a/lib/dns/openssldh_link.c b/lib/dns/openssldh_link.c index 43506d5555..8773cbf9c3 100644 --- a/lib/dns/openssldh_link.c +++ b/lib/dns/openssldh_link.c @@ -31,7 +31,7 @@ /* * Principal Author: Brian Wellington - * $Id: openssldh_link.c,v 1.16 2009/09/03 23:48:13 tbox Exp $ + * $Id: openssldh_link.c,v 1.17 2009/10/24 09:46:19 fdupont Exp $ */ #ifdef OPENSSL @@ -149,12 +149,28 @@ openssldh_paramcompare(const dst_key_t *key1, const dst_key_t *key2) { return (ISC_TRUE); } +#if OPENSSL_VERSION_NUMBER > 0x00908000L +static int +progress_cb(int p, int n, BN_GENCB *cb) +{ + void (*callback)(int) = cb->arg; + + UNUSED(n); + if (callback != NULL) + callback(p); + return (1); +} +#endif + static isc_result_t -openssldh_generate(dst_key_t *key, int generator) { +openssldh_generate(dst_key_t *key, int generator, void (*callback)(int)) { + DH *dh = NULL; #if OPENSSL_VERSION_NUMBER > 0x00908000L BN_GENCB cb; +#else + + UNUSED(callback); #endif - DH *dh = NULL; if (generator == 0) { if (key->key_size == 768 || @@ -181,7 +197,11 @@ openssldh_generate(dst_key_t *key, int generator) { if (dh == NULL) return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); - BN_GENCB_set_old(&cb, NULL, NULL); + if (callback == NULL) { + BN_GENCB_set_old(&cb, NULL, NULL); + } else { + BN_GENCB_set(&cb, &progress_cb, callback); + } if (!DH_generate_parameters_ex(dh, key->key_size, generator, &cb)) { diff --git a/lib/dns/openssldsa_link.c b/lib/dns/openssldsa_link.c index 3cad0f907a..e25b27e6ba 100644 --- a/lib/dns/openssldsa_link.c +++ b/lib/dns/openssldsa_link.c @@ -29,7 +29,7 @@ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: openssldsa_link.c,v 1.16 2009/09/03 04:09:58 marka Exp $ */ +/* $Id: openssldsa_link.c,v 1.17 2009/10/24 09:46:19 fdupont Exp $ */ #ifdef OPENSSL #ifndef USE_EVP @@ -313,15 +313,30 @@ openssldsa_compare(const dst_key_t *key1, const dst_key_t *key2) { return (ISC_TRUE); } -static isc_result_t -openssldsa_generate(dst_key_t *key, int unused) { #if OPENSSL_VERSION_NUMBER > 0x00908000L - BN_GENCB cb; +static int +progress_cb(int p, int n, BN_GENCB *cb) +{ + void (*callback)(int) = cb->arg; + + UNUSED(n); + if (callback != NULL) + callback(p); + return (1); +} #endif + +static isc_result_t +openssldsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { DSA *dsa; unsigned char rand_array[ISC_SHA1_DIGESTLENGTH]; isc_result_t result; +#if OPENSSL_VERSION_NUMBER > 0x00908000L + BN_GENCB cb; +#else + UNUSED(callback); +#endif UNUSED(unused); result = dst__entropy_getdata(rand_array, sizeof(rand_array), @@ -334,7 +349,11 @@ openssldsa_generate(dst_key_t *key, int unused) { if (dsa == NULL) return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); - BN_GENCB_set_old(&cb, NULL, NULL); + if (callback == NULL) { + BN_GENCB_set_old(&cb, NULL, NULL); + } else { + BN_GENCB_set(&cb, &progress_cb, callback); + } if (!DSA_generate_parameters_ex(dsa, key->key_size, rand_array, ISC_SHA1_DIGESTLENGTH, NULL, NULL, diff --git a/lib/dns/opensslrsa_link.c b/lib/dns/opensslrsa_link.c index 71c3fa90a5..68b0a84d8c 100644 --- a/lib/dns/opensslrsa_link.c +++ b/lib/dns/opensslrsa_link.c @@ -17,7 +17,7 @@ /* * Principal Author: Brian Wellington - * $Id: opensslrsa_link.c,v 1.32 2009/10/22 23:48:07 tbox Exp $ + * $Id: opensslrsa_link.c,v 1.33 2009/10/24 09:46:19 fdupont Exp $ */ #ifdef OPENSSL #ifndef USE_EVP @@ -653,8 +653,21 @@ opensslrsa_compare(const dst_key_t *key1, const dst_key_t *key2) { return (ISC_TRUE); } +#if OPENSSL_VERSION_NUMBER > 0x00908000L +static int +progress_cb(int p, int n, BN_GENCB *cb) +{ + void (*callback)(int) = cb->arg; + + UNUSED(n); + if (callback != NULL) + callback(p); + return (1); +} +#endif + static isc_result_t -opensslrsa_generate(dst_key_t *key, int exp) { +opensslrsa_generate(dst_key_t *key, int exp, void (*callback)(int)) { #if OPENSSL_VERSION_NUMBER > 0x00908000L BN_GENCB cb; RSA *rsa = RSA_new(); @@ -682,7 +695,11 @@ opensslrsa_generate(dst_key_t *key, int exp) { BN_set_bit(e, 32); } - BN_GENCB_set_old(&cb, NULL, NULL); + if (callback == NULL) { + BN_GENCB_set_old(&cb, NULL, NULL); + } else { + BN_GENCB_set(&cb, &progress_cb, callback); + } if (RSA_generate_key_ex(rsa, key->key_size, e, &cb)) { BN_free(e); @@ -713,8 +730,12 @@ err: #if USE_EVP EVP_PKEY *pkey = EVP_PKEY_new(); + UNUSED(callback); + if (pkey == NULL) return (ISC_R_NOMEMORY); +#else + UNUSED(callback); #endif if (exp == 0) diff --git a/lib/dns/win32/libdns.def b/lib/dns/win32/libdns.def index 657c72c662..f0c8522e01 100644 --- a/lib/dns/win32/libdns.def +++ b/lib/dns/win32/libdns.def @@ -881,6 +881,7 @@ dst_key_fromgssapi dst_key_fromlabel dst_key_fromnamedfile dst_key_generate +dst_key_generate2 dst_key_getprivateformat dst_key_gettime dst_key_id