/* Whether daemon is deprecated */
#undef DEPRECATED_DAEMON
+/* Deprecate RSA 1024 bit length, makes that an unsupported key */
+#undef DEPRECATE_RSA_1024
+
/* Define this to enable kernel based UDP source port randomization. */
#undef DISABLE_EXPLICIT_PORT_RANDOMISATION
enable_gost
enable_ecdsa
enable_dsa
+with_deprecate_rsa_1024
enable_ed25519
enable_ed448
enable_event_api
/usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw
/usr)
--with-libbsd Use portable libbsd functions
+ --with-deprecate-rsa-1024
+ Deprecate RSA 1024 bit length, makes that an
+ unsupported key, for use when OpenSSL FIPS refuses
+ 1024 bit verification
--with-libevent=pathname
use libevent (will check /usr/local /opt/local
/usr/lib /usr/pkg /usr/sfw /usr or you can specify
;;
esac
+
+# Check whether --with-deprecate-rsa-1024 was given.
+if test "${with_deprecate_rsa_1024+set}" = set; then :
+ withval=$with_deprecate_rsa_1024;
+fi
+
+if test "$with_deprecate_rsa_1024" = "yes"; then
+
+$as_echo "#define DEPRECATE_RSA_1024 1" >>confdefs.h
+
+fi
+
# Check whether --enable-ed25519 was given.
if test "${enable_ed25519+set}" = set; then :
enableval=$enable_ed25519;
;;
esac
+AC_ARG_WITH(deprecate-rsa-1024, AS_HELP_STRING([--with-deprecate-rsa-1024],[Deprecate RSA 1024 bit length, makes that an unsupported key, for use when OpenSSL FIPS refuses 1024 bit verification]))
+if test "$with_deprecate_rsa_1024" = "yes"; then
+ AC_DEFINE([DEPRECATE_RSA_1024], [1], [Deprecate RSA 1024 bit length, makes that an unsupported key])
+fi
+
AC_ARG_ENABLE(ed25519, AS_HELP_STRING([--disable-ed25519],[Disable ED25519 support]))
use_ed25519="no"
case "$enable_ed25519" in
7 May 2021: Wouter
- Fix #485: Unbound occasionally reports broken stats.
+ - Add ./configure --with-deprecate-rsa-1024 that turns off RSA 1024.
4 May 2021: George
- Fix for #367: only attempt to get the interface for queries that are no
for(ds_idx=0; ds_idx<num; ds_idx++) {
if(!ds_digest_algo_is_supported(ds_rrset, ds_idx) ||
!ds_key_algo_is_supported(ds_rrset, ds_idx) ||
+ !dnskey_size_is_supported(dnskey_rrset, key_idx) ||
ds_get_digest_algo(ds_rrset, ds_idx) != d)
continue;
if(ds_get_key_algo(ds_rrset, ds_idx)
}
/* is a key of this type supported?. Note rr_list and
* packed_rrset are in the same order. */
- if(!dnskey_algo_is_supported(dnskey_rrset, i)) {
+ if(!dnskey_algo_is_supported(dnskey_rrset, i) ||
+ !dnskey_size_is_supported(dnskey_rrset, i)) {
/* skip unknown algorithm key, it is useless to us */
log_nametypeclass(VERB_DETAIL, "trust point has "
"unsupported algorithm at",
{
size_t i, num = 0;
for(i=0; i<ta->numDNSKEY; i++) {
- if(!dnskey_algo_is_supported(ta->dnskey_rrset, i))
+ if(!dnskey_algo_is_supported(ta->dnskey_rrset, i) ||
+ !dnskey_size_is_supported(ta->dnskey_rrset, i))
num++;
}
return num;
dnskey_idx));
}
+int dnskey_size_is_supported(struct ub_packed_rrset_key* dnskey_rrset,
+ size_t dnskey_idx)
+{
+#ifdef DEPRECATE_RSA_1024
+ uint8_t* rdata;
+ size_t len;
+ int alg = dnskey_get_algo(dnskey_rrset, dnskey_idx);
+ size_t keysize;
+
+ rrset_get_rdata(dnskey_rrset, dnskey_idx, &rdata, &len);
+ if(len < 2+4)
+ return 0;
+ keysize = sldns_rr_dnskey_key_size_raw(rdata+2+4, len-2-4, alg);
+
+ switch((sldns_algorithm)alg) {
+ case LDNS_RSAMD5:
+ case LDNS_RSASHA1:
+ case LDNS_RSASHA1_NSEC3:
+ case LDNS_RSASHA256:
+ case LDNS_RSASHA512:
+ /* reject RSA keys of 1024 bits and shorter */
+ if(keysize <= 1024)
+ return 0;
+ default:
+ break;
+ }
+#else
+ (void)dnskey_rrset; (void)dnskey_idx;
+#endif /* DEPRECATE_RSA_1024 */
+ return 1;
+}
+
+int dnskeyset_size_is_supported(struct ub_packed_rrset_key* dnskey_rrset)
+{
+ size_t i, num = rrset_get_count(dnskey_rrset);
+ for(i=0; i<num; i++) {
+ if(!dnskey_size_is_supported(dnskey_rrset, i))
+ return 0;
+ }
+ return 1;
+}
+
void algo_needs_init_dnskey_add(struct algo_needs* n,
struct ub_packed_rrset_key* dnskey, uint8_t* sigalg)
{
int dnskey_algo_is_supported(struct ub_packed_rrset_key* dnskey_rrset,
size_t dnskey_idx);
+/**
+ * See if the DNSKEY size at that algorithm is supported.
+ * @param dnskey_rrset: DNSKEY rrset.
+ * @param dnskey_idx: index of RR in rrset.
+ * @return true if supported.
+ */
+int dnskey_size_is_supported(struct ub_packed_rrset_key* dnskey_rrset,
+ size_t dnskey_idx);
+
+/**
+ * See if the DNSKEY size at that algorithm is supported for all the
+ * RRs in the DNSKEY RRset.
+ * @param dnskey_rrset: DNSKEY rrset.
+ * @return true if supported.
+ */
+int dnskeyset_size_is_supported(struct ub_packed_rrset_key* dnskey_rrset);
+
/**
* See if DS digest algorithm is supported
* @param ds_rrset: DS rrset
struct module_qstate* qstate)
{
enum sec_status sec = sec_status_bogus;
- size_t i, num, numchecked = 0, numhashok = 0;
+ size_t i, num, numchecked = 0, numhashok = 0, numsizesupp = 0;
num = rrset_get_count(dnskey_rrset);
for(i=0; i<num; i++) {
/* Skip DNSKEYs that don't match the basic criteria. */
continue;
}
numhashok++;
+ if(!dnskey_size_is_supported(dnskey_rrset, i)) {
+ verbose(VERB_ALGO, "DS okay but that DNSKEY size is not supported");
+ numsizesupp++;
+ continue;
+ }
verbose(VERB_ALGO, "DS match digest ok, trying signature");
/* Otherwise, we have a match! Make sure that the DNSKEY
}
/* If it didn't validate with the DNSKEY, try the next one! */
}
+ if(numsizesupp != 0) {
+ /* there is a working DS, but that DNSKEY is not supported */
+ return sec_status_insecure;
+ }
if(numchecked == 0)
algo_needs_reason(env, ds_get_key_algo(ds_rrset, ds_idx),
reason, "no keys have a DS");
continue;
}
+ sec = verify_dnskeys_with_ds_rr(env, ve, dnskey_rrset,
+ ds_rrset, i, reason, qstate);
+ if(sec == sec_status_insecure)
+ continue;
+
/* Once we see a single DS with a known digestID and
* algorithm, we cannot return INSECURE (with a
* "null" KeyEntry). */
has_useful_ds = 1;
- sec = verify_dnskeys_with_ds_rr(env, ve, dnskey_rrset,
- ds_rrset, i, reason, qstate);
if(sec == sec_status_secure) {
if(!sigalg || algo_needs_set_secure(&needs,
(uint8_t)ds_get_key_algo(ds_rrset, i))) {
verbose(VERB_ALGO, "DS matched DNSKEY.");
+ if(!dnskeyset_size_is_supported(dnskey_rrset)) {
+ verbose(VERB_ALGO, "DS works, but dnskeyset contain keys that are unsupported, treat as insecure");
+ return sec_status_insecure;
+ }
return sec_status_secure;
}
} else if(sigalg && sec == sec_status_bogus) {
ds_get_digest_algo(ta_ds, i) != digest_algo)
continue;
+ sec = verify_dnskeys_with_ds_rr(env, ve, dnskey_rrset,
+ ta_ds, i, reason, qstate);
+ if(sec == sec_status_insecure)
+ continue;
+
/* Once we see a single DS with a known digestID and
* algorithm, we cannot return INSECURE (with a
* "null" KeyEntry). */
has_useful_ta = 1;
- sec = verify_dnskeys_with_ds_rr(env, ve, dnskey_rrset,
- ta_ds, i, reason, qstate);
if(sec == sec_status_secure) {
if(!sigalg || algo_needs_set_secure(&needs,
(uint8_t)ds_get_key_algo(ta_ds, i))) {
verbose(VERB_ALGO, "DS matched DNSKEY.");
+ if(!dnskeyset_size_is_supported(dnskey_rrset)) {
+ verbose(VERB_ALGO, "trustanchor works, but dnskeyset contain keys that are unsupported, treat as insecure");
+ return sec_status_insecure;
+ }
return sec_status_secure;
}
} else if(sigalg && sec == sec_status_bogus) {
/* Check to see if we can understand this DNSKEY */
if(!dnskey_algo_is_supported(ta_dnskey, i))
continue;
+ if(!dnskey_size_is_supported(ta_dnskey, i))
+ continue;
/* we saw a useful TA */
has_useful_ta = 1;
if(!sigalg || algo_needs_set_secure(&needs,
(uint8_t)dnskey_get_algo(ta_dnskey, i))) {
verbose(VERB_ALGO, "anchor matched DNSKEY.");
+ if(!dnskeyset_size_is_supported(dnskey_rrset)) {
+ verbose(VERB_ALGO, "trustanchor works, but dnskeyset contain keys that are unsupported, treat as insecure");
+ return sec_status_insecure;
+ }
return sec_status_secure;
}
} else if(sigalg && sec == sec_status_bogus) {