Merge remote-tracking branch 'origin/vendor/LDNS'
authorzrj <zrj@dragonflybsd.org>
Wed, 24 Apr 2019 17:14:10 +0000 (20:14 +0300)
committerzrj <zrj@dragonflybsd.org>
Wed, 24 Apr 2019 17:14:10 +0000 (20:14 +0300)
1  2 
contrib/ldns/dnssec_verify.c
contrib/ldns/keys.c

@@@ -16,7 -16,7 +16,7 @@@
  #include <openssl/md5.h>
  
  ldns_dnssec_data_chain *
- ldns_dnssec_data_chain_new()
+ ldns_dnssec_data_chain_new(void)
  {
        ldns_dnssec_data_chain *nc = LDNS_CALLOC(ldns_dnssec_data_chain, 1);
          if(!nc) return NULL;
@@@ -216,7 -216,7 +216,7 @@@ ldns_dnssec_build_data_chain_other(ldns
        }
  }
  
- ldns_dnssec_data_chain *
static ldns_dnssec_data_chain *
  ldns_dnssec_build_data_chain_nokeyname(ldns_resolver *res,
                                         uint16_t qflags,
                                         ldns_rr *orig_rr,
@@@ -439,7 -439,7 +439,7 @@@ ldns_dnssec_build_data_chain(ldns_resol
  }
  
  ldns_dnssec_trust_tree *
- ldns_dnssec_trust_tree_new()
+ ldns_dnssec_trust_tree_new(void)
  {
        ldns_dnssec_trust_tree *new_tree = LDNS_XMALLOC(ldns_dnssec_trust_tree,
                                                                                   1);
@@@ -495,7 -495,7 +495,7 @@@ print_tabs(FILE *out, size_t nr, uint8_
        }
  }
  
- void
static void
  ldns_dnssec_trust_tree_print_sm_fmt(FILE *out, 
                const ldns_output_format *fmt,
                ldns_dnssec_trust_tree *tree,
        }
  }
  
- void
- ldns_dnssec_trust_tree_print_sm(FILE *out, 
-               ldns_dnssec_trust_tree *tree,
-               size_t tabs,
-               bool extended,
-               uint8_t *sibmap,
-               size_t treedepth)
- {
-       ldns_dnssec_trust_tree_print_sm_fmt(out, ldns_output_format_default, 
-                       tree, tabs, extended, sibmap, treedepth);
- }
  void
  ldns_dnssec_trust_tree_print_fmt(FILE *out, const ldns_output_format *fmt,
                ldns_dnssec_trust_tree *tree,
@@@ -1100,8 -1088,8 +1088,8 @@@ ldns_dnssec_trust_tree_contains_keys(ld
  
  ldns_status
  ldns_verify_time(
-               ldns_rr_list *rrset,
-               ldns_rr_list *rrsig, 
+               const ldns_rr_list *rrset,
+               const ldns_rr_list *rrsig, 
                const ldns_rr_list *keys, 
                time_t check_time,
                ldns_rr_list *good_keys
@@@ -1596,7 -1584,7 +1584,7 @@@ ldns_dnssec_verify_denial_nsec3_match( 
        ldns_rdf *zone_name;
        ldns_rdf *hashed_name;
        /* self assignment to suppress uninitialized warning */
 -      ldns_rdf *next_closer = next_closer;
 +      ldns_rdf *next_closer = NULL;
        ldns_rdf *hashed_next_closer;
        size_t i;
        ldns_status result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
@@@ -1821,7 -1809,7 +1809,7 @@@ ldns_dnssec_verify_denial_nsec3(ldns_r
  
  #ifdef USE_GOST
  EVP_PKEY*
- ldns_gost2pkey_raw(unsigned char* key, size_t keylen)
+ ldns_gost2pkey_raw(const unsigned char* key, size_t keylen)
  {
        /* prefix header for X509 encoding */
        uint8_t asn[37] = { 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85, 
  }
  
  static ldns_status
- ldns_verify_rrsig_gost_raw(unsigned char* sig, size_t siglen, 
-       ldns_buffer* rrset, unsigned char* key, size_t keylen)
+ ldns_verify_rrsig_gost_raw(const unsigned char* sig, size_t siglen, 
+       const ldns_buffer* rrset, const unsigned char* key, size_t keylen)
  {
        EVP_PKEY *evp_key;
        ldns_status result;
  }
  #endif
  
+ #ifdef USE_ED25519
+ EVP_PKEY*
+ ldns_ed255192pkey_raw(const unsigned char* key, size_t keylen)
+ {
+         const unsigned char* pp = key; /* pp gets modified by o2i() */
+         EVP_PKEY *evp_key;
+         EC_KEY *ec;
+       if(keylen != 32)
+               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;
+       }
+         return evp_key;
+ }
+ static ldns_status
+ ldns_verify_rrsig_ed25519_raw(unsigned char* sig, size_t siglen,
+       ldns_buffer* rrset, unsigned char* key, size_t keylen)
+ {
+         EVP_PKEY *evp_key;
+         ldns_status result;
+         evp_key = ldns_ed255192pkey_raw(key, keylen);
+         if(!evp_key) {
+               /* could not convert key */
+               return LDNS_STATUS_CRYPTO_BOGUS;
+         }
+       result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key,
+               EVP_sha512());
+       EVP_PKEY_free(evp_key);
+       return result;
+ }
+ #endif /* USE_ED25519 */
+ #ifdef USE_ED448
+ EVP_PKEY*
+ ldns_ed4482pkey_raw(const unsigned char* key, size_t keylen)
+ {
+         const unsigned char* pp = key; /* pp gets modified by o2i() */
+         EVP_PKEY *evp_key;
+         EC_KEY *ec;
+       if(keylen != 57)
+               return NULL; /* wrong length */
+         ec = EC_KEY_new_by_curve_name(NID_X448);
+       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;
+       }
+         return evp_key;
+ }
+ static ldns_status
+ ldns_verify_rrsig_ed448_raw(unsigned char* sig, size_t siglen,
+       ldns_buffer* rrset, unsigned char* key, size_t keylen)
+ {
+         EVP_PKEY *evp_key;
+         ldns_status result;
+         evp_key = ldns_ed4482pkey_raw(key, keylen);
+         if(!evp_key) {
+               /* could not convert key */
+               return LDNS_STATUS_CRYPTO_BOGUS;
+         }
+       result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key,
+               EVP_sha512());
+       EVP_PKEY_free(evp_key);
+       return result;
+ }
+ #endif /* USE_ED448 */
  #ifdef USE_ECDSA
  EVP_PKEY*
- ldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo)
+ ldns_ecdsa2pkey_raw(const unsigned char* key, size_t keylen, uint8_t algo)
  {
        unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
          const unsigned char* pp = buf;
@@@ -1947,6 -2029,7 +2029,7 @@@ ldns_verify_rrsig_buffers_raw(unsigned 
  {
        /* check for right key */
        switch(algo) {
+ #ifdef USE_DSA
        case LDNS_DSA:
        case LDNS_DSA_NSEC3:
                return ldns_verify_rrsig_dsa_raw(sig,
                                                                   key,
                                                                   keylen);
                break;
+ #endif
        case LDNS_RSASHA1:
        case LDNS_RSASHA1_NSEC3:
                return ldns_verify_rrsig_rsasha1_raw(sig,
                return ldns_verify_rrsig_ecdsa_raw(sig, siglen, verify_buf,
                        key, keylen, algo);
                break;
+ #endif
+ #ifdef USE_ED25519
+       case LDNS_ED25519:
+               return ldns_verify_rrsig_ed25519_raw(sig, siglen, verify_buf,
+                       key, keylen);
+               break;
+ #endif
+ #ifdef USE_ED448
+       case LDNS_ED448:
+               return ldns_verify_rrsig_ed448_raw(sig, siglen, verify_buf,
+                       key, keylen);
+               break;
  #endif
        case LDNS_RSAMD5:
                return ldns_verify_rrsig_rsamd5_raw(sig,
   * @param sig: signature to take TTL and wildcard values from
   */
  static void
- ldns_rrset_use_signature_ttl(ldns_rr_list* rrset_clone, ldns_rr* rrsig)
+ ldns_rrset_use_signature_ttl(ldns_rr_list* rrset_clone, const ldns_rr* rrsig)
  {
        uint32_t orig_ttl;
        uint16_t i;
   * @return OK or more specific error.
   */
  static ldns_status
- ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, ldns_rr* rrsig)
+ ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, const ldns_rr* rrsig)
  {
        uint8_t sig_algo;
         
                        return LDNS_STATUS_MEM_ERR;
                }
                break;
+ #ifdef USE_DSA
        case LDNS_DSA:
        case LDNS_DSA_NSEC3:
                /* EVP takes rfc2459 format, which is a tad longer than dns format */
                        return LDNS_STATUS_MEM_ERR;
                }
                break;
+ #endif
  #ifdef USE_ECDSA
          case LDNS_ECDSAP256SHA256:
          case LDNS_ECDSAP384SHA384:
                        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:
   * @return status code LDNS_STATUS_OK if all is fine.
   */
  static ldns_status
- ldns_rrsig_check_timestamps(ldns_rr* rrsig, time_t now)
+ ldns_rrsig_check_timestamps(const ldns_rr* rrsig, time_t now)
  {
        int32_t inception, expiration;
        
   */
  static ldns_status
  ldns_prepare_for_verify(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf, 
-       ldns_rr_list* rrset_clone, ldns_rr* rrsig)
+       ldns_rr_list* rrset_clone, const ldns_rr* rrsig)
  {
        ldns_status result;
  
   */
  static ldns_status
  ldns_verify_test_sig_key(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf, 
-       ldns_rr* rrsig, ldns_rr* key)
+       const ldns_rr* rrsig, ldns_rr* key)
  {
        uint8_t sig_algo;
         
   */
  ldns_status
  ldns_verify_rrsig_keylist_time(
-               ldns_rr_list *rrset,
-               ldns_rr *rrsig,
+               const ldns_rr_list *rrset,
+               const ldns_rr *rrsig,
                const ldns_rr_list *keys, 
                time_t check_time,
                ldns_rr_list *good_keys)
@@@ -2346,8 -2470,8 +2470,8 @@@ ldns_verify_rrsig_keylist(ldns_rr_list 
  }
  
  ldns_status
- ldns_verify_rrsig_keylist_notime(ldns_rr_list *rrset,
-                                        ldns_rr *rrsig,
+ ldns_verify_rrsig_keylist_notime(const ldns_rr_list *rrset,
+                                        const ldns_rr *rrsig,
                                         const ldns_rr_list *keys, 
                                         ldns_rr_list *good_keys)
  {
@@@ -2494,21 -2618,28 +2618,28 @@@ ldns_verify_rrsig_evp(ldns_buffer *sig
  }
  
  ldns_status
- ldns_verify_rrsig_evp_raw(unsigned char *sig, size_t siglen, 
-                                        ldns_buffer *rrset, EVP_PKEY *key, const EVP_MD *digest_type)
+ ldns_verify_rrsig_evp_raw(const unsigned char *sig, size_t siglen, 
+                                        const ldns_buffer *rrset, EVP_PKEY *key, const EVP_MD *digest_type)
  {
-       EVP_MD_CTX ctx;
+       EVP_MD_CTX *ctx;
        int res;
  
-       EVP_MD_CTX_init(&ctx);
+ #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)
+               return LDNS_STATUS_MEM_ERR;
        
-       EVP_VerifyInit(&ctx, digest_type);
-       EVP_VerifyUpdate(&ctx,
+       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);
+       res = EVP_VerifyFinal(ctx, sig, (unsigned int) siglen, key);
        
-       EVP_MD_CTX_cleanup(&ctx);
+       EVP_MD_CTX_destroy(ctx);
        
        if (res == 1) {
                return LDNS_STATUS_OK;
@@@ -2557,6 -2688,7 +2688,7 @@@ ldns_statu
  ldns_verify_rrsig_dsa_raw(unsigned char* sig, size_t siglen,
                                         ldns_buffer* rrset, unsigned char* key, size_t keylen)
  {
+ #ifdef USE_DSA
        EVP_PKEY *evp_key;
        ldns_status result;
  
                                                                siglen,
                                                                rrset,
                                                                evp_key,
-                                                               EVP_dss1());
+ # ifdef HAVE_EVP_DSS1
+                                                               EVP_dss1()
+ # else
+                                                               EVP_sha1()
+ # endif
+                                                               );
        } else {
                result = LDNS_STATUS_SSL_ERR;
        }
        EVP_PKEY_free(evp_key);
        return result;
+ #else
+       (void)sig; (void)siglen; (void)rrset; (void)key; (void)keylen;
+       return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL;
+ #endif
  }
  
  ldns_status
diff --combined contrib/ldns/keys.c
@@@ -16,9 -16,7 +16,9 @@@
  
  #ifdef HAVE_SSL
  #include <openssl/ssl.h>
 +#ifndef OPENSSL_NO_ENGINE
  #include <openssl/engine.h>
 +#endif
  #include <openssl/rand.h>
  #endif /* HAVE_SSL */
  
@@@ -37,16 -35,27 +37,27 @@@ ldns_lookup_table ldns_signing_algorith
          { LDNS_SIGN_ECDSAP256SHA256, "ECDSAP256SHA256" },
          { LDNS_SIGN_ECDSAP384SHA384, "ECDSAP384SHA384" },
  #endif
+ #ifdef USE_ED25519
+       { LDNS_SIGN_ED25519, "ED25519" },
+ #endif
+ #ifdef USE_ED448
+       { LDNS_SIGN_ED448, "ED448" },
+ #endif
+ #ifdef USE_DSA
          { LDNS_SIGN_DSA, "DSA" },
          { LDNS_SIGN_DSA_NSEC3, "DSA-NSEC3-SHA1" },
+ #endif
          { LDNS_SIGN_HMACMD5, "hmac-md5.sig-alg.reg.int" },
          { LDNS_SIGN_HMACSHA1, "hmac-sha1" },
          { LDNS_SIGN_HMACSHA256, "hmac-sha256" },
+         { LDNS_SIGN_HMACSHA224, "hmac-sha224" },
+         { LDNS_SIGN_HMACSHA384, "hmac-sha384" },
+         { LDNS_SIGN_HMACSHA512, "hmac-sha512" },
          { 0, NULL }
  };
  
  ldns_key_list *
- ldns_key_list_new()
+ ldns_key_list_new(void)
  {
        ldns_key_list *key_list = LDNS_MALLOC(ldns_key_list);
        if (!key_list) {
@@@ -59,7 -68,7 +70,7 @@@
  }
  
  ldns_key *
- ldns_key_new()
+ ldns_key_new(void)
  {
        ldns_key *newkey;
  
@@@ -90,7 -99,7 +101,7 @@@ ldns_key_new_frm_fp(ldns_key **k, FILE 
        return ldns_key_new_frm_fp_l(k, fp, NULL);
  }
  
 -#ifdef HAVE_SSL
 +#if defined(HAVE_SSL) && !defined(OPENSSL_NO_ENGINE)
  ldns_status
  ldns_key_new_frm_engine(ldns_key **key, ENGINE *e, char *key_id, ldns_algorithm alg)
  {
@@@ -246,7 -255,7 +257,7 @@@ ldns_key_new_frm_fp_ecdsa_l(FILE* fp, l
          BIGNUM* bn;
          EVP_PKEY* evp_key;
          EC_KEY* ec;
-       if (ldns_fget_keyword_data_l(fp, "PrivateKey", ": ", token, "\n", 
+       if (ldns_fget_keyword_data_l(fp, "PrivateKey", ": ", token, "\n",
                sizeof(token), line_nr) == -1)
                return NULL;
        if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK)
          return evp_key;
  }
  #endif
-       
+ #ifdef USE_ED25519
+ /** turn private key buffer into EC_KEY structure */
+ static EC_KEY*
+ 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
+        * 30320201010420 <32byteskey>
+        * andparameters a00b06092b06010401da470f01
+        * (noparameters, preamble is 30250201010420).
+        * the key is reversed (little endian).
+        */
+       buflen = pre_len + plen + post_len;
+       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);
+       pp = buf;
+       return d2i_ECPrivateKey(NULL, &pp, buflen);
+ }
+ /** read ED25519 private key */
+ static EVP_PKEY*
+ 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;
+       if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK)
+               return NULL;
+       /* we use d2i_ECPrivateKey because it calculates the public key
+        * 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 */
+       ec = 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*
+ ldns_ed448_priv_raw(uint8_t* pkey, int plen)
+ {
+       const unsigned char* pp;
+       uint8_t buf[256];
+       int buflen = 0;
+       uint8_t pre[] = {0x30, 0x4b, 0x02, 0x01, 0x01, 0x04, 0x39};
+       int pre_len = 7;
+       uint8_t post[] = {0xa0, 0x0b, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04,
+               0x01, 0xda, 0x47, 0x0f, 0x02};
+       int post_len = 13;
+       int i;
+       /* ASN looks like this for ED25519
+        * And for ED448, the parameters are ...02 instead of ...01
+        * For ED25519 it was:
+        * 30320201010420 <32byteskey>
+        * andparameters a00b06092b06010401da470f01
+        * (noparameters, preamble is 30250201010420).
+        * the key is reversed (little endian).
+        *
+        * For ED448 the key is 57 bytes, and that changes lengths.
+        * 304b0201010439 <57bytekey> a00b06092b06010401da470f02
+        */
+       buflen = pre_len + plen + post_len;
+       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);
+       pp = buf;
+       return d2i_ECPrivateKey(NULL, &pp, buflen);
+ }
+ /** read ED448 private key */
+ static EVP_PKEY*
+ 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;
+       if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK)
+               return NULL;
+       /* convert private key into ASN notation and then convert that */
+       ec = 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
  ldns_status
  ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr)
  {
        ldns_rr *key_rr;
  #ifdef HAVE_SSL
        RSA *rsa;
+ #ifdef USE_DSA
        DSA *dsa;
+ #endif
        unsigned char *hmac;
        size_t hmac_size;
  #endif /* HAVE_SSL */
                alg = (ldns_signing_algorithm)LDNS_DH;
        }
        if (strncmp(d, "3 DSA", 2) == 0) {
+ #ifdef USE_DSA
                alg = LDNS_SIGN_DSA;
+ #else
+ # ifdef STDERR_MSGS
+               fprintf(stderr, "Warning: DSA not compiled into this ");
+               fprintf(stderr, "version of ldns\n");
+ # endif
+ #endif
        }
        if (strncmp(d, "4 ECC", 2) == 0) {
                alg = (ldns_signing_algorithm)LDNS_ECC;
                alg = LDNS_SIGN_RSASHA1;
        }
        if (strncmp(d, "6 DSA", 2) == 0) {
+ #ifdef USE_DSA
                alg = LDNS_SIGN_DSA_NSEC3;
+ #else
+ # ifdef STDERR_MSGS
+               fprintf(stderr, "Warning: DSA not compiled into this ");
+               fprintf(stderr, "version of ldns\n");
+ # endif
+ #endif
        }
        if (strncmp(d, "7 RSASHA1", 2) == 0) {
                alg = LDNS_SIGN_RSASHA1_NSEC3;
  #ifdef USE_SHA2
                alg = LDNS_SIGN_RSASHA256;
  #else
+ # ifdef STDERR_MSGS
                fprintf(stderr, "Warning: SHA256 not compiled into this ");
                fprintf(stderr, "version of ldns\n");
+ # endif
  #endif
        }
        if (strncmp(d, "10 RSASHA512", 3) == 0) {
  #ifdef USE_SHA2
                alg = LDNS_SIGN_RSASHA512;
  #else
+ # ifdef STDERR_MSGS
                fprintf(stderr, "Warning: SHA512 not compiled into this ");
                fprintf(stderr, "version of ldns\n");
+ # endif
  #endif
        }
        if (strncmp(d, "12 ECC-GOST", 3) == 0) {
  #ifdef USE_GOST
                alg = LDNS_SIGN_ECC_GOST;
  #else
+ # ifdef STDERR_MSGS
                fprintf(stderr, "Warning: ECC-GOST not compiled into this ");
                fprintf(stderr, "version of ldns, use --enable-gost\n");
+ # endif
  #endif
        }
        if (strncmp(d, "13 ECDSAP256SHA256", 3) == 0) {
  #ifdef USE_ECDSA
                  alg = LDNS_SIGN_ECDSAP256SHA256;
  #else
+ # ifdef STDERR_MSGS
                fprintf(stderr, "Warning: ECDSA not compiled into this ");
                fprintf(stderr, "version of ldns, use --enable-ecdsa\n");
+ # endif
  #endif
          }
        if (strncmp(d, "14 ECDSAP384SHA384", 3) == 0) {
  #ifdef USE_ECDSA
                  alg = LDNS_SIGN_ECDSAP384SHA384;
  #else
+ # ifdef STDERR_MSGS
                fprintf(stderr, "Warning: ECDSA not compiled into this ");
                fprintf(stderr, "version of ldns, use --enable-ecdsa\n");
+ # endif
+ #endif
+         }
+       if (strncmp(d, "15 ED25519", 3) == 0) {
+ #ifdef USE_ED25519
+                 alg = LDNS_SIGN_ED25519;
+ #else
+ # ifdef STDERR_MSGS
+               fprintf(stderr, "Warning: ED25519 not compiled into this ");
+               fprintf(stderr, "version of ldns, use --enable-ed25519\n");
+ # endif
+ #endif
+         }
+       if (strncmp(d, "16 ED448", 3) == 0) {
+ #ifdef USE_ED448
+                 alg = LDNS_SIGN_ED448;
+ #else
+ # ifdef STDERR_MSGS
+               fprintf(stderr, "Warning: ED448 not compiled into this ");
+               fprintf(stderr, "version of ldns, use --enable-ed448\n");
+ # endif
  #endif
          }
        if (strncmp(d, "157 HMAC-MD5", 4) == 0) {
        if (strncmp(d, "159 HMAC-SHA256", 4) == 0) {
                alg = LDNS_SIGN_HMACSHA256;
        }
+       /* For compatibility with dnssec-keygen */
+       if (strncmp(d, "161 ", 4) == 0) {
+               alg = LDNS_SIGN_HMACSHA1;
+       }
+       if (strncmp(d, "162 HMAC-SHA224", 4) == 0) {
+               alg = LDNS_SIGN_HMACSHA224;
+       }
+       /* For compatibility with dnssec-keygen */
+       if (strncmp(d, "163 ", 4) == 0) {
+               alg = LDNS_SIGN_HMACSHA256;
+       }
+       if (strncmp(d, "164 HMAC-SHA384", 4) == 0) {
+               alg = LDNS_SIGN_HMACSHA384;
+       }
+       if (strncmp(d, "165 HMAC-SHA512", 4) == 0) {
+               alg = LDNS_SIGN_HMACSHA512;
+       }
        LDNS_FREE(d);
  
        switch(alg) {
                        ldns_key_assign_rsa_key(k, rsa);
  #endif /* HAVE_SSL */
                        break;
+ #ifdef USE_DSA
                case LDNS_SIGN_DSA:
                case LDNS_SIGN_DSA_NSEC3:
                        ldns_key_set_algorithm(k, alg);
                        ldns_key_assign_dsa_key(k, dsa);
  #endif /* HAVE_SSL */
                        break;
+ #endif /* USE_DSA */
                case LDNS_SIGN_HMACMD5:
                case LDNS_SIGN_HMACSHA1:
+               case LDNS_SIGN_HMACSHA224:
                case LDNS_SIGN_HMACSHA256:
+               case LDNS_SIGN_HMACSHA384:
+               case LDNS_SIGN_HMACSHA512:
                        ldns_key_set_algorithm(k, alg);
  #ifdef HAVE_SSL
                        hmac = ldns_key_new_frm_fp_hmac_l(fp, line_nr, &hmac_size);
                        }
  #endif /* splint */
                        break;
+ #endif
+ #ifdef USE_ED25519
+               case LDNS_SIGN_ED25519:
+                         ldns_key_set_algorithm(k, alg);
+                         ldns_key_set_evp_key(k,
+                                 ldns_key_new_frm_fp_ed25519_l(fp, line_nr));
+ #ifndef S_SPLINT_S
+                       if(!k->_key.key) {
+                               ldns_key_free(k);
+                               return LDNS_STATUS_ERR;
+                       }
+ #endif /* splint */
+                       break;
+ #endif
+ #ifdef USE_ED448
+               case LDNS_SIGN_ED448:
+                         ldns_key_set_algorithm(k, alg);
+                         ldns_key_set_evp_key(k,
+                                 ldns_key_new_frm_fp_ed448_l(fp, line_nr));
+ #ifndef S_SPLINT_S
+                       if(!k->_key.key) {
+                               ldns_key_free(k);
+                               return LDNS_STATUS_ERR;
+                       }
+ #endif /* splint */
+                       break;
  #endif
                default:
                        ldns_key_free(k);
@@@ -544,15 -798,17 +800,17 @@@ ldns_key_new_frm_fp_rsa_l(FILE *f, int 
           *     // ...
         *
         */
-       char *d;
+       char *b;
        RSA *rsa;
        uint8_t *buf;
        int i;
+       BIGNUM *n=NULL, *e=NULL, *d=NULL, *p=NULL, *q=NULL,
+               *dmp1=NULL, *dmq1=NULL, *iqmp=NULL;
  
-       d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
+       b = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
        buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN);
        rsa = RSA_new();
-       if (!d || !rsa || !buf) {
+       if (!b || !rsa || !buf) {
                  goto error;
        }
  
         */
  
        /* Modules, rsa->n */
-       if (ldns_fget_keyword_data_l(f, "Modulus", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
+       if (ldns_fget_keyword_data_l(f, "Modulus", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
                goto error;
        }
-       i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
+       i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b)));
  #ifndef S_SPLINT_S
-       rsa->n = BN_bin2bn((const char unsigned*)buf, i, NULL);
-       if (!rsa->n) {
+       n = BN_bin2bn((const char unsigned*)buf, i, NULL);
+       if (!n) {
                goto error;
        }
  
        /* PublicExponent, rsa->e */
-       if (ldns_fget_keyword_data_l(f, "PublicExponent", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
+       if (ldns_fget_keyword_data_l(f, "PublicExponent", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
                goto error;
        }
-       i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
-       rsa->e = BN_bin2bn((const char unsigned*)buf, i, NULL);
-       if (!rsa->e) {
+       i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b)));
+       e = BN_bin2bn((const char unsigned*)buf, i, NULL);
+       if (!e) {
                goto error;
        }
  
        /* PrivateExponent, rsa->d */
-       if (ldns_fget_keyword_data_l(f, "PrivateExponent", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
+       if (ldns_fget_keyword_data_l(f, "PrivateExponent", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
                goto error;
        }
-       i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
-       rsa->d = BN_bin2bn((const char unsigned*)buf, i, NULL);
-       if (!rsa->d) {
+       i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b)));
+       d = BN_bin2bn((const char unsigned*)buf, i, NULL);
+       if (!d) {
                goto error;
        }
  
        /* Prime1, rsa->p */
-       if (ldns_fget_keyword_data_l(f, "Prime1", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
+       if (ldns_fget_keyword_data_l(f, "Prime1", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
                goto error;
        }
-       i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
-       rsa->p = BN_bin2bn((const char unsigned*)buf, i, NULL);
-       if (!rsa->p) {
+       i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b)));
+       p = BN_bin2bn((const char unsigned*)buf, i, NULL);
+       if (!p) {
                goto error;
        }
  
        /* Prime2, rsa->q */
-       if (ldns_fget_keyword_data_l(f, "Prime2", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
+       if (ldns_fget_keyword_data_l(f, "Prime2", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
                goto error;
        }
-       i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
-       rsa->q = BN_bin2bn((const char unsigned*)buf, i, NULL);
-       if (!rsa->q) {
+       i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b)));
+       q = BN_bin2bn((const char unsigned*)buf, i, NULL);
+       if (!q) {
                goto error;
        }
  
        /* Exponent1, rsa->dmp1 */
-       if (ldns_fget_keyword_data_l(f, "Exponent1", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
+       if (ldns_fget_keyword_data_l(f, "Exponent1", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
                goto error;
        }
-       i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
-       rsa->dmp1 = BN_bin2bn((const char unsigned*)buf, i, NULL);
-       if (!rsa->dmp1) {
+       i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b)));
+       dmp1 = BN_bin2bn((const char unsigned*)buf, i, NULL);
+       if (!dmp1) {
                goto error;
        }
  
        /* Exponent2, rsa->dmq1 */
-       if (ldns_fget_keyword_data_l(f, "Exponent2", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
+       if (ldns_fget_keyword_data_l(f, "Exponent2", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
                goto error;
        }
-       i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
-       rsa->dmq1 = BN_bin2bn((const char unsigned*)buf, i, NULL);
-       if (!rsa->dmq1) {
+       i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b)));
+       dmq1 = BN_bin2bn((const char unsigned*)buf, i, NULL);
+       if (!dmq1) {
                goto error;
        }
  
        /* Coefficient, rsa->iqmp */
-       if (ldns_fget_keyword_data_l(f, "Coefficient", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
+       if (ldns_fget_keyword_data_l(f, "Coefficient", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
                goto error;
        }
-       i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
-       rsa->iqmp = BN_bin2bn((const char unsigned*)buf, i, NULL);
-       if (!rsa->iqmp) {
+       i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b)));
+       iqmp = BN_bin2bn((const char unsigned*)buf, i, NULL);
+       if (!iqmp) {
                goto error;
        }
  #endif /* splint */
  
+ #if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
+ # ifndef S_SPLINT_S
+       rsa->n = n;
+       rsa->e = e;
+       rsa->d = d;
+       rsa->p = p;
+       rsa->q = q;
+       rsa->dmp1 = dmp1;
+       rsa->dmq1 = dmq1;
+       rsa->iqmp = iqmp;
+ # endif
+ #else
+       if(!RSA_set0_key(rsa, n, e, d))
+               goto error;
+       n = NULL;
+       e = NULL;
+       d = NULL;
+       if(!RSA_set0_factors(rsa, p, q))
+               goto error;
+       p = NULL;
+       q = NULL;
+       if(!RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp))
+               goto error;
+ #endif
        LDNS_FREE(buf);
-       LDNS_FREE(d);
+       LDNS_FREE(b);
        return rsa;
  
  error:
        RSA_free(rsa);
-       LDNS_FREE(d);
+       LDNS_FREE(b);
        LDNS_FREE(buf);
+       BN_free(n);
+       BN_free(e);
+       BN_free(d);
+       BN_free(p);
+       BN_free(q);
+       BN_free(dmp1);
+       BN_free(dmq1);
+       BN_free(iqmp);
        return NULL;
  }
  
@@@ -666,6 -955,7 +957,7 @@@ ldns_key_new_frm_fp_dsa_l(FILE *f, ATTR
        char *d;
        DSA *dsa;
        uint8_t *buf;
+       BIGNUM *p=NULL, *q=NULL, *g=NULL, *priv_key=NULL, *pub_key=NULL;
  
        d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
        buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN);
        }
        i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
  #ifndef S_SPLINT_S
-       dsa->p = BN_bin2bn((const char unsigned*)buf, i, NULL);
-       if (!dsa->p) {
+       p = BN_bin2bn((const char unsigned*)buf, i, NULL);
+       if (!p) {
                goto error;
        }
  
                goto error;
        }
        i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
-       dsa->q = BN_bin2bn((const char unsigned*)buf, i, NULL);
-       if (!dsa->q) {
+       q = BN_bin2bn((const char unsigned*)buf, i, NULL);
+       if (!q) {
                goto error;
        }
  
                goto error;
        }
        i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
-       dsa->g = BN_bin2bn((const char unsigned*)buf, i, NULL);
-       if (!dsa->g) {
+       g = BN_bin2bn((const char unsigned*)buf, i, NULL);
+       if (!g) {
                goto error;
        }
  
                goto error;
        }
        i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
-       dsa->priv_key = BN_bin2bn((const char unsigned*)buf, i, NULL);
-       if (!dsa->priv_key) {
+       priv_key = BN_bin2bn((const char unsigned*)buf, i, NULL);
+       if (!priv_key) {
                goto error;
        }
  
                goto error;
        }
        i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
-       dsa->pub_key = BN_bin2bn((const char unsigned*)buf, i, NULL);
-       if (!dsa->pub_key) {
+       pub_key = BN_bin2bn((const char unsigned*)buf, i, NULL);
+       if (!pub_key) {
                goto error;
        }
  #endif /* splint */
  
+ #if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
+ # ifndef S_SPLINT_S
+       dsa->p = p;
+       dsa->q = q;
+       dsa->g = g;
+       dsa->priv_key = priv_key;
+       dsa->pub_key = pub_key;
+ # endif
+ #else
+       if(!DSA_set0_pqg(dsa, p, q, g))
+               goto error;
+       p = NULL;
+       q = NULL;
+       g = NULL;
+       if(!DSA_set0_key(dsa, pub_key, priv_key))
+               goto error;
+ #endif
        LDNS_FREE(buf);
        LDNS_FREE(d);
  
@@@ -737,6 -1045,11 +1047,11 @@@ error
        LDNS_FREE(d);
        LDNS_FREE(buf);
          DSA_free(dsa);
+       BN_free(p);
+       BN_free(q);
+       BN_free(g);
+       BN_free(priv_key);
+       BN_free(pub_key);
        return NULL;
  }
  
@@@ -812,11 -1125,17 +1127,17 @@@ ldns_key_new_frm_algorithm(ldns_signing
  {
        ldns_key *k;
  #ifdef HAVE_SSL
+ #ifdef USE_DSA
        DSA *d;
-       RSA *r;
+ #endif /* USE_DSA */
  #  ifdef USE_ECDSA
          EC_KEY *ec = NULL;
  #  endif
+ #  ifdef HAVE_EVP_PKEY_KEYGEN
+       EVP_PKEY_CTX *ctx;
+ #  else
+       RSA *r;
+ #  endif
  #else
        int i;
        uint16_t offset = 0;
                case LDNS_SIGN_RSASHA256:
                case LDNS_SIGN_RSASHA512:
  #ifdef HAVE_SSL
+ #ifdef HAVE_EVP_PKEY_KEYGEN
+                       ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
+                       if(!ctx) {
+                               ldns_key_free(k);
+                               return NULL;
+                       }
+                       if(EVP_PKEY_keygen_init(ctx) <= 0) {
+                               ldns_key_free(k);
+                               EVP_PKEY_CTX_free(ctx);
+                               return NULL;
+                       }
+                       if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, size) <= 0) {
+                               ldns_key_free(k);
+                               EVP_PKEY_CTX_free(ctx);
+                               return NULL;
+                       }
+ #ifndef S_SPLINT_S
+                       if (EVP_PKEY_keygen(ctx, &k->_key.key) <= 0) {
+                               ldns_key_free(k);
+                               EVP_PKEY_CTX_free(ctx);
+                               return NULL;
+                       }
+ #endif
+                       EVP_PKEY_CTX_free(ctx);
+ #else /* HAVE_EVP_PKEY_KEYGEN */
                        r = RSA_generate_key((int)size, RSA_F4, NULL, NULL);
                          if(!r) {
                                ldns_key_free(k);
                        }
                        ldns_key_set_rsa_key(k, r);
                        RSA_free(r);
+ #endif /* HAVE_EVP_PKEY_KEYGEN */
  #endif /* HAVE_SSL */
                        break;
                case LDNS_SIGN_DSA:
                case LDNS_SIGN_DSA_NSEC3:
+ #ifdef USE_DSA
  #ifdef HAVE_SSL
+ # if OPENSSL_VERSION_NUMBER < 0x00908000L
                        d = DSA_generate_parameters((int)size, NULL, 0, NULL, NULL, NULL, NULL);
                        if (!d) {
                                ldns_key_free(k);
                                return NULL;
                        }
+ # else
+                       if (! (d = DSA_new())) {
+                               ldns_key_free(k);
+                               return NULL;
+                       }
+                       if (! DSA_generate_parameters_ex(d, (int)size, NULL, 0, NULL, NULL, NULL)) {
+                               DSA_free(d);
+                               ldns_key_free(k);
+                               return NULL;
+                       }
+ # endif
                        if (DSA_generate_key(d) != 1) {
                                ldns_key_free(k);
                                return NULL;
                        ldns_key_set_dsa_key(k, d);
                        DSA_free(d);
  #endif /* HAVE_SSL */
+ #endif /* USE_DSA */
                        break;
                case LDNS_SIGN_HMACMD5:
                case LDNS_SIGN_HMACSHA1:
+               case LDNS_SIGN_HMACSHA224:
                case LDNS_SIGN_HMACSHA256:
+               case LDNS_SIGN_HMACSHA384:
+               case LDNS_SIGN_HMACSHA512:
  #ifdef HAVE_SSL
  #ifndef S_SPLINT_S
                        k->_key.key = NULL;
                        return NULL;
  #endif /* ECDSA */
                        break;
+ #ifdef USE_ED25519
+               case LDNS_SIGN_ED25519:
+ #ifdef HAVE_EVP_PKEY_KEYGEN
+                       ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
+                       if(!ctx) {
+                               ldns_key_free(k);
+                               return NULL;
+                       }
+                       if(EVP_PKEY_keygen_init(ctx) <= 0) {
+                               ldns_key_free(k);
+                               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);
+                               return NULL;
+                       }
+                       EVP_PKEY_CTX_free(ctx);
+ #endif
+                       break;
+ #endif /* ED25519 */
+ #ifdef USE_ED448
+               case LDNS_SIGN_ED448:
+ #ifdef HAVE_EVP_PKEY_KEYGEN
+                       ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
+                       if(!ctx) {
+                               ldns_key_free(k);
+                               return NULL;
+                       }
+                       if(EVP_PKEY_keygen_init(ctx) <= 0) {
+                               ldns_key_free(k);
+                               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);
+                               return NULL;
+                       }
+                       EVP_PKEY_CTX_free(ctx);
+ #endif
+                       break;
+ #endif /* ED448 */
        }
        ldns_key_set_algorithm(k, alg);
        return k;
@@@ -997,9 -1416,13 +1418,13 @@@ ldns_key_set_rsa_key(ldns_key *k, RSA *
  void
  ldns_key_set_dsa_key(ldns_key *k, DSA *d)
  {
+ #ifdef USE_DSA
        EVP_PKEY *key = EVP_PKEY_new();
        EVP_PKEY_set1_DSA(key, d);
        k->_key.key  = key;
+ #else
+       (void)k; (void)d;
+ #endif
  }
  
  void
@@@ -1013,9 -1436,13 +1438,13 @@@ ldns_key_assign_rsa_key(ldns_key *k, RS
  void
  ldns_key_assign_dsa_key(ldns_key *k, DSA *d)
  {
+ #ifdef USE_DSA
        EVP_PKEY *key = EVP_PKEY_new();
        EVP_PKEY_assign_DSA(key, d);
        k->_key.key  = key;
+ #else
+       (void)k; (void)d;
+ #endif
  }
  #endif /* splint */
  #endif /* HAVE_SSL */
@@@ -1129,11 -1556,16 +1558,16 @@@ ldns_key_rsa_key(const ldns_key *k
  DSA *
  ldns_key_dsa_key(const ldns_key *k)
  {
+ #ifdef USE_DSA
        if (k->_key.key) {
                return EVP_PKEY_get1_DSA(k->_key.key);
        } else {
                return NULL;
        }
+ #else
+       (void)k;
+       return NULL;
+ #endif
  }
  #endif /* splint */
  #endif /* HAVE_SSL */
@@@ -1276,63 -1708,87 +1710,87 @@@ static boo
  ldns_key_rsa2bin(unsigned char *data, RSA *k, uint16_t *size)
  {
        int i,j;
+       const BIGNUM *n=NULL, *e=NULL;
        
        if (!k) {
                return false;
        }
+ #if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
+       n = k->n;
+       e = k->e;
+ #else
+       RSA_get0_key(k, &n, &e, NULL);
+ #endif
        
-       if (BN_num_bytes(k->e) <= 256) {
+       if (BN_num_bytes(e) <= 256) {
                /* normally only this path is executed (small factors are
                 * more common 
                 */
-               data[0] = (unsigned char) BN_num_bytes(k->e);
-               i = BN_bn2bin(k->e, data + 1);  
-               j = BN_bn2bin(k->n, data + i + 1);
+               data[0] = (unsigned char) BN_num_bytes(e);
+               i = BN_bn2bin(e, data + 1);  
+               j = BN_bn2bin(n, data + i + 1);
                *size = (uint16_t) i + j;
-       } else if (BN_num_bytes(k->e) <= 65536) {
+       } else if (BN_num_bytes(e) <= 65536) {
                data[0] = 0;
                /* BN_bn2bin does bigendian, _uint16 also */
-               ldns_write_uint16(data + 1, (uint16_t) BN_num_bytes(k->e)); 
+               ldns_write_uint16(data + 1, (uint16_t) BN_num_bytes(e)); 
  
-               BN_bn2bin(k->e, data + 3); 
-               BN_bn2bin(k->n, data + 4 + BN_num_bytes(k->e));
-               *size = (uint16_t) BN_num_bytes(k->n) + 6;
+               BN_bn2bin(e, data + 3); 
+               BN_bn2bin(n, data + 4 + BN_num_bytes(e));
+               *size = (uint16_t) BN_num_bytes(n) + 6;
        } else {
                return false;
        }
        return true;
  }
  
+ #ifdef USE_DSA
  /* data pointer must be large enough (LDNS_MAX_KEYLEN) */
  static bool
  ldns_key_dsa2bin(unsigned char *data, DSA *k, uint16_t *size)
  {
        uint8_t T;
+       const BIGNUM *p, *q, *g;
+       const BIGNUM *pub_key, *priv_key;
  
        if (!k) {
                return false;
        }
        
        /* See RFC2536 */
-       *size = (uint16_t)BN_num_bytes(k->p);
+ # ifdef HAVE_DSA_GET0_PQG
+       DSA_get0_pqg(k, &p, &q, &g);
+ # else
+       p = k->p; q = k->q; g = k->g;
+ # endif
+ # ifdef HAVE_DSA_GET0_KEY
+       DSA_get0_key(k, &pub_key, &priv_key);
+ # else
+       pub_key = k->pub_key; priv_key = k->priv_key;
+ # endif
+       (void)priv_key;
+       *size = (uint16_t)BN_num_bytes(p);
        T = (*size - 64) / 8;
-       memcpy(data, &T, 1);
  
        if (T > 8) {
+ #ifdef STDERR_MSGS
                fprintf(stderr, "DSA key with T > 8 (ie. > 1024 bits)");
                fprintf(stderr, " not implemented\n");
+ #endif
                return false;
        }
  
        /* size = 64 + (T * 8); */
+       memset(data, 0, 21 + *size * 3);
        data[0] = (unsigned char)T;
-       BN_bn2bin(k->q, data + 1 );             /* 20 octects */
-       BN_bn2bin(k->p, data + 21 );            /* offset octects */
-       BN_bn2bin(k->g, data + 21 + *size);     /* offset octets */
-       BN_bn2bin(k->pub_key, data + 21 + *size + *size); /* offset octets */
-       *size = 21 + (*size * 3);
+       BN_bn2bin(q, data + 1 );                /* 20 octects */
+       BN_bn2bin(p, data + 21 );               /* offset octects */
+       BN_bn2bin(g, data + 21 + *size * 2 - BN_num_bytes(g));
+       BN_bn2bin(pub_key,data + 21 + *size * 3 - BN_num_bytes(pub_key));
+       *size = 21 + *size * 3;
        return true;
  }
+ #endif /* USE_DSA */
  
  #ifdef USE_GOST
  static bool
@@@ -1342,13 -1798,13 +1800,13 @@@ ldns_key_gost2bin(unsigned char* data, 
        unsigned char* pp = NULL;
        if(i2d_PUBKEY(k, &pp) != 37 + 64) {
                /* expect 37 byte(ASN header) and 64 byte(X and Y) */
-               CRYPTO_free(pp);
+               free(pp);
                return false;
        }
        /* omit ASN header */
        for(i=0; i<64; i++)
                data[i] = pp[i+37];
-       CRYPTO_free(pp);
+       free(pp);
        *size = 64;
        return true;
  }
@@@ -1370,7 -1826,9 +1828,9 @@@ ldns_key2rr(const ldns_key *k
        uint16_t size = 0;
  #ifdef HAVE_SSL
        RSA *rsa = NULL;
+ #ifdef USE_DSA
        DSA *dsa = NULL;
+ #endif /* USE_DSA */
  #endif /* HAVE_SSL */
  #ifdef USE_ECDSA
          EC_KEY* ec;
        switch (ldns_key_algorithm(k)) {
        case LDNS_SIGN_HMACMD5:
        case LDNS_SIGN_HMACSHA1:
+       case LDNS_SIGN_HMACSHA224:
        case LDNS_SIGN_HMACSHA256:
+       case LDNS_SIGN_HMACSHA384:
+       case LDNS_SIGN_HMACSHA512:
                ldns_rr_set_type(pubkey, LDNS_RR_TYPE_KEY);
                break;
        default:
                case LDNS_SIGN_DSA:
                        ldns_rr_push_rdf(pubkey,
                                        ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA));
+ #ifdef USE_DSA
  #ifdef HAVE_SSL
                        dsa = ldns_key_dsa_key(k);
                        if (dsa) {
                                internal_data = 1;
                        }
  #endif /* HAVE_SSL */
+ #endif /* USE_DSA */
                        break;
                case LDNS_SIGN_DSA_NSEC3:
                        ldns_rr_push_rdf(pubkey,
                                        ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA_NSEC3));
+ #ifdef USE_DSA
  #ifdef HAVE_SSL
                        dsa = ldns_key_dsa_key(k);
                        if (dsa) {
                                internal_data = 1;
                        }
  #endif /* HAVE_SSL */
+ #endif /* USE_DSA */
                        break;
                case LDNS_SIGN_ECC_GOST:
                        ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8(
                        return NULL;
  #endif /* ECDSA */
                          break;
+ #ifdef USE_ED25519
+                 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);
+                                 ldns_rr_free(pubkey);
+                                 return NULL;
+                         }
+                         /* down the reference count for ec, its still assigned
+                          * to the pkey */
+                         EC_KEY_free(ec);
+                       internal_data = 1;
+                       break;
+ #endif
+ #ifdef USE_ED448
+                 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);
+                                 ldns_rr_free(pubkey);
+                                 return NULL;
+                         }
+                         /* down the reference count for ec, its still assigned
+                          * to the pkey */
+                         EC_KEY_free(ec);
+                       internal_data = 1;
+                       break;
+ #endif
                case LDNS_SIGN_HMACMD5:
                case LDNS_SIGN_HMACSHA1:
+               case LDNS_SIGN_HMACSHA224:
                case LDNS_SIGN_HMACSHA256:
+               case LDNS_SIGN_HMACSHA384:
+               case LDNS_SIGN_HMACSHA512:
                        bin = LDNS_XMALLOC(unsigned char, ldns_key_hmac_size(k));
                        if (!bin) {
                                  ldns_rr_free(pubkey);
@@@ -1607,7 -2113,9 +2115,9 @@@ ldns_read_anchor_file(const char *filen
  
        fp = fopen(filename, "r");
        if (!fp) {
+ #ifdef STDERR_MSGS
                fprintf(stderr, "Unable to open %s: %s\n", filename, strerror(errno));
+ #endif
                LDNS_FREE(line);
                return NULL;
        }
        fclose(fp);
        
        if (i <= 0) {
+ #ifdef STDERR_MSGS
                fprintf(stderr, "nothing read from %s", filename);
+ #endif
                LDNS_FREE(line);
                return NULL;
        } else {
                        LDNS_FREE(line);
                        return r;
                } else {
+ #ifdef STDERR_MSGS
                        fprintf(stderr, "Error creating DNSKEY or DS rr from %s: %s\n", filename, ldns_get_errorstr_by_id(status));
+ #endif
                        LDNS_FREE(line);
                        return NULL;
                }
  }
  
  char *
- ldns_key_get_file_base_name(ldns_key *key)
+ ldns_key_get_file_base_name(const ldns_key *key)
  {
        ldns_buffer *buffer;
        char *file_base_name;
@@@ -1675,7 -2187,9 +2189,9 @@@ ldns_signing_algorithm ldns_get_signing
                  {LDNS_SIGN_DSA_NSEC3, "NSEC3DSA"},
                  {LDNS_SIGN_RSASHA1_NSEC3, "NSEC3RSASHA1"},
                  /* old ldns usage, now RFC names */
+ #ifdef USE_DSA
                  {LDNS_SIGN_DSA_NSEC3, "DSA_NSEC3" },
+ #endif
                  {LDNS_SIGN_RSASHA1_NSEC3, "RSASHA1_NSEC3" },
  #ifdef USE_GOST
                  {LDNS_SIGN_ECC_GOST, "GOST"},
                  {LDNS_PRIVATEOID, "PRIVATEOID"},
                  {0, NULL}};
          ldns_lookup_table* lt = ldns_signing_algorithms;
+       ldns_signing_algorithm a;
+       char *endptr;
          while(lt->name) {
                  if(strcasecmp(lt->name, name) == 0)
                          return lt->id;
                          return lt->id;
                  lt++;
          }
-         if(atoi(name) != 0)
-                 return atoi(name);
+       a = strtol(name, &endptr, 10);
+       if (*name && !*endptr)
+               return a;
          return 0;
  }