]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Minor] Add method to decrypt data using keypair
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 19 May 2018 13:50:43 +0000 (14:50 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 19 May 2018 13:50:43 +0000 (14:50 +0100)
src/libcryptobox/keypair.c
src/libcryptobox/keypair.h

index 98401e10fa7351a70499277554d315e1191bff94..1f8acc6d1d803def07468e461fa4b7cf042260bd 100644 (file)
@@ -20,6 +20,8 @@
 #include "libutil/str_util.h"
 #include "libutil/printf.h"
 
+const guchar encrypted_magic[7] = {'r', 'u', 'c', 'l', 'e', 'v', '1'};
+
 static GQuark
 rspamd_keypair_quark (void)
 {
@@ -908,3 +910,70 @@ rspamd_pubkey_equal (const struct rspamd_cryptobox_pubkey *k1,
 
        return FALSE;
 }
+
+gboolean
+rspamd_keypair_decrypt (struct rspamd_cryptobox_keypair *kp,
+                                               const guchar *in, gsize inlen,
+                                               guchar **out, gsize *outlen,
+                                               GError **err)
+{
+       const guchar *nonce, *mac, *data, *pubkey;
+
+       g_assert (kp != NULL);
+       g_assert (in != NULL);
+
+       if (kp->type != RSPAMD_KEYPAIR_KEX) {
+               g_set_error (err, rspamd_keypair_quark (), EINVAL,
+                               "invalid keypair type");
+
+               return FALSE;
+       }
+
+       if (inlen < sizeof (encrypted_magic) + rspamd_cryptobox_pk_bytes (kp->alg) +
+                               rspamd_cryptobox_mac_bytes (kp->alg) +
+                               rspamd_cryptobox_nonce_bytes (kp->alg)) {
+               g_set_error (err, rspamd_keypair_quark (), E2BIG, "invalid size: too small");
+
+               return FALSE;
+       }
+
+       if (memcmp (in, encrypted_magic, sizeof (encrypted_magic)) != 0) {
+               g_set_error (err, rspamd_keypair_quark (), EINVAL,
+                               "invalid magic");
+
+               return FALSE;
+       }
+
+       /* Set pointers */
+       pubkey = in + sizeof (encrypted_magic);
+       mac = pubkey + rspamd_cryptobox_pk_bytes (kp->alg);
+       nonce = mac + rspamd_cryptobox_mac_bytes (kp->alg);
+       data = nonce + rspamd_cryptobox_nonce_bytes (kp->alg);
+
+       if (data - in >= inlen) {
+               g_set_error (err, rspamd_keypair_quark (), E2BIG, "invalid size: too small");
+
+               return FALSE;
+       }
+
+       inlen -= data - in;
+
+       /* Allocate memory for output */
+       *out = g_malloc (inlen);
+       memcpy (*out, data, inlen);
+
+       if (!rspamd_cryptobox_decrypt_inplace (*out, inlen, nonce, pubkey,
+                       rspamd_keypair_component (kp, RSPAMD_KEYPAIR_COMPONENT_SK, NULL),
+                       mac, kp->alg)) {
+               g_set_error (err, rspamd_keypair_quark (), EPERM, "verification failed");
+               g_free (*out);
+
+               return FALSE;
+       }
+
+       if (outlen) {
+               *outlen = inlen;
+       }
+
+       return TRUE;
+}
index b24ecc9aa980279b69c65ab8c86d08c5877adc2c..fc17412e21f323bebfb4b5f94ed23281b52fea25 100644 (file)
@@ -28,6 +28,8 @@ enum rspamd_cryptobox_keypair_type {
        RSPAMD_KEYPAIR_SIGN
 };
 
+extern const guchar encrypted_magic[7];
+
 /**
  * Opaque structure for the full (public + private) keypair
  */
@@ -270,5 +272,20 @@ gboolean rspamd_keypair_verify (struct rspamd_cryptobox_pubkey *pk,
 gboolean rspamd_pubkey_equal (const struct rspamd_cryptobox_pubkey *k1,
                const struct rspamd_cryptobox_pubkey *k2);
 
+/**
+ * Decrypts data using keypair and a pubkey stored in in, in must start from
+ * `encrypted_magic` constant
+ * @param kp keypair
+ * @param in raw input
+ * @param inlen input length
+ * @param out output (allocated internally using g_malloc)
+ * @param outlen output size
+ * @return TRUE if decryption is completed, out must be freed in this case
+ */
+gboolean rspamd_keypair_decrypt (struct rspamd_cryptobox_keypair *kp,
+                                                                const guchar *in, gsize inlen,
+                                                                guchar **out, gsize *outlen,
+                                                                GError **err);
+
 
 #endif /* SRC_LIBCRYPTOBOX_KEYPAIR_H_ */