]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- OpenSSL 1.1.0 portability, --disable-dsa configure option.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 23 Mar 2016 08:19:49 +0000 (08:19 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 23 Mar 2016 08:19:49 +0000 (08:19 +0000)
git-svn-id: file:///svn/unbound/trunk@3689 be551aaa-1e26-0410-a405-d3ace91eadb9

config.h.in
configure
configure.ac
daemon/daemon.c
doc/Changelog
testcode/petal.c
testcode/unitverify.c
util/net_help.c
validator/val_anchor.c
validator/val_secalgo.c

index e9223139d185350a34be0d75763505487ddb257c..011357b06d47a234d231e4437483e1d5a16260a1 100644 (file)
 /* Define to 1 if you have the <event.h> header file. */
 #undef HAVE_EVENT_H
 
+/* Define to 1 if you have the `EVP_MD_CTX_new' function. */
+#undef HAVE_EVP_MD_CTX_NEW
+
 /* Define to 1 if you have the `EVP_sha1' function. */
 #undef HAVE_EVP_SHA1
 
 /* Define to 1 to enable dnstap support */
 #undef USE_DNSTAP
 
+/* Define this to enable DSA support. */
+#undef USE_DSA
+
 /* Define this to enable ECDSA support. */
 #undef USE_ECDSA
 
index 7b72be1220412d4a6dd42c44b6a3c044c51d5d2e..96f8d0effba7dd485d5d67cec0b77856da71f4cf 100755 (executable)
--- a/configure
+++ b/configure
@@ -832,6 +832,7 @@ with_ssl
 enable_sha2
 enable_gost
 enable_ecdsa
+enable_dsa
 enable_event_api
 with_libevent
 with_libexpat
@@ -1495,6 +1496,7 @@ Optional Features:
   --disable-sha2          Disable SHA256 and SHA512 RRSIG support
   --disable-gost          Disable GOST support
   --disable-ecdsa         Disable ECDSA support
+  --disable-dsa           Disable DSA support
   --enable-event-api      Enable (experimental) pluggable event base
                           libunbound API installed to unbound-event.h
   --enable-static-exe     enable to compile executables statically against
@@ -17483,7 +17485,7 @@ fi
 
 done
 
-for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode
+for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -17850,6 +17852,35 @@ _ACEOF
       ;;
 esac
 
+# Check whether --enable-dsa was given.
+if test "${enable_dsa+set}" = set; then :
+  enableval=$enable_dsa;
+fi
+
+use_dsa="no"
+case "$enable_ecdsa" in
+    no)
+      ;;
+    *)
+      # detect if DSA is supported, and turn it off if not.
+      ac_fn_c_check_func "$LINENO" "EVP_dss1" "ac_cv_func_EVP_dss1"
+if test "x$ac_cv_func_EVP_dss1" = xyes; then :
+
+
+cat >>confdefs.h <<_ACEOF
+#define USE_DSA 1
+_ACEOF
+
+
+else
+  if test "x$enable_dsa" = "xyes"; then as_fn_error $? "OpenSSL does not support DSA and you used --enable-dsa." "$LINENO" 5
+               fi
+fi
+
+      ;;
+esac
+
+
 # Check whether --enable-event-api was given.
 if test "${enable_event_api+set}" = set; then :
   enableval=$enable_event_api;
index 4f29963431642d39f7ea0fa8a1158851ea899d9d..aa1fb92fbe7483ea3b41e9eb3880fcb07c9c4d5d 100644 (file)
@@ -658,7 +658,7 @@ else
 fi
 AC_CHECK_HEADERS([openssl/conf.h],,, [AC_INCLUDES_DEFAULT])
 AC_CHECK_HEADERS([openssl/engine.h],,, [AC_INCLUDES_DEFAULT])
-AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode])
+AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new])
 AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto], [], [], [
 AC_INCLUDES_DEFAULT
 #ifdef HAVE_OPENSSL_ERR_H
@@ -840,6 +840,21 @@ case "$enable_ecdsa" in
       ;;
 esac
 
+AC_ARG_ENABLE(dsa, AC_HELP_STRING([--disable-dsa], [Disable DSA support]))
+use_dsa="no"
+case "$enable_ecdsa" in
+    no)
+      ;;
+    *)
+      # detect if DSA is supported, and turn it off if not.
+      AC_CHECK_FUNC(EVP_dss1, [
+      AC_DEFINE_UNQUOTED([USE_DSA], [1], [Define this to enable DSA support.])
+      ], [if test "x$enable_dsa" = "xyes"; then AC_MSG_ERROR([OpenSSL does not support DSA and you used --enable-dsa.])
+               fi ])
+      ;;
+esac
+
+
 AC_ARG_ENABLE(event-api, AC_HELP_STRING([--enable-event-api], [Enable (experimental) pluggable event base libunbound API installed to unbound-event.h]))
 case "$enable_event_api" in
     yes)
index 7edff800ce0ae42254ff24237490176f97739753..1036fcde2001008fdde2e318812dd907e92de189 100644 (file)
@@ -644,17 +644,23 @@ daemon_delete(struct daemon* daemon)
 #  endif
 #  if HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS && HAVE_DECL_SK_SSL_COMP_POP_FREE
 #    ifndef S_SPLINT_S
+#      if OPENSSL_VERSION_NUMBER < 0x10100000
        sk_SSL_COMP_pop_free(comp_meth, (void(*)())CRYPTO_free);
+#      endif
 #    endif
 #  endif
 #  ifdef HAVE_OPENSSL_CONFIG
        EVP_cleanup();
+#  if OPENSSL_VERSION_NUMBER < 0x10100000
        ENGINE_cleanup();
+#  endif
        CONF_modules_free();
 #  endif
        CRYPTO_cleanup_all_ex_data(); /* safe, no more threads right now */
        ERR_free_strings();
+#  if OPENSSL_VERSION_NUMBER < 0x10100000
        RAND_cleanup();
+#  endif
 #  if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
        ub_openssl_lock_delete();
 #  endif
index 87853665905a99c9ef2ada6b1522b5465cf0271d..f991038111caeb750d880de903f00c1b53919073 100644 (file)
@@ -1,3 +1,6 @@
+23 March 2016: Wouter
+       - OpenSSL 1.1.0 portability, --disable-dsa configure option.
+
 21 March 2016: Wouter
        - Fix compile of getentropy_linux for SLES11 servicepack 4.
        - Fix dnstap-log-resolver-response-messages, from Nikolay Edigaryev.
index 269b109b8f88482506f58f6bc3ed5ed91d0223c2..24d94a5569697ac6ef78a59a52ccfc7c3f385da9 100644 (file)
@@ -643,6 +643,5 @@ int main(int argc, char* argv[])
 
        CRYPTO_cleanup_all_ex_data();
        ERR_free_strings();
-       RAND_cleanup();
        return 0;
 }
index 9cb0eb99e7ccfacf61755e409764ba6ce12e6be3..f6445e2815c407c5ddae1ce2e86c50e3a0e784e5 100644 (file)
@@ -497,12 +497,14 @@ verify_test(void)
 {
        unit_show_feature("signature verify");
        verifytest_file("testdata/test_signatures.1", "20070818005004");
+#ifdef USE_DSA
        verifytest_file("testdata/test_signatures.2", "20080414005004");
        verifytest_file("testdata/test_signatures.3", "20080416005004");
        verifytest_file("testdata/test_signatures.4", "20080416005004");
        verifytest_file("testdata/test_signatures.5", "20080416005004");
        verifytest_file("testdata/test_signatures.6", "20080416005004");
        verifytest_file("testdata/test_signatures.7", "20070829144150");
+#endif /* USE_DSA */
        verifytest_file("testdata/test_signatures.8", "20070829144150");
 #if (defined(HAVE_EVP_SHA256) || defined(HAVE_NSS) || defined(HAVE_NETTLE)) && defined(USE_SHA2)
        verifytest_file("testdata/test_sigs.rsasha256", "20070829144150");
index eb03cd0ae6d26f7ab3e19723cc620b5da64c3457..5d6c033d659793714e1135467cdb7bcf08507286 100644 (file)
@@ -783,7 +783,7 @@ void* outgoing_ssl_fd(void* sslctx, int fd)
 #endif
 }
 
-#if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
+#if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK)
 /** global lock list for openssl locks */
 static lock_basic_t *ub_openssl_locks = NULL;
 
@@ -808,7 +808,7 @@ ub_crypto_lock_cb(int mode, int type, const char *ATTR_UNUSED(file),
 
 int ub_openssl_lock_init(void)
 {
-#if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
+#if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK)
        int i;
        ub_openssl_locks = (lock_basic_t*)reallocarray(
                NULL, (size_t)CRYPTO_num_locks(), sizeof(lock_basic_t));
@@ -825,7 +825,7 @@ int ub_openssl_lock_init(void)
 
 void ub_openssl_lock_delete(void)
 {
-#if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
+#if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK)
        int i;
        if(!ub_openssl_locks)
                return;
index bc9f8b8773f98900da828c864852a14d2364cb51..4d470b69227d2171562bc218e2695ec99a360968 100644 (file)
@@ -1030,6 +1030,8 @@ anchors_assemble_rrsets(struct val_anchors* anchors)
                                ")", b);
                        (void)rbtree_delete(anchors->tree, &ta->node);
                        lock_basic_unlock(&ta->lock);
+                       if(anchors->dlv_anchor == ta)
+                               anchors->dlv_anchor = NULL;
                        anchors_delfunc(&ta->node, NULL);
                        ta = next;
                        continue;
index baa4dae1a871d7aee8775a504c3136ca7a63e290..be5ba63194055766e09d6c770e23cda9adf9878e 100644 (file)
@@ -186,8 +186,10 @@ dnskey_algo_id_is_supported(int id)
        case LDNS_RSAMD5:
                /* RFC 6725 deprecates RSAMD5 */
                return 0;
+#ifdef USE_DSA
        case LDNS_DSA:
        case LDNS_DSA_NSEC3:
+#endif
        case LDNS_RSASHA1:
        case LDNS_RSASHA1_NSEC3:
 #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2)
@@ -227,6 +229,7 @@ log_crypto_error(const char* str, unsigned long e)
        log_err("%s crypto %s", str, buf);
 }
 
+#ifdef USE_DSA
 /**
  * Setup DSA key digest in DER encoding ... 
  * @param sig: input is signature output alloced ptr (unless failure).
@@ -268,6 +271,7 @@ setup_dsa_sig(unsigned char** sig, unsigned int* len)
        DSA_SIG_free(dsasig);
        return 1;
 }
+#endif /* USE_DSA */
 
 #ifdef USE_ECDSA
 /**
@@ -281,32 +285,61 @@ setup_dsa_sig(unsigned char** sig, unsigned int* len)
 static int
 setup_ecdsa_sig(unsigned char** sig, unsigned int* len)
 {
-       ECDSA_SIG* ecdsa_sig;
-       int newlen;
+        /* convert from two BIGNUMs in the rdata buffer, to ASN notation.
+        * ASN preable:  30440220 <R 32bytefor256> 0220 <S 32bytefor256>
+        * the '20' is the length of that field (=bnsize).
+i       * the '44' is the total remaining length.
+        * if negative, start with leading zero.
+        * if starts with 00s, remove them from the number.
+        */
+        uint8_t pre[] = {0x30, 0x44, 0x02, 0x20};
+        int pre_len = 4;
+        uint8_t mid[] = {0x02, 0x20};
+        int mid_len = 2;
+        int raw_sig_len, r_high, s_high, r_rem=0, s_rem=0;
        int bnsize = (int)((*len)/2);
+        unsigned char* d = *sig;
+       unsigned char* p;
        /* if too short or not even length, fails */
        if(*len < 16 || bnsize*2 != (int)*len)
                return 0;
-       /* use the raw data to parse two evenly long BIGNUMs, "r | s". */
-       ecdsa_sig = ECDSA_SIG_new();
-       if(!ecdsa_sig) return 0;
-       ecdsa_sig->r = BN_bin2bn(*sig, bnsize, ecdsa_sig->r);
-       ecdsa_sig->s = BN_bin2bn(*sig+bnsize, bnsize, ecdsa_sig->s);
-       if(!ecdsa_sig->r || !ecdsa_sig->s) {
-               ECDSA_SIG_free(ecdsa_sig);
-               return 0;
-       }
 
-       /* spool it into ASN format */
-       *sig = NULL;
-       newlen = i2d_ECDSA_SIG(ecdsa_sig, sig);
-       if(newlen <= 0) {
-               ECDSA_SIG_free(ecdsa_sig);
-               free(*sig);
+        /* strip leading zeroes from r (but not last one) */
+        while(r_rem < bnsize-1 && d[r_rem] == 0)
+                r_rem++;
+        /* strip leading zeroes from s (but not last one) */
+        while(s_rem < bnsize-1 && d[bnsize+s_rem] == 0)
+                s_rem++;
+
+        r_high = ((d[0+r_rem]&0x80)?1:0);
+        s_high = ((d[bnsize+s_rem]&0x80)?1:0);
+        raw_sig_len = pre_len + r_high + bnsize - r_rem + mid_len +
+                s_high + bnsize - s_rem;
+       *sig = (unsigned char*)malloc(raw_sig_len);
+       if(!*sig)
                return 0;
+       p = *sig;
+       p[0] = pre[0];
+       p[1] = raw_sig_len-2;
+       p[2] = pre[2];
+       p[3] = bnsize + r_high - r_rem;
+       p += 4;
+       if(r_high) {
+               *p = 0;
+               p += 1;
        }
-       *len = (unsigned int)newlen;
-       ECDSA_SIG_free(ecdsa_sig);
+       memmove(p, d+r_rem, bnsize-r_rem);
+       p += bnsize-r_rem;
+       memmove(p, mid, mid_len-1);
+       p += mid_len-1;
+       *p = bnsize + s_high - s_rem;
+       p += 1;
+        if(s_high) {
+               *p = 0;
+               p += 1;
+       }
+       memmove(p, d+bnsize+s_rem, bnsize-s_rem);
+       *len = (unsigned int)raw_sig_len;
        return 1;
 }
 #endif /* USE_ECDSA */
@@ -325,10 +358,13 @@ static int
 setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type, 
        unsigned char* key, size_t keylen)
 {
+#ifdef USE_DSA
        DSA* dsa;
+#endif
        RSA* rsa;
 
        switch(algo) {
+#ifdef USE_DSA
                case LDNS_DSA:
                case LDNS_DSA_NSEC3:
                        *evp_key = EVP_PKEY_new();
@@ -350,6 +386,7 @@ setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type,
                        *digest_type = EVP_dss1();
 
                        break;
+#endif /* USE_DSA */
                case LDNS_RSASHA1:
                case LDNS_RSASHA1_NSEC3:
 #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2)
@@ -508,7 +545,7 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
        char** reason)
 {
        const EVP_MD *digest_type;
-       EVP_MD_CTX ctx;
+       EVP_MD_CTX* ctx;
        int res, dofree = 0;
        EVP_PKEY *evp_key = NULL;
        
@@ -518,6 +555,7 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
                EVP_PKEY_free(evp_key);
                return sec_status_bogus;
        }
+#ifdef USE_DSA
        /* if it is a DSA signature in bind format, convert to DER format */
        if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) && 
                sigblock_len == 1+2*SHA_DIGEST_LENGTH) {
@@ -529,8 +567,12 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
                }
                dofree = 1;
        }
+#endif
+#if defined(USE_ECDSA) && defined(USE_DSA)
+       else 
+#endif
 #ifdef USE_ECDSA
-       else if(algo == LDNS_ECDSAP256SHA256 || algo == LDNS_ECDSAP384SHA384) {
+       if(algo == LDNS_ECDSAP256SHA256 || algo == LDNS_ECDSAP384SHA384) {
                /* EVP uses ASN prefix on sig, which is not in the wire data */
                if(!setup_ecdsa_sig(&sigblock, &sigblock_len)) {
                        verbose(VERB_QUERY, "verify: failed to setup ECDSA sig");
@@ -543,28 +585,34 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
 #endif /* USE_ECDSA */
 
        /* do the signature cryptography work */
-       EVP_MD_CTX_init(&ctx);
-       if(EVP_VerifyInit(&ctx, digest_type) == 0) {
-               verbose(VERB_QUERY, "verify: EVP_VerifyInit failed");
+#ifdef HAVE_EVP_MD_CTX_NEW
+       ctx = EVP_MD_CTX_new();
+#else
+       ctx = (EVP_MD_CTX*)malloc(sizeof(*ctx));
+       if(ctx) EVP_MD_CTX_init(ctx);
+#endif
+       if(!ctx) {
+               log_err("EVP_MD_CTX_new: malloc failure");
                EVP_PKEY_free(evp_key);
                if(dofree) free(sigblock);
                return sec_status_unchecked;
        }
-       if(EVP_VerifyUpdate(&ctx, (unsigned char*)sldns_buffer_begin(buf), 
-               (unsigned int)sldns_buffer_limit(buf)) == 0) {
-               verbose(VERB_QUERY, "verify: EVP_VerifyUpdate failed");
+       if(EVP_VerifyInit(ctx, digest_type) == 0) {
+               verbose(VERB_QUERY, "verify: EVP_VerifyInit failed");
                EVP_PKEY_free(evp_key);
                if(dofree) free(sigblock);
                return sec_status_unchecked;
        }
-
-       res = EVP_VerifyFinal(&ctx, sigblock, sigblock_len, evp_key);
-       if(EVP_MD_CTX_cleanup(&ctx) == 0) {
-               verbose(VERB_QUERY, "verify: EVP_MD_CTX_cleanup failed");
+       if(EVP_VerifyUpdate(ctx, (unsigned char*)sldns_buffer_begin(buf), 
+               (unsigned int)sldns_buffer_limit(buf)) == 0) {
+               verbose(VERB_QUERY, "verify: EVP_VerifyUpdate failed");
                EVP_PKEY_free(evp_key);
                if(dofree) free(sigblock);
                return sec_status_unchecked;
        }
+
+       res = EVP_VerifyFinal(ctx, sigblock, sigblock_len, evp_key);
+       EVP_MD_CTX_destroy(ctx);
        EVP_PKEY_free(evp_key);
 
        if(dofree)
@@ -678,8 +726,10 @@ dnskey_algo_id_is_supported(int id)
        case LDNS_RSAMD5:
                /* RFC 6725 deprecates RSAMD5 */
                return 0;
+#ifdef USE_DSA
        case LDNS_DSA:
        case LDNS_DSA_NSEC3:
+#endif
        case LDNS_RSASHA1:
        case LDNS_RSASHA1_NSEC3:
 #ifdef USE_SHA2
@@ -920,6 +970,7 @@ nss_setup_key_digest(int algo, SECKEYPublicKey** pubkey, HASH_HashType* htype,
        */
 
        switch(algo) {
+#ifdef USE_DSA
                case LDNS_DSA:
                case LDNS_DSA_NSEC3:
                        *pubkey = nss_buf2dsa(key, keylen);
@@ -930,6 +981,7 @@ nss_setup_key_digest(int algo, SECKEYPublicKey** pubkey, HASH_HashType* htype,
                        *htype = HASH_AlgSHA1;
                        /* no prefix for DSA verification */
                        break;
+#endif
                case LDNS_RSASHA1:
                case LDNS_RSASHA1_NSEC3:
 #ifdef USE_SHA2
@@ -1046,6 +1098,7 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
                return sec_status_bogus;
        }
 
+#ifdef USE_DSA
        /* need to convert DSA, ECDSA signatures? */
        if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3)) {
                if(sigblock_len == 1+2*SHA1_LENGTH) {
@@ -1068,6 +1121,7 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
                        SECITEM_FreeItem(p, PR_TRUE);
                }
        }
+#endif /* USE_DSA */
 
        /* do the signature cryptography work */
        /* hash the data */
@@ -1263,8 +1317,10 @@ dnskey_algo_id_is_supported(int id)
 {
        /* uses libnettle */
        switch(id) {
+#ifdef USE_DSA
        case LDNS_DSA:
        case LDNS_DSA_NSEC3:
+#endif
        case LDNS_RSASHA1:
        case LDNS_RSASHA1_NSEC3:
 #ifdef USE_SHA2
@@ -1541,6 +1597,7 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
        }
 
        switch(algo) {
+#ifdef USE_DSA
        case LDNS_DSA:
        case LDNS_DSA_NSEC3:
                *reason = _verify_nettle_dsa(buf, sigblock, sigblock_len, key, keylen);
@@ -1548,6 +1605,7 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
                        return sec_status_bogus;
                else
                        return sec_status_secure;
+#endif /* USE_DSA */
 
        case LDNS_RSASHA1:
        case LDNS_RSASHA1_NSEC3: