]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Project] Fix digest calculation (use siphash)
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 12 Jul 2019 14:11:19 +0000 (15:11 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 12 Jul 2019 14:18:17 +0000 (15:18 +0100)
src/libmime/message.c
src/libmime/message.h

index 106556c667e5058115178ec75f558a757666aaae..a725d7e89608747400e93f2be235e19ebfa2ad07 100644 (file)
@@ -34,6 +34,7 @@
 
 #include <math.h>
 #include <unicode/uchar.h>
+#include "sodium.h"
 #include "libserver/cfg_file_private.h"
 #include "lua/lua_common.h"
 #include "contrib/uthash/utlist.h"
@@ -1157,8 +1158,6 @@ rspamd_message_parse (struct rspamd_task *task)
        gsize len;
        guint i;
        GError *err = NULL;
-       rspamd_cryptobox_hash_state_t st;
-       guchar digest_out[rspamd_cryptobox_HASHBYTES];
 
        if (RSPAMD_TASK_IS_EMPTY (task)) {
                /* Don't do anything with empty task */
@@ -1210,7 +1209,6 @@ rspamd_message_parse (struct rspamd_task *task)
                rspamd_message_unref (task->message);
        }
 
-       rspamd_cryptobox_hash_init (&st, NULL, 0);
        task->message = rspamd_message_new (task);
 
        if (task->flags & RSPAMD_TASK_FLAG_MIME) {
@@ -1344,26 +1342,37 @@ rspamd_message_parse (struct rspamd_task *task)
                }
        }
 
+       struct rspamd_mime_part *part;
+
+       /* Blake2b applied to string 'rspamd' */
+       static const guchar RSPAMD_ALIGNED(32) hash_key[] = {
+                       0xef,0x43,0xae,0x80,0xcc,0x8d,0xc3,0x4c,
+                       0x6f,0x1b,0xd6,0x18,0x1b,0xae,0x87,0x74,
+                       0x0c,0xca,0xf7,0x8e,0x5f,0x2e,0x54,0x32,
+                       0xf6,0x79,0xb9,0x27,0x26,0x96,0x20,0x92,
+                       0x70,0x07,0x85,0xeb,0x83,0xf7,0x89,0xe0,
+                       0xd7,0x32,0x2a,0xd2,0x1a,0x64,0x41,0xef,
+                       0x49,0xff,0xc3,0x8c,0x54,0xf9,0x67,0x74,
+                       0x30,0x1e,0x70,0x2e,0xb7,0x12,0x09,0xfe,
+       };
+
+       PTR_ARRAY_FOREACH (MESSAGE_FIELD (task, parts), i, part) {
+               crypto_shorthash_siphashx24 (MESSAGE_FIELD (task, digest),
+                               part->digest, sizeof (part->digest),
+                               i == 0 ? hash_key : MESSAGE_FIELD (task, digest));
+       }
+
        /* Parse urls inside Subject header */
        if (MESSAGE_FIELD (task, subject)) {
                p = MESSAGE_FIELD (task, subject);
                len = strlen (p);
-               rspamd_cryptobox_hash_update (&st, p, len);
+               crypto_shorthash_siphashx24 (MESSAGE_FIELD (task, digest), p, len,
+                               MESSAGE_FIELD (task, digest));
                rspamd_url_find_multiple (task->task_pool, p, len,
                                RSPAMD_URL_FIND_STRICT, NULL,
                                rspamd_url_task_subject_callback, task);
        }
 
-       struct rspamd_mime_part *part;
-
-       PTR_ARRAY_FOREACH (MESSAGE_FIELD (task, parts), i, part) {
-               rspamd_cryptobox_hash_update (&st, part->digest, sizeof (part->digest));
-       }
-
-       rspamd_cryptobox_hash_final (&st, digest_out);
-       memcpy (MESSAGE_FIELD (task, digest), digest_out,
-                       sizeof (MESSAGE_FIELD (task, digest)));
-
        if (task->queue_id) {
                msg_info_task ("loaded message; id: <%s>; queue-id: <%s>; size: %z; "
                                "checksum: <%*xs>",
@@ -1558,3 +1567,17 @@ void rspamd_message_unref (struct rspamd_message *msg)
                REF_RELEASE (msg);
        }
 }
+
+void rspamd_message_update_digest (struct rspamd_message *msg,
+                                                                  const void *input, gsize len)
+{
+       guchar RSPAMD_ALIGNED(32) ex_key[crypto_shorthash_siphashx24_KEYBYTES];
+
+       /* Sanity */
+       G_STATIC_ASSERT (sizeof (ex_key) == sizeof (msg->digest));
+       G_STATIC_ASSERT (crypto_shorthash_siphashx24_BYTES == sizeof (msg->digest));
+
+       memcpy (ex_key, msg->digest, sizeof (msg->digest));
+
+       crypto_shorthash_siphashx24 (msg->digest, input, len, ex_key);
+}
\ No newline at end of file
index a453db0866ffed81ab00ee17a3adf04885fd58f7..cc4db39f4edb7a6aaa78eb26ef4aa80e9749c369 100644 (file)
@@ -132,17 +132,19 @@ struct rspamd_mime_text_part {
        guint unicode_scripts;
 };
 
+struct rspamd_message_raw_headers_content {
+       const gchar *begin;
+       gsize len;
+       const gchar *body_start;
+};
+
 struct rspamd_message {
        const gchar *message_id;
        gchar *subject;
 
        GPtrArray *parts;                               /**< list of parsed parts                                                       */
        GPtrArray *text_parts;                  /**< list of text parts                                                         */
-       struct {
-               const gchar *begin;
-               gsize len;
-               const gchar *body_start;
-       } raw_headers_content;                                          /**< list of raw headers                                                        */
+       struct rspamd_message_raw_headers_content raw_headers_content;
        struct rspamd_received_header *received;        /**< list of received headers                                           */
        GHashTable *urls;                                                       /**< list of parsed urls                                                        */
        GHashTable *emails;                                                     /**< list of parsed emails                                                      */
@@ -155,14 +157,7 @@ struct rspamd_message {
        ref_entry_t ref;
 };
 
-#ifndef FULL_DEBUG
 #define MESSAGE_FIELD(task, field) ((task)->message->field)
-#else
-#define MESSAGE_FIELD(task, field)
-       ((!(task)->message) ? \
-       (__typeof__((task)->message->field))(msg_err_task("no message when getting field %s", #field), g_assert(0), NULL) : \
-       ((task)->message->field))
-#endif
 
 /**
  * Parse and pre-process mime message
@@ -198,6 +193,15 @@ struct rspamd_message *rspamd_message_ref (struct rspamd_message *msg);
 
 void rspamd_message_unref (struct rspamd_message *msg);
 
+/**
+ * Updates digest of the message if modified
+ * @param msg
+ * @param input
+ * @param len
+ */
+void rspamd_message_update_digest (struct rspamd_message *msg,
+               const void *input, gsize len);
+
 #ifdef  __cplusplus
 }
 #endif