Browse Source

[Fix] Fix and rework various parts

pull/5072/head
Vsevolod Stakhov 1 year ago
parent
commit
d46c5ad4a5
No known key found for this signature in database GPG Key ID: 7647B6790081437
  1. 2
      contrib/aho-corasick/acism.c
  2. 97
      src/libcryptobox/cryptobox.c
  3. 33
      src/libcryptobox/cryptobox.h
  4. 16
      src/libserver/dkim.c

2
contrib/aho-corasick/acism.c

@ -38,8 +38,6 @@
#include "_acism.h"
#include "unix-std.h"
#define BACK ((SYMBOL) 0)
#define ROOT ((STATE) 0)
extern const unsigned char lc_map[256];
int acism_lookup(ac_trie_t const *psp, const char *text, size_t len,

97
src/libcryptobox/cryptobox.c

@ -410,8 +410,6 @@ void rspamd_cryptobox_keypair_sig(rspamd_sig_pk_t pk, rspamd_sig_sk_t sk,
g_assert(0);
#else
const EC_POINT *ec_pub;
EC_GROUP *group;
gsize len;
#if OPENSSL_VERSION_MAJOR >= 3
OSSL_LIB_CTX *libctx = OSSL_LIB_CTX_new();
@ -436,6 +434,8 @@ void rspamd_cryptobox_keypair_sig(rspamd_sig_pk_t pk, rspamd_sig_sk_t sk,
#else
EC_KEY *ec_sec;
const BIGNUM *bn_sec;
const EC_POINT *ec_pub;
EC_GROUP *group;
ec_sec = EC_KEY_new_by_curve_name(CRYPTOBOX_CURVE_NID);
g_assert(ec_sec != NULL);
@ -459,9 +459,9 @@ void rspamd_cryptobox_keypair_sig(rspamd_sig_pk_t pk, rspamd_sig_sk_t sk,
len = BN_num_bytes(bn_sec);
g_assert(len <= (int) sizeof(rspamd_sk_t));
BN_bn2bin(bn_sec, sk);
EC_GROUP_free(group);
#endif
EC_GROUP_free(group);
#endif
}
}
@ -532,7 +532,6 @@ void rspamd_cryptobox_nm(rspamd_nm_t nm,
#ifndef HAVE_USABLE_OPENSSL
g_assert(0);
#else
int len;
unsigned char s[32];
#if OPENSSL_VERSION_MAJOR >= 3
@ -572,6 +571,7 @@ void rspamd_cryptobox_nm(rspamd_nm_t nm,
OSSL_LIB_CTX_free(libctx);
#else
//g_error(ERR_error_string(ERR_get_error(), NULL));
int len;
EC_KEY *lk;
EC_POINT *ec_pub;
BIGNUM *bn_pub, *bn_sec;
@ -688,48 +688,75 @@ void rspamd_cryptobox_sign(unsigned char *sig, unsigned long long *siglen_p,
}
}
bool rspamd_cryptobox_verify_compat(int nid,
const unsigned char *sig,
gsize siglen,
const unsigned char *digest,
gsize dlen,
struct evp_pkey_st *pub_key, int ktype,
enum rspamd_cryptobox_mode mode)
#ifdef HAVE_OPENSSL
bool rspamd_cryptobox_verify_evp_ed25519(int nid,
const unsigned char *sig,
gsize siglen,
const unsigned char *digest,
gsize dlen,
struct evp_pkey_st *pub_key)
{
bool ret = false;
if (G_LIKELY(mode == RSPAMD_CRYPTOBOX_MODE_25519)) {
if (siglen == rspamd_cryptobox_signature_bytes(RSPAMD_CRYPTOBOX_MODE_25519)) {
rspamd_pk_t pk;
size_t len_pk = sizeof(rspamd_pk_t);
EVP_PKEY_get_raw_public_key(pub_key, pk, &len_pk);
ret = (crypto_sign_verify_detached(sig, digest, dlen, pk) == 0);
}
if (siglen == rspamd_cryptobox_signature_bytes(RSPAMD_CRYPTOBOX_MODE_25519)) {
rspamd_pk_t pk;
size_t len_pk = sizeof(rspamd_pk_t);
EVP_PKEY_get_raw_public_key(pub_key, pk, &len_pk);
ret = (crypto_sign_verify_detached(sig, digest, dlen, pk) == 0);
}
else {
#ifndef HAVE_USABLE_OPENSSL
g_assert(0);
#else
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(pub_key, NULL);
g_assert(pctx != NULL);
EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
EVP_MD *md = EVP_get_digestbynid(nid);
g_assert(EVP_PKEY_verify_init(pctx) == 1);
return ret;
}
if (ktype == 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);
bool rspamd_cryptobox_verify_evp_ecdsa(int nid,
const unsigned char *sig,
gsize siglen,
const unsigned char *digest,
gsize dlen,
EVP_PKEY *pub_key)
{
bool ret = false;
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(pub_key, NULL);
g_assert(pctx != NULL);
EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
const EVP_MD *md = EVP_get_digestbynid(nid);
ret = (EVP_PKEY_verify(pctx, sig, siglen, digest, dlen) == 1);
g_assert(EVP_PKEY_verify_init(pctx) == 1);
g_assert(EVP_PKEY_CTX_set_signature_md(pctx, md) == 1);
EVP_PKEY_CTX_free(pctx);
EVP_MD_free(md);
EVP_MD_CTX_free(mdctx);
#endif
}
ret = (EVP_PKEY_verify(pctx, sig, siglen, digest, dlen) == 1);
EVP_PKEY_CTX_free(pctx);
EVP_MD_CTX_free(mdctx);
return ret;
}
bool rspamd_cryptobox_verify_evp_rsa(int nid,
const unsigned char *sig,
gsize siglen,
const unsigned char *digest,
gsize dlen,
EVP_PKEY *pub_key)
{
bool ret = false;
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(pub_key, NULL);
g_assert(pctx != NULL);
EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
const EVP_MD *md = EVP_get_digestbynid(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);
ret = (EVP_PKEY_verify(pctx, sig, siglen, digest, dlen) == 1);
EVP_PKEY_CTX_free(pctx);
EVP_MD_CTX_free(mdctx);
return ret;
}
#endif
bool rspamd_cryptobox_verify(const unsigned char *sig,
gsize siglen,

33
src/libcryptobox/cryptobox.h

@ -18,7 +18,10 @@
#define CRYPTOBOX_H_
#include "config.h"
#include "openssl/evp.h"
#ifdef HAVE_OPENSSL
#include <openssl/evp.h>
#endif
#include <sodium.h>
@ -224,22 +227,34 @@ bool rspamd_cryptobox_verify(const unsigned char *sig,
const rspamd_pk_t pk,
enum rspamd_cryptobox_mode mode);
#ifdef HAVE_OPENSSL
/**
* Verifies digital signature for specified raw digest with specified pubkey
* @param nid signing algorithm nid
* @param sig signature source
* @param digest raw digest
* @param pub_key public key for verification
* @param ktype type of public key (1 - RSA, 0 - ECDSA)
* @return true if signature is valid, false otherwise
*/
bool rspamd_cryptobox_verify_compat(int nid,
const unsigned char *sig,
gsize siglen,
const unsigned char *digest,
gsize dlen,
struct evp_pkey_st *pub_key, int ktype,
enum rspamd_cryptobox_mode mode);
bool rspamd_cryptobox_verify_evp_ed25519(int nid,
const unsigned char *sig,
gsize siglen,
const unsigned char *digest,
gsize dlen,
EVP_PKEY *pub_key);
bool rspamd_cryptobox_verify_evp_ecdsa(int nid,
const unsigned char *sig,
gsize siglen,
const unsigned char *digest,
gsize dlen,
EVP_PKEY *pub_key);
bool rspamd_cryptobox_verify_evp_rsa(int nid,
const unsigned char *sig,
gsize siglen,
const unsigned char *digest,
gsize dlen,
EVP_PKEY *pub_key);
#endif
/**
* Securely clear the buffer specified

16
src/libserver/dkim.c

@ -2143,7 +2143,8 @@ rspamd_dkim_canonize_body(struct rspamd_task *task,
if (ctx->body_canon_type == DKIM_CANON_SIMPLE) {
/* Simple canonization */
while (rspamd_dkim_simple_body_step(ctx, ctx->body_hash,
&start, end - start, &remain));
&start, end - start, &remain))
;
/*
* If we have l= tag then we cannot add crlf...
@ -2179,7 +2180,8 @@ rspamd_dkim_canonize_body(struct rspamd_task *task,
size_t orig_len = remain;
while (rspamd_dkim_relaxed_body_step(ctx, ctx->body_hash,
&start, end - start, &remain));
&start, end - start, &remain))
;
if (ctx->len > 0 && remain > (double) orig_len * 0.1) {
msg_info_task("DKIM l tag does not cover enough of the body: %d (%d actual size)",
@ -2199,7 +2201,6 @@ rspamd_dkim_canonize_body(struct rspamd_task *task,
return TRUE;
}
/* TODO: Implement relaxed algorithm */
return FALSE;
}
@ -2873,8 +2874,8 @@ rspamd_dkim_check(rspamd_dkim_context_t *ctx,
}
switch (key->type) {
case RSPAMD_DKIM_KEY_RSA:
if (!rspamd_cryptobox_verify_compat(nid, ctx->b, ctx->blen, raw_digest, dlen,
key->specific.key_ssl.key_evp, 1, RSPAMD_CRYPTOBOX_MODE_NIST)) {
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;
@ -2892,9 +2893,8 @@ rspamd_dkim_check(rspamd_dkim_context_t *ctx,
}
break;
case RSPAMD_DKIM_KEY_ECDSA:
/* TODO: this is currently badly broken, as it tries to verify RSA instead of ECDSA */
if (rspamd_cryptobox_verify_compat(nid, ctx->b, ctx->blen, raw_digest, dlen,
key->specific.key_ssl.key_evp, 0, RSPAMD_CRYPTOBOX_MODE_NIST) != 1) {
if (rspamd_cryptobox_verify_evp_ecdsa(nid, ctx->b, ctx->blen, raw_digest, dlen,
key->specific.key_ssl.key_evp) != 1) {
msg_info_dkim(
"%s: headers ECDSA verification failure; "
"body length %d->%d; headers length %d; d=%s; s=%s; key_md5=%*xs; orig header: %s",

Loading…
Cancel
Save