summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2018-06-29 11:24:43 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2018-06-29 11:24:43 +0100
commitc4ccac7afb09784d15a38a27ec1b4c167cb031c5 (patch)
tree6fed6fb64529498175c57190582c975a63d3ec6d
parent53632b619666d67d14640b1dc0832b2ab6eb8aa8 (diff)
downloadrspamd-c4ccac7afb09784d15a38a27ec1b4c167cb031c5.tar.gz
rspamd-c4ccac7afb09784d15a38a27ec1b4c167cb031c5.zip
[CritFix] Check NM part of pubkey to match it with rotating keypairs
-rw-r--r--src/fuzzy_storage.c4
-rw-r--r--src/libcryptobox/keypair.c12
-rw-r--r--src/libcryptobox/keypair.h3
-rw-r--r--src/libcryptobox/keypair_private.h1
-rw-r--r--src/libutil/http.c4
-rw-r--r--src/libutil/logger.c2
-rw-r--r--src/plugins/fuzzy_check.c5
7 files changed, 21 insertions, 10 deletions
diff --git a/src/fuzzy_storage.c b/src/fuzzy_storage.c
index 5499fa732..9243e369e 100644
--- a/src/fuzzy_storage.c
+++ b/src/fuzzy_storage.c
@@ -1060,7 +1060,7 @@ rspamd_fuzzy_decrypt_command (struct fuzzy_session *s)
/* Now decrypt request */
if (!rspamd_cryptobox_decrypt_nm_inplace (payload, payload_len, hdr->nonce,
- rspamd_pubkey_get_nm (rk),
+ rspamd_pubkey_get_nm (rk, key->key),
hdr->mac, RSPAMD_CRYPTOBOX_MODE_25519)) {
msg_err ("decryption failed");
rspamd_pubkey_unref (rk);
@@ -1068,7 +1068,7 @@ rspamd_fuzzy_decrypt_command (struct fuzzy_session *s)
return FALSE;
}
- memcpy (s->nm, rspamd_pubkey_get_nm (rk), sizeof (s->nm));
+ memcpy (s->nm, rspamd_pubkey_get_nm (rk, key->key), sizeof (s->nm));
rspamd_pubkey_unref (rk);
return TRUE;
diff --git a/src/libcryptobox/keypair.c b/src/libcryptobox/keypair.c
index c8fa5633a..ee9fa4649 100644
--- a/src/libcryptobox/keypair.c
+++ b/src/libcryptobox/keypair.c
@@ -444,12 +444,19 @@ rspamd_pubkey_from_bin (const guchar *raw,
const guchar *
-rspamd_pubkey_get_nm (struct rspamd_cryptobox_pubkey *p)
+rspamd_pubkey_get_nm (struct rspamd_cryptobox_pubkey *p,
+ struct rspamd_cryptobox_keypair *kp)
{
g_assert (p != NULL);
if (p->nm) {
- return p->nm->nm;
+ if (memcmp (kp->id, (const guchar *)&p->nm->sk_id, sizeof (guint64)) == 0) {
+ return p->nm->nm;
+ }
+
+ /* Wrong ID, need to recalculate */
+ REF_RELEASE (p->nm);
+ p->nm = NULL;
}
return NULL;
@@ -468,6 +475,7 @@ rspamd_pubkey_calculate_nm (struct rspamd_cryptobox_pubkey *p,
abort ();
}
+ memcpy (&p->nm->sk_id, kp->id, sizeof (guint64));
REF_INIT_RETAIN (p->nm, rspamd_cryptobox_nm_dtor);
}
diff --git a/src/libcryptobox/keypair.h b/src/libcryptobox/keypair.h
index d7c386b91..92af13b68 100644
--- a/src/libcryptobox/keypair.h
+++ b/src/libcryptobox/keypair.h
@@ -139,7 +139,8 @@ enum rspamd_cryptobox_mode rspamd_pubkey_alg (struct rspamd_cryptobox_pubkey *p)
* @param p
* @return
*/
-const guchar * rspamd_pubkey_get_nm (struct rspamd_cryptobox_pubkey *p);
+const guchar * rspamd_pubkey_get_nm (struct rspamd_cryptobox_pubkey *p,
+ struct rspamd_cryptobox_keypair *kp);
/**
* Calculate and store nm value for the specified local key (performs ECDH)
diff --git a/src/libcryptobox/keypair_private.h b/src/libcryptobox/keypair_private.h
index d91d1c68e..78b894d38 100644
--- a/src/libcryptobox/keypair_private.h
+++ b/src/libcryptobox/keypair_private.h
@@ -25,6 +25,7 @@
*/
struct RSPAMD_ALIGNED(32) rspamd_cryptobox_nm {
guchar RSPAMD_ALIGNED(32) nm[rspamd_cryptobox_MAX_NMBYTES];
+ guint64 sk_id; /* Used to store secret key id */
ref_entry_t ref;
};
diff --git a/src/libutil/http.c b/src/libutil/http.c
index fea3cadb4..2f78def47 100644
--- a/src/libutil/http.c
+++ b/src/libutil/http.c
@@ -844,7 +844,7 @@ rspamd_http_decrypt_message (struct rspamd_http_connection *conn,
dec_len = msg->body_buf.len - rspamd_cryptobox_nonce_bytes (mode) -
rspamd_cryptobox_mac_bytes (mode);
- if ((nm = rspamd_pubkey_get_nm (peer_key)) == NULL) {
+ if ((nm = rspamd_pubkey_get_nm (peer_key, priv->local_key)) == NULL) {
nm = rspamd_pubkey_calculate_nm (peer_key, priv->local_key);
}
@@ -1703,7 +1703,7 @@ rspamd_http_connection_encrypt_message (
cnt = i;
- if ((nm = rspamd_pubkey_get_nm (peer_key)) == NULL) {
+ if ((nm = rspamd_pubkey_get_nm (peer_key, priv->local_key)) == NULL) {
nm = rspamd_pubkey_calculate_nm (peer_key, priv->local_key);
}
diff --git a/src/libutil/logger.c b/src/libutil/logger.c
index 99c22390f..bbdc69e97 100644
--- a/src/libutil/logger.c
+++ b/src/libutil/logger.c
@@ -584,7 +584,7 @@ rspamd_log_encrypt_message (const gchar *begin, const gchar *end,
mac = p;
p += rspamd_cryptobox_mac_bytes (RSPAMD_CRYPTOBOX_MODE_25519);
memcpy (p, begin, end - begin);
- comp = rspamd_pubkey_get_nm (rspamd_log->pk);
+ comp = rspamd_pubkey_get_nm (rspamd_log->pk, rspamd_log->keypair);
g_assert (comp != NULL);
rspamd_cryptobox_encrypt_nm_inplace (p, end - begin, nonce, comp, mac,
RSPAMD_CRYPTOBOX_MODE_25519);
diff --git a/src/plugins/fuzzy_check.c b/src/plugins/fuzzy_check.c
index e1ac4743b..777f6fa62 100644
--- a/src/plugins/fuzzy_check.c
+++ b/src/plugins/fuzzy_check.c
@@ -1214,7 +1214,8 @@ fuzzy_encrypt_cmd (struct fuzzy_rule *rule,
rspamd_keypair_cache_process (fuzzy_module_ctx->keypairs_cache,
rule->local_key, rule->peer_key);
rspamd_cryptobox_encrypt_nm_inplace (data, datalen,
- hdr->nonce, rspamd_pubkey_get_nm (rule->peer_key), hdr->mac,
+ hdr->nonce, rspamd_pubkey_get_nm (rule->peer_key, rule->local_key),
+ hdr->mac,
rspamd_pubkey_alg (rule->peer_key));
}
@@ -1769,7 +1770,7 @@ fuzzy_process_reply (guchar **pos, gint *r, GPtrArray *req,
if (!rspamd_cryptobox_decrypt_nm_inplace ((guchar *)&encrep.rep,
sizeof (encrep.rep),
encrep.hdr.nonce,
- rspamd_pubkey_get_nm (rule->peer_key),
+ rspamd_pubkey_get_nm (rule->peer_key, rule->local_key),
encrep.hdr.mac,
rspamd_pubkey_alg (rule->peer_key))) {
msg_info ("cannot decrypt reply");