]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Add ./configure --with-deprecate-rsa-1024 that turns off RSA 1024.
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Fri, 7 May 2021 12:28:20 +0000 (14:28 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Fri, 7 May 2021 12:28:20 +0000 (14:28 +0200)
config.h.in
configure
configure.ac
doc/Changelog
validator/autotrust.c
validator/val_anchor.c
validator/val_sigcrypt.c
validator/val_sigcrypt.h
validator/val_utils.c

index a843d703d7ced6b729fac16a66c4df1196864569..cb27afa4fe27e63a34407f1f9c1e0f5fefc253b8 100644 (file)
@@ -28,6 +28,9 @@
 /* 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
 
index 30e061f350e04d8b242a8a2fda1af4290ff2dfb6..fb3bcffe2f529d7e0a1d010eb96f5478784c0842 100755 (executable)
--- a/configure
+++ b/configure
@@ -877,6 +877,7 @@ enable_subnet
 enable_gost
 enable_ecdsa
 enable_dsa
+with_deprecate_rsa_1024
 enable_ed25519
 enable_ed448
 enable_event_api
@@ -1639,6 +1640,10 @@ Optional Packages:
                           /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
@@ -19035,6 +19040,18 @@ _ACEOF
       ;;
 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;
index 14d9b02c28a6b4d55cc22be766a979ee193d6148..62bcee1df3db897c8e62634fe1b853811e659ad2 100644 (file)
@@ -1155,6 +1155,11 @@ AC_INCLUDES_DEFAULT
       ;;
 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
index 61fd924c378c22be3cb211703ad768bbefd2516b..2ed0bf92c8f706d9758e5506d108dac8d55b83fa 100644 (file)
@@ -1,5 +1,6 @@
 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
index 7ce07e0d82d768bed42160cac96288d0421f9f58..adf8367543929c8a14a5765b1a7f6db301543a51 100644 (file)
@@ -1579,6 +1579,7 @@ key_matches_a_ds(struct module_env* env, struct val_env* ve,
        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)
@@ -1633,7 +1634,8 @@ update_events(struct module_env* env, struct val_env* ve,
                }
                /* 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", 
index 52711bbcb35ceb3ce2fd3c98a1e91c37558ad0ad..b1a54e1f0195ffad28ad962079dbf2bdd3f78804 100644 (file)
@@ -971,7 +971,8 @@ anchors_dnskey_unsupported(struct trust_anchor* ta)
 {
        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;
index 14e13da0653ce82f2965c2ba7c6cafab61be4c09..5ce20b2232c9911add2a0db9837631476d67a812 100644 (file)
@@ -386,6 +386,48 @@ int dnskey_algo_is_supported(struct ub_packed_rrset_key* dnskey_rrset,
                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)
 {
index 23ca1d91b7b5e9588835cd4b1d424901ad0ed011..bbb95780d7fe69a747bba8fd657672706d2fc1ee 100644 (file)
@@ -180,6 +180,23 @@ uint16_t ds_get_keytag(struct ub_packed_rrset_key* ds_rrset, size_t ds_idx);
 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
index 2f36fccfd4fe3b16106aa995cc6cac48cd738d41..dd8d320e515d03f44782a3d13c365e21cdcb12ed 100644 (file)
@@ -418,7 +418,7 @@ verify_dnskeys_with_ds_rr(struct module_env* env, struct val_env* ve,
        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. */
@@ -441,6 +441,11 @@ verify_dnskeys_with_ds_rr(struct module_env* env, struct val_env* ve,
                        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 
@@ -452,6 +457,10 @@ verify_dnskeys_with_ds_rr(struct module_env* env, struct val_env* ve,
                }
                /* 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");
@@ -519,17 +528,24 @@ val_verify_DNSKEY_with_DS(struct module_env* env, struct val_env* ve,
                        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) {
@@ -631,17 +647,24 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
                        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) {
@@ -658,6 +681,8 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
                /* 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;
@@ -668,6 +693,10 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
                        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) {