aboutsummaryrefslogtreecommitdiffstats
path: root/dnssec_verify.c
diff options
context:
space:
mode:
Diffstat (limited to 'dnssec_verify.c')
-rw-r--r--dnssec_verify.c202
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