diff options
author | Dag-Erling Smørgrav <des@FreeBSD.org> | 2017-02-03 13:01:00 +0000 |
---|---|---|
committer | Dag-Erling Smørgrav <des@FreeBSD.org> | 2017-02-03 13:01:00 +0000 |
commit | c6342fe2e90510d8d2296423f2ca92818a7b3d18 (patch) | |
tree | 0cc9064980c804a7bf5cc6d96c9249950c7e56a9 /dnssec_verify.c | |
parent | 65be028f32ed37dce84f6328d4a7172132c8c224 (diff) |
Notes
Diffstat (limited to 'dnssec_verify.c')
-rw-r--r-- | dnssec_verify.c | 202 |
1 files changed, 177 insertions, 25 deletions
diff --git a/dnssec_verify.c b/dnssec_verify.c index 1af6635b9d22..c554e4f4cb19 100644 --- a/dnssec_verify.c +++ b/dnssec_verify.c @@ -1088,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 @@ -1809,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, @@ -1832,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; @@ -1854,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; @@ -1935,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, @@ -1943,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, @@ -1980,6 +2076,18 @@ ldns_verify_rrsig_buffers_raw(unsigned char* sig, size_t siglen, 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, siglen, @@ -2002,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; @@ -2051,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; @@ -2088,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 */ @@ -2104,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: @@ -2119,6 +2229,32 @@ ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, ldns_rr* rrsig) } 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: case LDNS_INDIRECT: @@ -2136,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; @@ -2171,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; @@ -2218,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; @@ -2285,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) @@ -2334,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) { @@ -2482,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; @@ -2545,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; @@ -2554,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 |