aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rspamd.com>2024-10-15 19:43:20 +0600
committerGitHub <noreply@github.com>2024-10-15 19:43:20 +0600
commit68b4601ed596ae1ce1890f83988a34d3445acc87 (patch)
treeac25064ebe8ff9d0518a29613c1c1a2de3fb72c2
parent395c6641b2fc5751776b26baabec21ea8e83f375 (diff)
parentb921df4f27100a7fcaed868432ba7fd9d222dbe2 (diff)
downloadrspamd-68b4601ed596ae1ce1890f83988a34d3445acc87.tar.gz
rspamd-68b4601ed596ae1ce1890f83988a34d3445acc87.zip
Merge pull request #5188 from rspamd/vstakhov-openssl-provider-message
[Fix] Do not abort when OpenSSL is broken, report that to a user
-rw-r--r--src/libcryptobox/cryptobox.c19
-rw-r--r--src/libcryptobox/cryptobox.h3
-rw-r--r--src/libserver/dkim.c53
3 files changed, 56 insertions, 19 deletions
diff --git a/src/libcryptobox/cryptobox.c b/src/libcryptobox/cryptobox.c
index a976653df..190d0e4a3 100644
--- a/src/libcryptobox/cryptobox.c
+++ b/src/libcryptobox/cryptobox.c
@@ -40,6 +40,7 @@
#include <openssl/opensslv.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
+#include <openssl/err.h>
#endif
#include <signal.h>
@@ -456,9 +457,10 @@ bool rspamd_cryptobox_verify_evp_rsa(int nid,
gsize siglen,
const unsigned char *digest,
gsize dlen,
- EVP_PKEY *pub_key)
+ EVP_PKEY *pub_key,
+ GError **err)
{
- bool ret = false;
+ bool ret = false, r;
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(pub_key, NULL);
g_assert(pctx != NULL);
@@ -467,7 +469,18 @@ bool rspamd_cryptobox_verify_evp_rsa(int nid,
g_assert(EVP_PKEY_verify_init(pctx) == 1);
g_assert(EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PADDING) == 1);
- g_assert(EVP_PKEY_CTX_set_signature_md(pctx, md) == 1);
+
+ if ((r = EVP_PKEY_CTX_set_signature_md(pctx, md)) <= 0) {
+ g_set_error(err, g_quark_from_static_string("OpenSSL"),
+ r,
+ "cannot set digest %s for RSA verification (%s returned from OpenSSL), try use `update-crypto-policies --set LEGACY` on RH",
+ EVP_MD_name(md),
+ ERR_lib_error_string(ERR_get_error()));
+ EVP_PKEY_CTX_free(pctx);
+ EVP_MD_CTX_free(mdctx);
+
+ return false;
+ }
ret = (EVP_PKEY_verify(pctx, sig, siglen, digest, dlen) == 1);
diff --git a/src/libcryptobox/cryptobox.h b/src/libcryptobox/cryptobox.h
index afe9c4f9a..8d1f5669e 100644
--- a/src/libcryptobox/cryptobox.h
+++ b/src/libcryptobox/cryptobox.h
@@ -238,7 +238,8 @@ bool rspamd_cryptobox_verify_evp_rsa(int nid,
gsize siglen,
const unsigned char *digest,
gsize dlen,
- EVP_PKEY *pub_key);
+ EVP_PKEY *pub_key,
+ GError **err);
#endif
/**
diff --git a/src/libserver/dkim.c b/src/libserver/dkim.c
index a76ed31ab..0f51c66c0 100644
--- a/src/libserver/dkim.c
+++ b/src/libserver/dkim.c
@@ -2871,25 +2871,48 @@ rspamd_dkim_check(rspamd_dkim_context_t *ctx,
nid = NID_sha1;
}
switch (key->type) {
- case RSPAMD_DKIM_KEY_RSA:
+ case RSPAMD_DKIM_KEY_RSA: {
+ GError *err = NULL;
+
if (!rspamd_cryptobox_verify_evp_rsa(nid, ctx->b, ctx->blen, raw_digest, dlen,
- key->specific.key_ssl.key_evp)) {
- msg_debug_dkim("headers rsa verify failed");
- ERR_clear_error();
- res->rcode = DKIM_REJECT;
- res->fail_reason = "headers rsa verify failed";
+ key->specific.key_ssl.key_evp, &err)) {
- msg_info_dkim(
- "%s: headers RSA verification failure; "
- "body length %d->%d; headers length %d; d=%s; s=%s; key_md5=%*xs; orig header: %s",
- rspamd_dkim_type_to_string(ctx->common.type),
- (int) (body_end - body_start), ctx->common.body_canonicalised,
- ctx->common.headers_canonicalised,
- ctx->domain, ctx->selector,
- RSPAMD_DKIM_KEY_ID_LEN, rspamd_dkim_key_id(key),
- ctx->dkim_header);
+ if (err == NULL) {
+ msg_debug_dkim("headers rsa verify failed");
+ ERR_clear_error();
+ res->rcode = DKIM_REJECT;
+ res->fail_reason = "headers rsa verify failed";
+
+ msg_info_dkim(
+ "%s: headers RSA verification failure; "
+ "body length %d->%d; headers length %d; d=%s; s=%s; key_md5=%*xs; orig header: %s",
+ rspamd_dkim_type_to_string(ctx->common.type),
+ (int) (body_end - body_start), ctx->common.body_canonicalised,
+ ctx->common.headers_canonicalised,
+ ctx->domain, ctx->selector,
+ RSPAMD_DKIM_KEY_ID_LEN, rspamd_dkim_key_id(key),
+ ctx->dkim_header);
+ }
+ else {
+ res->rcode = DKIM_PERM_ERROR;
+ res->fail_reason = "openssl internal error";
+ msg_err_dkim("internal OpenSSL error: %s", err->message);
+ msg_info_dkim(
+ "%s: headers RSA verification failure due to OpenSSL internal error; "
+ "body length %d->%d; headers length %d; d=%s; s=%s; key_md5=%*xs; orig header: %s",
+ rspamd_dkim_type_to_string(ctx->common.type),
+ (int) (body_end - body_start), ctx->common.body_canonicalised,
+ ctx->common.headers_canonicalised,
+ ctx->domain, ctx->selector,
+ RSPAMD_DKIM_KEY_ID_LEN, rspamd_dkim_key_id(key),
+ ctx->dkim_header);
+
+ ERR_clear_error();
+ g_error_free(err);
+ }
}
break;
+ }
case RSPAMD_DKIM_KEY_ECDSA:
if (rspamd_cryptobox_verify_evp_ecdsa(nid, ctx->b, ctx->blen, raw_digest, dlen,
key->specific.key_ssl.key_evp) != 1) {