]> source.dussan.org Git - rspamd.git/commitdiff
[Fix] Do not abort when OpenSSL is broken, report that to a user vstakhov-openssl-provider-message
authorVsevolod Stakhov <vsevolod@rspamd.com>
Tue, 15 Oct 2024 13:22:03 +0000 (14:22 +0100)
committerVsevolod Stakhov <vsevolod@rspamd.com>
Tue, 15 Oct 2024 13:22:03 +0000 (14:22 +0100)
Issue: #5181

src/libcryptobox/cryptobox.c
src/libcryptobox/cryptobox.h
src/libserver/dkim.c

index a976653dfab6400c0eedfbc85d91761511b52dfc..6c9f9a82e6b161690cea20047daab5e1da77c8de 100644 (file)
@@ -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_get0_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);
 
index afe9c4f9a6caf581d21e5b654351c013e62dc8b1..8d1f5669ec8006397454847c52126f840ebdbb4e 100644 (file)
@@ -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
 
 /**
index a76ed31abe931d53d34484b0b17ba88cc03525fd..0f51c66c053ab9b67c2d0b7226b54305481307ff 100644 (file)
@@ -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) {