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
enable_gost
enable_ecdsa
enable_dsa
+enable_ed25519
enable_event_api
enable_tfo_client
enable_tfo_server
--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
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 :
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"
;;
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
+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.
}
#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)
*/
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.
}
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
--- /dev/null
+; 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
+
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
#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);
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);
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);
}
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