aboutsummaryrefslogtreecommitdiffstats
path: root/src/libcryptobox
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2018-05-19 14:50:43 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2018-05-19 14:50:43 +0100
commit3fc31cc8724885d8d0f2d7ff8028f3b4f6b49c8e (patch)
treec0ce728b942f020b5eb033613dab2e8340dfc60d /src/libcryptobox
parenta661d5e4c0487a6015db7d4fe3ddcf1cf3f99f5f (diff)
downloadrspamd-3fc31cc8724885d8d0f2d7ff8028f3b4f6b49c8e.tar.gz
rspamd-3fc31cc8724885d8d0f2d7ff8028f3b4f6b49c8e.zip
[Minor] Add method to decrypt data using keypair
Diffstat (limited to 'src/libcryptobox')
-rw-r--r--src/libcryptobox/keypair.c69
-rw-r--r--src/libcryptobox/keypair.h17
2 files changed, 86 insertions, 0 deletions
diff --git a/src/libcryptobox/keypair.c b/src/libcryptobox/keypair.c
index 98401e10f..1f8acc6d1 100644
--- a/src/libcryptobox/keypair.c
+++ b/src/libcryptobox/keypair.c
@@ -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;
+}
diff --git a/src/libcryptobox/keypair.h b/src/libcryptobox/keypair.h
index b24ecc9aa..fc17412e2 100644
--- a/src/libcryptobox/keypair.h
+++ b/src/libcryptobox/keypair.h
@@ -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_ */