]> git.ipfire.org Git - thirdparty/ldns.git/commitdiff
Add openssl ED25519 support.
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Tue, 30 May 2017 10:53:46 +0000 (12:53 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Tue, 30 May 2017 10:53:46 +0000 (12:53 +0200)
configure.ac
dnssec.c
dnssec_sign.c
dnssec_verify.c
host2str.c
keys.c
ldns/dnssec.h

index c7b64ca2bd4fa7722f4e5b55086c672c9f5d59c6..76a35596b49aa4613ef4753f5b041e5d40b256c8 100644 (file)
@@ -519,7 +519,7 @@ case "$enable_ed25519" in
       if test "x$HAVE_SSL" != "xyes"; then
         AC_MSG_ERROR([ED25519 enabled, but no SSL support])
       fi
-      AC_CHECK_DECLS([NID_X25519], [], [AC_MSG_ERROR([OpenSSL does not support the EDDSA curve: please upgrade OpenSSL or rerun with --disable-ed25519])], [AC_INCLUDES_DEFAULT
+      AC_CHECK_DECLS([NID_ED25519], [], [AC_MSG_ERROR([OpenSSL does not support the EDDSA curve: please upgrade OpenSSL or rerun with --disable-ed25519])], [AC_INCLUDES_DEFAULT
 #include <openssl/evp.h>
       ])
       AC_DEFINE_UNQUOTED([USE_ED25519], [1], [Define this to enable ED25519 support.])
@@ -534,7 +534,7 @@ case "$enable_ed448" in
       if test "x$HAVE_SSL" != "xyes"; then
         AC_MSG_ERROR([ED448 enabled, but no SSL support])
       fi
-      AC_CHECK_DECLS([NID_X448], [], [AC_MSG_ERROR([OpenSSL does not support the EDDSA curve: please upgrade OpenSSL or rerun with --disable-ed448])], [AC_INCLUDES_DEFAULT
+      AC_CHECK_DECLS([NID_ED448], [], [AC_MSG_ERROR([OpenSSL does not support the EDDSA curve: please upgrade OpenSSL or rerun with --disable-ed448])], [AC_INCLUDES_DEFAULT
 #include <openssl/evp.h>
       ])
       AC_DEFINE_UNQUOTED([USE_ED448], [1], [Define this to enable ED448 support.])
index e3c99de27693e2cc8e6d7bdd77fa6128d8c6440b..86752990646f07bd8ad0fee433608a19d228ff4e 100644 (file)
--- a/dnssec.c
+++ b/dnssec.c
@@ -1942,69 +1942,4 @@ ldns_convert_ecdsa_rrsig_rdf2asn1(ldns_buffer *target_buffer,
 
 #endif /* S_SPLINT_S */
 #endif /* USE_ECDSA */
-
-#if defined(USE_ED25519) || defined(USE_ED448)
-/* debug printout routine */
-static void print_hex(const char* str, uint8_t* d, int len)
-{
-       const char hex[] = "0123456789abcdef";
-       int i;
-       printf("%s [len=%d]: ", str, len);
-       for(i=0; i<len; i++) {
-               int x = (d[i]&0xf0)>>4;
-               int y = (d[i]&0x0f);
-               printf("%c%c", hex[x], hex[y]);
-       }
-       printf("\n");
-}
-#endif
-
-#ifdef USE_ED25519
-ldns_rdf *
-ldns_convert_ed25519_rrsig_asn12rdf(const ldns_buffer *sig, long sig_len)
-{
-       unsigned char *data = (unsigned char*)ldns_buffer_begin(sig);
-        ldns_rdf* rdf = NULL;
-
-       /* TODO when Openssl supports signing and you can test this */
-       print_hex("sig in ASN", data, sig_len);
-
-        return rdf;
-}
-
-ldns_status
-ldns_convert_ed25519_rrsig_rdf2asn1(ldns_buffer *target_buffer,
-        const ldns_rdf *sig_rdf)
-{
-       /* TODO when Openssl supports signing and you can test this. */
-       /* convert sig_buf into ASN1 into the target_buffer */
-       print_hex("sig raw", ldns_rdf_data(sig_rdf), ldns_rdf_size(sig_rdf));
-        return ldns_buffer_status(target_buffer);
-}
-#endif /* USE_ED25519 */
-
-#ifdef USE_ED448
-ldns_rdf *
-ldns_convert_ed448_rrsig_asn12rdf(const ldns_buffer *sig, long sig_len)
-{
-       unsigned char *data = (unsigned char*)ldns_buffer_begin(sig);
-        ldns_rdf* rdf = NULL;
-
-       /* TODO when Openssl supports signing and you can test this */
-       print_hex("sig in ASN", data, sig_len);
-
-       return rdf;
-}
-
-ldns_status
-ldns_convert_ed448_rrsig_rdf2asn1(ldns_buffer *target_buffer,
-        const ldns_rdf *sig_rdf)
-{
-       /* TODO when Openssl supports signing and you can test this. */
-       /* convert sig_buf into ASN1 into the target_buffer */
-       print_hex("sig raw", ldns_rdf_data(sig_rdf), ldns_rdf_size(sig_rdf));
-        return ldns_buffer_status(target_buffer);
-}
-#endif /* USE_ED448 */
-
 #endif /* HAVE_SSL */
index 22f09816dafe2a270465162496a6816a9cfb6b34..4475b1b81a8a9f60041a0fd282defeca006f4da7 100644 (file)
@@ -184,7 +184,7 @@ ldns_sign_public_buffer(ldns_buffer *sign_buf, ldns_key *current_key)
                b64rdf = ldns_sign_public_evp(
                                   sign_buf,
                                   ldns_key_evp_key(current_key),
-                                  EVP_sha512());
+                                  NULL);
                 break;
 #endif
 #ifdef USE_ED448
@@ -192,7 +192,7 @@ ldns_sign_public_buffer(ldns_buffer *sign_buf, ldns_key *current_key)
                b64rdf = ldns_sign_public_evp(
                                   sign_buf,
                                   ldns_key_evp_key(current_key),
-                                  EVP_sha512());
+                                  NULL);
                 break;
 #endif
        case LDNS_SIGN_RSAMD5:
@@ -456,8 +456,19 @@ ldns_sign_public_evp(ldns_buffer *to_sign,
 
        /* initializes a signing context */
        md_type = digest_type;
+#ifdef USE_ED25519
+       if(EVP_PKEY_id(key) == NID_ED25519) {
+               /* digest must be NULL for ED25519 sign and verify */
+               md_type = NULL;
+       } else
+#endif
+#ifdef USE_ED448
+       if(EVP_PKEY_id(key) == NID_ED448) {
+               md_type = NULL;
+       } else
+#endif
        if(!md_type) {
-               /* unknown message difest */
+               /* unknown message digest */
                ldns_buffer_free(b64sig);
                return NULL;
        }
@@ -473,23 +484,32 @@ ldns_sign_public_evp(ldns_buffer *to_sign,
                return NULL;
        }
 
-       r = EVP_SignInit(ctx, md_type);
-       if(r == 1) {
-               r = EVP_SignUpdate(ctx, (unsigned char*)
-                                           ldns_buffer_begin(to_sign),
-                                           ldns_buffer_position(to_sign));
-       } else {
-               ldns_buffer_free(b64sig);
-               EVP_MD_CTX_destroy(ctx);
-               return NULL;
-       }
-       if(r == 1) {
-               r = EVP_SignFinal(ctx, (unsigned char*)
-                                          ldns_buffer_begin(b64sig), &siglen, key);
-       } else {
-               ldns_buffer_free(b64sig);
-               EVP_MD_CTX_destroy(ctx);
-               return NULL;
+#if defined(USE_ED25519) || defined(USE_ED448)
+       if(md_type == NULL) {
+               /* for these methods we must use the one-shot DigestSign */
+               r = EVP_DigestSignInit(ctx, NULL, md_type, NULL, key);
+               if(r == 1) {
+                       size_t siglen_sizet = ldns_buffer_capacity(b64sig);
+                       r = EVP_DigestSign(ctx,
+                               (unsigned char*)ldns_buffer_begin(b64sig),
+                               &siglen_sizet,
+                               (unsigned char*)ldns_buffer_begin(to_sign),
+                               ldns_buffer_position(to_sign));
+                       siglen = (unsigned int)siglen_sizet;
+               }
+       } else
+#endif
+       if(md_type != NULL) {
+               r = EVP_SignInit(ctx, md_type);
+               if(r == 1) {
+                       r = EVP_SignUpdate(ctx, (unsigned char*)
+                                                   ldns_buffer_begin(to_sign),
+                                                   ldns_buffer_position(to_sign));
+               }
+               if(r == 1) {
+                       r = EVP_SignFinal(ctx, (unsigned char*)
+                                                  ldns_buffer_begin(b64sig), &siglen, key);
+               }
        }
        if(r != 1) {
                ldns_buffer_free(b64sig);
@@ -512,7 +532,7 @@ ldns_sign_public_evp(ldns_buffer *to_sign,
        }
 #endif
 #endif
-#if defined(USE_ECDSA) || defined(USE_ED25519) || defined(USE_ED448)
+#if defined(USE_ECDSA)
        if(
 #  ifdef HAVE_EVP_PKEY_BASE_ID
                EVP_PKEY_base_id(key)
@@ -527,20 +547,6 @@ ldns_sign_public_evp(ldns_buffer *to_sign,
                                b64sig, (long)siglen, ldns_pkey_is_ecdsa(key));
                }
 #  endif /* USE_ECDSA */
-#  ifdef USE_ED25519
-               if(EVP_PKEY_id(key) == NID_X25519) {
-                       r = 1;
-                       sigdata_rdf = ldns_convert_ed25519_rrsig_asn12rdf(
-                               b64sig, siglen);
-               }
-#  endif /* USE_ED25519 */
-#  ifdef USE_ED448
-               if(EVP_PKEY_id(key) == NID_X448) {
-                       r = 1;
-                       sigdata_rdf = ldns_convert_ed448_rrsig_asn12rdf(
-                               b64sig, siglen);
-               }
-#  endif /* USE_ED448 */
        }
 #endif /* PKEY_EC */
        if(r == 0) {
index c554e4f4cb19ab618f5854e54b8575eafc969c8f..616f7b76e3e6aa188ef09555435078752e15ba3c 100644 (file)
@@ -1858,27 +1858,19 @@ ldns_verify_rrsig_gost_raw(const unsigned char* sig, size_t siglen,
 EVP_PKEY*
 ldns_ed255192pkey_raw(const unsigned char* key, size_t keylen)
 {
-        const unsigned char* pp = key; /* pp gets modified by o2i() */
+       /* 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;
-        EC_KEY *ec;
-       if(keylen != 32)
+       /* pp gets modified by d2i() */
+        const unsigned char* pp = (unsigned char*)buf;
+       if(keylen != 32 || keylen + pre_len > sizeof(buf))
                return NULL; /* wrong length */
-        ec = EC_KEY_new_by_curve_name(NID_X25519);
-       if(!ec) return NULL;
-        if(!o2i_ECPublicKey(&ec, &pp, (int)keylen)) {
-                EC_KEY_free(ec);
-                return NULL;
-       }
-        evp_key = EVP_PKEY_new();
-        if(!evp_key) {
-                EC_KEY_free(ec);
-                return NULL;
-        }
-        if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
-               EVP_PKEY_free(evp_key);
-               EC_KEY_free(ec);
-               return NULL;
-       }
+       memmove(buf, pre, pre_len);
+       memmove(buf+pre_len, key, keylen);
+       evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen));
         return evp_key;
 }
 
@@ -1894,8 +1886,7 @@ ldns_verify_rrsig_ed25519_raw(unsigned char* sig, size_t siglen,
                /* could not convert key */
                return LDNS_STATUS_CRYPTO_BOGUS;
         }
-       result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key,
-               EVP_sha512());
+       result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key, NULL);
        EVP_PKEY_free(evp_key);
        return result;
 }
@@ -1910,7 +1901,7 @@ ldns_ed4482pkey_raw(const unsigned char* key, size_t keylen)
         EC_KEY *ec;
        if(keylen != 57)
                return NULL; /* wrong length */
-        ec = EC_KEY_new_by_curve_name(NID_X448);
+        ec = EC_KEY_new_by_curve_name(NID_ED448);
        if(!ec) return NULL;
         if(!o2i_ECPublicKey(&ec, &pp, (int)keylen)) {
                 EC_KEY_free(ec);
@@ -1941,8 +1932,7 @@ ldns_verify_rrsig_ed448_raw(unsigned char* sig, size_t siglen,
                /* could not convert key */
                return LDNS_STATUS_CRYPTO_BOGUS;
         }
-       result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key,
-               EVP_sha512());
+       result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key, NULL);
        EVP_PKEY_free(evp_key);
        return result;
 }
@@ -2187,6 +2177,12 @@ ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, const ldns_rr* rrsig)
 #endif
 #ifdef USE_GOST
        case LDNS_ECC_GOST:
+#endif
+#ifdef USE_ED25519
+       case LDNS_ED25519:
+#endif
+#ifdef USE_ED448
+       case LDNS_ED448:
 #endif
                if (ldns_rr_rdf(rrsig, 8) == NULL) {
                        return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
@@ -2228,32 +2224,6 @@ ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, const ldns_rr* rrsig)
                        return LDNS_STATUS_MEM_ERR;
                 }
                 break;
-#endif
-#ifdef USE_ED25519
-       case LDNS_ED25519:
-                /* EVP produces an ASN prefix on the signature, which is
-                 * not used in the DNS */
-               if (ldns_rr_rdf(rrsig, 8) == NULL) {
-                       return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
-               }
-               if (ldns_convert_ed25519_rrsig_rdf2asn1(
-                       rawsig_buf, ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
-                       return LDNS_STATUS_MEM_ERR;
-                }
-               break;
-#endif
-#ifdef USE_ED448
-       case LDNS_ED448:
-                /* EVP produces an ASN prefix on the signature, which is
-                 * not used in the DNS */
-               if (ldns_rr_rdf(rrsig, 8) == NULL) {
-                       return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
-               }
-               if (ldns_convert_ed448_rrsig_rdf2asn1(
-                       rawsig_buf, ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
-                       return LDNS_STATUS_MEM_ERR;
-                }
-               break;
 #endif
        case LDNS_DH:
        case LDNS_ECC:
@@ -2633,11 +2603,23 @@ ldns_verify_rrsig_evp_raw(const unsigned char *sig, size_t siglen,
        if(!ctx)
                return LDNS_STATUS_MEM_ERR;
        
-       EVP_VerifyInit(ctx, digest_type);
-       EVP_VerifyUpdate(ctx,
-                                 ldns_buffer_begin(rrset),
-                                 ldns_buffer_position(rrset));
-       res = EVP_VerifyFinal(ctx, sig, (unsigned int) siglen, key);
+#if defined(USE_ED25519) || defined(USE_ED448)
+       if(!digest_type) {
+               res = EVP_DigestVerifyInit(ctx, NULL, digest_type, NULL, key);
+               if(res == 1) {
+                       res = EVP_DigestVerify(ctx, sig, siglen,
+                               ldns_buffer_begin(rrset),
+                               ldns_buffer_position(rrset));
+               }
+       } else
+#endif
+       if(digest_type) {
+               EVP_VerifyInit(ctx, digest_type);
+               EVP_VerifyUpdate(ctx,
+                                         ldns_buffer_begin(rrset),
+                                         ldns_buffer_position(rrset));
+               res = EVP_VerifyFinal(ctx, sig, (unsigned int) siglen, key);
+       }
        
        EVP_MD_CTX_destroy(ctx);
        
index 747d54310cf9849707b33457aac2a87eb8cb46bb..0725cabe77dc8a0de019f76e95843f3a74c4c02e 100644 (file)
@@ -1929,6 +1929,34 @@ ldns_gost_key2buffer_str(ldns_buffer *output, EVP_PKEY *p)
 }
 #endif
 
+#if defined(HAVE_SSL) && defined(USE_ED25519)
+static ldns_status
+ldns_ed25519_key2buffer_str(ldns_buffer *output, EVP_PKEY *p)
+{
+       unsigned char* pp = NULL;
+       int ret;
+       ldns_rdf *b64_bignum;
+       ldns_status status;
+
+       ldns_buffer_printf(output, "PrivateKey: ");
+
+       ret = i2d_PrivateKey(p, &pp);
+       /* 16 byte asn (302e020100300506032b657004220420) + 32byte key */
+       if(ret != 16 + 32) {
+               OPENSSL_free(pp);
+               return LDNS_STATUS_ERR;
+       }
+       b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64,
+               (size_t)ret-16, pp+16);
+       status = ldns_rdf2buffer_str(output, b64_bignum);
+
+       ldns_rdf_deep_free(b64_bignum);
+       OPENSSL_free(pp);
+       ldns_buffer_printf(output, "\n");
+       return status;
+}
+#endif
+
 /** print one b64 encoded bignum to a line in the keybuffer */
 static int
 ldns_print_bignum_b64_line(ldns_buffer* output, const char* label, const BIGNUM* num)
@@ -2160,16 +2188,8 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
                                ldns_buffer_printf(output, "Algorithm: %d (", ldns_key_algorithm(k));
                                 status=ldns_algorithm2buffer_str(output, (ldns_algorithm)ldns_key_algorithm(k));
                                ldns_buffer_printf(output, ")\n");
-                               if(k->_key.key) {
-                                        EC_KEY* ec = EVP_PKEY_get1_EC_KEY(k->_key.key);
-                                        const BIGNUM* b = EC_KEY_get0_private_key(ec);
-                                       if(!ldns_print_bignum_b64_line(output, "PrivateKey", b))
-                                               goto error;
-                                        /* down reference count in EC_KEY
-                                         * its still assigned to the PKEY */
-                                        EC_KEY_free(ec);
-                               }
-                               ldns_buffer_printf(output, "\n");
+                               status = ldns_ed25519_key2buffer_str(output,
+                                       k->_key.key);
                                break;
 #endif /* USE_ED25519 */
 #ifdef USE_ED448
diff --git a/keys.c b/keys.c
index 31208cb3a43fc7b0f786ac650a7a210ac67295df..85d7923a5cba54305863c18c952f51d15f49b151 100644 (file)
--- a/keys.c
+++ b/keys.c
@@ -300,34 +300,36 @@ ldns_key_new_frm_fp_ecdsa_l(FILE* fp, ldns_algorithm alg, int* line_nr)
 
 #ifdef USE_ED25519
 /** turn private key buffer into EC_KEY structure */
-static EC_KEY*
+static EVP_PKEY*
 ldns_ed25519_priv_raw(uint8_t* pkey, int plen)
 {
        const unsigned char* pp;
        uint8_t buf[256];
        int buflen = 0;
-       uint8_t pre[] = {0x30, 0x32, 0x02, 0x01, 0x01, 0x04, 0x20};
-       int pre_len = 7;
-       uint8_t post[] = {0xa0, 0x0b, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04,
-               0x01, 0xda, 0x47, 0x0f, 0x01};
-       int post_len = 13;
-       int i;
-       /* ASN looks like this for ED25519
+       uint8_t pre[] = {0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06,
+               0x03, 0x2b, 0x65, 0x70, 0x04, 0x22, 0x04, 0x20};
+       int pre_len = 16;
+       /* ASN looks like this for ED25519 public key
+        * 302a300506032b6570032100 <32byteskey>
+        * for ED25519 private key
+        * 302e020100300506032b657004220420 <32bytes>
+        *
+        * for X25519 this was
         * 30320201010420 <32byteskey>
         * andparameters a00b06092b06010401da470f01
         * (noparameters, preamble is 30250201010420).
         * the key is reversed (little endian).
         */
-       buflen = pre_len + plen + post_len;
+       buflen = pre_len + plen;
        if((size_t)buflen > sizeof(buf))
                return NULL;
        memmove(buf, pre, pre_len);
-       /* reverse the pkey into the buf */
-       for(i=0; i<plen; i++)
-               buf[pre_len+i] = pkey[plen-1-i];
-       memmove(buf+pre_len+plen, post, post_len);
+       memmove(buf+pre_len, pkey, plen);
+       /* reverse the pkey into the buf - key is not reversed it seems */
+       /* for(i=0; i<plen; i++)
+               buf[pre_len+i] = pkey[plen-1-i]; */
        pp = buf;
-       return d2i_ECPrivateKey(NULL, &pp, buflen);
+       return d2i_PrivateKey(NID_ED25519, NULL, &pp, buflen);
 }
 
 /** read ED25519 private key */
@@ -337,7 +339,6 @@ ldns_key_new_frm_fp_ed25519_l(FILE* fp, int* line_nr)
        char token[16384];
         ldns_rdf* b64rdf = NULL;
         EVP_PKEY* evp_key;
-        EC_KEY* ec;
        if (ldns_fget_keyword_data_l(fp, "PrivateKey", ": ", token, "\n",
                sizeof(token), line_nr) == -1)
                return NULL;
@@ -348,35 +349,18 @@ ldns_key_new_frm_fp_ed25519_l(FILE* fp, int* line_nr)
         * from the private part, which others, EC_KEY_set_private_key,
         * and o2i methods, do not do */
        /* for that the private key has to be encoded in ASN1 notation
-        * with a X25519 prefix on it */
+        * with a ED25519 prefix on it */
 
-       ec = ldns_ed25519_priv_raw(ldns_rdf_data(b64rdf),
+       evp_key = ldns_ed25519_priv_raw(ldns_rdf_data(b64rdf),
                (int)ldns_rdf_size(b64rdf));
        ldns_rdf_deep_free(b64rdf);
-       if(!ec) return NULL;
-       if(EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)) != NID_X25519) {
-               /* wrong group, bad asn conversion */
-                EC_KEY_free(ec);
-               return NULL;
-       }
-
-        evp_key = EVP_PKEY_new();
-        if(!evp_key) {
-                EC_KEY_free(ec);
-                return NULL;
-        }
-        if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
-               EVP_PKEY_free(evp_key);
-                EC_KEY_free(ec);
-                return NULL;
-       }
         return evp_key;
 }
 #endif
 
 #ifdef USE_ED448
 /** turn private key buffer into EC_KEY structure */
-static EC_KEY*
+static EVP_PKEY*
 ldns_ed448_priv_raw(uint8_t* pkey, int plen)
 {
        const unsigned char* pp;
@@ -408,7 +392,7 @@ ldns_ed448_priv_raw(uint8_t* pkey, int plen)
                buf[pre_len+i] = pkey[plen-1-i];
        memmove(buf+pre_len+plen, post, post_len);
        pp = buf;
-       return d2i_ECPrivateKey(NULL, &pp, buflen);
+       return d2i_PrivateKey(NID_ED448, NULL, &pp, buflen);
 }
 
 /** read ED448 private key */
@@ -418,7 +402,6 @@ ldns_key_new_frm_fp_ed448_l(FILE* fp, int* line_nr)
        char token[16384];
         ldns_rdf* b64rdf = NULL;
         EVP_PKEY* evp_key;
-        EC_KEY* ec;
        if (ldns_fget_keyword_data_l(fp, "PrivateKey", ": ", token, "\n", 
                sizeof(token), line_nr) == -1)
                return NULL;
@@ -426,26 +409,9 @@ ldns_key_new_frm_fp_ed448_l(FILE* fp, int* line_nr)
                return NULL;
 
        /* convert private key into ASN notation and then convert that */
-       ec = ldns_ed448_priv_raw(ldns_rdf_data(b64rdf),
+       evp_key = ldns_ed448_priv_raw(ldns_rdf_data(b64rdf),
                (int)ldns_rdf_size(b64rdf));
        ldns_rdf_deep_free(b64rdf);
-       if(!ec) return NULL;
-       if(EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)) != NID_X448) {
-               /* wrong group, bad asn conversion */
-                EC_KEY_free(ec);
-               return NULL;
-       }
-
-        evp_key = EVP_PKEY_new();
-        if(!evp_key) {
-                EC_KEY_free(ec);
-                return NULL;
-        }
-        if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
-               EVP_PKEY_free(evp_key);
-                EC_KEY_free(ec);
-                return NULL;
-       }
        return evp_key;
 }
 #endif
@@ -1314,7 +1280,7 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size)
 #ifdef USE_ED25519
                case LDNS_SIGN_ED25519:
 #ifdef HAVE_EVP_PKEY_KEYGEN
-                       ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
+                       ctx = EVP_PKEY_CTX_new_id(NID_ED25519, NULL);
                        if(!ctx) {
                                ldns_key_free(k);
                                return NULL;
@@ -1324,12 +1290,6 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size)
                                EVP_PKEY_CTX_free(ctx);
                                return NULL;
                        }
-                       if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx,
-                               NID_X25519) <= 0) {
-                               ldns_key_free(k);
-                               EVP_PKEY_CTX_free(ctx);
-                               return NULL;
-                       }
                        if (EVP_PKEY_keygen(ctx, &k->_key.key) <= 0) {
                                ldns_key_free(k);
                                EVP_PKEY_CTX_free(ctx);
@@ -1342,7 +1302,7 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size)
 #ifdef USE_ED448
                case LDNS_SIGN_ED448:
 #ifdef HAVE_EVP_PKEY_KEYGEN
-                       ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
+                       ctx = EVP_PKEY_CTX_new_id(NID_ED448, NULL);
                        if(!ctx) {
                                ldns_key_free(k);
                                return NULL;
@@ -1352,12 +1312,6 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size)
                                EVP_PKEY_CTX_free(ctx);
                                return NULL;
                        }
-                       if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx,
-                               NID_X448) <= 0) {
-                               ldns_key_free(k);
-                               EVP_PKEY_CTX_free(ctx);
-                               return NULL;
-                       }
                        if (EVP_PKEY_keygen(ctx, &k->_key.key) <= 0) {
                                ldns_key_free(k);
                                EVP_PKEY_CTX_free(ctx);
@@ -1809,9 +1763,66 @@ ldns_key_gost2bin(unsigned char* data, EVP_PKEY* k, uint16_t* size)
        return true;
 }
 #endif /* USE_GOST */
+
+#ifdef USE_ED25519
+static bool
+ldns_key_ed255192bin(unsigned char* data, EVP_PKEY* k, uint16_t* size)
+{
+       int i;
+       unsigned char* pp = NULL;
+       if(i2d_PUBKEY(k, &pp) != 12 + 32) {
+               /* expect 12 byte(ASN header) and 32 byte(pubkey) */
+               free(pp);
+               return false;
+       }
+       /* omit ASN header */
+       for(i=0; i<32; i++)
+               data[i] = pp[i+12];
+       free(pp);
+       *size = 32;
+       return true;
+}
+#endif /* USE_ED25519 */
+
+#ifdef USE_ED448
+static bool
+ldns_key_ed4482bin(unsigned char* data, EVP_PKEY* k, uint16_t* size)
+{
+       int i;
+       unsigned char* pp = NULL;
+       /* untested, not sure what the lengths are for the prefix */
+       if(i2d_PUBKEY(k, &pp) != 12 + 56) {
+               /* expect 12 byte(ASN header) and 56 byte(pubkey) */
+               free(pp);
+               return false;
+       }
+       /* omit ASN header */
+       for(i=0; i<56; i++)
+               data[i] = pp[i+12];
+       free(pp);
+       *size = 56;
+       return true;
+}
+#endif /* USE_ED448 */
 #endif /* splint */
 #endif /* HAVE_SSL */
 
+#if defined(USE_ED448)
+/* debug printout routine */
+static void print_hex(const char* str, uint8_t* d, int len)
+{
+       const char hex[] = "0123456789abcdef";
+       int i;
+       printf("%s [len=%d]: ", str, len);
+       for(i=0; i<len; i++) {
+               int x = (d[i]&0xf0)>>4;
+               int y = (d[i]&0x0f);
+               printf("%c%c", hex[x], hex[y]);
+       }
+       printf("\n");
+}
+#endif
+
 ldns_rr *
 ldns_key2rr(const ldns_key *k)
 {
@@ -1999,18 +2010,16 @@ ldns_key2rr(const ldns_key *k)
                 case LDNS_SIGN_ED25519:
                        ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8(
                                LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
-                        bin = NULL;
-                        ec = EVP_PKEY_get1_EC_KEY(k->_key.key);
-                        EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED);
-                        size = (uint16_t)i2o_ECPublicKey(ec, NULL);
-                        if(!i2o_ECPublicKey(ec, &bin)) {
-                                EC_KEY_free(ec);
+                       bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
+                       if (!bin) {
                                 ldns_rr_free(pubkey);
-                                return NULL;
+                               return NULL;
                         }
-                        /* down the reference count for ec, its still assigned
-                         * to the pkey */
-                        EC_KEY_free(ec);
+                       if (!ldns_key_ed255192bin(bin, k->_key.key, &size)) {
+                               LDNS_FREE(bin);
+                                ldns_rr_free(pubkey);
+                               return NULL;
+                       }
                        internal_data = 1;
                        break;
 #endif
@@ -2018,18 +2027,16 @@ ldns_key2rr(const ldns_key *k)
                 case LDNS_SIGN_ED448:
                        ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8(
                                LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
-                        bin = NULL;
-                        ec = EVP_PKEY_get1_EC_KEY(k->_key.key);
-                        EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED);
-                        size = (uint16_t)i2o_ECPublicKey(ec, NULL);
-                        if(!i2o_ECPublicKey(ec, &bin)) {
-                                EC_KEY_free(ec);
+                       bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
+                       if (!bin) {
                                 ldns_rr_free(pubkey);
-                                return NULL;
+                               return NULL;
                         }
-                        /* down the reference count for ec, its still assigned
-                         * to the pkey */
-                        EC_KEY_free(ec);
+                       if (!ldns_key_ed4482bin(bin, k->_key.key, &size)) {
+                               LDNS_FREE(bin);
+                                ldns_rr_free(pubkey);
+                               return NULL;
+                       }
                        internal_data = 1;
                        break;
 #endif
index 41691b63e73213390416a8dc7571c4b2615dec1a..9881fda72355045caee5010d69cba7e8e799376d 100644 (file)
@@ -556,56 +556,6 @@ ldns_status
 ldns_convert_ecdsa_rrsig_rdf2asn1(ldns_buffer *target_buffer,
         const ldns_rdf *sig_rdf);
 
-/**
- * Converts the ECDSA signature from ASN1 representation (as
- * used by OpenSSL) to raw signature data as used in DNS
- * This routine is only present if ldns is compiled with ED25519 support.
- *
- * \param[in] sig The signature in ASN1 format
- * \param[in] sig_len The length of the signature
- * \return a new rdf with the signature
- */
-ldns_rdf *
-ldns_convert_ed25519_rrsig_asn12rdf(const ldns_buffer *sig, long sig_len);
-
-/**
- * Converts the RRSIG signature RDF (from DNS) to a buffer with the
- * signature in ASN1 format as openssl uses it.
- * This routine is only present if ldns is compiled with ED25519 support.
- *
- * \param[out] target_buffer buffer to place the signature data in ASN1.
- * \param[in] sig_rdf The signature rdf to convert
- * \return LDNS_STATUS_OK on success, error code otherwise
- */
-ldns_status
-ldns_convert_ed25519_rrsig_rdf2asn1(ldns_buffer *target_buffer,
-        const ldns_rdf *sig_rdf);
-
-/**
- * Converts the ECDSA signature from ASN1 representation (as
- * used by OpenSSL) to raw signature data as used in DNS
- * This routine is only present if ldns is compiled with ED448 support.
- *
- * \param[in] sig The signature in ASN1 format
- * \param[in] sig_len The length of the signature
- * \return a new rdf with the signature
- */
-ldns_rdf *
-ldns_convert_ed448_rrsig_asn12rdf(const ldns_buffer *sig, long sig_len);
-
-/**
- * Converts the RRSIG signature RDF (from DNS) to a buffer with the
- * signature in ASN1 format as openssl uses it.
- * This routine is only present if ldns is compiled with ED448 support.
- *
- * \param[out] target_buffer buffer to place the signature data in ASN1.
- * \param[in] sig_rdf The signature rdf to convert
- * \return LDNS_STATUS_OK on success, error code otherwise
- */
-ldns_status
-ldns_convert_ed448_rrsig_rdf2asn1(ldns_buffer *target_buffer,
-        const ldns_rdf *sig_rdf);
-
 #endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
 
 #ifdef __cplusplus