]> source.dussan.org Git - rspamd.git/commitdiff
Implement keypairs creation
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 5 Feb 2016 17:27:24 +0000 (17:27 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 5 Feb 2016 17:27:24 +0000 (17:27 +0000)
src/libcryptobox/keypair.c
src/libcryptobox/keypair.h
src/libcryptobox/keypair_private.h
src/libcryptobox/keypairs_cache.c

index 9e652ea1c4da47b7d2c5e996dd80e651e62f087a..dd06c74dc82a02a23709ef5195dfe67ce93c3cc1 100644 (file)
 #include "keypair.h"
 #include "keypair_private.h"
 
+/**
+ * Returns specific private key for different keypair types
+ */
+static void *
+rspamd_cryptobox_keypair_sk (struct rspamd_cryptobox_keypair *kp,
+               guint *len)
+{
+       g_assert (kp != NULL);
+
+       if (kp->alg == RSPAMD_CRYPTOBOX_MODE_25519) {
+               if (kp->type == RSPAMD_KEYPAIR_KEX) {
+                       *len = 32;
+                       return RSPAMD_CRYPTOBOX_KEYPAIR_25519(kp)->sk;
+               }
+               else {
+                       *len = 64;
+                       return RSPAMD_CRYPTOBOX_KEYPAIR_SIG_25519(kp)->sk;
+               }
+       }
+       else {
+               if (kp->type == RSPAMD_KEYPAIR_KEX) {
+                       *len = 32;
+                       return RSPAMD_CRYPTOBOX_KEYPAIR_NIST(kp)->sk;
+               }
+               else {
+                       *len = 32;
+                       return RSPAMD_CRYPTOBOX_KEYPAIR_SIG_NIST(kp)->sk;
+               }
+       }
+
+       /* Not reached */
+       return NULL;
+}
+
+static void *
+rspamd_cryptobox_keypair_pk (struct rspamd_cryptobox_keypair *kp,
+               guint *len)
+{
+       g_assert (kp != NULL);
+
+       if (kp->alg == RSPAMD_CRYPTOBOX_MODE_25519) {
+               if (kp->type == RSPAMD_KEYPAIR_KEX) {
+                       *len = 32;
+                       return RSPAMD_CRYPTOBOX_KEYPAIR_25519(kp)->pk;
+               }
+               else {
+                       *len = 32;
+                       return RSPAMD_CRYPTOBOX_KEYPAIR_SIG_25519(kp)->pk;
+               }
+       }
+       else {
+               if (kp->type == RSPAMD_KEYPAIR_KEX) {
+                       *len = 65;
+                       return RSPAMD_CRYPTOBOX_KEYPAIR_NIST(kp)->pk;
+               }
+               else {
+                       *len = 65;
+                       return RSPAMD_CRYPTOBOX_KEYPAIR_SIG_NIST(kp)->pk;
+               }
+       }
+
+       /* Not reached */
+       return NULL;
+}
+
+static struct rspamd_cryptobox_keypair *
+rspamd_cryptobox_keypair_alloc (enum rspamd_cryptobox_keypair_type type,
+               enum rspamd_cryptobox_mode alg)
+{
+       struct rspamd_cryptobox_keypair *kp;
+       guint size = 0;
+
+       if (alg == RSPAMD_CRYPTOBOX_MODE_25519) {
+               if (type == RSPAMD_KEYPAIR_KEX) {
+                       size = sizeof (struct rspamd_cryptobox_keypair_25519);
+               }
+               else {
+                       size = sizeof (struct rspamd_cryptobox_keypair_sig_25519);
+               }
+       }
+       else {
+               if (type == RSPAMD_KEYPAIR_KEX) {
+                       size = sizeof (struct rspamd_cryptobox_keypair_nist);
+               }
+               else {
+                       size = sizeof (struct rspamd_cryptobox_keypair_sig_nist);
+               }
+       }
+
+       g_assert (size >= sizeof (*kp));
+
+       if (posix_memalign ((void **)&kp, 32, size) != 0) {
+               abort ();
+       }
+
+       return kp;
+}
+
 void
 rspamd_cryptobox_nm_dtor (struct rspamd_cryptobox_nm *nm)
 {
        rspamd_explicit_memzero (nm->nm, sizeof (nm->nm));
-       g_slice_free1 (sizeof (*nm), nm);
+       free (nm);
+}
+
+void
+rspamd_cryptobox_keypair_dtor (struct rspamd_cryptobox_keypair *kp)
+{
+       void *sk;
+       guint len = 0;
+
+       sk = rspamd_cryptobox_keypair_sk (kp, &len);
+       g_assert (sk != NULL && len > 0);
+       rspamd_explicit_memzero (sk, len);
+       /* Not g_free as kp is aligned using posix_memalign */
+       free (kp);
+}
+
+void
+rspamd_cryptobox_pubkey_dtor (struct rspamd_cryptobox_pubkey *p)
+{
+       if (p->nm) {
+               REF_RELEASE (p->nm);
+       }
+
+       /* Not g_free as p is aligned using posix_memalign */
+       free (p);
+}
+
+struct rspamd_cryptobox_keypair*
+rspamd_keypair_new (enum rspamd_cryptobox_keypair_type type,
+               enum rspamd_cryptobox_mode alg)
+{
+       struct rspamd_cryptobox_keypair *kp;
+       void *pk, *sk;
+       guint size;
+
+       kp = rspamd_cryptobox_keypair_alloc (type, alg);
+
+       sk = rspamd_cryptobox_keypair_sk (kp, &size);
+       pk = rspamd_cryptobox_keypair_pk (kp, &size);
+
+       if (type == RSPAMD_KEYPAIR_KEX) {
+               rspamd_cryptobox_keypair (pk, sk, alg);
+       }
+       else {
+               rspamd_cryptobox_keypair_sig (pk, sk, alg);
+       }
+
+       rspamd_cryptobox_hash (kp->id, pk, size, NULL, 0);
+       kp->alg = alg;
+       kp->type = type;
+
+       REF_INIT_RETAIN (kp, rspamd_cryptobox_keypair_dtor);
+
+       return pk;
+}
+
+
+struct rspamd_cryptobox_keypair*
+rspamd_keypair_ref (struct rspamd_cryptobox_keypair *kp)
+{
+       REF_RETAIN (kp);
+       return kp;
+}
+
+
+void
+rspamd_keypair_unref (struct rspamd_cryptobox_keypair *kp)
+{
+       REF_RELEASE (kp);
+}
+
+
+struct rspamd_cryptobox_pubkey*
+rspamd_pubkey_ref (struct rspamd_cryptobox_pubkey *kp)
+{
+       REF_RETAIN (kp);
+       return kp;
+}
+
+void
+rspamd_pubkey_unref (struct rspamd_cryptobox_pubkey *kp)
+{
+       REF_RELEASE (kp);
 }
index fb4aa9d9cc6f4b8943fe7a8cb802465499ee9e24..4208cf3720a85ad1ec28ae2c0b1c88dbc635619c 100644 (file)
@@ -61,4 +61,18 @@ struct rspamd_cryptobox_keypair* rspamd_keypair_ref (
  */
 void rspamd_keypair_unref (struct rspamd_cryptobox_keypair *kp);
 
+/**
+ * Increase refcount for the specific pubkey
+ * @param kp
+ * @return
+ */
+struct rspamd_cryptobox_pubkey* rspamd_pubkey_ref (
+               struct rspamd_cryptobox_pubkey *kp);
+
+/**
+ * Decrease refcount for the specific pubkey (or destroy when refcount == 0)
+ * @param kp
+ */
+void rspamd_pubkey_unref (struct rspamd_cryptobox_pubkey *kp);
+
 #endif /* SRC_LIBCRYPTOBOX_KEYPAIR_H_ */
index 6528087db7bff53f6bc427633030c6cc440c52b6..59071e3189fa8f73e8a8ac971e3bfdc343585427 100644 (file)
@@ -127,5 +127,6 @@ struct RSPAMD_ALIGNED(32) rspamd_cryptobox_pubkey_sig_25519 {
 
 void rspamd_cryptobox_nm_dtor (struct rspamd_cryptobox_nm *nm);
 void rspamd_cryptobox_keypair_dtor (struct rspamd_cryptobox_keypair *kp);
+void rspamd_cryptobox_pubkey_dtor (struct rspamd_cryptobox_pubkey *p);
 
 #endif /* KEYPAIR_PRIVATE_H_ */
index 6e1d056e7a184f152a36b0638de63508ac3c4b7f..a259c2ac12151ba14959b00d229edc0fe243e6a9 100644 (file)
@@ -95,7 +95,11 @@ rspamd_keypair_cache_process (struct rspamd_keypair_cache *c,
 
        if (new == NULL) {
                new = g_slice_alloc0 (sizeof (*new));
-               new->nm = g_slice_alloc (sizeof (*new->nm));
+
+               if (posix_memalign ((void **)&new->nm, 32, sizeof (*new->nm)) != 0) {
+                       abort ();
+               }
+
                REF_INIT_RETAIN (new->nm, rspamd_cryptobox_nm_dtor);
 
                memcpy (new->pair, rk->id, rspamd_cryptobox_HASHBYTES);