]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- implement draft-ietf-dnsext-ecdsa-04; which is in IETF LC; This
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 8 Feb 2012 13:22:44 +0000 (13:22 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 8 Feb 2012 13:22:44 +0000 (13:22 +0000)
  implementation is experimental at this time and not recommended
  for use on the public internet (the protocol numbers have not
  been assigned).  Needs recent ldns with --enable-ecdsa.
- fix memory leak in errorcase for DSA signatures.

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

config.h.in
configure
configure.ac
doc/Changelog
testcode/testbound.c
testcode/unitverify.c
testdata/test_ds.sha384 [new file with mode: 0644]
testdata/test_sigs.ecdsa_p256 [new file with mode: 0644]
testdata/test_sigs.ecdsa_p384 [new file with mode: 0644]
validator/val_sigcrypt.c

index 63538a692153146ef5a0cdf52b0f50af0a302b73..4f9bbd1b7b3c7073d1db0da0352effe44f4d695d 100644 (file)
 /* Define to 1 if you have the `daemon' function. */
 #undef HAVE_DAEMON
 
+/* 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 declaration of `NID_X9_62_prime256v1', and to 0
+   if you don't. */
+#undef HAVE_DECL_NID_X9_62_PRIME256V1
+
 /* Define to 1 if you have the declaration of `sk_SSL_COMP_pop_free', and to 0
    if you don't. */
 #undef HAVE_DECL_SK_SSL_COMP_POP_FREE
 /* define this to enable debug checks. */
 #undef UNBOUND_DEBUG
 
+/* Define this to enable ECDSA support. */
+#undef USE_ECDSA
+
 /* Define this to enable GOST support. */
 #undef USE_GOST
 
index 42c0f73c9762efc15ba3083a0458eb323160dade..3ffe9842114c42b52bcd508a7c0d9b2b15c63e03 100755 (executable)
--- a/configure
+++ b/configure
@@ -791,6 +791,7 @@ with_pythonmodule
 with_ssl
 enable_sha2
 enable_gost
+enable_ecdsa
 with_libevent
 with_libexpat
 enable_static_exe
@@ -1445,6 +1446,7 @@ Optional Features:
                           purposes
   --disable-sha2          Disable SHA256 and SHA512 RRSIG support
   --disable-gost          Disable GOST support
+  --enable-ecdsa          Enable ECDSA support, experimental
   --enable-static-exe     enable to compile executables statically against
                           event, ldns libs, for debug purposes
   --enable-lock-checks    enable to check lock and unlock calls, for debug
@@ -16553,6 +16555,89 @@ $as_echo "#define USE_GOST 1" >>confdefs.h
        ;;
 esac
 
+# Check whether --enable-ecdsa was given.
+if test "${enable_ecdsa+set}" = set; then :
+  enableval=$enable_ecdsa;
+fi
+
+use_ecdsa="no"
+case "$enable_ecdsa" in
+    yes)
+      ac_fn_c_check_func "$LINENO" "ECDSA_sign" "ac_cv_func_ECDSA_sign"
+if test "x$ac_cv_func_ECDSA_sign" = xyes; then :
+
+else
+  as_fn_error $? "OpenSSL does not support ECDSA" "$LINENO" 5
+fi
+
+      ac_fn_c_check_func "$LINENO" "SHA384_Init" "ac_cv_func_SHA384_Init"
+if test "x$ac_cv_func_SHA384_Init" = xyes; then :
+
+else
+  as_fn_error $? "OpenSSL does not support SHA384" "$LINENO" 5
+fi
+
+      ac_fn_c_check_decl "$LINENO" "NID_X9_62_prime256v1" "ac_cv_have_decl_NID_X9_62_prime256v1" "$ac_includes_default
+#include <openssl/evp.h>
+
+"
+if test "x$ac_cv_have_decl_NID_X9_62_prime256v1" = xyes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_NID_X9_62_PRIME256V1 $ac_have_decl
+_ACEOF
+if test $ac_have_decl = 1; then :
+
+else
+  as_fn_error $? "OpenSSL does not support the ECDSA curves" "$LINENO" 5
+fi
+ac_fn_c_check_decl "$LINENO" "NID_secp384r1" "ac_cv_have_decl_NID_secp384r1" "$ac_includes_default
+#include <openssl/evp.h>
+
+"
+if test "x$ac_cv_have_decl_NID_secp384r1" = xyes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_NID_SECP384R1 $ac_have_decl
+_ACEOF
+if test $ac_have_decl = 1; then :
+
+else
+  as_fn_error $? "OpenSSL does not support the ECDSA curves" "$LINENO" 5
+fi
+
+      # we now know we have ECDSA and the required curves.
+
+cat >>confdefs.h <<_ACEOF
+#define USE_ECDSA 1
+_ACEOF
+
+      use_ecdsa="yes"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
+      *****************************************************************
+      *** YOU HAVE ENABLED ECDSA WHICH IS EXPERIMENTAL AT THIS TIME ***
+      *** PLEASE DO NOT USE THIS ON THE PUBLIC INTERNET             ***
+      *****************************************************************" >&5
+$as_echo "$as_me: WARNING:
+      *****************************************************************
+      *** YOU HAVE ENABLED ECDSA WHICH IS EXPERIMENTAL AT THIS TIME ***
+      *** PLEASE DO NOT USE THIS ON THE PUBLIC INTERNET             ***
+      *****************************************************************" >&2;}
+      ;;
+    no)
+      ;;
+    *)
+      ;;
+esac
+
 # check for libevent
 
 # Check whether --with-libevent was given.
@@ -17701,6 +17786,19 @@ done
 else
     ac_cv_func_ldns_key_EVP_load_gost_id="yes"
 fi
+if test x$use_ecdsa = xyes; then
+    ac_fn_c_check_decl "$LINENO" "LDNS_ECDSAP384SHA384" "ac_cv_have_decl_LDNS_ECDSAP384SHA384" "
+$ac_includes_default
+#include <ldns/ldns.h>
+
+"
+if test "x$ac_cv_have_decl_LDNS_ECDSAP384SHA384" = xyes; then :
+
+fi
+
+else
+    ac_cv_have_decl_LDNS_ECDSAP384SHA384="yes"
+fi
 for ac_header in ldns/ldns.h
 do :
   ac_fn_c_check_header_compile "$LINENO" "ldns/ldns.h" "ac_cv_header_ldns_ldns_h" "$ac_includes_default
@@ -17743,7 +17841,8 @@ if test $ac_cv_func_ldns_buffer_copy = yes \
     -a $ac_cv_func_ldns_get_random = yes \
     -a $ac_cv_header_ldns_ldns_h = yes \
     -a $ac_cv_func_ldns_b32_ntop_extended_hex = yes \
-    -a $ac_cv_func_ldns_key_EVP_load_gost_id = yes; then
+    -a $ac_cv_func_ldns_key_EVP_load_gost_id = yes \
+    -a $ac_cv_have_decl_LDNS_ECDSAP384SHA384 = yes; then
         :
 else
     as_fn_error $? "ldns library is not recent, update the ldns library, install it into system lib dir or use --with-ldns=path to other location.  The --with-ldns can point to the make-dir of ldns.  Package libldns or download source http://www.nlnetlabs.nl/projects/ldns" "$LINENO" 5
index 12ef2fa6cd17366de137f53ff91e83b542bb641b..97e909ebe776515dd5d127a4a85ed421b9641df7 100644 (file)
@@ -658,6 +658,30 @@ case "$enable_gost" in
        ;;
 esac
 
+AC_ARG_ENABLE(ecdsa, AC_HELP_STRING([--enable-ecdsa], [Enable ECDSA support, experimental]))
+use_ecdsa="no"
+case "$enable_ecdsa" in
+    yes)
+      AC_CHECK_FUNC(ECDSA_sign, [], [AC_MSG_ERROR([OpenSSL does not support ECDSA])])
+      AC_CHECK_FUNC(SHA384_Init, [], [AC_MSG_ERROR([OpenSSL does not support SHA384])])
+      AC_CHECK_DECLS([NID_X9_62_prime256v1, NID_secp384r1], [], [AC_MSG_ERROR([OpenSSL does not support the ECDSA curves])], [AC_INCLUDES_DEFAULT
+#include <openssl/evp.h>
+      ])
+      # we now know we have ECDSA and the required curves.
+      AC_DEFINE_UNQUOTED([USE_ECDSA], [1], [Define this to enable ECDSA support.])
+      use_ecdsa="yes"
+      AC_WARN([
+      *****************************************************************
+      *** YOU HAVE ENABLED ECDSA WHICH IS EXPERIMENTAL AT THIS TIME ***
+      *** PLEASE DO NOT USE THIS ON THE PUBLIC INTERNET             ***
+      *****************************************************************])
+      ;;
+    no)
+      ;;
+    *)
+      ;;
+esac
+
 # check for libevent
 AC_ARG_WITH(libevent, AC_HELP_STRING([--with-libevent=pathname],
     [use libevent (will check /usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr  or you can specify an explicit path). Slower, but allows use of large outgoing port ranges.]),
@@ -942,6 +966,14 @@ if test x$use_gost = xyes; then
 else
     ac_cv_func_ldns_key_EVP_load_gost_id="yes"
 fi
+if test x$use_ecdsa = xyes; then
+    AC_CHECK_DECL([LDNS_ECDSAP384SHA384], [], [], [
+AC_INCLUDES_DEFAULT
+#include <ldns/ldns.h>
+    ])
+else
+    ac_cv_have_decl_LDNS_ECDSAP384SHA384="yes"
+fi
 AC_CHECK_HEADERS([ldns/ldns.h],,[
        AC_MSG_ERROR([No ldns include file found, install the ldns library development files.  Install package ldns-dev or ldns-devel or download source http://www.nlnetlabs.nl/projects/ldns])
        ], [AC_INCLUDES_DEFAULT
@@ -970,7 +1002,8 @@ if test $ac_cv_func_ldns_buffer_copy = yes \
     -a $ac_cv_func_ldns_get_random = yes \
     -a $ac_cv_header_ldns_ldns_h = yes \
     -a $ac_cv_func_ldns_b32_ntop_extended_hex = yes \
-    -a $ac_cv_func_ldns_key_EVP_load_gost_id = yes; then
+    -a $ac_cv_func_ldns_key_EVP_load_gost_id = yes \
+    -a $ac_cv_have_decl_LDNS_ECDSAP384SHA384 = yes; then
     dnl ldns was found
     :
 else
index abe454bf36a05679d488b5933a288dd653b80240..69ccfa718def9252417bc5f6469ad78cb0e1d01f 100644 (file)
@@ -1,3 +1,10 @@
+8 February 2012: Wouter
+       - implement draft-ietf-dnsext-ecdsa-04; which is in IETF LC; This
+         implementation is experimental at this time and not recommended
+         for use on the public internet (the protocol numbers have not
+         been assigned).  Needs recent ldns with --enable-ecdsa.
+       - fix memory leak in errorcase for DSA signatures.
+
 3 February 2012: Wouter
        - fix for windows, rename() is not posix compliant on windows.
 
index 2adffc2eaf14e3347e8eca77ee57411ade86f0ed..05982849cc29ce596f3f3255e6e843838178ccb1 100644 (file)
@@ -70,6 +70,7 @@ testbound_usage()
        printf("-p file playback text file\n");
        printf("-2      detect SHA256 support (exit code 0 or 1)\n");
        printf("-g      detect GOST support (exit code 0 or 1)\n");
+       printf("-e      detect ECDSA support (exit code 0 or 1)\n");
        printf("-s      testbound self-test - unit test of testbound parts.\n");
        printf("-o str  unbound commandline options separated by spaces.\n");
        printf("Version %s\n", PACKAGE_VERSION);
@@ -272,7 +273,7 @@ main(int argc, char* argv[])
        pass_argc = 1;
        pass_argv[0] = "unbound";
        add_opts("-d", &pass_argc, pass_argv);
-       while( (c=getopt(argc, argv, "2gho:p:s")) != -1) {
+       while( (c=getopt(argc, argv, "2egho:p:s")) != -1) {
                switch(c) {
                case 's':
                        free(pass_argv[1]);
@@ -286,6 +287,15 @@ main(int argc, char* argv[])
 #else
                        printf("SHA256 not supported\n");
                        exit(1);
+#endif
+                       break;
+               case 'e':
+#if defined(USE_ECDSA)
+                       printf("ECDSA supported\n");
+                       exit(0);
+#else
+                       printf("ECDSA not supported\n");
+                       exit(1);
 #endif
                        break;
                case 'g':
index 56475f8234c0467db6223e23e855be4604cfb00f..2bc842c75374165f0880c10a35d29ff96695e26e 100644 (file)
@@ -519,6 +519,11 @@ verify_test(void)
        if(ldns_key_EVP_load_gost_id())
          verifytest_file("testdata/test_sigs.gost", "20090807060504");
        else printf("Warning: skipped GOST, openssl does not provide gost.\n");
+#endif
+#ifdef USE_ECDSA
+       verifytest_file("testdata/test_sigs.ecdsa_p256", "20100908100439");
+       verifytest_file("testdata/test_sigs.ecdsa_p384", "20100908100439");
+       dstest_file("testdata/test_ds.sha384");
 #endif
        dstest_file("testdata/test_ds.sha1");
        nsectest();
diff --git a/testdata/test_ds.sha384 b/testdata/test_ds.sha384
new file mode 100644 (file)
index 0000000..50a377b
--- /dev/null
@@ -0,0 +1,45 @@
+;
+; DS match test file.
+; test matching of DS hash against DNSKEYs.
+;
+; enter ENTRYs with a DS and a DNSKEY.
+; These are matched against another.
+; If the query name starts with 'yes' then it must match.
+; If the query name starts with 'no' then it must not match.
+
+; These are SHA256 and SHA384 tests from the draft-ietf-dnsext-ecdsa-04
+
+ENTRY_BEGIN
+SECTION QUESTION
+yes. IN A
+SECTION ANSWER
+example.net. 3600 IN DS 55648 13 2 ( b4c8c1fe2e7477127b27115656ad6256f424625bf5c1 e2770ce6d6e37df61d17 )
+example.net. 3600 IN DNSKEY 257 3 13 ( GojIhhXUN/u4v54ZQqGSnyhWJwaubCvTmeexv7bR6edb krSqQpF64cYbcB7wNcP+e+MAnLr+Wi9xMWyQLc8NAA== )
+ENTRY_END
+
+ENTRY_BEGIN
+SECTION QUESTION
+yes. IN A
+SECTION ANSWER
+example.net. 3600 IN DS 10771 14 4 ( 72d7b62976ce06438e9c0bf319013cf801f09ecc84b8 d7e9495f27e305c6a9b0563a9b5f4d288405c3008a94 6df983d6 )
+example.net. 3600 IN DNSKEY 257 3 14 ( xKYaNhWdGOfJ+nPrL8/arkwf2EY3MDJ+SErKivBVSum1 w/egsXvSADtNJhyem5RCOpgQ6K8X1DRSEkrbYQ+OB+v8 /uX45NBwY8rp65F6Glur8I/mlVNgF6W/qTI37m40 )
+ENTRY_END
+
+; same entry as above, but corrupted by a change in the DS, MUST fail
+ENTRY_BEGIN
+SECTION QUESTION
+no. IN A
+SECTION ANSWER
+example.net. 3600 IN DS 55648 13 2 ( b4c8c1fe2e7477126b27115656ad6256f424625bf5c1 e2770ce6d6e37df61d17 )
+example.net. 3600 IN DNSKEY 257 3 13 ( GojIhhXUN/u4v54ZQqGSnyhWJwaubCvTmeexv7bR6edb krSqQpF64cYbcB7wNcP+e+MAnLr+Wi9xMWyQLc8NAA== )
+ENTRY_END
+
+; same entry as above, but corrupted by a change in the DS, MUST fail
+ENTRY_BEGIN
+SECTION QUESTION
+no. IN A
+SECTION ANSWER
+example.net. 3600 IN DS 10771 14 4 ( 72d7b62976ce06438e9c0cf319013cf801f09ecc84b8 d7e9495f27e305c6a9b0563a9b5f4d288405c3008a94 6df983d6 )
+example.net. 3600 IN DNSKEY 257 3 14 ( xKYaNhWdGOfJ+nPrL8/arkwf2EY3MDJ+SErKivBVSum1 w/egsXvSADtNJhyem5RCOpgQ6K8X1DRSEkrbYQ+OB+v8 /uX45NBwY8rp65F6Glur8I/mlVNgF6W/qTI37m40 )
+ENTRY_END
+
diff --git a/testdata/test_sigs.ecdsa_p256 b/testdata/test_sigs.ecdsa_p256
new file mode 100644 (file)
index 0000000..28d08a7
--- /dev/null
@@ -0,0 +1,23 @@
+; Signature test file
+
+; first entry is a DNSKEY answer, with the DNSKEY rrset used for verification. 
+; later entries are verified with it.
+
+; Test ECDSA P256 signatures from draft-ietf-dnsext-ecdsa-04
+
+ENTRY_BEGIN
+SECTION QUESTION
+example.net.   IN DNSKEY
+SECTION ANSWER
+example.net. 3600 IN DNSKEY 257 3 13 ( GojIhhXUN/u4v54ZQqGSnyhWJwaubCvTmeexv7bR6edb krSqQpF64cYbcB7wNcP+e+MAnLr+Wi9xMWyQLc8NAA== )
+ENTRY_END
+
+; entry to test
+ENTRY_BEGIN
+SECTION QUESTION
+www.example.net.    IN      A 
+SECTION ANSWER
+www.example.net. 3600 IN A 192.0.2.1
+www.example.net. 3600 IN RRSIG A 13 3 3600 ( 20100909100439 20100812100439 55648 example.net.  qx6wLYqmh+l9oCKTN6qIc+bw6ya+KJ8oMz0YP107epXA yGmt+3SNruPFKG7tZoLBLlUzGGus7ZwmwWep666VCw== )
+ENTRY_END
+
diff --git a/testdata/test_sigs.ecdsa_p384 b/testdata/test_sigs.ecdsa_p384
new file mode 100644 (file)
index 0000000..fc5d12e
--- /dev/null
@@ -0,0 +1,23 @@
+; Signature test file
+
+; first entry is a DNSKEY answer, with the DNSKEY rrset used for verification. 
+; later entries are verified with it.
+
+; Test ECDSA P384 signatures from draft-ietf-dnsext-ecdsa-04
+
+ENTRY_BEGIN
+SECTION QUESTION
+example.net.   IN DNSKEY
+SECTION ANSWER
+example.net. 3600 IN DNSKEY 257 3 14 ( xKYaNhWdGOfJ+nPrL8/arkwf2EY3MDJ+SErKivBVSum1 w/egsXvSADtNJhyem5RCOpgQ6K8X1DRSEkrbYQ+OB+v8 /uX45NBwY8rp65F6Glur8I/mlVNgF6W/qTI37m40 )
+ENTRY_END
+
+; entry to test
+ENTRY_BEGIN
+SECTION QUESTION
+www.example.net.    IN      A 
+SECTION ANSWER
+www.example.net. 3600 IN A 192.0.2.1
+www.example.net. 3600 IN RRSIG A 14 3 3600 ( 20100909102025 20100812102025 10771 example.net.  /L5hDKIvGDyI1fcARX3z65qrmPsVz73QD1Mr5CEqOiLP 95hxQouuroGCeZOvzFaxsT8Glr74hbavRKayJNuydCuz WTSSPdz7wnqXL5bdcJzusdnI0RSMROxxwGipWcJm )
+ENTRY_END
+
index 436b5e844877c558bab46a1f4cb2ee304efabbdc..460e4f7313d887d0594755f0df4e05c922620bec 100644 (file)
@@ -279,6 +279,10 @@ ds_digest_size_algo(struct ub_packed_rrset_key* k, size_t idx)
                        if(EVP_get_digestbyname("md_gost94"))
                                return 32;
                        else    return 0;
+#endif
+#ifdef USE_ECDSA
+               case LDNS_SHA384:
+                       return SHA384_DIGEST_LENGTH;
 #endif
                default: break;
        }
@@ -347,6 +351,12 @@ ds_create_dnskey_digest(struct module_env* env,
                        if(do_gost94((unsigned char*)ldns_buffer_begin(b), 
                                ldns_buffer_limit(b), (unsigned char*)digest))
                                return 1;
+#endif
+#ifdef USE_ECDSA
+               case LDNS_SHA384:
+                       (void)SHA384((unsigned char*)ldns_buffer_begin(b),
+                               ldns_buffer_limit(b), (unsigned char*)digest);
+                       return 1;
 #endif
                default: 
                        verbose(VERB_QUERY, "unknown DS digest algorithm %d", 
@@ -417,6 +427,10 @@ dnskey_algo_id_is_supported(int id)
 #endif
 #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2)
        case LDNS_RSASHA512:
+#endif
+#ifdef USE_ECDSA
+       case LDNS_ECDSAP256SHA256:
+       case LDNS_ECDSAP384SHA384:
 #endif
                return 1;
 #ifdef USE_GOST
@@ -1321,7 +1335,7 @@ log_crypto_error(const char* str, unsigned long e)
  * Setup DSA key digest in DER encoding ... 
  * @param sig: input is signature output alloced ptr (unless failure).
  *     caller must free alloced ptr if this routine returns true.
- * @param len: intput is initial siglen, output is output len.
+ * @param len: input is initial siglen, output is output len.
  * @return false on failure.
  */
 static int
@@ -1350,6 +1364,7 @@ setup_dsa_sig(unsigned char** sig, unsigned int* len)
        *sig = NULL;
        newlen = i2d_DSA_SIG(dsasig, sig);
        if(newlen < 0) {
+               DSA_SIG_free(dsasig);
                free(*sig);
                return 0;
        }
@@ -1358,6 +1373,48 @@ setup_dsa_sig(unsigned char** sig, unsigned int* len)
        return 1;
 }
 
+#ifdef USE_ECDSA
+/**
+ * Setup the ECDSA signature in its encoding that the library wants.
+ * Converts from plain numbers to ASN formatted.
+ * @param sig: input is signature, output alloced ptr (unless failure).
+ *     caller must free alloced ptr if this routine returns true.
+ * @param len: input is initial siglen, output is output len.
+ * @return false on failure.
+ */
+static int
+setup_ecdsa_sig(unsigned char** sig, unsigned int* len)
+{
+       ECDSA_SIG* ecdsa_sig;
+       int newlen;
+       unsigned int bnsize = (*len)/2;
+       /* if too short or not even length, fails */
+       if(*len < 16 || bnsize*2 != *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);
+               return 0;
+       }
+       *len = (unsigned int)newlen;
+       ECDSA_SIG_free(ecdsa_sig);
+       return 1;
+}
+#endif /* USE_ECDSA */
+
 /**
  * Setup key and digest for verification. Adjust sig if necessary.
  *
@@ -1471,6 +1528,28 @@ setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type,
                                return 0;
                        }
                        break;
+#endif
+#ifdef USE_ECDSA
+               case LDNS_ECDSAP256SHA256:
+                       *evp_key = ldns_ecdsa2pkey_raw(key, keylen,
+                               LDNS_ECDSAP256SHA256);
+                       if(!*evp_key) {
+                               verbose(VERB_QUERY, "verify: "
+                                       "ldns_ecdsa2pkey_raw failed");
+                               return 0;
+                       }
+                       *digest_type = EVP_sha256();
+                       break;
+               case LDNS_ECDSAP384SHA384:
+                       *evp_key = ldns_ecdsa2pkey_raw(key, keylen,
+                               LDNS_ECDSAP384SHA384);
+                       if(!*evp_key) {
+                               verbose(VERB_QUERY, "verify: "
+                                       "ldns_ecdsa2pkey_raw failed");
+                               return 0;
+                       }
+                       *digest_type = EVP_sha384();
+                       break;
 #endif
                default:
                        verbose(VERB_QUERY, "verify: unknown algorithm %d", 
@@ -1519,7 +1598,19 @@ verify_canonrrset(ldns_buffer* buf, int algo, unsigned char* sigblock,
                        return sec_status_bogus;
                }
                dofree = 1;
-       } 
+       }
+#ifdef USE_ECDSA
+       else 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");
+                       *reason = "use of signature for ECDSA crypto failed";
+                       EVP_PKEY_free(evp_key);
+                       return sec_status_bogus;
+               }
+               dofree = 1;
+       }
+#endif /* USE_ECDSA */
 
        /* do the signature cryptography work */
        EVP_MD_CTX_init(&ctx);
@@ -1536,7 +1627,7 @@ verify_canonrrset(ldns_buffer* buf, int algo, unsigned char* sigblock,
                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");