]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Support for openssl EVP_DigestVerify.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 30 May 2017 12:28:25 +0000 (12:28 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 30 May 2017 12:28:25 +0000 (12:28 +0000)
- Support for the ED25519 algorithm with openssl (from openssl 1.1.1).

git-svn-id: file:///svn/unbound/trunk@4198 be551aaa-1e26-0410-a405-d3ace91eadb9

config.h.in
configure
configure.ac
doc/Changelog
sldns/keyraw.c
sldns/keyraw.h
testcode/unitverify.c
testdata/test_sigs.ed25519 [new file with mode: 0644]
validator/val_secalgo.c

index 2713bcdab62935386ea29bfc1a42b30f7214b9ba..20fdf98616bcf6a8c29beb9248cc7f2555fba345 100644 (file)
    don't. */
 #undef HAVE_DECL_INET_PTON
 
+/* Define to 1 if you have the declaration of `NID_ED25519', and to 0 if you
+   don't. */
+#undef HAVE_DECL_NID_ED25519
+
 /* Define to 1 if you have the declaration of `NID_secp384r1', and to 0 if you
    don't. */
 #undef HAVE_DECL_NID_SECP384R1
 /* Define to 1 if you have the `EVP_cleanup' function. */
 #undef HAVE_EVP_CLEANUP
 
+/* Define to 1 if you have the `EVP_DigestVerify' function. */
+#undef HAVE_EVP_DIGESTVERIFY
+
 /* Define to 1 if you have the `EVP_dss1' function. */
 #undef HAVE_EVP_DSS1
 
 /* Define this to enable an EVP workaround for older openssl */
 #undef USE_ECDSA_EVP_WORKAROUND
 
+/* Define this to enable ED25519 support. */
+#undef USE_ED25519
+
 /* Define this to enable GOST support. */
 #undef USE_GOST
 
index 16297e06f27d5e34404a3ffccbf0d08713637fff..c27c35d76794cf998de9c661b65f05094c5fbd05 100755 (executable)
--- a/configure
+++ b/configure
@@ -856,6 +856,7 @@ enable_subnet
 enable_gost
 enable_ecdsa
 enable_dsa
+enable_ed25519
 enable_event_api
 enable_tfo_client
 enable_tfo_server
@@ -1537,6 +1538,7 @@ Optional Features:
   --disable-gost          Disable GOST support
   --disable-ecdsa         Disable ECDSA support
   --disable-dsa           Disable DSA support
+  --disable-ed25519       Disable ED25519 support
   --enable-event-api      Enable (experimental) pluggable event base
                           libunbound API installed to unbound-event.h
   --enable-tfo-client     Enable TCP Fast Open for client mode
@@ -17617,7 +17619,7 @@ fi
 
 done
 
-for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1
+for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify
 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"
       ;;
 esac
 
+# Check whether --enable-ed25519 was given.
+if test "${enable_ed25519+set}" = set; then :
+  enableval=$enable_ed25519;
+fi
+
+use_ed25519="no"
+case "$enable_ed25519" in
+    no)
+      ;;
+    *)
+      if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
+             ac_fn_c_check_decl "$LINENO" "NID_ED25519" "ac_cv_have_decl_NID_ED25519" "$ac_includes_default
+#include <openssl/evp.h>
+
+"
+if test "x$ac_cv_have_decl_NID_ED25519" = xyes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_NID_ED25519 $ac_have_decl
+_ACEOF
+if test $ac_have_decl = 1; then :
+
+
+cat >>confdefs.h <<_ACEOF
+#define USE_ED25519 1
+_ACEOF
+
+               use_ed25519="yes"
+
+else
+   if test "x$enable_ed25519" = "xyes"; then as_fn_error $? "OpenSSL does not support ED25519 and you used --enable-ed25519." "$LINENO" 5
+               fi
+fi
+
+      fi
+      ;;
+esac
 
 # Check whether --enable-event-api was given.
 if test "${enable_event_api+set}" = set; then :
index 059243c3da9ab6dae2c47b457aa415c586b4b171..3652deecc9ea2f9b34d5bcc4e3ebda80342c6d85 100644 (file)
@@ -691,7 +691,7 @@ else
        AC_MSG_RESULT([no])
 fi
 AC_CHECK_HEADERS([openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h],,, [AC_INCLUDES_DEFAULT])
-AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1])
+AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify])
 
 # these check_funcs need -lssl
 BAKLIBS="$LIBS"
@@ -917,6 +917,23 @@ case "$enable_dsa" in
       ;;
 esac
 
+AC_ARG_ENABLE(ed25519, AC_HELP_STRING([--disable-ed25519], [Disable ED25519 support]))
+use_ed25519="no"
+case "$enable_ed25519" in
+    no)
+      ;;
+    *)
+      if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
+             AC_CHECK_DECLS([NID_ED25519], [
+               AC_DEFINE_UNQUOTED([USE_ED25519], [1], [Define this to enable ED25519 support.])
+               use_ed25519="yes"
+             ], [ if test "x$enable_ed25519" = "xyes"; then AC_MSG_ERROR([OpenSSL does not support ED25519 and you used --enable-ed25519.])
+               fi ], [AC_INCLUDES_DEFAULT
+#include <openssl/evp.h>
+             ])
+      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
index c08f4b5db793e3b0868496ea929555b645720299..291a13ec140d68f44c8d8a8129f8f475b9fe7cd1 100644 (file)
@@ -1,3 +1,7 @@
+30 May 2017: Wouter
+       - Support for openssl EVP_DigestVerify.
+       - Support for the ED25519 algorithm with openssl (from openssl 1.1.1).
+
 29 May 2017: Wouter
        - Fix assertion for low buffer size and big edns payload when worker
          overrides udpsize.
index e8f2da089d6a501bb401ba0db0202c0d5e8b3e5e..e2f14f2a4e972054ae7d9185684c75a2dd635c70 100644 (file)
@@ -388,6 +388,27 @@ sldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo)
 }
 #endif /* USE_ECDSA */
 
+#ifdef USE_ED25519
+EVP_PKEY*
+sldns_ed255192pkey_raw(const unsigned char* key, size_t keylen)
+{
+       /* ASN1 for ED25519 is 302a300506032b6570032100 <32byteskey> */
+       uint8_t pre[] = {0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
+               0x70, 0x03, 0x21, 0x00};
+       int pre_len = 12;
+       uint8_t buf[256];
+       EVP_PKEY *evp_key;
+       /* pp gets modified by d2i() */
+       const unsigned char* pp = (unsigned char*)buf;
+       if(keylen != 32 || keylen + pre_len > sizeof(buf))
+               return NULL; /* wrong length */
+       memmove(buf, pre, pre_len);
+       memmove(buf+pre_len, key, keylen);
+       evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen));
+       return evp_key;
+}
+#endif /* USE_ED25519 */
+
 int
 sldns_digest_evp(unsigned char* data, unsigned int len, unsigned char* dest,
        const EVP_MD* md)
index 8abe235097b279315faece8b33a008fb0a02fdf4..19653b46c7ba815a597ed267f42862aaa0a1c99c 100644 (file)
@@ -92,6 +92,15 @@ EVP_PKEY* sldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo);
  */
 RSA *sldns_key_buf2rsa_raw(unsigned char* key, size_t len);
 
+/**
+ * Converts a holding buffer with key material to EVP PKEY in openssl.
+ * Only available if ldns was compiled with ED25519.
+ * \param[in] key the uncompressed wireformat of the key.
+ * \param[in] len length of key data
+ * \return the key or NULL on error.
+ */
+EVP_PKEY* sldns_ed255192pkey_raw(const unsigned char* key, size_t len);
+
 /**
  * Utility function to calculate hash using generic EVP_MD pointer.
  * \param[in] data the data to hash.
index 37994a377c28e9d6a53d8f09814b6130cb9d2551..e5e5b0f7bacb07802102ab2ec759ef8b51f9d563 100644 (file)
@@ -537,6 +537,11 @@ verify_test(void)
        }
        dstest_file("testdata/test_ds.sha384");
 #endif
+#ifdef USE_ED25519
+       if(dnskey_algo_id_is_supported(LDNS_ED25519)) {
+               verifytest_file("testdata/test_sigs.ed25519", "20170530140439");
+       }
+#endif
 #ifdef USE_SHA1
        dstest_file("testdata/test_ds.sha1");
 #endif
diff --git a/testdata/test_sigs.ed25519 b/testdata/test_sigs.ed25519
new file mode 100644 (file)
index 0000000..b159225
--- /dev/null
@@ -0,0 +1,21 @@
+; Signature test file
+
+; first entry is a DNSKEY answer, with the DNSKEY rrset used for verification. 
+; later entries are verified with it.
+
+ENTRY_BEGIN
+SECTION QUESTION
+example.com.   IN DNSKEY
+SECTION ANSWER
+example.com.   3600    IN      DNSKEY  256 3 15 +sZnc8HII6xxA9Ili5bboiKH0Ipv/Ap1aucIt/CVF2M= ;{id = 57147 (zsk), size = 256b}
+ENTRY_END
+
+; entry to test
+ENTRY_BEGIN
+SECTION QUESTION
+www.example.com.    IN      A 
+SECTION ANSWER
+www.example.com.       3600    IN      A       10.0.0.1
+www.example.com.       3600    IN      RRSIG   A 15 3 3600 20170627103620 20170530103620 57147 example.com. daYG6zZJ3BJwGOS4PC0tDnxssVNYoenOHocoIfx0GeXNkKHSyXF+XHgD5LKbG3ZN0dZJ/4To5eni9QXOXiR4CA==
+ENTRY_END
+
index 508bca6f5b6d050f1c016df528a137b1f0f8060d..88d23472118f49304a590e58ba61390a2b6c4967 100644 (file)
@@ -228,6 +228,9 @@ dnskey_algo_id_is_supported(int id)
        case LDNS_ECDSAP256SHA256:
        case LDNS_ECDSAP384SHA384:
 #endif
+#ifdef USE_ED25519
+       case LDNS_ED25519:
+#endif
 #if (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) || defined(USE_ECDSA)
                return 1;
 #endif
@@ -555,6 +558,17 @@ setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type,
 #endif
                        break;
 #endif /* USE_ECDSA */
+#ifdef USE_ED25519
+               case LDNS_ED25519:
+                       *evp_key = sldns_ed255192pkey_raw(key, keylen);
+                       if(!*evp_key) {
+                               verbose(VERB_QUERY, "verify: "
+                                       "sldns_ed255192pkey_raw failed");
+                               return 0;
+                       }
+                       *digest_type = NULL;
+                       break;
+#endif /* USE_ED25519 */
                default:
                        verbose(VERB_QUERY, "verify: unknown algorithm %d", 
                                algo);
@@ -644,9 +658,15 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
                else if(docrypto_free) OPENSSL_free(sigblock);
                return sec_status_unchecked;
        }
+#ifndef HAVE_EVP_DIGESTVERIFY
        if(EVP_DigestInit(ctx, digest_type) == 0) {
                verbose(VERB_QUERY, "verify: EVP_DigestInit failed");
+#ifdef HAVE_EVP_MD_CTX_NEW
                EVP_MD_CTX_destroy(ctx);
+#else
+               EVP_MD_CTX_cleanup(ctx);
+               free(ctx);
+#endif
                EVP_PKEY_free(evp_key);
                if(dofree) free(sigblock);
                else if(docrypto_free) OPENSSL_free(sigblock);
@@ -655,7 +675,12 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
        if(EVP_DigestUpdate(ctx, (unsigned char*)sldns_buffer_begin(buf), 
                (unsigned int)sldns_buffer_limit(buf)) == 0) {
                verbose(VERB_QUERY, "verify: EVP_DigestUpdate failed");
+#ifdef HAVE_EVP_MD_CTX_NEW
                EVP_MD_CTX_destroy(ctx);
+#else
+               EVP_MD_CTX_cleanup(ctx);
+               free(ctx);
+#endif
                EVP_PKEY_free(evp_key);
                if(dofree) free(sigblock);
                else if(docrypto_free) OPENSSL_free(sigblock);
@@ -663,6 +688,24 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
        }
 
        res = EVP_VerifyFinal(ctx, sigblock, sigblock_len, evp_key);
+#else /* HAVE_EVP_DIGESTVERIFY */
+       if(EVP_DigestVerifyInit(ctx, NULL, digest_type, NULL, evp_key) == 0) {
+               verbose(VERB_QUERY, "verify: EVP_DigestVerifyInit failed");
+#ifdef HAVE_EVP_MD_CTX_NEW
+               EVP_MD_CTX_destroy(ctx);
+#else
+               EVP_MD_CTX_cleanup(ctx);
+               free(ctx);
+#endif
+               EVP_PKEY_free(evp_key);
+               if(dofree) free(sigblock);
+               else if(docrypto_free) OPENSSL_free(sigblock);
+               return sec_status_unchecked;
+       }
+       res = EVP_DigestVerify(ctx, sigblock, sigblock_len,
+               (unsigned char*)sldns_buffer_begin(buf),
+               sldns_buffer_limit(buf));
+#endif
 #ifdef HAVE_EVP_MD_CTX_NEW
        EVP_MD_CTX_destroy(ctx);
 #else