From 094529b9cd48a56f1cbd154bb626795ac865388e Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Fri, 5 Feb 2016 17:27:24 +0000 Subject: [PATCH] Implement keypairs creation --- src/libcryptobox/keypair.c | 182 ++++++++++++++++++++++++++++- src/libcryptobox/keypair.h | 14 +++ src/libcryptobox/keypair_private.h | 1 + src/libcryptobox/keypairs_cache.c | 6 +- 4 files changed, 201 insertions(+), 2 deletions(-) diff --git a/src/libcryptobox/keypair.c b/src/libcryptobox/keypair.c index 9e652ea1c..dd06c74dc 100644 --- a/src/libcryptobox/keypair.c +++ b/src/libcryptobox/keypair.c @@ -18,9 +18,189 @@ #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); } diff --git a/src/libcryptobox/keypair.h b/src/libcryptobox/keypair.h index fb4aa9d9c..4208cf372 100644 --- a/src/libcryptobox/keypair.h +++ b/src/libcryptobox/keypair.h @@ -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_ */ diff --git a/src/libcryptobox/keypair_private.h b/src/libcryptobox/keypair_private.h index 6528087db..59071e318 100644 --- a/src/libcryptobox/keypair_private.h +++ b/src/libcryptobox/keypair_private.h @@ -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_ */ diff --git a/src/libcryptobox/keypairs_cache.c b/src/libcryptobox/keypairs_cache.c index 6e1d056e7..a259c2ac1 100644 --- a/src/libcryptobox/keypairs_cache.c +++ b/src/libcryptobox/keypairs_cache.c @@ -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); -- 2.39.5