From: Vsevolod Stakhov Date: Wed, 28 Jan 2015 21:42:25 +0000 (+0000) Subject: Implement decryption of messages. X-Git-Tag: 0.9.0~817^2~4 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=ed558e60e70f0b41e533beca5eb1d1954249fc93;p=rspamd.git Implement decryption of messages. --- 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 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;