]> source.dussan.org Git - rspamd.git/commitdiff
Rework HTTP encryption
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 5 Feb 2016 23:20:10 +0000 (23:20 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 5 Feb 2016 23:20:10 +0000 (23:20 +0000)
src/libcryptobox/keypair.c
src/libcryptobox/keypair.h
src/libutil/http.c
src/libutil/http.h

index ae4d2b71d23064e7199c95bb0023d82ee374924e..61a5f687d459abfd6aca776bad0d567d80541fa4 100644 (file)
@@ -18,6 +18,7 @@
 #include "libcryptobox/keypair.h"
 #include "libcryptobox/keypair_private.h"
 #include "libutil/str_util.h"
+#include "libutil/printf.h"
 
 /**
  * Returns specific private key for different keypair types
@@ -244,7 +245,7 @@ rspamd_keypair_new (enum rspamd_cryptobox_keypair_type type,
 
 
 struct rspamd_cryptobox_keypair*
-rspamd_keypair_ref (struct rspamd_cryptobox_keypair *kp)
+rspamd__keypair_ref (struct rspamd_cryptobox_keypair *kp)
 {
        REF_RETAIN (kp);
        return kp;
@@ -405,3 +406,110 @@ rspamd_pubkey_get_nm (struct rspamd_cryptobox_pubkey *p)
 
        return NULL;
 }
+
+const guchar *
+rspamd_pubkey_calculate_nm (struct rspamd_cryptobox_pubkey *p,
+               struct rspamd_cryptobox_keypair *kp)
+{
+       g_assert (kp->alg == p->alg);
+       g_assert (kp->type == p->type);
+       g_assert (p->type == RSPAMD_KEYPAIR_KEX);
+
+       if (kp->alg == RSPAMD_CRYPTOBOX_MODE_25519) {
+               struct rspamd_cryptobox_pubkey_25519 *rk_25519 =
+                               RSPAMD_CRYPTOBOX_PUBKEY_25519(p);
+               struct rspamd_cryptobox_keypair_25519 *sk_25519 =
+                               RSPAMD_CRYPTOBOX_KEYPAIR_25519(kp);
+
+               rspamd_cryptobox_nm (p->nm->nm, rk_25519->pk, sk_25519->sk, p->alg);
+       }
+       else {
+               struct rspamd_cryptobox_pubkey_nist *rk_nist =
+                               RSPAMD_CRYPTOBOX_PUBKEY_NIST(p);
+               struct rspamd_cryptobox_keypair_nist *sk_nist =
+                               RSPAMD_CRYPTOBOX_KEYPAIR_NIST(kp);
+
+               rspamd_cryptobox_nm (p->nm->nm, rk_nist->pk, sk_nist->sk, p->alg);
+       }
+
+       return p->nm->nm;
+}
+
+const guchar *
+rspamd_keypair_get_id (struct rspamd_cryptobox_keypair *kp)
+{
+       g_assert (kp != NULL);
+
+       return kp->id;
+}
+
+const guchar *
+rspamd_pubkey_get_id (struct rspamd_cryptobox_pubkey *pk)
+{
+       g_assert (pk != NULL);
+
+       return pk->id;
+}
+
+
+static void
+rspamd_keypair_print_component (guchar *data, gsize datalen,
+               GString *res, guint how, const gchar *description)
+{
+       gint olen, b32_len;
+
+       if (how & RSPAMD_KEYPAIR_HUMAN) {
+               g_string_append_printf (res, "%s: ", description);
+       }
+
+       if (how & RSPAMD_KEYPAIR_BASE32) {
+               b32_len = (datalen * 8 / 5) + 2;
+               g_string_set_size (res, res->len + b32_len);
+               olen = rspamd_encode_base32_buf (data, datalen, res->str + res->len,
+                               res->len + b32_len - 1);
+
+               if (olen > 0) {
+                       res->len += olen;
+                       res->str[res->len] = '\0';
+               }
+       }
+       else if (how & RSPAMD_KEYPAIR_HEX) {
+               rspamd_printf_gstring (res, "%*xs", (gint)datalen, data);
+       }
+       else {
+               g_string_append_len (res, data, datalen);
+       }
+
+       if (how & RSPAMD_KEYPAIR_HUMAN) {
+               g_string_append_c (res, '\n');
+       }
+}
+
+GString *
+rspamd_keypair_print (struct rspamd_cryptobox_keypair *kp, guint how)
+{
+       GString *res;
+       guint len;
+       gpointer p;
+
+       g_assert (kp != NULL);
+
+       res = g_string_sized_new (64);
+
+       if ((how & RSPAMD_KEYPAIR_PUBKEY)) {
+               p = rspamd_cryptobox_keypair_pk (kp, &len);
+               rspamd_keypair_print_component (p, len, res, how, "Public key");
+       }
+       if ((how & RSPAMD_KEYPAIR_PRIVKEY)) {
+               p = rspamd_cryptobox_keypair_sk (kp, &len);
+               rspamd_keypair_print_component (p, len, res, how, "Private key");
+       }
+       if ((how & RSPAMD_KEYPAIR_ID_SHORT)) {
+               rspamd_keypair_print_component (kp->id, 5, res, how, "Short key ID");
+       }
+       if ((how & RSPAMD_KEYPAIR_ID)) {
+               rspamd_keypair_print_component (kp->id, sizeof (kp->id), res, how, "Key ID");
+       }
+
+       return res;
+}
index 80d50b2f3ce137a6fbf7f6711e691e70cc0754ac..bd82b64ae55c7c8ea2d0677ad738ec1afd7f0e06 100644 (file)
@@ -127,5 +127,48 @@ enum rspamd_cryptobox_mode rspamd_pubkey_alg (struct rspamd_cryptobox_pubkey *p)
  */
 const guchar * rspamd_pubkey_get_nm (struct rspamd_cryptobox_pubkey *p);
 
+/**
+ * Calculate and store nm value for the specified local key (performs ECDH)
+ * @param p
+ * @return
+ */
+const guchar * rspamd_pubkey_calculate_nm (struct rspamd_cryptobox_pubkey *p,
+               struct rspamd_cryptobox_keypair *kp);
+
+/**
+ * Get raw public key id for a specified keypair (rspamd_cryptobox_HASHBYTES)
+ * @param kp
+ * @return
+ */
+const guchar * rspamd_keypair_get_id (struct rspamd_cryptobox_keypair *kp);
+/**
+ * Get raw public key id for a specified key (rspamd_cryptobox_HASHBYTES)
+ * @param kp
+ * @return
+ */
+const guchar * rspamd_pubkey_get_id (struct rspamd_cryptobox_pubkey *pk);
+
+
+/** Print pubkey */
+#define RSPAMD_KEYPAIR_PUBKEY 0x1
+/** Print secret key */
+#define RSPAMD_KEYPAIR_PRIVKEY 0x2
+/** Print key id */
+#define RSPAMD_KEYPAIR_ID 0x4
+/** Print short key id */
+#define RSPAMD_KEYPAIR_ID_SHORT 0x8
+/** Encode output with base 32 */
+#define RSPAMD_KEYPAIR_BASE32 0x10
+/** Human readable output */
+#define RSPAMD_KEYPAIR_HUMAN 0x20
+#define RSPAMD_KEYPAIR_HEX 0x40
+/**
+ * Print keypair encoding it if needed
+ * @param key key to print
+ * @param how flags that specifies printing behaviour
+ * @return newly allocated string with keypair
+ */
+GString *rspamd_keypair_print (struct rspamd_cryptobox_keypair *kp,
+               guint how);
 
 #endif /* SRC_LIBCRYPTOBOX_KEYPAIR_H_ */
index c72031bca23e3f7bc700992eb573d4feb054f9ec..4640fbffebc7b4515ef82d819c7d09cff09575d9 100644 (file)
@@ -36,8 +36,8 @@ struct rspamd_http_connection_private {
        struct _rspamd_http_privbuf *buf;
        gboolean new_header;
        gboolean encrypted;
-       gpointer peer_key;
-       struct rspamd_http_keypair *local_key;
+       struct rspamd_cryptobox_pubkey *peer_key;
+       struct rspamd_cryptobox_keypair *local_key;
        struct rspamd_http_header *header;
        struct http_parser parser;
        struct http_parser_settings parser_cb;
@@ -93,14 +93,6 @@ http_error_quark (void)
        return g_quark_from_static_string ("http-error-quark");
 }
 
-static void
-rspamd_http_keypair_dtor (struct rspamd_http_keypair *kp)
-{
-       rspamd_explicit_memzero (kp->sk, sizeof (kp->sk));
-       rspamd_explicit_memzero (kp->nm, sizeof (kp->nm));
-       g_slice_free1 (sizeof (*kp), kp);
-}
-
 static void
 rspamd_http_privbuf_dtor (gpointer ud)
 {
@@ -408,10 +400,10 @@ static void
 rspamd_http_parse_key (rspamd_ftok_t *data, struct rspamd_http_connection *conn,
                struct rspamd_http_connection_private *priv)
 {
-       guchar *decoded_id, *decoded_key;
+       guchar *decoded_id;
        const gchar *eq_pos;
-       gsize id_len, key_len;
-       struct rspamd_http_keypair *kp;
+       gsize id_len;
+       struct rspamd_cryptobox_pubkey *pk;
 
        if (priv->local_key == NULL) {
                /* In this case we cannot do anything, e.g. we cannot decrypt payload */
@@ -423,17 +415,17 @@ rspamd_http_parse_key (rspamd_ftok_t *data, struct rspamd_http_connection *conn,
                if (eq_pos != NULL) {
                        decoded_id = rspamd_decode_base32 (data->begin, eq_pos - data->begin,
                                        &id_len);
-                       decoded_key = rspamd_decode_base32 (eq_pos + 1, data->begin + data->len -
-                                       eq_pos - 1, &key_len);
-                       if (decoded_id != NULL && decoded_key != NULL) {
-                               if (id_len >= RSPAMD_HTTP_KEY_ID_LEN  &&
-                                               key_len >= rspamd_cryptobox_pk_bytes ()) {
-                                       if (memcmp (priv->local_key->id, decoded_id,
+
+                       if (decoded_id != NULL && id_len >= RSPAMD_HTTP_KEY_ID_LEN) {
+                               pk = rspamd_pubkey_from_base32 (eq_pos + 1,
+                                               data->begin + data->len - eq_pos - 1,
+                                               RSPAMD_KEYPAIR_KEX,
+                                               RSPAMD_CRYPTOBOX_MODE_25519);
+                               if (pk != NULL) {
+                                       if (memcmp (rspamd_keypair_get_id (priv->local_key),
+                                                       decoded_id,
                                                        RSPAMD_HTTP_KEY_ID_LEN) == 0) {
-                                               kp = g_slice_alloc0 (sizeof (*kp));
-                                               REF_INIT_RETAIN (kp, rspamd_http_keypair_dtor);
-                                               memcpy (kp->pk, decoded_key, rspamd_cryptobox_pk_bytes ());
-                                               priv->msg->peer_key = kp;
+                                               priv->msg->peer_key = pk;
 
                                                if (conn->cache && priv->msg->peer_key) {
                                                        rspamd_keypair_cache_process (conn->cache,
@@ -442,8 +434,8 @@ rspamd_http_parse_key (rspamd_ftok_t *data, struct rspamd_http_connection *conn,
                                        }
                                }
                        }
+
                        priv->encrypted = TRUE;
-                       g_free (decoded_key);
                        g_free (decoded_id);
                }
        }
@@ -688,29 +680,30 @@ rspamd_http_on_headers_complete_decrypted (http_parser *parser)
 static int
 rspamd_http_decrypt_message (struct rspamd_http_connection *conn,
                struct rspamd_http_connection_private *priv,
-               struct rspamd_http_keypair *peer_key)
+               struct rspamd_cryptobox_pubkey *peer_key)
 {
        guchar *nonce, *m;
+       const guchar *nm;
        gsize dec_len;
        struct rspamd_http_message *msg = priv->msg;
        struct rspamd_http_header *hdr, *hdrtmp;
        struct http_parser decrypted_parser;
        struct http_parser_settings decrypted_cb;
+       enum rspamd_cryptobox_mode mode;
 
+       mode = rspamd_keypair_alg (priv->local_key);
        nonce = msg->body->str;
-       m = msg->body->str + rspamd_cryptobox_nonce_bytes () +
-                       rspamd_cryptobox_mac_bytes ();
-       dec_len = msg->body->len - rspamd_cryptobox_nonce_bytes () -
-                       rspamd_cryptobox_mac_bytes ();
+       m = msg->body->str + rspamd_cryptobox_nonce_bytes (mode) +
+                       rspamd_cryptobox_mac_bytes (mode);
+       dec_len = msg->body->len - rspamd_cryptobox_nonce_bytes (mode) -
+                       rspamd_cryptobox_mac_bytes (mode);
 
-       if (!peer_key->has_nm) {
-               /* We still save NM for the following encryption */
-               rspamd_cryptobox_nm (peer_key->nm, peer_key->pk, priv->local_key->sk);
-               peer_key->has_nm = TRUE;
+       if ((nm = rspamd_pubkey_get_nm (peer_key)) == NULL) {
+               nm = rspamd_pubkey_calculate_nm (peer_key, priv->local_key);
        }
 
        if (!rspamd_cryptobox_decrypt_nm_inplace (m, dec_len, nonce,
-                       peer_key->nm, m - rspamd_cryptobox_mac_bytes ())) {
+                       nm, m - rspamd_cryptobox_mac_bytes (mode), mode)) {
                msg_err ("cannot verify encrypted message");
                return -1;
        }
@@ -761,21 +754,22 @@ rspamd_http_on_message_complete (http_parser * parser)
                (struct rspamd_http_connection *)parser->data;
        struct rspamd_http_connection_private *priv;
        int ret = 0;
-       struct rspamd_http_keypair *peer_key = NULL;
+       enum rspamd_cryptobox_mode mode;
 
        priv = conn->priv;
 
        if ((conn->opts & RSPAMD_HTTP_BODY_PARTIAL) == 0 && priv->encrypted) {
+               mode = rspamd_keypair_alg (priv->local_key);
+
                if (priv->local_key == NULL || priv->msg->peer_key == NULL ||
-                               priv->msg->body->len < rspamd_cryptobox_nonce_bytes () +
-                               rspamd_cryptobox_mac_bytes ()) {
+                               priv->msg->body->len < rspamd_cryptobox_nonce_bytes (mode) +
+                               rspamd_cryptobox_mac_bytes (mode)) {
                        msg_err ("cannot decrypt message");
                        return -1;
                }
 
                /* We have keys, so we can decrypt message */
-               peer_key = (struct rspamd_http_keypair *)priv->msg->peer_key;
-               ret = rspamd_http_decrypt_message (conn, priv, peer_key);
+               ret = rspamd_http_decrypt_message (conn, priv, priv->msg->peer_key);
 
                if (ret != 0) {
                        return ret;
@@ -1163,7 +1157,6 @@ void
 rspamd_http_connection_free (struct rspamd_http_connection *conn)
 {
        struct rspamd_http_connection_private *priv;
-       struct rspamd_http_keypair *peer_key;
 
        priv = conn->priv;
 
@@ -1171,11 +1164,10 @@ rspamd_http_connection_free (struct rspamd_http_connection *conn)
                rspamd_http_connection_reset (conn);
 
                if (priv->local_key) {
-                       REF_RELEASE (priv->local_key);
+                       rspamd_keypair_unref (priv->local_key);
                }
                if (priv->peer_key) {
-                       peer_key = (struct rspamd_http_keypair *)priv->peer_key;
-                       REF_RELEASE (peer_key);
+                       rspamd_pubkey_unref (priv->peer_key);
                }
 
                g_slice_free1 (sizeof (struct rspamd_http_connection_private), priv);
@@ -1241,13 +1233,18 @@ rspamd_http_connection_encrypt_message (
                gint hdrcount,
                guchar *np,
                guchar *mp,
-               struct rspamd_http_keypair *peer_key)
+               struct rspamd_cryptobox_pubkey *peer_key)
 {
        struct rspamd_cryptobox_segment *segments;
-       guchar *crlfp = mp + rspamd_cryptobox_mac_bytes ();
+       guchar *crlfp;
+       const guchar *nm;
        gint i, cnt;
        guint outlen;
        struct rspamd_http_header *hdr;
+       enum rspamd_cryptobox_mode mode;
+
+       mode = rspamd_keypair_alg (priv->local_key);
+       crlfp = mp + rspamd_cryptobox_mac_bytes (mode);
 
        outlen = priv->out[0].iov_len + priv->out[1].iov_len;
        /*
@@ -1294,15 +1291,11 @@ rspamd_http_connection_encrypt_message (
 
        cnt = i;
 
-       if (!peer_key->has_nm) {
-               rspamd_cryptobox_nm (peer_key->nm, peer_key->pk, priv->local_key->sk);
-               peer_key->has_nm = TRUE;
+       if ((nm = rspamd_pubkey_get_nm (peer_key))) {
+               nm = rspamd_pubkey_calculate_nm (peer_key, priv->local_key);
        }
 
-       rspamd_cryptobox_encryptv_nm_inplace (segments,
-                       cnt,
-                       np,
-                       peer_key->nm, mp);
+       rspamd_cryptobox_encryptv_nm_inplace (segments, cnt, np, nm, mp, mode);
 
        /*
         * iov[0] = base HTTP request
@@ -1312,11 +1305,12 @@ rspamd_http_connection_encrypt_message (
         * iov[4..i] = encrypted HTTP request/reply
         */
        priv->out[2].iov_base = np;
-       priv->out[2].iov_len = rspamd_cryptobox_nonce_bytes ();
+       priv->out[2].iov_len = rspamd_cryptobox_nonce_bytes (mode);
        priv->out[3].iov_base = mp;
-       priv->out[3].iov_len = rspamd_cryptobox_mac_bytes ();
+       priv->out[3].iov_len = rspamd_cryptobox_mac_bytes (mode);
 
-       outlen += rspamd_cryptobox_nonce_bytes () + rspamd_cryptobox_mac_bytes ();
+       outlen += rspamd_cryptobox_nonce_bytes (mode) +
+                       rspamd_cryptobox_mac_bytes (mode);
 
        for (i = 0; i < cnt; i ++) {
                priv->out[i + 4].iov_base = segments[i].data;
@@ -1342,11 +1336,11 @@ rspamd_http_connection_write_message (struct rspamd_http_connection *conn,
        gsize bodylen, enclen = 0;
        rspamd_fstring_t *buf;
        gboolean encrypted = FALSE;
-       gchar *b32_key, *b32_id;
        guchar nonce[rspamd_cryptobox_MAX_NONCEBYTES], mac[rspamd_cryptobox_MAX_MACBYTES],
                id[rspamd_cryptobox_HASHBYTES];
        guchar *np = NULL, *mp = NULL, *meth_pos = NULL;
-       struct rspamd_http_keypair *peer_key = NULL;
+       struct rspamd_cryptobox_pubkey *peer_key = NULL;
+       enum rspamd_cryptobox_mode mode;
 
        conn->fd = fd;
        conn->ud = ud;
@@ -1381,6 +1375,8 @@ rspamd_http_connection_write_message (struct rspamd_http_connection *conn,
        }
 
        if (encrypted) {
+               mode = rspamd_keypair_alg (priv->local_key);
+
                if (msg->body == NULL || msg->body->len == 0) {
                        pbody = NULL;
                        bodylen = 0;
@@ -1405,8 +1401,8 @@ rspamd_http_connection_write_message (struct rspamd_http_connection *conn,
                         * [iov[n + 2] = encrypted body]
                         */
                        priv->outlen = 7;
-                       enclen = rspamd_cryptobox_nonce_bytes () +
-                                       rspamd_cryptobox_mac_bytes () +
+                       enclen = rspamd_cryptobox_nonce_bytes (mode) +
+                                       rspamd_cryptobox_mac_bytes (mode) +
                                        4 + /* 2 * CRLF */
                                        bodylen;
                }
@@ -1434,8 +1430,8 @@ rspamd_http_connection_write_message (struct rspamd_http_connection *conn,
                                                ENCRYPTED_VERSION);
                        }
 
-                       enclen = rspamd_cryptobox_nonce_bytes () +
-                                       rspamd_cryptobox_mac_bytes () +
+                       enclen = rspamd_cryptobox_nonce_bytes (mode) +
+                                       rspamd_cryptobox_mac_bytes (mode) +
                                        preludelen + /* version [content-length] + 2 * CRLF */
                                        bodylen;
                }
@@ -1470,7 +1466,7 @@ rspamd_http_connection_write_message (struct rspamd_http_connection *conn,
                }
        }
 
-       peer_key = (struct rspamd_http_keypair *)msg->peer_key;
+       peer_key = msg->peer_key;
 
        priv->wr_total = bodylen + buf->len + 2;
        hdrcount = 0;
@@ -1625,10 +1621,13 @@ rspamd_http_connection_write_message (struct rspamd_http_connection *conn,
 
                }
                if (encrypted) {
-                       memcpy (id, peer_key->id, sizeof (id));
-                       b32_key = rspamd_encode_base32 (priv->local_key->pk,
-                                       rspamd_cryptobox_pk_bytes ());
-                       b32_id = rspamd_encode_base32 (id, RSPAMD_HTTP_KEY_ID_LEN);
+                       GString *b32_key, *b32_id;
+
+                       memcpy (id, rspamd_pubkey_get_id (peer_key), sizeof (id));
+                       b32_key = rspamd_keypair_print (priv->local_key,
+                                       RSPAMD_KEYPAIR_PUBKEY|RSPAMD_KEYPAIR_BASE32);
+                       b32_id = rspamd_keypair_print (priv->local_key,
+                                       RSPAMD_KEYPAIR_ID_SHORT|RSPAMD_KEYPAIR_BASE32);
                        /* XXX: add some fuzz here */
                        rspamd_printf_fstring (&buf, "Key: %s=%s\r\n", b32_id, b32_key);
                        g_free (b32_key);
@@ -1643,9 +1642,10 @@ rspamd_http_connection_write_message (struct rspamd_http_connection *conn,
        /* Buf will be used eventually for encryption */
        if (encrypted) {
                gint meth_offset, nonce_offset, mac_offset;
+               mode = rspamd_keypair_alg (priv->local_key);
 
-               ottery_rand_bytes (nonce, rspamd_cryptobox_nonce_bytes ());
-               memset (mac, 0, rspamd_cryptobox_mac_bytes ());
+               ottery_rand_bytes (nonce, rspamd_cryptobox_nonce_bytes (mode));
+               memset (mac, 0, rspamd_cryptobox_mac_bytes (mode));
                meth_offset = buf->len;
 
                if (conn->type == RSPAMD_HTTP_SERVER) {
@@ -1659,9 +1659,11 @@ rspamd_http_connection_write_message (struct rspamd_http_connection *conn,
                }
 
                nonce_offset = buf->len;
-               buf = rspamd_fstring_append (buf, nonce, rspamd_cryptobox_nonce_bytes ());
+               buf = rspamd_fstring_append (buf, nonce,
+                               rspamd_cryptobox_nonce_bytes (mode));
                mac_offset = buf->len;
-               buf = rspamd_fstring_append (buf, mac, rspamd_cryptobox_mac_bytes ());
+               buf = rspamd_fstring_append (buf, mac,
+                               rspamd_cryptobox_mac_bytes (mode));
 
                /* Need to be encrypted */
                if (conn->type == RSPAMD_HTTP_SERVER) {
@@ -1829,7 +1831,7 @@ rspamd_http_message_free (struct rspamd_http_message *msg)
                rspamd_fstring_free (msg->host);
        }
        if (msg->peer_key != NULL) {
-               rspamd_http_connection_key_unref (msg->peer_key);
+               rspamd_pubkey_unref (msg->peer_key);
        }
 
        g_slice_free1 (sizeof (struct rspamd_http_message), msg);
@@ -2213,14 +2215,11 @@ rspamd_http_router_new (rspamd_http_router_error_handler_t eh,
 
 void
 rspamd_http_router_set_key (struct rspamd_http_connection_router *router,
-               gpointer key)
+               struct rspamd_cryptobox_keypair *key)
 {
-       struct rspamd_http_keypair *kp = (struct rspamd_http_keypair *)key;
-
        g_assert (key != NULL);
-       REF_RETAIN (kp);
 
-       router->key = key;
+       router->key = rspamd_keypair_ref (key);
 }
 
 void
@@ -2273,7 +2272,6 @@ void
 rspamd_http_router_free (struct rspamd_http_connection_router *router)
 {
        struct rspamd_http_connection_entry *conn, *tmp;
-       struct rspamd_http_keypair *kp;
 
        if (router) {
                DL_FOREACH_SAFE (router->conns, conn, tmp)
@@ -2282,8 +2280,7 @@ rspamd_http_router_free (struct rspamd_http_connection_router *router)
                }
 
                if (router->key) {
-                       kp = (struct rspamd_http_keypair *)router->key;
-                       REF_RELEASE (kp);
+                       rspamd_keypair_unref (router->key);
                }
 
                if (router->cache) {
@@ -2298,131 +2295,14 @@ rspamd_http_router_free (struct rspamd_http_connection_router *router)
        }
 }
 
-gpointer
-rspamd_http_connection_make_key (gchar *key, gsize keylen)
-{
-       guchar *decoded_sk, *decoded_pk;
-       gchar *semicolon;
-       gsize decoded_len;
-       struct rspamd_http_keypair *kp;
-       guchar kh[rspamd_cryptobox_HASHBYTES];
-
-       semicolon = memchr (key, ':', keylen);
-
-       if (semicolon) {
-               decoded_sk = rspamd_decode_base32 (key, semicolon - key, &decoded_len);
-               decoded_pk = rspamd_decode_base32 (semicolon + 1,
-                               keylen - (semicolon - key + 1),
-                               &decoded_len);
-       }
-       else {
-               decoded_sk = rspamd_decode_base32 (key, keylen / 2, &decoded_len);
-               decoded_pk = rspamd_decode_base32 (key + keylen / 2,
-                               keylen / 2,
-                               &decoded_len);
-       }
-
-       if (decoded_pk != NULL && decoded_sk != NULL) {
-               if (decoded_len == rspamd_cryptobox_pk_bytes ()) {
-                       kp = g_slice_alloc (sizeof (*kp));
-                       REF_INIT_RETAIN (kp, rspamd_http_keypair_dtor);
-                       memcpy (kp->sk, decoded_sk, rspamd_cryptobox_sk_bytes ());
-                       memcpy (kp->pk, decoded_pk, rspamd_cryptobox_pk_bytes ());
-                       rspamd_cryptobox_hash (kh, kp->pk, rspamd_cryptobox_pk_bytes (),
-                                       NULL, 0);
-                       memcpy (kp->id, kh, sizeof (kp->id));
-
-                       return (gpointer) kp;
-               }
-               g_free (decoded_pk);
-               g_free (decoded_sk);
-       }
-
-       return NULL;
-}
-
-gpointer
-rspamd_http_connection_gen_key (void)
-{
-       struct rspamd_http_keypair *kp;
-       guchar kh[rspamd_cryptobox_HASHBYTES];
-
-       kp = g_slice_alloc (sizeof (*kp));
-       REF_INIT_RETAIN (kp, rspamd_http_keypair_dtor);
-
-       rspamd_cryptobox_keypair (kp->pk, kp->sk);
-       rspamd_cryptobox_hash (kh, kp->pk, rspamd_cryptobox_pk_bytes (),
-                       NULL, 0);
-       memcpy (kp->id, kh, sizeof (kp->id));
-
-       return (gpointer)kp;
-}
-
-static void
-rspamd_http_print_key_component (guchar *data, gsize datalen,
-               GString *res, guint how, const gchar *description)
-{
-       gchar *b32;
-
-       if (how & RSPAMD_KEYPAIR_HUMAN) {
-               g_string_append_printf (res, "%s: ", description);
-       }
-
-       if (how & RSPAMD_KEYPAIR_BASE32) {
-               b32 = rspamd_encode_base32 (data, datalen);
-               g_string_append_printf (res, "%s", b32);
-               g_free (b32);
-       }
-       else if (how & RSPAMD_KEYPAIR_HEX) {
-               rspamd_printf_gstring (res, "%*xs", (gint)datalen, data);
-       }
-       else {
-               g_string_append_len (res, data, datalen);
-       }
-
-       if (how & RSPAMD_KEYPAIR_HUMAN) {
-               g_string_append_c (res, '\n');
-       }
-}
-
-GString *
-rspamd_http_connection_print_key (gpointer key, guint how)
-{
-       struct rspamd_http_keypair *kp = (struct rspamd_http_keypair *)key;
-       GString *res;
-
-       g_assert (key != NULL);
-
-       res = g_string_new (NULL);
-
-       if ((how & RSPAMD_KEYPAIR_PUBKEY)) {
-               rspamd_http_print_key_component (kp->pk,
-                               rspamd_cryptobox_pk_bytes (), res, how,
-                               "Public key");
-       }
-       if ((how & RSPAMD_KEYPAIR_PRIVKEY)) {
-               rspamd_http_print_key_component (kp->sk, rspamd_cryptobox_sk_bytes (),
-                               res, how,
-                               "Private key");
-       }
-       if ((how & RSPAMD_KEYPAIR_ID)) {
-               rspamd_http_print_key_component (kp->id, RSPAMD_HTTP_KEY_ID_LEN, res, how,
-                               "Key ID");
-       }
-
-       return res;
-}
-
 void
 rspamd_http_connection_set_key (struct rspamd_http_connection *conn,
-               gpointer key)
+               struct rspamd_cryptobox_keypair *key)
 {
        struct rspamd_http_connection_private *priv = conn->priv;
-       struct rspamd_http_keypair *kp = (struct rspamd_http_keypair *)key;
 
        g_assert (key != NULL);
-       REF_RETAIN (kp);
-       priv->local_key = kp;
+       priv->local_key = rspamd_keypair_ref (key);
 }
 
 gboolean
@@ -2440,50 +2320,6 @@ rspamd_http_connection_is_encrypted (struct rspamd_http_connection *conn)
        return FALSE;
 }
 
-void
-rspamd_http_connection_key_unref (gpointer key)
-{
-       struct rspamd_http_keypair *kp = (struct rspamd_http_keypair *)key;
-
-       g_assert (key != NULL);
-       REF_RELEASE (kp);
-}
-
-gpointer
-rspamd_http_connection_key_ref (gpointer key)
-{
-       struct rspamd_http_keypair *kp = (struct rspamd_http_keypair *)key;
-
-       g_assert (key != NULL);
-       REF_RETAIN (kp);
-
-       return kp;
-}
-
-gpointer
-rspamd_http_connection_make_peer_key (const gchar *key)
-{
-       guchar *pk_decoded;
-       gsize dec_len;
-       struct rspamd_http_keypair *kp = NULL;
-       guchar kh[rspamd_cryptobox_HASHBYTES];
-
-       pk_decoded = rspamd_decode_base32 (key, strlen (key), &dec_len);
-
-       if (pk_decoded != NULL && dec_len == rspamd_cryptobox_pk_bytes ()) {
-               kp = g_slice_alloc0 (sizeof (*kp));
-               REF_INIT_RETAIN (kp, rspamd_http_keypair_dtor);
-               memcpy (kp->pk, pk_decoded, rspamd_cryptobox_pk_bytes ());
-               rspamd_cryptobox_hash (kh, kp->pk, rspamd_cryptobox_pk_bytes (),
-                               NULL, 0);
-               memcpy (kp->id, kh, sizeof (kp->id));
-       }
-
-       g_free (pk_decoded);
-
-       return kp;
-}
-
 GHashTable *
 rspamd_http_message_parse_query (struct rspamd_http_message *msg)
 {
index 39d4e37069c1d73785efea32e61a2d38f97bc9cc..34c72d5190081137439b9a5cc93e7c764ae3d6e2 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "config.h"
 #include "http_parser.h"
+#include "keypair.h"
 #include "keypairs_cache.h"
 #include "fstring.h"
 
@@ -59,7 +60,7 @@ struct rspamd_http_message {
        struct rspamd_http_header *headers;
        rspamd_fstring_t *body;
        rspamd_ftok_t body_buf;
-       gpointer peer_key;
+       struct rspamd_cryptobox_pubkey *peer_key;
        enum http_parser_type type;
        time_t date;
        gint code;
@@ -135,7 +136,7 @@ struct rspamd_http_connection_router {
        struct event_base *ev_base;
        struct rspamd_keypair_cache *cache;
        gchar *default_fs_path;
-       gpointer key;
+       struct rspamd_cryptobox_keypair *key;
        rspamd_http_router_error_handler_t error_handler;
        rspamd_http_router_finish_handler_t finish_handler;
 };
@@ -154,19 +155,6 @@ struct rspamd_http_connection * rspamd_http_connection_new (
        enum rspamd_http_connection_type type,
        struct rspamd_keypair_cache *cache);
 
-/**
- * Load the encryption keypair
- * @param key base32 encoded privkey and pubkey (in that order)
- * @param keylen length of base32 string
- * @return opaque pointer pr NULL in case of error
- */
-gpointer rspamd_http_connection_make_key (gchar *key, gsize keylen);
-
-/**
- * Generate the encryption keypair
- * @return opaque pointer pr NULL in case of error
- */
-gpointer rspamd_http_connection_gen_key (void);
 
 /**
  * Set key pointed by an opaque pointer
@@ -174,7 +162,7 @@ gpointer rspamd_http_connection_gen_key (void);
  * @param key opaque key structure
  */
 void rspamd_http_connection_set_key (struct rspamd_http_connection *conn,
-               gpointer key);
+               struct rspamd_cryptobox_keypair *key);
 
 /**
  * Returns TRUE if a connection is encrypted
@@ -183,39 +171,6 @@ void rspamd_http_connection_set_key (struct rspamd_http_connection *conn,
  */
 gboolean rspamd_http_connection_is_encrypted (struct rspamd_http_connection *conn);
 
-/** Print pubkey */
-#define RSPAMD_KEYPAIR_PUBKEY 0x1
-/** Print secret key */
-#define RSPAMD_KEYPAIR_PRIVKEY 0x2
-/** Print key id */
-#define RSPAMD_KEYPAIR_ID 0x4
-/** Encode output with base 32 */
-#define RSPAMD_KEYPAIR_BASE32 0x8
-/** Human readable output */
-#define RSPAMD_KEYPAIR_HUMAN 0x10
-#define RSPAMD_KEYPAIR_HEX 0x20
-/**
- * Print keypair encoding it if needed
- * @param key key to print
- * @param how flags that specifies printing behaviour
- * @return newly allocated string with keypair
- */
-GString *rspamd_http_connection_print_key (gpointer key, guint how);
-
-/**
- * Release key pointed by an opaque pointer
- * @param key opaque key structure
- */
-void rspamd_http_connection_key_unref (gpointer key);
-
-/**
- * Increase refcount for a key pointed by an opaque pointer
- * @param key opaque key structure
- */
-gpointer rspamd_http_connection_key_ref (gpointer key);
-
-gpointer rspamd_http_connection_make_peer_key (const gchar *key);
-
 /**
  * Handle a request using socket fd and user data ud
  * @param conn connection structure
@@ -368,7 +323,7 @@ struct rspamd_http_connection_router * rspamd_http_router_new (
  * @param key opaque key structure
  */
 void rspamd_http_router_set_key (struct rspamd_http_connection_router *router,
-               gpointer key);
+               struct rspamd_cryptobox_keypair *key);
 
 /**
  * Add new path to the router