aboutsummaryrefslogtreecommitdiffstats
path: root/src/libutil/http.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2015-01-28 21:42:25 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2015-01-28 21:42:25 +0000
commited558e60e70f0b41e533beca5eb1d1954249fc93 (patch)
tree38ca195d3fb420ab64572497704d2e7b2ee94ba7 /src/libutil/http.c
parentbebc8737c80b00ba41221e9380b3eb35070ed1b4 (diff)
downloadrspamd-ed558e60e70f0b41e533beca5eb1d1954249fc93.tar.gz
rspamd-ed558e60e70f0b41e533beca5eb1d1954249fc93.zip
Implement decryption of messages.
Diffstat (limited to 'src/libutil/http.c')
-rw-r--r--src/libutil/http.c51
1 files changed, 44 insertions, 7 deletions
diff --git a/src/libutil/http.c b/src/libutil/http.c
index 4ecfdc50d..81771987d 100644
--- a/src/libutil/http.c
+++ b/src/libutil/http.c
@@ -34,7 +34,6 @@
#include <limits.h>
struct rspamd_http_keypair {
- guchar beforenm[crypto_box_BEFORENMBYTES];
guchar pk[crypto_box_PUBLICKEYBYTES];
guchar sk[crypto_box_SECRETKEYBYTES];
guchar id[BLAKE2B_OUTBYTES];
@@ -568,7 +567,8 @@ rspamd_http_on_body (http_parser * parser, const gchar *at, size_t length)
g_string_append_len (priv->msg->body, at, length);
- if (conn->opts & RSPAMD_HTTP_BODY_PARTIAL) {
+ if ((conn->opts & RSPAMD_HTTP_BODY_PARTIAL) && !priv->encrypted) {
+ /* Incremental update is basically impossible for encrypted requests */
return (conn->body_handler (conn, priv->msg, at, length));
}
@@ -582,18 +582,57 @@ rspamd_http_on_message_complete (http_parser * parser)
(struct rspamd_http_connection *)parser->data;
struct rspamd_http_connection_private *priv;
int ret = 0;
+ guchar *nonce, *m;
+ gsize dec_len;
+ GError *err;
priv = conn->priv;
if (conn->body_handler != NULL) {
- rspamd_http_connection_ref (conn);
- if ((conn->opts & RSPAMD_HTTP_BODY_PARTIAL) == 0) {
+
+ if (priv->encrypted) {
+ if (priv->local_key == NULL || priv->peer_key == NULL ||
+ priv->msg->body->len < crypto_box_NONCEBYTES + crypto_box_ZEROBYTES) {
+ err = g_error_new (HTTP_ERROR, 500, "Cannot decrypt message");
+ rspamd_http_connection_ref (conn);
+ conn->error_handler (conn, err);
+ rspamd_http_connection_unref (conn);
+ g_error_free (err);
+ return -1;
+ }
+ /* We have keys, so we can decrypt message */
+ /* TODO: add pubkey<->privkey pairs to LRU cache */
+ nonce = priv->msg->body->str;
+ m = priv->msg->body->str + crypto_box_NONCEBYTES;
+ dec_len = priv->msg->body->len - crypto_box_NONCEBYTES;
+
+ if (crypto_box_open (m + crypto_box_ZEROBYTES, m, dec_len, nonce,
+ priv->peer_key->str, priv->local_key->sk) != 0) {
+ err = g_error_new (HTTP_ERROR, 500, "Cannot verify encrypted message");
+ rspamd_http_connection_ref (conn);
+ conn->error_handler (conn, err);
+ rspamd_http_connection_unref (conn);
+ g_error_free (err);
+ return -1;
+ }
+ m += crypto_box_ZEROBYTES;
+ dec_len -= crypto_box_ZEROBYTES;
+
+ rspamd_http_connection_ref (conn);
+ ret = conn->body_handler (conn,
+ priv->msg,
+ m,
+ dec_len);
+ rspamd_http_connection_unref (conn);
+ }
+ else if ((conn->opts & RSPAMD_HTTP_BODY_PARTIAL) == 0) {
+ rspamd_http_connection_ref (conn);
ret = conn->body_handler (conn,
priv->msg,
priv->msg->body->str,
priv->msg->body->len);
+ rspamd_http_connection_unref (conn);
}
- rspamd_http_connection_unref (conn);
}
if (ret == 0) {
@@ -1563,8 +1602,6 @@ rspamd_http_connection_make_key (gchar *key, gsize keylen)
memcpy (kp->sk, decoded, crypto_box_SECRETKEYBYTES);
memcpy (kp->pk, decoded + crypto_box_SECRETKEYBYTES,
crypto_box_PUBLICKEYBYTES);
- crypto_box_beforenm (kp->beforenm, kp->pk,
- kp->sk);
blake2b (kp->id, kp->pk, NULL, sizeof (kp->id), sizeof (kp->pk), 0);
return (gpointer)kp;