return 1;
}
+static void
+digest_ctx_free(EVP_MD_CTX* ctx, EVP_PKEY *evp_key,
+ unsigned char* sigblock, int dofree, int docrypto_free)
+{
+#ifdef HAVE_EVP_MD_CTX_NEW
+ EVP_MD_CTX_destroy(ctx);
+#else
+ EVP_MD_CTX_cleanup(ctx);
+ free(ctx);
+#endif
+ EVP_PKEY_free(evp_key);
+ if(dofree) free(sigblock);
+ else if(docrypto_free) OPENSSL_free(sigblock);
+}
+
+static enum sec_status
+digest_error_status(void)
+{
+#ifdef EVP_R_INVALID_DIGEST
+ unsigned long e = ERR_get_error();
+ if (ERR_GET_LIB(e) == ERR_LIB_EVP &&
+ ERR_GET_REASON(e) == EVP_R_INVALID_DIGEST)
+ return sec_status_indeterminate;
+#endif
+ return sec_status_unchecked;
+}
+
/**
* Check a canonical sig+rrset and signature against a dnskey
* @param buf: buffer with data to verify, the first rrsig part and the
}
#ifndef HAVE_EVP_DIGESTVERIFY
if(EVP_DigestInit(ctx, digest_type) == 0) {
+ enum sec_status sec = digest_error_status();
verbose(VERB_QUERY, "verify: EVP_DigestInit failed");
-#ifdef HAVE_EVP_MD_CTX_NEW
- EVP_MD_CTX_destroy(ctx);
-#else
- EVP_MD_CTX_cleanup(ctx);
- free(ctx);
-#endif
- EVP_PKEY_free(evp_key);
- if(dofree) free(sigblock);
- else if(docrypto_free) OPENSSL_free(sigblock);
- return sec_status_unchecked;
+ digest_ctx_free(ctx, evp_key, sigblock,
+ dofree, docrypto_free);
+ return sec;
}
if(EVP_DigestUpdate(ctx, (unsigned char*)sldns_buffer_begin(buf),
(unsigned int)sldns_buffer_limit(buf)) == 0) {
verbose(VERB_QUERY, "verify: EVP_DigestUpdate failed");
-#ifdef HAVE_EVP_MD_CTX_NEW
- EVP_MD_CTX_destroy(ctx);
-#else
- EVP_MD_CTX_cleanup(ctx);
- free(ctx);
-#endif
- EVP_PKEY_free(evp_key);
- if(dofree) free(sigblock);
- else if(docrypto_free) OPENSSL_free(sigblock);
+ digest_ctx_free(ctx, evp_key, sigblock,
+ dofree, docrypto_free);
return sec_status_unchecked;
}
res = EVP_VerifyFinal(ctx, sigblock, sigblock_len, evp_key);
#else /* HAVE_EVP_DIGESTVERIFY */
if(EVP_DigestVerifyInit(ctx, NULL, digest_type, NULL, evp_key) == 0) {
+ enum sec_status sec = digest_error_status();
verbose(VERB_QUERY, "verify: EVP_DigestVerifyInit failed");
-#ifdef HAVE_EVP_MD_CTX_NEW
- EVP_MD_CTX_destroy(ctx);
-#else
- EVP_MD_CTX_cleanup(ctx);
- free(ctx);
-#endif
- EVP_PKEY_free(evp_key);
- if(dofree) free(sigblock);
- else if(docrypto_free) OPENSSL_free(sigblock);
- return sec_status_unchecked;
+ digest_ctx_free(ctx, evp_key, sigblock,
+ dofree, docrypto_free);
+ return sec;
}
res = EVP_DigestVerify(ctx, sigblock, sigblock_len,
(unsigned char*)sldns_buffer_begin(buf),
sldns_buffer_limit(buf));
#endif
-#ifdef HAVE_EVP_MD_CTX_NEW
- EVP_MD_CTX_destroy(ctx);
-#else
- EVP_MD_CTX_cleanup(ctx);
- free(ctx);
-#endif
- EVP_PKEY_free(evp_key);
-
- if(dofree) free(sigblock);
- else if(docrypto_free) OPENSSL_free(sigblock);
+ digest_ctx_free(ctx, evp_key, sigblock,
+ dofree, docrypto_free);
if(res == 1) {
return sec_status_secure;
int algo = rrset_get_sig_algo(rrset, sig_idx);
size_t i, num = rrset_get_count(dnskey);
size_t numchecked = 0;
+ size_t numindeterminate = 0;
int buf_canon = 0;
verbose(VERB_ALGO, "verify sig %d %d", (int)tag, algo);
if(!dnskey_algo_id_is_supported(algo)) {
sig_idx, sortree, &buf_canon, reason, section, qstate);
if(sec == sec_status_secure)
return sec;
+ else if(sec == sec_status_indeterminate)
+ numindeterminate ++;
}
if(numchecked == 0) {
*reason = "signatures from unknown keys";
verbose(VERB_QUERY, "verify: could not find appropriate key");
return sec_status_bogus;
}
+ if (numindeterminate == numchecked)
+ return sec_status_indeterminate;
return sec_status_bogus;
}