Merge remote-tracking branch 'origin/vendor/LDNS'
[dragonfly.git] / contrib / ldns / dnssec_verify.c
index d8d4664..8ba4c81 100644 (file)
@@ -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 @@ ldns_dnssec_build_data_chain_other(ldns_resolver *res,
        }
 }
 
-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 @@ ldns_dnssec_build_data_chain(ldns_resolver *res,
 }
 
 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 @@ print_tabs(FILE *out, size_t nr, uint8_t *map, size_t treedepth)
        }
 }
 
-void
+static void
 ldns_dnssec_trust_tree_print_sm_fmt(FILE *out, 
                const ldns_output_format *fmt,
                ldns_dnssec_trust_tree *tree,
@@ -628,18 +628,6 @@ ldns_dnssec_trust_tree_print_sm_fmt(FILE *out,
        }
 }
 
-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 @@ ldns_dnssec_trust_tree_contains_keys(ldns_dnssec_trust_tree *tree,
 
 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
@@ -1821,7 +1809,7 @@ ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
 
 #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, 
@@ -1844,8 +1832,8 @@ ldns_gost2pkey_raw(unsigned char* key, size_t keylen)
 }
 
 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;
@@ -1866,9 +1854,103 @@ ldns_verify_rrsig_gost_raw(unsigned char* sig, size_t siglen,
 }
 #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 @@ ldns_verify_rrsig_buffers_raw(unsigned char* sig, size_t siglen,
 {
        /* check for right key */
        switch(algo) {
+#ifdef USE_DSA
        case LDNS_DSA:
        case LDNS_DSA_NSEC3:
                return ldns_verify_rrsig_dsa_raw(sig,
@@ -1955,6 +2038,7 @@ ldns_verify_rrsig_buffers_raw(unsigned char* sig, size_t siglen,
                                                                   key,
                                                                   keylen);
                break;
+#endif
        case LDNS_RSASHA1:
        case LDNS_RSASHA1_NSEC3:
                return ldns_verify_rrsig_rsasha1_raw(sig,
@@ -1991,6 +2075,18 @@ ldns_verify_rrsig_buffers_raw(unsigned char* sig, size_t siglen,
                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,
@@ -2014,7 +2110,7 @@ ldns_verify_rrsig_buffers_raw(unsigned char* sig, size_t siglen,
  * @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;
@@ -2063,7 +2159,7 @@ ldns_rrset_use_signature_ttl(ldns_rr_list* rrset_clone, ldns_rr* rrsig)
  * @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;
        
@@ -2100,6 +2196,7 @@ ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, ldns_rr* rrsig)
                        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 */
@@ -2116,6 +2213,7 @@ ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, ldns_rr* rrsig)
                        return LDNS_STATUS_MEM_ERR;
                }
                break;
+#endif
 #ifdef USE_ECDSA
         case LDNS_ECDSAP256SHA256:
         case LDNS_ECDSAP384SHA384:
@@ -2130,6 +2228,32 @@ ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, 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:
@@ -2148,7 +2272,7 @@ ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, ldns_rr* rrsig)
  * @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;
        
@@ -2183,7 +2307,7 @@ ldns_rrsig_check_timestamps(ldns_rr* rrsig, time_t now)
  */
 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;
 
@@ -2230,7 +2354,7 @@ ldns_prepare_for_verify(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf,
  */
 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;
        
@@ -2297,8 +2421,8 @@ ldns_verify_test_sig_key(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf,
  */
 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 @@ ldns_verify_rrsig_keylist(ldns_rr_list *rrset,
 }
 
 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 @@ 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 @@ ldns_status
 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;
 
@@ -2566,13 +2698,21 @@ ldns_verify_rrsig_dsa_raw(unsigned char* sig, size_t siglen,
                                                                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