You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1396 lines
45 KiB
1396 lines
45 KiB
From 5f9236521f5add49669a97875b7d26cf35b28963 Mon Sep 17 00:00:00 2001 |
|
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com> |
|
Date: Fri, 22 Jun 2018 14:05:18 +0200 |
|
Subject: [PATCH 1/2] Squashed commit of the following: |
|
MIME-Version: 1.0 |
|
Content-Type: text/plain; charset=UTF-8 |
|
Content-Transfer-Encoding: 8bit |
|
|
|
commit 3fd542379fa381b54381e07d6625ce53f9f9b1f0 |
|
Author: Petr Menšík <pemensik@redhat.com> |
|
Date: Thu Jun 21 12:00:35 2018 +0200 |
|
|
|
Revert "4450. [port] Provide more nuanced HSM support which better matches" |
|
|
|
This reverts commit f3b4d031c1f714ff6e862670663aa5a18650951e. |
|
|
|
Revert PK11_MD5_DISABLED also from remaining files. Keep documentation |
|
changes. |
|
|
|
commit f90934f734796595135cdd7a5008555a615dfe8e |
|
Author: Petr Menšík <pemensik@redhat.com> |
|
Date: Wed Jun 20 19:31:19 2018 +0200 |
|
|
|
Fix rndc-confgen default algorithm, report true algorithm in usage. |
|
|
|
commit dd53212c12c6943a21a3c24d60995edd19e1d9f7 |
|
Author: Petr Menšík <pemensik@redhat.com> |
|
Date: Fri Feb 23 21:21:30 2018 +0100 |
|
|
|
Cleanup only if initialization was successful |
|
|
|
commit f163ea51c46bb22bf264a1ac983e2027e43845fa |
|
Author: Petr Menšík <pemensik@redhat.com> |
|
Date: Mon Feb 5 12:19:28 2018 +0100 |
|
|
|
Ensure dst backend is initialized first even before hmac algorithms. |
|
|
|
commit 58751b60bd39168b7c8f817ede70473842432081 |
|
Author: Petr Menšík <pemensik@redhat.com> |
|
Date: Mon Feb 5 12:17:54 2018 +0100 |
|
|
|
Skip initialization of MD5 based algorithms if not available. |
|
|
|
commit 0572b98430d3c80f4a0b0c592b1e3bf7fde9b768 |
|
Author: Petr Menšík <pemensik@redhat.com> |
|
Date: Mon Feb 5 10:21:27 2018 +0100 |
|
|
|
Change secalgs skipping to be more safe |
|
|
|
commit 994f497a032930fce1370d507a265fbb293c66f4 |
|
Author: Petr Menšík <pemensik@redhat.com> |
|
Date: Wed Jan 31 18:26:11 2018 +0100 |
|
|
|
Skip MD5 algorithm also in case of NULL name |
|
|
|
commit abd82fbd2507c4b8f20e1ade202fd66d224fd646 |
|
Author: Petr Menšík <pemensik@redhat.com> |
|
Date: Wed Jan 31 16:54:29 2018 +0100 |
|
|
|
Revert part of commit 1b5c641416eb6de7fc232fc89d31a40a4d439f3d related |
|
to SHA1. |
|
|
|
commit b3c832d53a14a0779f598869bb99685c8e4b2bc0 |
|
Author: Petr Menšík <pemensik@redhat.com> |
|
Date: Wed Jan 31 11:38:12 2018 +0100 |
|
|
|
Make MD5 behave like unknown algorithm in TSIG. |
|
|
|
commit a64a3d6962ee93d6f8699b29bd6507dba0c244ed |
|
Author: Petr Menšík <pemensik@redhat.com> |
|
Date: Tue Nov 28 20:14:37 2017 +0100 |
|
|
|
Select token with most supported functions, instead of demanding it must support all functions |
|
|
|
Initialize PKCS#11 always until successfully initialized |
|
|
|
commit db118c6368668099ea1b6e75860cc12e178afa3b |
|
Author: Petr Menšík <pemensik@redhat.com> |
|
Date: Mon Jan 22 16:17:44 2018 +0100 |
|
|
|
Handle MD5 unavailability from DST |
|
|
|
commit 8f8824dca2f5b4d5a3a176d31ac3ee612321c4e3 |
|
Author: Petr Menšík <pemensik@redhat.com> |
|
Date: Mon Jan 22 14:11:16 2018 +0100 |
|
|
|
Check runtime flag from library and applications, fail gracefully. |
|
|
|
commit bd431384af7dcde8827e670c8749517ad677a967 |
|
Author: Petr Menšík <pemensik@redhat.com> |
|
Date: Mon Jan 22 08:39:08 2018 +0100 |
|
|
|
Modify libraries to use isc_md5_available() if PK11_MD5_DISABLE is not |
|
defined. |
|
TODO: pk11.c should accept slot without MD5 support. |
|
|
|
commit 160b13979ef3d0e92d2dd52d0987a3ec979be6cf |
|
Author: Petr Menšík <pemensik@redhat.com> |
|
Date: Mon Jan 22 07:21:04 2018 +0100 |
|
|
|
Add runtime detection whether MD5 is useable. |
|
|
|
commit 23b27ce0f2ad496c331ae40349cc1074a1b11804 |
|
Author: Mark Andrews <marka@isc.org> |
|
Date: Fri Aug 19 08:25:54 2016 +1000 |
|
|
|
4450. [port] Provide more nuanced HSM support which better matches |
|
the specific PKCS11 providers capabilities. [RT #42458] |
|
|
|
(cherry picked from commit 8ee6f289d87851a5b898b24a64587f0e6bc225bc) |
|
|
|
Fix compiler warnings |
|
--- |
|
bin/confgen/keygen.c | 10 +++++- |
|
bin/confgen/rndc-confgen.c | 12 ++++--- |
|
bin/confgen/rndc-confgen.docbook | 3 +- |
|
bin/dig/dig.c | 5 ++- |
|
bin/dig/dig.docbook | 6 ++-- |
|
bin/dig/dighost.c | 14 ++++++-- |
|
bin/dnssec/dnssec-keyfromlabel.c | 9 +++++ |
|
bin/dnssec/dnssec-keygen.c | 19 +++++++++-- |
|
bin/named/config.c | 23 +++++++++++-- |
|
bin/nsupdate/nsupdate.c | 20 +++++++---- |
|
bin/nsupdate/nsupdate.docbook | 9 ++++- |
|
bin/rndc/rndc.c | 3 +- |
|
bin/tests/hashes/t_hashes.c | 20 ++++++----- |
|
lib/bind9/check.c | 8 +++++ |
|
lib/dns/dst_api.c | 23 +++++++++---- |
|
lib/dns/dst_internal.h | 3 +- |
|
lib/dns/dst_parse.c | 12 ++++++- |
|
lib/dns/hmac_link.c | 2 +- |
|
lib/dns/opensslrsa_link.c | 4 +++ |
|
lib/dns/pkcs11rsa_link.c | 25 ++++++++++++-- |
|
lib/dns/rcode.c | 19 +++++++++-- |
|
lib/dns/tests/tsig_test.c | 1 + |
|
lib/dns/tkey.c | 9 +++++ |
|
lib/dns/tsec.c | 8 ++++- |
|
lib/dns/tsig.c | 22 +++++------- |
|
lib/isc/include/isc/md5.h | 3 ++ |
|
lib/isc/md5.c | 59 ++++++++++++++++++++++++++++++++ |
|
lib/isc/pk11.c | 72 +++++++++++++++++++++++++++++++--------- |
|
lib/isccc/cc.c | 48 ++++++++++++++++----------- |
|
29 files changed, 373 insertions(+), 98 deletions(-) |
|
|
|
diff --git a/bin/confgen/keygen.c b/bin/confgen/keygen.c |
|
index d0cdafed36..4eb027e723 100644 |
|
--- a/bin/confgen/keygen.c |
|
+++ b/bin/confgen/keygen.c |
|
@@ -28,6 +28,7 @@ |
|
#include <isc/entropy.h> |
|
#include <isc/file.h> |
|
#include <isc/keyboard.h> |
|
+#include <isc/md5.h> |
|
#include <isc/mem.h> |
|
#include <isc/result.h> |
|
#include <isc/string.h> |
|
@@ -69,7 +70,7 @@ alg_totext(dns_secalg_t alg) { |
|
*/ |
|
dns_secalg_t |
|
alg_fromtext(const char *name) { |
|
- if (strcmp(name, "hmac-md5") == 0) |
|
+ if (strcmp(name, "hmac-md5") == 0 && isc_md5_available()) |
|
return DST_ALG_HMACMD5; |
|
if (strcmp(name, "hmac-sha1") == 0) |
|
return DST_ALG_HMACSHA1; |
|
@@ -126,6 +127,13 @@ generate_key(isc_mem_t *mctx, const char *randomfile, dns_secalg_t alg, |
|
|
|
switch (alg) { |
|
case DST_ALG_HMACMD5: |
|
+ if (isc_md5_available() == ISC_FALSE) { |
|
+ fatal("unsupported algorithm %d\n", alg); |
|
+ } else if (keysize < 1 || keysize > 512) { |
|
+ fatal("keysize %d out of range (must be 1-512)\n", |
|
+ keysize); |
|
+ } |
|
+ break; |
|
case DST_ALG_HMACSHA1: |
|
case DST_ALG_HMACSHA224: |
|
case DST_ALG_HMACSHA256: |
|
diff --git a/bin/confgen/rndc-confgen.c b/bin/confgen/rndc-confgen.c |
|
index 3fd54fe2bb..c48a38f094 100644 |
|
--- a/bin/confgen/rndc-confgen.c |
|
+++ b/bin/confgen/rndc-confgen.c |
|
@@ -41,6 +41,7 @@ |
|
#include <isc/file.h> |
|
#include <isc/keyboard.h> |
|
#include <isc/mem.h> |
|
+#include <isc/md5.h> |
|
#include <isc/net.h> |
|
#include <isc/print.h> |
|
#include <isc/result.h> |
|
@@ -66,7 +67,7 @@ const char *progname; |
|
|
|
isc_boolean_t verbose = ISC_FALSE; |
|
|
|
-const char *keyfile, *keydef; |
|
+const char *keyfile, *keydef, *algdef; |
|
|
|
ISC_PLATFORM_NORETURN_PRE static void |
|
usage(int status) ISC_PLATFORM_NORETURN_POST; |
|
@@ -79,7 +80,7 @@ Usage:\n\ |
|
%s [-a] [-b bits] [-c keyfile] [-k keyname] [-p port] [-r randomfile] \ |
|
[-s addr] [-t chrootdir] [-u user]\n\ |
|
-a: generate just the key clause and write it to keyfile (%s)\n\ |
|
- -A alg: algorithm (default hmac-md5)\n\ |
|
+ -A alg: algorithm (default %s)\n\ |
|
-b bits: from 1 through 512, default 256; total length of the secret\n\ |
|
-c keyfile: specify an alternate key file (requires -a)\n\ |
|
-k keyname: the name as it will be used in named.conf and rndc.conf\n\ |
|
@@ -88,7 +89,7 @@ Usage:\n\ |
|
-s addr: the address to which rndc should connect\n\ |
|
-t chrootdir: write a keyfile in chrootdir as well (requires -a)\n\ |
|
-u user: set the keyfile owner to \"user\" (requires -a)\n", |
|
- progname, keydef); |
|
+ progname, keydef, algdef); |
|
|
|
exit (status); |
|
} |
|
@@ -124,9 +125,12 @@ main(int argc, char **argv) { |
|
progname = program; |
|
|
|
keyname = DEFAULT_KEYNAME; |
|
- alg = DST_ALG_HMACMD5; |
|
serveraddr = DEFAULT_SERVER; |
|
port = DEFAULT_PORT; |
|
+ alg = DST_ALG_HMACSHA256; |
|
+ if (isc_md5_available()) |
|
+ alg = DST_ALG_HMACMD5; |
|
+ algdef = alg_totext(alg); |
|
|
|
isc_commandline_errprint = ISC_FALSE; |
|
|
|
diff --git a/bin/confgen/rndc-confgen.docbook b/bin/confgen/rndc-confgen.docbook |
|
index f367b94aae..add8d7357f 100644 |
|
--- a/bin/confgen/rndc-confgen.docbook |
|
+++ b/bin/confgen/rndc-confgen.docbook |
|
@@ -136,7 +136,8 @@ |
|
<para> |
|
Specifies the algorithm to use for the TSIG key. Available |
|
choices are: hmac-md5, hmac-sha1, hmac-sha224, hmac-sha256, |
|
- hmac-sha384 and hmac-sha512. The default is hmac-md5. |
|
+ hmac-sha384 and hmac-sha512. The default is hmac-md5 or |
|
+ if MD5 was disabled hmac-sha256. |
|
</para> |
|
</listitem> |
|
</varlistentry> |
|
diff --git a/bin/dig/dig.c b/bin/dig/dig.c |
|
index 634ccfbfbf..4db0e6430f 100644 |
|
--- a/bin/dig/dig.c |
|
+++ b/bin/dig/dig.c |
|
@@ -25,6 +25,7 @@ |
|
#include <ctype.h> |
|
|
|
#include <isc/app.h> |
|
+#include <isc/md5.h> |
|
#include <isc/netaddr.h> |
|
#include <isc/parseint.h> |
|
#include <isc/print.h> |
|
@@ -1426,7 +1427,9 @@ dash_option(char *option, char *next, dig_lookup_t **lookup, |
|
ptr = ptr2; |
|
ptr2 = ptr3; |
|
} else { |
|
- hmacname = DNS_TSIG_HMACMD5_NAME; |
|
+ hmacname = DNS_TSIG_HMACSHA256_NAME; |
|
+ if (isc_md5_available()) |
|
+ hmacname = DNS_TSIG_HMACMD5_NAME; |
|
digestbits = 0; |
|
} |
|
strncpy(keynametext, ptr, sizeof(keynametext)); |
|
diff --git a/bin/dig/dig.docbook b/bin/dig/dig.docbook |
|
index 028f0fcd73..6ee5bd90bc 100644 |
|
--- a/bin/dig/dig.docbook |
|
+++ b/bin/dig/dig.docbook |
|
@@ -309,9 +309,11 @@ |
|
responses using transaction signatures (TSIG), specify a TSIG key file |
|
using the <option>-k</option> option. You can also specify the TSIG |
|
key itself on the command line using the <option>-y</option> option; |
|
- <parameter>hmac</parameter> is the type of the TSIG, default HMAC-MD5, |
|
+ <parameter>hmac</parameter> is the type of the TSIG, |
|
<parameter>name</parameter> is the name of the TSIG key and |
|
- <parameter>key</parameter> is the actual key. The key is a |
|
+ <parameter>key</parameter> is the actual key. If <parameter>hmac</parameter> |
|
+ is not specified, the default is <literal>hmac-md5</literal> |
|
+ or if MD5 was disabled <literal>hmac-sha256</literal>. The key is a |
|
base-64 |
|
encoded string, typically generated by |
|
<citerefentry> |
|
diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c |
|
index 3a066c68c9..3998a81a5d 100644 |
|
--- a/bin/dig/dighost.c |
|
+++ b/bin/dig/dighost.c |
|
@@ -81,6 +81,7 @@ |
|
#include <isc/file.h> |
|
#include <isc/lang.h> |
|
#include <isc/log.h> |
|
+#include <isc/md5.h> |
|
#include <isc/netaddr.h> |
|
#ifdef DIG_SIGCHASE |
|
#include <isc/netdb.h> |
|
@@ -1025,9 +1026,10 @@ parse_hmac(const char *hmac) { |
|
|
|
digestbits = 0; |
|
|
|
- if (strcasecmp(buf, "hmac-md5") == 0) { |
|
+ if (strcasecmp(buf, "hmac-md5") == 0 && isc_md5_available()) { |
|
hmacname = DNS_TSIG_HMACMD5_NAME; |
|
- } else if (strncasecmp(buf, "hmac-md5-", 9) == 0) { |
|
+ } else if (strncasecmp(buf, "hmac-md5-", 9) == 0 && |
|
+ isc_md5_available()) { |
|
hmacname = DNS_TSIG_HMACMD5_NAME; |
|
digestbits = parse_bits(&buf[9], "digest-bits [0..128]", 128); |
|
} else if (strcasecmp(buf, "hmac-sha1") == 0) { |
|
@@ -1145,7 +1147,13 @@ setup_file_key(void) { |
|
|
|
switch (dst_key_alg(dstkey)) { |
|
case DST_ALG_HMACMD5: |
|
- hmacname = DNS_TSIG_HMACMD5_NAME; |
|
+ if (isc_md5_available()) { |
|
+ hmacname = DNS_TSIG_HMACMD5_NAME; |
|
+ } else { |
|
+ printf(";; Couldn't create key %s: bad algorithm\n", |
|
+ keynametext); |
|
+ goto failure; |
|
+ } |
|
break; |
|
case DST_ALG_HMACSHA1: |
|
hmacname = DNS_TSIG_HMACSHA1_NAME; |
|
diff --git a/bin/dnssec/dnssec-keyfromlabel.c b/bin/dnssec/dnssec-keyfromlabel.c |
|
index cc212e1ed1..a5854a1f4c 100644 |
|
--- a/bin/dnssec/dnssec-keyfromlabel.c |
|
+++ b/bin/dnssec/dnssec-keyfromlabel.c |
|
@@ -27,6 +27,7 @@ |
|
#include <isc/commandline.h> |
|
#include <isc/entropy.h> |
|
#include <isc/mem.h> |
|
+#include <isc/md5.h> |
|
#include <isc/region.h> |
|
#include <isc/print.h> |
|
#include <isc/string.h> |
|
@@ -379,6 +380,11 @@ main(int argc, char **argv) { |
|
if (freeit != NULL) |
|
free(freeit); |
|
return (1); |
|
+ } else if (strcasecmp(algname, "RSAMD5") == 0 && isc_md5_available() == ISC_FALSE) { |
|
+ fprintf(stderr, "The use of RSAMD5 was disabled\n"); |
|
+ if (freeit != NULL) |
|
+ free(freeit); |
|
+ return (1); |
|
} else { |
|
r.base = algname; |
|
r.length = strlen(algname); |
|
@@ -412,6 +418,9 @@ main(int argc, char **argv) { |
|
fatal("invalid type %s", type); |
|
} |
|
|
|
+ if (alg == DST_ALG_RSAMD5 && isc_md5_available() == ISC_FALSE) |
|
+ fatal("Key uses disabled RSAMD5"); |
|
+ |
|
if (nametype == NULL) { |
|
if ((options & DST_TYPE_KEY) != 0) /* KEY */ |
|
fatal("no nametype specified"); |
|
diff --git a/bin/dnssec/dnssec-keygen.c b/bin/dnssec/dnssec-keygen.c |
|
index 97b96ee1dc..c147bb4e6c 100644 |
|
--- a/bin/dnssec/dnssec-keygen.c |
|
+++ b/bin/dnssec/dnssec-keygen.c |
|
@@ -42,6 +42,7 @@ |
|
#include <isc/buffer.h> |
|
#include <isc/commandline.h> |
|
#include <isc/entropy.h> |
|
+#include <isc/md5.h> |
|
#include <isc/mem.h> |
|
#include <isc/region.h> |
|
#include <isc/string.h> |
|
@@ -548,9 +549,21 @@ main(int argc, char **argv) { |
|
"\"-a RSAMD5\"\n"); |
|
INSIST(freeit == NULL); |
|
return (1); |
|
- } else if (strcasecmp(algname, "HMAC-MD5") == 0) |
|
- alg = DST_ALG_HMACMD5; |
|
- else if (strcasecmp(algname, "HMAC-SHA1") == 0) |
|
+ } else if (strcasecmp(algname, "HMAC-MD5") == 0) { |
|
+ if (isc_md5_available()) { |
|
+ alg = DST_ALG_HMACMD5; |
|
+ } else { |
|
+ fprintf(stderr, |
|
+ "The use of HMAC-MD5 was disabled\n"); |
|
+ INSIST(freeit == NULL); |
|
+ return (1); |
|
+ } |
|
+ } else if (strcasecmp(algname, "RSAMD5") == 0 && |
|
+ isc_md5_available() == ISC_FALSE) { |
|
+ fprintf(stderr, "The use of RSAMD5 was disabled\n"); |
|
+ INSIST(freeit == NULL); |
|
+ return (1); |
|
+ } else if (strcasecmp(algname, "HMAC-SHA1") == 0) |
|
alg = DST_ALG_HMACSHA1; |
|
else if (strcasecmp(algname, "HMAC-SHA224") == 0) |
|
alg = DST_ALG_HMACSHA224; |
|
diff --git a/bin/named/config.c b/bin/named/config.c |
|
index 818ed3797a..22d8a85405 100644 |
|
--- a/bin/named/config.c |
|
+++ b/bin/named/config.c |
|
@@ -25,6 +25,7 @@ |
|
|
|
#include <isc/buffer.h> |
|
#include <isc/log.h> |
|
+#include <isc/md5.h> |
|
#include <isc/mem.h> |
|
#include <isc/parseint.h> |
|
#include <isc/region.h> |
|
@@ -828,6 +829,19 @@ ns_config_getkeyalgorithm(const char *str, dns_name_t **name, |
|
return (ns_config_getkeyalgorithm2(str, name, NULL, digestbits)); |
|
} |
|
|
|
+static inline int |
|
+algorithms_start() { |
|
+ if (isc_md5_available() == ISC_FALSE) { |
|
+ int i = 0; |
|
+ while (algorithms[i].str != NULL && |
|
+ algorithms[i].hmac == hmacmd5) { |
|
+ i++; |
|
+ } |
|
+ return i; |
|
+ } |
|
+ return 0; |
|
+} |
|
+ |
|
isc_result_t |
|
ns_config_getkeyalgorithm2(const char *str, dns_name_t **name, |
|
unsigned int *typep, isc_uint16_t *digestbits) |
|
@@ -837,7 +851,7 @@ ns_config_getkeyalgorithm2(const char *str, dns_name_t **name, |
|
isc_uint16_t bits; |
|
isc_result_t result; |
|
|
|
- for (i = 0; algorithms[i].str != NULL; i++) { |
|
+ for (i = algorithms_start(); algorithms[i].str != NULL; i++) { |
|
len = strlen(algorithms[i].str); |
|
if (strncasecmp(algorithms[i].str, str, len) == 0 && |
|
(str[len] == '\0' || |
|
@@ -859,7 +873,12 @@ ns_config_getkeyalgorithm2(const char *str, dns_name_t **name, |
|
|
|
if (name != NULL) { |
|
switch (algorithms[i].hmac) { |
|
- case hmacmd5: *name = dns_tsig_hmacmd5_name; break; |
|
+ case hmacmd5: |
|
+ if (isc_md5_available()) { |
|
+ *name = dns_tsig_hmacmd5_name; break; |
|
+ } else { |
|
+ return (ISC_R_NOTFOUND); |
|
+ } |
|
case hmacsha1: *name = dns_tsig_hmacsha1_name; break; |
|
case hmacsha224: *name = dns_tsig_hmacsha224_name; break; |
|
case hmacsha256: *name = dns_tsig_hmacsha256_name; break; |
|
diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c |
|
index 644e3d9fc0..336597a95d 100644 |
|
--- a/bin/nsupdate/nsupdate.c |
|
+++ b/bin/nsupdate/nsupdate.c |
|
@@ -37,6 +37,7 @@ |
|
#include <isc/hash.h> |
|
#include <isc/lex.h> |
|
#include <isc/log.h> |
|
+#include <isc/md5.h> |
|
#include <isc/mem.h> |
|
#include <isc/parseint.h> |
|
#include <isc/print.h> |
|
@@ -440,9 +441,10 @@ parse_hmac(dns_name_t **hmac, const char *hmacstr, size_t len) { |
|
strncpy(buf, hmacstr, len); |
|
buf[len] = 0; |
|
|
|
- if (strcasecmp(buf, "hmac-md5") == 0) { |
|
+ if (strcasecmp(buf, "hmac-md5") == 0 && isc_md5_available()) { |
|
*hmac = DNS_TSIG_HMACMD5_NAME; |
|
- } else if (strncasecmp(buf, "hmac-md5-", 9) == 0) { |
|
+ } else if (strncasecmp(buf, "hmac-md5-", 9) == 0 && |
|
+ isc_md5_available()) { |
|
*hmac = DNS_TSIG_HMACMD5_NAME; |
|
result = isc_parse_uint16(&digestbits, &buf[9], 10); |
|
if (result != ISC_R_SUCCESS || digestbits > 128) |
|
@@ -538,7 +540,9 @@ setup_keystr(void) { |
|
secretstr = n + 1; |
|
digestbits = parse_hmac(&hmacname, keystr, s - keystr); |
|
} else { |
|
- hmacname = DNS_TSIG_HMACMD5_NAME; |
|
+ hmacname = DNS_TSIG_HMACSHA256_NAME; |
|
+ if (isc_md5_available()) |
|
+ hmacname = DNS_TSIG_HMACMD5_NAME; |
|
name = keystr; |
|
n = s; |
|
} |
|
@@ -670,7 +674,8 @@ setup_keyfile(isc_mem_t *mctx, isc_log_t *lctx) { |
|
|
|
switch (dst_key_alg(dstkey)) { |
|
case DST_ALG_HMACMD5: |
|
- hmacname = DNS_TSIG_HMACMD5_NAME; |
|
+ if (isc_md5_available()) |
|
+ hmacname = DNS_TSIG_HMACMD5_NAME; |
|
break; |
|
case DST_ALG_HMACSHA1: |
|
hmacname = DNS_TSIG_HMACSHA1_NAME; |
|
@@ -1462,8 +1467,11 @@ evaluate_key(char *cmdline) { |
|
if (n != NULL) { |
|
digestbits = parse_hmac(&hmacname, namestr, n - namestr); |
|
namestr = n + 1; |
|
- } else |
|
- hmacname = DNS_TSIG_HMACMD5_NAME; |
|
+ } else { |
|
+ hmacname = DNS_TSIG_HMACSHA256_NAME; |
|
+ if (isc_md5_available()) |
|
+ hmacname = DNS_TSIG_HMACMD5_NAME; |
|
+ } |
|
|
|
isc_buffer_init(&b, namestr, strlen(namestr)); |
|
isc_buffer_add(&b, strlen(namestr)); |
|
diff --git a/bin/nsupdate/nsupdate.docbook b/bin/nsupdate/nsupdate.docbook |
|
index bbcc68110f..7d8e78f894 100644 |
|
--- a/bin/nsupdate/nsupdate.docbook |
|
+++ b/bin/nsupdate/nsupdate.docbook |
|
@@ -158,6 +158,9 @@ |
|
<optional><parameter>hmac:</parameter></optional><parameter>keyname:secret.</parameter> |
|
<parameter>keyname</parameter> is the name of the key, and |
|
<parameter>secret</parameter> is the base64 encoded shared secret. |
|
+ If <parameter>hmac</parameter> is not specified, |
|
+ the default is <literal>hmac-md5</literal> |
|
+ or if MD5 was disabled <literal>hmac-sha256</literal>. |
|
Use of the <option>-y</option> option is discouraged because the |
|
shared secret is supplied as a command line argument in clear text. |
|
This may be visible in the output from |
|
@@ -371,13 +374,17 @@ |
|
<varlistentry> |
|
<term> |
|
<command>key</command> |
|
- <arg choice="req">name</arg> |
|
+ <arg choice="opt" rep="norepeat">hmac:</arg><arg choice="req">name</arg> |
|
<arg choice="req">secret</arg> |
|
</term> |
|
<listitem> |
|
<para> |
|
Specifies that all updates are to be TSIG-signed using the |
|
<parameter>keyname</parameter> <parameter>keysecret</parameter> pair. |
|
+ If <parameter>hmac</parameter> is specified, then it sets the |
|
+ signing algorithm in use; the default is |
|
+ <literal>hmac-md5</literal> or if MD5 was disabled |
|
+ <literal>hmac-sha256</literal>. |
|
The <command>key</command> command |
|
overrides any key specified on the command line via |
|
<option>-y</option> or <option>-k</option>. |
|
diff --git a/bin/rndc/rndc.c b/bin/rndc/rndc.c |
|
index 81e629f15c..0fd192d3a5 100644 |
|
--- a/bin/rndc/rndc.c |
|
+++ b/bin/rndc/rndc.c |
|
@@ -33,6 +33,7 @@ |
|
#include <isc/file.h> |
|
#include <isc/log.h> |
|
#include <isc/net.h> |
|
+#include <isc/md5.h> |
|
#include <isc/mem.h> |
|
#include <isc/random.h> |
|
#include <isc/socket.h> |
|
@@ -607,7 +608,7 @@ parse_config(isc_mem_t *mctx, isc_log_t *log, const char *keyname, |
|
secretstr = cfg_obj_asstring(secretobj); |
|
algorithmstr = cfg_obj_asstring(algorithmobj); |
|
|
|
- if (strcasecmp(algorithmstr, "hmac-md5") == 0) |
|
+ if (strcasecmp(algorithmstr, "hmac-md5") == 0 && isc_md5_available()) |
|
algorithm = ISCCC_ALG_HMACMD5; |
|
else if (strcasecmp(algorithmstr, "hmac-sha1") == 0) |
|
algorithm = ISCCC_ALG_HMACSHA1; |
|
diff --git a/bin/tests/hashes/t_hashes.c b/bin/tests/hashes/t_hashes.c |
|
index 47d08c572d..965271ad67 100644 |
|
--- a/bin/tests/hashes/t_hashes.c |
|
+++ b/bin/tests/hashes/t_hashes.c |
|
@@ -353,8 +353,10 @@ t_hashes(IN *in, OUT *out_sha1, OUT *out_sha224, OUT *out_md5) |
|
t_hash("SHA1", (HASH_INIT)isc_sha1_init, (UPDATE)isc_sha1_update, |
|
(FINAL)isc_sha1_final, in, out_sha1); |
|
t_sha224(in, out_sha224); |
|
- t_hash("md5", (HASH_INIT)isc_md5_init, (UPDATE)isc_md5_update, |
|
- (FINAL)isc_md5_final, in, out_md5); |
|
+ if (isc_md5_available()) { |
|
+ t_hash("md5", (HASH_INIT)isc_md5_init, (UPDATE)isc_md5_update, |
|
+ (FINAL)isc_md5_final, in, out_md5); |
|
+ } |
|
} |
|
|
|
|
|
@@ -435,12 +437,14 @@ t1(void) |
|
t_hashes(&abc, &abc_sha1, &abc_sha224, &abc_md5); |
|
t_hashes(&abc_blah, &abc_blah_sha1, &abc_blah_sha224, &abc_blah_md5); |
|
|
|
- /* |
|
- * three HMAC-md5 examples from RFC 2104 |
|
- */ |
|
- t_md5hmac(&rfc2104_1, &rfc2104_1_hmac); |
|
- t_md5hmac(&rfc2104_2, &rfc2104_2_hmac); |
|
- t_md5hmac(&rfc2104_3, &rfc2104_3_hmac); |
|
+ if (isc_md5_available()) { |
|
+ /* |
|
+ * three HMAC-md5 examples from RFC 2104 |
|
+ */ |
|
+ t_md5hmac(&rfc2104_1, &rfc2104_1_hmac); |
|
+ t_md5hmac(&rfc2104_2, &rfc2104_2_hmac); |
|
+ t_md5hmac(&rfc2104_3, &rfc2104_3_hmac); |
|
+ } |
|
|
|
/* |
|
* four HMAC-SHA tests from RFC 4634 starting on page 86 |
|
diff --git a/lib/bind9/check.c b/lib/bind9/check.c |
|
index 5131b521f4..00c4b3e509 100644 |
|
--- a/lib/bind9/check.c |
|
+++ b/lib/bind9/check.c |
|
@@ -26,6 +26,7 @@ |
|
#include <isc/base64.h> |
|
#include <isc/buffer.h> |
|
#include <isc/log.h> |
|
+#include <isc/md5.h> |
|
#include <isc/mem.h> |
|
#include <isc/netaddr.h> |
|
#include <isc/parseint.h> |
|
@@ -1895,6 +1896,13 @@ bind9_check_key(const cfg_obj_t *key, isc_log_t *logctx) { |
|
} |
|
|
|
algorithm = cfg_obj_asstring(algobj); |
|
+ /* Skip hmac-md5* algorithms */ |
|
+ if (isc_md5_available() == ISC_FALSE && |
|
+ strncasecmp(algorithm, "hmac-md5", 8) == 0) { |
|
+ cfg_obj_log(algobj, logctx, ISC_LOG_ERROR, |
|
+ "disabled algorithm '%s'", algorithm); |
|
+ return (ISC_R_DISABLED); |
|
+ } |
|
for (i = 0; algorithms[i].name != NULL; i++) { |
|
len = strlen(algorithms[i].name); |
|
if (strncasecmp(algorithms[i].name, algorithm, len) == 0 && |
|
diff --git a/lib/dns/dst_api.c b/lib/dns/dst_api.c |
|
index e71f2026e5..e6375cf406 100644 |
|
--- a/lib/dns/dst_api.c |
|
+++ b/lib/dns/dst_api.c |
|
@@ -202,6 +202,12 @@ dst_lib_init2(isc_mem_t *mctx, isc_entropy_t *ectx, |
|
dst_result_register(); |
|
|
|
memset(dst_t_func, 0, sizeof(dst_t_func)); |
|
+ |
|
+#ifdef OPENSSL |
|
+ RETERR(dst__openssl_init(engine)); |
|
+#elif PKCS11CRYPTO |
|
+ RETERR(dst__pkcs11_init(mctx, engine)); |
|
+#endif |
|
RETERR(dst__hmacmd5_init(&dst_t_func[DST_ALG_HMACMD5])); |
|
RETERR(dst__hmacsha1_init(&dst_t_func[DST_ALG_HMACSHA1])); |
|
RETERR(dst__hmacsha224_init(&dst_t_func[DST_ALG_HMACSHA224])); |
|
@@ -209,7 +215,6 @@ dst_lib_init2(isc_mem_t *mctx, isc_entropy_t *ectx, |
|
RETERR(dst__hmacsha384_init(&dst_t_func[DST_ALG_HMACSHA384])); |
|
RETERR(dst__hmacsha512_init(&dst_t_func[DST_ALG_HMACSHA512])); |
|
#ifdef OPENSSL |
|
- RETERR(dst__openssl_init(engine)); |
|
RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSAMD5], |
|
DST_ALG_RSAMD5)); |
|
RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA1], |
|
@@ -233,12 +238,16 @@ dst_lib_init2(isc_mem_t *mctx, isc_entropy_t *ectx, |
|
RETERR(dst__opensslecdsa_init(&dst_t_func[DST_ALG_ECDSA384])); |
|
#endif |
|
#elif PKCS11CRYPTO |
|
- RETERR(dst__pkcs11_init(mctx, engine)); |
|
- RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_RSAMD5])); |
|
- RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_RSASHA1])); |
|
- RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_NSEC3RSASHA1])); |
|
- RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_RSASHA256])); |
|
- RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_RSASHA512])); |
|
+ RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_RSAMD5], |
|
+ DST_ALG_RSAMD5)); |
|
+ RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_RSASHA1], |
|
+ DST_ALG_RSASHA1)); |
|
+ RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_NSEC3RSASHA1], |
|
+ DST_ALG_NSEC3RSASHA1)); |
|
+ RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_RSASHA256], |
|
+ DST_ALG_RSASHA256)); |
|
+ RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_RSASHA512], |
|
+ DST_ALG_RSASHA512)); |
|
RETERR(dst__pkcs11dsa_init(&dst_t_func[DST_ALG_DSA])); |
|
RETERR(dst__pkcs11dsa_init(&dst_t_func[DST_ALG_NSEC3DSA])); |
|
RETERR(dst__pkcs11dh_init(&dst_t_func[DST_ALG_DH])); |
|
diff --git a/lib/dns/dst_internal.h b/lib/dns/dst_internal.h |
|
index b15135e634..66d322a278 100644 |
|
--- a/lib/dns/dst_internal.h |
|
+++ b/lib/dns/dst_internal.h |
|
@@ -232,7 +232,8 @@ isc_result_t dst__hmacsha384_init(struct dst_func **funcp); |
|
isc_result_t dst__hmacsha512_init(struct dst_func **funcp); |
|
isc_result_t dst__opensslrsa_init(struct dst_func **funcp, |
|
unsigned char algorithm); |
|
-isc_result_t dst__pkcs11rsa_init(struct dst_func **funcp); |
|
+isc_result_t dst__pkcs11rsa_init(struct dst_func **funcp, |
|
+ unsigned char algorithm); |
|
isc_result_t dst__openssldsa_init(struct dst_func **funcp); |
|
isc_result_t dst__pkcs11dsa_init(struct dst_func **funcp); |
|
isc_result_t dst__openssldh_init(struct dst_func **funcp); |
|
diff --git a/lib/dns/dst_parse.c b/lib/dns/dst_parse.c |
|
index ec622d9603..0e889cc740 100644 |
|
--- a/lib/dns/dst_parse.c |
|
+++ b/lib/dns/dst_parse.c |
|
@@ -40,6 +40,7 @@ |
|
#include <isc/dir.h> |
|
#include <isc/fsaccess.h> |
|
#include <isc/lex.h> |
|
+#include <isc/md5.h> |
|
#include <isc/mem.h> |
|
#include <isc/stdtime.h> |
|
#include <isc/string.h> |
|
@@ -353,6 +354,10 @@ check_data(const dst_private_t *priv, const unsigned int alg, |
|
/* XXXVIX this switch statement is too sparse to gen a jump table. */ |
|
switch (alg) { |
|
case DST_ALG_RSAMD5: |
|
+ if (isc_md5_available()) |
|
+ return (check_rsa(priv, external)); |
|
+ else |
|
+ return (DST_R_UNSUPPORTEDALG); |
|
case DST_ALG_RSASHA1: |
|
case DST_ALG_NSEC3RSASHA1: |
|
case DST_ALG_RSASHA256: |
|
@@ -369,7 +374,10 @@ check_data(const dst_private_t *priv, const unsigned int alg, |
|
case DST_ALG_ECDSA384: |
|
return (check_ecdsa(priv, external)); |
|
case DST_ALG_HMACMD5: |
|
- return (check_hmac_md5(priv, old)); |
|
+ if (isc_md5_available()) |
|
+ return (check_hmac_md5(priv, old)); |
|
+ else |
|
+ return (DST_R_UNSUPPORTEDALG); |
|
case DST_ALG_HMACSHA1: |
|
return (check_hmac_sha(priv, HMACSHA1_NTAGS, alg)); |
|
case DST_ALG_HMACSHA224: |
|
@@ -587,6 +595,8 @@ dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex, |
|
goto fail; |
|
} |
|
|
|
+ if (isc_md5_available() == ISC_FALSE && alg == DST_ALG_RSA) |
|
+ alg = DST_ALG_RSASHA1; |
|
check = check_data(priv, alg, ISC_TRUE, external); |
|
if (check < 0) { |
|
ret = DST_R_INVALIDPRIVATEKEY; |
|
diff --git a/lib/dns/hmac_link.c b/lib/dns/hmac_link.c |
|
index 3ac01a8c20..6b6801af1c 100644 |
|
--- a/lib/dns/hmac_link.c |
|
+++ b/lib/dns/hmac_link.c |
|
@@ -340,7 +340,7 @@ static dst_func_t hmacmd5_functions = { |
|
isc_result_t |
|
dst__hmacmd5_init(dst_func_t **funcp) { |
|
REQUIRE(funcp != NULL); |
|
- if (*funcp == NULL) |
|
+ if (*funcp == NULL && isc_md5_available()) |
|
*funcp = &hmacmd5_functions; |
|
return (ISC_R_SUCCESS); |
|
} |
|
diff --git a/lib/dns/opensslrsa_link.c b/lib/dns/opensslrsa_link.c |
|
index 53c6d4bdd9..08291af016 100644 |
|
--- a/lib/dns/opensslrsa_link.c |
|
+++ b/lib/dns/opensslrsa_link.c |
|
@@ -1484,6 +1484,10 @@ dst__opensslrsa_init(dst_func_t **funcp, unsigned char algorithm) { |
|
|
|
if (*funcp == NULL) { |
|
switch (algorithm) { |
|
+ case DST_ALG_RSAMD5: |
|
+ if (isc_md5_available()) |
|
+ *funcp = &opensslrsa_functions; |
|
+ break; |
|
case DST_ALG_RSASHA256: |
|
#if defined(HAVE_EVP_SHA256) || !USE_EVP |
|
*funcp = &opensslrsa_functions; |
|
diff --git a/lib/dns/pkcs11rsa_link.c b/lib/dns/pkcs11rsa_link.c |
|
index 010d4b64fc..6b556bcd11 100644 |
|
--- a/lib/dns/pkcs11rsa_link.c |
|
+++ b/lib/dns/pkcs11rsa_link.c |
|
@@ -89,6 +89,9 @@ pkcs11rsa_createctx_sign(dst_key_t *key, dst_context_t *dctx) { |
|
key->key_alg == DST_ALG_RSASHA256 || |
|
key->key_alg == DST_ALG_RSASHA512); |
|
|
|
+ if (key->key_alg == DST_ALG_RSAMD5 && isc_md5_available() == ISC_FALSE) |
|
+ return (ISC_R_FAILURE); |
|
+ |
|
rsa = key->keydata.pkey; |
|
|
|
pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, |
|
@@ -216,6 +219,8 @@ pkcs11rsa_createctx_sign(dst_key_t *key, dst_context_t *dctx) { |
|
|
|
switch (dctx->key->key_alg) { |
|
case DST_ALG_RSAMD5: |
|
+ if (isc_md5_available() == ISC_FALSE) |
|
+ return (ISC_R_FAILURE); |
|
mech.mechanism = CKM_MD5_RSA_PKCS; |
|
break; |
|
case DST_ALG_RSASHA1: |
|
@@ -297,6 +302,9 @@ pkcs11rsa_createctx_verify(dst_key_t *key, unsigned int maxbits, |
|
key->key_alg == DST_ALG_RSASHA256 || |
|
key->key_alg == DST_ALG_RSASHA512); |
|
|
|
+ if (key->key_alg == DST_ALG_RSAMD5 && isc_md5_available() == ISC_FALSE) |
|
+ return (ISC_R_FAILURE); |
|
+ |
|
rsa = key->keydata.pkey; |
|
|
|
pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, |
|
@@ -350,6 +358,8 @@ pkcs11rsa_createctx_verify(dst_key_t *key, unsigned int maxbits, |
|
|
|
switch (dctx->key->key_alg) { |
|
case DST_ALG_RSAMD5: |
|
+ if (isc_md5_available() == ISC_FALSE) |
|
+ return (ISC_R_FAILURE); |
|
mech.mechanism = CKM_MD5_RSA_PKCS; |
|
break; |
|
case DST_ALG_RSASHA1: |
|
@@ -1565,11 +1575,20 @@ static dst_func_t pkcs11rsa_functions = { |
|
}; |
|
|
|
isc_result_t |
|
-dst__pkcs11rsa_init(dst_func_t **funcp) { |
|
+dst__pkcs11rsa_init(dst_func_t **funcp, unsigned char algorithm) { |
|
REQUIRE(funcp != NULL); |
|
|
|
- if (*funcp == NULL) |
|
- *funcp = &pkcs11rsa_functions; |
|
+ if (*funcp == NULL) { |
|
+ switch (algorithm) { |
|
+ case DST_ALG_RSAMD5: |
|
+ if (isc_md5_available()) |
|
+ *funcp = &pkcs11rsa_functions; |
|
+ break; |
|
+ default: |
|
+ *funcp = &pkcs11rsa_functions; |
|
+ break; |
|
+ } |
|
+ } |
|
return (ISC_R_SUCCESS); |
|
} |
|
|
|
diff --git a/lib/dns/rcode.c b/lib/dns/rcode.c |
|
index 091b3c70fb..c1251225d5 100644 |
|
--- a/lib/dns/rcode.c |
|
+++ b/lib/dns/rcode.c |
|
@@ -21,6 +21,7 @@ |
|
#include <ctype.h> |
|
|
|
#include <isc/buffer.h> |
|
+#include <isc/md5.h> |
|
#include <isc/parseint.h> |
|
#include <isc/print.h> |
|
#include <isc/region.h> |
|
@@ -310,17 +311,31 @@ dns_cert_totext(dns_cert_t cert, isc_buffer_t *target) { |
|
return (dns_mnemonic_totext(cert, target, certs)); |
|
} |
|
|
|
+static inline struct tbl * |
|
+secalgs_tbl_start() { |
|
+ struct tbl *algs = secalgs; |
|
+ |
|
+ if (isc_md5_available() == ISC_FALSE) { |
|
+ while (algs->name != NULL && |
|
+ algs->value == DNS_KEYALG_RSAMD5) |
|
+ ++algs; |
|
+ } |
|
+ return algs; |
|
+} |
|
+ |
|
isc_result_t |
|
dns_secalg_fromtext(dns_secalg_t *secalgp, isc_textregion_t *source) { |
|
unsigned int value; |
|
- RETERR(dns_mnemonic_fromtext(&value, source, secalgs, 0xff)); |
|
+ |
|
+ RETERR(dns_mnemonic_fromtext(&value, source, |
|
+ secalgs_tbl_start(), 0xff)); |
|
*secalgp = value; |
|
return (ISC_R_SUCCESS); |
|
} |
|
|
|
isc_result_t |
|
dns_secalg_totext(dns_secalg_t secalg, isc_buffer_t *target) { |
|
- return (dns_mnemonic_totext(secalg, target, secalgs)); |
|
+ return (dns_mnemonic_totext(secalg, target, secalgs_tbl_start())); |
|
} |
|
|
|
void |
|
diff --git a/lib/dns/tests/tsig_test.c b/lib/dns/tests/tsig_test.c |
|
index 956e4a0469..c4b2f84837 100644 |
|
--- a/lib/dns/tests/tsig_test.c |
|
+++ b/lib/dns/tests/tsig_test.c |
|
@@ -10,6 +10,7 @@ |
|
|
|
#include <config.h> |
|
#include <atf-c.h> |
|
+#include <isc/md5.h> |
|
#include <isc/mem.h> |
|
|
|
#include <dns/rdatalist.h> |
|
diff --git a/lib/dns/tkey.c b/lib/dns/tkey.c |
|
index 7343b4c26f..59a78c8dca 100644 |
|
--- a/lib/dns/tkey.c |
|
+++ b/lib/dns/tkey.c |
|
@@ -230,6 +230,9 @@ compute_secret(isc_buffer_t *shared, isc_region_t *queryrandomness, |
|
unsigned char digests[32]; |
|
unsigned int i; |
|
|
|
+ if (isc_md5_available() == ISC_FALSE) |
|
+ return (ISC_R_NOTIMPLEMENTED); |
|
+ |
|
isc_buffer_usedregion(shared, &r); |
|
|
|
/* |
|
@@ -298,6 +301,12 @@ process_dhtkey(dns_message_t *msg, dns_name_t *signer, dns_name_t *name, |
|
return (DNS_R_REFUSED); |
|
} |
|
|
|
+ if (isc_md5_available() == ISC_FALSE) { |
|
+ tkey_log("process_dhtkey: MD5 was disabled"); |
|
+ tkeyout->error = dns_tsigerror_badalg; |
|
+ return (ISC_R_SUCCESS); |
|
+ } |
|
+ |
|
if (!dns_name_equal(&tkeyin->algorithm, DNS_TSIG_HMACMD5_NAME)) { |
|
tkey_log("process_dhtkey: algorithms other than " |
|
"hmac-md5 are not supported"); |
|
diff --git a/lib/dns/tsec.c b/lib/dns/tsec.c |
|
index bfa6195d0d..fad645668c 100644 |
|
--- a/lib/dns/tsec.c |
|
+++ b/lib/dns/tsec.c |
|
@@ -18,6 +18,7 @@ |
|
|
|
#include <config.h> |
|
|
|
+#include <isc/md5.h> |
|
#include <isc/mem.h> |
|
|
|
#include <dns/tsec.h> |
|
@@ -66,7 +67,12 @@ dns_tsec_create(isc_mem_t *mctx, dns_tsectype_t type, dst_key_t *key, |
|
case dns_tsectype_tsig: |
|
switch (dst_key_alg(key)) { |
|
case DST_ALG_HMACMD5: |
|
- algname = dns_tsig_hmacmd5_name; |
|
+ if (isc_md5_available()) { |
|
+ algname = dns_tsig_hmacmd5_name; |
|
+ } else { |
|
+ isc_mem_put(mctx, tsec, sizeof(*tsec)); |
|
+ return (DNS_R_BADALG); |
|
+ } |
|
break; |
|
case DST_ALG_HMACSHA1: |
|
algname = dns_tsig_hmacsha1_name; |
|
diff --git a/lib/dns/tsig.c b/lib/dns/tsig.c |
|
index 325c901f93..804ef821f0 100644 |
|
--- a/lib/dns/tsig.c |
|
+++ b/lib/dns/tsig.c |
|
@@ -24,6 +24,7 @@ |
|
|
|
#include <isc/buffer.h> |
|
#include <isc/mem.h> |
|
+#include <isc/md5.h> |
|
#include <isc/print.h> |
|
#include <isc/refcount.h> |
|
#include <isc/serial.h> |
|
@@ -316,7 +317,7 @@ dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm, |
|
goto cleanup_key; |
|
(void)dns_name_downcase(&tkey->name, &tkey->name, NULL); |
|
|
|
- if (dns_name_equal(algorithm, DNS_TSIG_HMACMD5_NAME)) { |
|
+ if (dns_name_equal(algorithm, DNS_TSIG_HMACMD5_NAME) && isc_md5_available()) { |
|
tkey->algorithm = DNS_TSIG_HMACMD5_NAME; |
|
if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACMD5) { |
|
ret = DNS_R_BADALG; |
|
@@ -539,7 +540,7 @@ destroyring(dns_tsig_keyring_t *ring) { |
|
|
|
static unsigned int |
|
dst_alg_fromname(dns_name_t *algorithm) { |
|
- if (dns_name_equal(algorithm, DNS_TSIG_HMACMD5_NAME)) { |
|
+ if (dns_name_equal(algorithm, DNS_TSIG_HMACMD5_NAME) && isc_md5_available()) { |
|
return (DST_ALG_HMACMD5); |
|
} else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA1_NAME)) { |
|
return (DST_ALG_HMACSHA1); |
|
@@ -724,7 +725,7 @@ dns_tsigkey_create(dns_name_t *name, dns_name_t *algorithm, |
|
if (length > 0) |
|
REQUIRE(secret != NULL); |
|
|
|
- if (dns_name_equal(algorithm, DNS_TSIG_HMACMD5_NAME)) { |
|
+ if (dns_name_equal(algorithm, DNS_TSIG_HMACMD5_NAME) && isc_md5_available()) { |
|
if (secret != NULL) { |
|
isc_buffer_t b; |
|
|
|
@@ -1322,7 +1323,8 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg, |
|
ret = dst_key_sigsize(key, &siglen); |
|
if (ret != ISC_R_SUCCESS) |
|
return (ret); |
|
- if (alg == DST_ALG_HMACMD5 || alg == DST_ALG_HMACSHA1 || |
|
+ if ((alg == DST_ALG_HMACMD5 && isc_md5_available()) || |
|
+ alg == DST_ALG_HMACSHA1 || |
|
alg == DST_ALG_HMACSHA224 || alg == DST_ALG_HMACSHA256 || |
|
alg == DST_ALG_HMACSHA384 || alg == DST_ALG_HMACSHA512) |
|
{ |
|
@@ -1484,9 +1486,7 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg, |
|
} |
|
|
|
if ( |
|
-#ifndef PK11_MD5_DISABLE |
|
- alg == DST_ALG_HMACMD5 || |
|
-#endif |
|
+ (alg == DST_ALG_HMACMD5 && isc_md5_available()) || |
|
alg == DST_ALG_HMACSHA1 || |
|
alg == DST_ALG_HMACSHA224 || alg == DST_ALG_HMACSHA256 || |
|
alg == DST_ALG_HMACSHA384 || alg == DST_ALG_HMACSHA512) |
|
@@ -1626,9 +1626,7 @@ tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) { |
|
if (ret != ISC_R_SUCCESS) |
|
goto cleanup_querystruct; |
|
if ( |
|
-#ifndef PK11_MD5_DISABLE |
|
- alg == DST_ALG_HMACMD5 || |
|
-#endif |
|
+ (alg == DST_ALG_HMACMD5 && isc_md5_available()) || |
|
alg == DST_ALG_HMACSHA1 || |
|
alg == DST_ALG_HMACSHA224 || |
|
alg == DST_ALG_HMACSHA256 || |
|
@@ -1801,9 +1799,7 @@ tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) { |
|
if (ret != ISC_R_SUCCESS) |
|
goto cleanup_context; |
|
if ( |
|
-#ifndef PK11_MD5_DISABLE |
|
- alg == DST_ALG_HMACMD5 || |
|
-#endif |
|
+ (alg == DST_ALG_HMACMD5 && isc_md5_available()) || |
|
alg == DST_ALG_HMACSHA1 || |
|
alg == DST_ALG_HMACSHA224 || |
|
alg == DST_ALG_HMACSHA256 || |
|
diff --git a/lib/isc/include/isc/md5.h b/lib/isc/include/isc/md5.h |
|
index a2e00b382a..d4c2b8ab48 100644 |
|
--- a/lib/isc/include/isc/md5.h |
|
+++ b/lib/isc/include/isc/md5.h |
|
@@ -83,6 +83,9 @@ isc_md5_update(isc_md5_t *ctx, const unsigned char *buf, unsigned int len); |
|
void |
|
isc_md5_final(isc_md5_t *ctx, unsigned char *digest); |
|
|
|
+isc_boolean_t |
|
+isc_md5_available(void); |
|
+ |
|
ISC_LANG_ENDDECLS |
|
|
|
#endif /* ISC_MD5_H */ |
|
diff --git a/lib/isc/md5.c b/lib/isc/md5.c |
|
index 2e3cf9a4a3..a5113df4b8 100644 |
|
--- a/lib/isc/md5.c |
|
+++ b/lib/isc/md5.c |
|
@@ -38,6 +38,7 @@ |
|
|
|
#include <isc/assertions.h> |
|
#include <isc/md5.h> |
|
+#include <isc/once.h> |
|
#include <isc/platform.h> |
|
#include <isc/string.h> |
|
#include <isc/types.h> |
|
@@ -51,6 +52,9 @@ |
|
|
|
#ifdef ISC_PLATFORM_OPENSSLHASH |
|
|
|
+static isc_once_t available_once = ISC_ONCE_INIT; |
|
+static isc_boolean_t available = ISC_FALSE; |
|
+ |
|
void |
|
isc_md5_init(isc_md5_t *ctx) { |
|
EVP_DigestInit(ctx, EVP_md5()); |
|
@@ -71,8 +75,33 @@ isc_md5_final(isc_md5_t *ctx, unsigned char *digest) { |
|
EVP_DigestFinal(ctx, digest, NULL); |
|
} |
|
|
|
+static void |
|
+do_detect_available() { |
|
+ isc_md5_t local; |
|
+ isc_md5_t *ctx = &local; |
|
+ unsigned char digest[ISC_MD5_DIGESTLENGTH]; |
|
+ |
|
+ ctx->ctx = EVP_MD_CTX_new(); |
|
+ RUNTIME_CHECK(ctx->ctx != NULL); |
|
+ available = ISC_TF(EVP_DigestInit(ctx->ctx, EVP_md5()) == 1); |
|
+ if (available) |
|
+ (void)EVP_DigestFinal(ctx->ctx, digest, NULL); |
|
+ EVP_MD_CTX_free(ctx->ctx); |
|
+ ctx->ctx = NULL; |
|
+} |
|
+ |
|
+isc_boolean_t |
|
+isc_md5_available() { |
|
+ RUNTIME_CHECK(isc_once_do(&available_once, do_detect_available) |
|
+ == ISC_R_SUCCESS); |
|
+ return available; |
|
+} |
|
+ |
|
#elif PKCS11CRYPTO |
|
|
|
+static isc_once_t available_once = ISC_ONCE_INIT; |
|
+static isc_boolean_t available = ISC_FALSE; |
|
+ |
|
void |
|
isc_md5_init(isc_md5_t *ctx) { |
|
CK_RV rv; |
|
@@ -115,6 +144,31 @@ isc_md5_final(isc_md5_t *ctx, unsigned char *digest) { |
|
pk11_return_session(ctx); |
|
} |
|
|
|
+static void |
|
+do_detect_available() { |
|
+ isc_md5_t local; |
|
+ isc_md5_t *ctx = &local; |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { CKM_MD5, NULL, 0 }; |
|
+ |
|
+ if (pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE, |
|
+ ISC_FALSE, NULL, 0) == ISC_R_SUCCESS) |
|
+ { |
|
+ rv = pkcs_C_DigestInit(ctx->session, &mech); |
|
+ isc_md5_invalidate(ctx); |
|
+ available = (ISC_TF(rv == CKR_OK)); |
|
+ } else { |
|
+ available = ISC_FALSE; |
|
+ } |
|
+} |
|
+ |
|
+isc_boolean_t |
|
+isc_md5_available() { |
|
+ RUNTIME_CHECK(isc_once_do(&available_once, do_detect_available) |
|
+ == ISC_R_SUCCESS); |
|
+ return available; |
|
+} |
|
+ |
|
#else |
|
|
|
static void |
|
@@ -324,4 +378,9 @@ isc_md5_final(isc_md5_t *ctx, unsigned char *digest) { |
|
memcpy(digest, ctx->buf, 16); |
|
memset(ctx, 0, sizeof(isc_md5_t)); /* In case it's sensitive */ |
|
} |
|
+ |
|
+isc_boolean_t |
|
+isc_md5_available() { |
|
+ return ISC_TRUE; |
|
+} |
|
#endif |
|
diff --git a/lib/isc/pk11.c b/lib/isc/pk11.c |
|
index de4479b7b0..6cce70f0cf 100644 |
|
--- a/lib/isc/pk11.c |
|
+++ b/lib/isc/pk11.c |
|
@@ -139,6 +139,8 @@ |
|
#define PK11_NO_LOGERR 1 |
|
#endif |
|
|
|
+LIBISC_EXTERNAL_DATA isc_boolean_t pk11_verbose_init = ISC_FALSE; |
|
+ |
|
static isc_once_t once = ISC_ONCE_INIT; |
|
static isc_mem_t *pk11_mctx = NULL; |
|
static isc_int32_t allocsize = 0; |
|
@@ -283,13 +285,12 @@ pk11_initialize(isc_mem_t *mctx, const char *engine) { |
|
LOCK(&alloclock); |
|
if ((mctx != NULL) && (pk11_mctx == NULL) && (allocsize == 0)) |
|
isc_mem_attach(mctx, &pk11_mctx); |
|
+ UNLOCK(&alloclock); |
|
+ |
|
+ LOCK(&sessionlock); |
|
if (initialized) { |
|
- UNLOCK(&alloclock); |
|
- return (ISC_R_SUCCESS); |
|
- } else { |
|
- LOCK(&sessionlock); |
|
- initialized = ISC_TRUE; |
|
- UNLOCK(&alloclock); |
|
+ result = ISC_R_SUCCESS; |
|
+ goto unlock; |
|
} |
|
|
|
ISC_LIST_INIT(tokens); |
|
@@ -327,6 +328,7 @@ pk11_initialize(isc_mem_t *mctx, const char *engine) { |
|
} |
|
#endif |
|
#endif /* PKCS11CRYPTO */ |
|
+ initialized = ISC_TRUE; |
|
result = ISC_R_SUCCESS; |
|
unlock: |
|
UNLOCK(&sessionlock); |
|
@@ -363,9 +365,14 @@ pk11_finalize(void) { |
|
pk11_mem_put(token, sizeof(*token)); |
|
token = next; |
|
} |
|
+ LOCK(&alloclock); |
|
if (pk11_mctx != NULL) |
|
isc_mem_detach(&pk11_mctx); |
|
+ UNLOCK(&alloclock); |
|
+ |
|
+ LOCK(&sessionlock); |
|
initialized = ISC_FALSE; |
|
+ UNLOCK(&sessionlock); |
|
return (ret); |
|
} |
|
|
|
@@ -655,6 +662,15 @@ token_login(pk11_session_t *sp) { |
|
return (ret); |
|
} |
|
|
|
+#define PK11_TRACE(fmt) \ |
|
+ if (pk11_verbose_init) fprintf(stderr, fmt) |
|
+#define PK11_TRACE1(fmt, arg) \ |
|
+ if (pk11_verbose_init) fprintf(stderr, fmt, arg) |
|
+#define PK11_TRACE2(fmt, arg1, arg2) \ |
|
+ if (pk11_verbose_init) fprintf(stderr, fmt, arg1, arg2) |
|
+#define PK11_TRACEM(mech) \ |
|
+ if (pk11_verbose_init) fprintf(stderr, #mech ": 0x%lx\n", rv) |
|
+ |
|
static void |
|
choose_slots(void) { |
|
CK_MECHANISM_INFO mechInfo; |
|
@@ -665,6 +681,8 @@ choose_slots(void) { |
|
CK_ULONG slotCount; |
|
pk11_token_t *token; |
|
unsigned int i; |
|
+ unsigned int best_rsa_algorithms = 0; |
|
+ unsigned int best_digest_algorithms = 0; |
|
|
|
slotCount = 0; |
|
PK11_FATALCHECK(pkcs_C_GetSlotList, (CK_FALSE, NULL_PTR, &slotCount)); |
|
@@ -676,6 +694,8 @@ choose_slots(void) { |
|
PK11_FATALCHECK(pkcs_C_GetSlotList, (CK_FALSE, slotList, &slotCount)); |
|
|
|
for (i = 0; i < slotCount; i++) { |
|
+ unsigned int rsa_algorithms = 0; |
|
+ unsigned int digest_algorithms = 0; |
|
slot = slotList[i]; |
|
|
|
rv = pkcs_C_GetTokenInfo(slot, &tokenInfo); |
|
@@ -708,8 +728,11 @@ choose_slots(void) { |
|
&mechInfo); |
|
if ((rv != CKR_OK) || |
|
((mechInfo.flags & CKF_SIGN) == 0) || |
|
- ((mechInfo.flags & CKF_VERIFY) == 0)) |
|
- goto try_dsa; |
|
+ ((mechInfo.flags & CKF_VERIFY) == 0)) { |
|
+ PK11_TRACEM(CKM_MD5_RSA_PKCS); |
|
+ } |
|
+ else |
|
+ ++rsa_algorithms; |
|
rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA1_RSA_PKCS, |
|
&mechInfo); |
|
if ((rv != CKR_OK) || |
|
@@ -729,8 +752,14 @@ choose_slots(void) { |
|
((mechInfo.flags & CKF_VERIFY) == 0)) |
|
goto try_dsa; |
|
token->operations |= 1 << OP_RSA; |
|
- if (best_rsa_token == NULL) |
|
+ if (best_rsa_token == NULL) { |
|
best_rsa_token = token; |
|
+ best_rsa_algorithms = rsa_algorithms; |
|
+ } else if (rsa_algorithms > best_rsa_algorithms) { |
|
+ pk11_mem_put(best_rsa_token, sizeof(*best_rsa_token)); |
|
+ best_rsa_token = token; |
|
+ best_rsa_algorithms = rsa_algorithms; |
|
+ } |
|
|
|
try_dsa: |
|
rv = pkcs_C_GetMechanismInfo(slot, CKM_DSA_PARAMETER_GEN, |
|
@@ -773,8 +802,11 @@ choose_slots(void) { |
|
|
|
try_digest: |
|
rv = pkcs_C_GetMechanismInfo(slot, CKM_MD5, &mechInfo); |
|
- if ((rv != CKR_OK) || ((mechInfo.flags & CKF_DIGEST) == 0)) |
|
- continue; |
|
+ if ((rv != CKR_OK) || ((mechInfo.flags & CKF_DIGEST) == 0)) { |
|
+ PK11_TRACEM(CKM_MD5); |
|
+ } |
|
+ else |
|
+ ++digest_algorithms; |
|
rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA_1, &mechInfo); |
|
if ((rv != CKR_OK) || ((mechInfo.flags & CKF_DIGEST) == 0)) |
|
continue; |
|
@@ -792,13 +824,15 @@ choose_slots(void) { |
|
continue; |
|
#ifdef PKCS11CRYPTOWITHHMAC |
|
rv = pkcs_C_GetMechanismInfo(slot, CKM_MD5_HMAC, &mechInfo); |
|
- if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0)) |
|
- continue; |
|
+ if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0)) { |
|
+ PK11_TRACEM(CKM_MD5_HMAC); |
|
+ } |
|
+ else |
|
+ ++digest_algorithms; |
|
#endif |
|
rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA_1_HMAC, &mechInfo); |
|
if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0)) |
|
continue; |
|
- rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA224_HMAC, &mechInfo); |
|
if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0)) |
|
continue; |
|
rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA256_HMAC, &mechInfo); |
|
@@ -811,8 +845,14 @@ choose_slots(void) { |
|
if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0)) |
|
continue; |
|
token->operations |= 1 << OP_DIGEST; |
|
- if (digest_token == NULL) |
|
- digest_token = token; |
|
+ if (digest_token == NULL) { |
|
+ digest_token = token; |
|
+ best_digest_algorithms = digest_algorithms; |
|
+ } else if (digest_algorithms > best_digest_algorithms) { |
|
+ pk11_mem_put(digest_token, sizeof(*digest_token)); |
|
+ digest_token = token; |
|
+ best_digest_algorithms = digest_algorithms; |
|
+ } |
|
|
|
/* ECDSA requires digest */ |
|
rv = pkcs_C_GetMechanismInfo(slot, CKM_EC_KEY_PAIR_GEN, |
|
diff --git a/lib/isccc/cc.c b/lib/isccc/cc.c |
|
index 9428374cc1..ca3cff27c9 100644 |
|
--- a/lib/isccc/cc.c |
|
+++ b/lib/isccc/cc.c |
|
@@ -254,11 +254,15 @@ sign(unsigned char *data, unsigned int length, unsigned char *hmac, |
|
|
|
switch (algorithm) { |
|
case ISCCC_ALG_HMACMD5: |
|
- isc_hmacmd5_init(&ctx.hmd5, secret->rstart, |
|
- REGION_SIZE(*secret)); |
|
- isc_hmacmd5_update(&ctx.hmd5, data, length); |
|
- isc_hmacmd5_sign(&ctx.hmd5, digest); |
|
- source.rend = digest + ISC_MD5_DIGESTLENGTH; |
|
+ if (isc_md5_available()) { |
|
+ isc_hmacmd5_init(&ctx.hmd5, secret->rstart, |
|
+ REGION_SIZE(*secret)); |
|
+ isc_hmacmd5_update(&ctx.hmd5, data, length); |
|
+ isc_hmacmd5_sign(&ctx.hmd5, digest); |
|
+ source.rend = digest + ISC_MD5_DIGESTLENGTH; |
|
+ } else { |
|
+ return (ISC_R_FAILURE); |
|
+ } |
|
break; |
|
|
|
case ISCCC_ALG_HMACSHA1: |
|
@@ -329,14 +333,14 @@ isccc_cc_towire(isccc_sexpr_t *alist, isccc_region_t *target, |
|
{ |
|
unsigned char *hmac_rstart, *signed_rstart; |
|
isc_result_t result; |
|
+ const isc_boolean_t md5 = ISC_TF(algorithm == ISCCC_ALG_HMACMD5); |
|
|
|
- if (algorithm == ISCCC_ALG_HMACMD5) { |
|
- if (REGION_SIZE(*target) < 4 + sizeof(auth_hmd5)) |
|
- return (ISC_R_NOSPACE); |
|
- } else { |
|
- if (REGION_SIZE(*target) < 4 + sizeof(auth_hsha)) |
|
- return (ISC_R_NOSPACE); |
|
- } |
|
+ if (md5 && isc_md5_available() == ISC_FALSE) |
|
+ return (ISC_R_NOTIMPLEMENTED); |
|
+ if (REGION_SIZE(*target) < 4 + ((md5) ? |
|
+ sizeof(auth_hmd5) : |
|
+ sizeof(auth_hsha))) |
|
+ return (ISC_R_NOSPACE); |
|
|
|
/* |
|
* Emit protocol version. |
|
@@ -348,7 +352,7 @@ isccc_cc_towire(isccc_sexpr_t *alist, isccc_region_t *target, |
|
* We'll replace the zeros with the real signature once |
|
* we know what it is. |
|
*/ |
|
- if (algorithm == ISCCC_ALG_HMACMD5) { |
|
+ if (md5) { |
|
hmac_rstart = target->rstart + HMD5_OFFSET; |
|
PUT_MEM(auth_hmd5, sizeof(auth_hmd5), target->rstart); |
|
} else { |
|
@@ -404,7 +408,7 @@ verify(isccc_sexpr_t *alist, unsigned char *data, unsigned int length, |
|
_auth = isccc_alist_lookup(alist, "_auth"); |
|
if (!isccc_alist_alistp(_auth)) |
|
return (ISC_R_FAILURE); |
|
- if (algorithm == ISCCC_ALG_HMACMD5) |
|
+ if (algorithm == ISCCC_ALG_HMACMD5 && isc_md5_available()) |
|
hmac = isccc_alist_lookup(_auth, "hmd5"); |
|
else |
|
hmac = isccc_alist_lookup(_auth, "hsha"); |
|
@@ -417,12 +421,16 @@ verify(isccc_sexpr_t *alist, unsigned char *data, unsigned int length, |
|
target.rstart = digestb64; |
|
switch (algorithm) { |
|
case ISCCC_ALG_HMACMD5: |
|
- isc_hmacmd5_init(&ctx.hmd5, secret->rstart, |
|
- REGION_SIZE(*secret)); |
|
- isc_hmacmd5_update(&ctx.hmd5, data, length); |
|
- isc_hmacmd5_sign(&ctx.hmd5, digest); |
|
- source.rend = digest + ISC_MD5_DIGESTLENGTH; |
|
- break; |
|
+ if (isc_md5_available()) { |
|
+ isc_hmacmd5_init(&ctx.hmd5, secret->rstart, |
|
+ REGION_SIZE(*secret)); |
|
+ isc_hmacmd5_update(&ctx.hmd5, data, length); |
|
+ isc_hmacmd5_sign(&ctx.hmd5, digest); |
|
+ source.rend = digest + ISC_MD5_DIGESTLENGTH; |
|
+ break; |
|
+ } else { |
|
+ return (ISC_R_FAILURE); |
|
+ } |
|
|
|
case ISCCC_ALG_HMACSHA1: |
|
isc_hmacsha1_init(&ctx.hsha, secret->rstart, |
|
-- |
|
2.14.4 |
|
|
|
|