aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2016-04-21 12:10:59 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2016-04-21 12:10:59 +0100
commitb212e765ad521f685bb6817e9b65b19a51d9a933 (patch)
tree9ec1059eadd8e5bf925e32e801ffbddee7f239d0 /src
parentb4389fd12e501a30af0f27693a6ab60bb3c8ad3e (diff)
downloadrspamd-b212e765ad521f685bb6817e9b65b19a51d9a933.tar.gz
rspamd-b212e765ad521f685bb6817e9b65b19a51d9a933.zip
[Feature] Allow catena encrypted passwords in controller
Diffstat (limited to 'src')
-rw-r--r--src/controller.c21
-rw-r--r--src/libcryptobox/catena/catena.c9
-rw-r--r--src/libcryptobox/catena/catena.h4
-rw-r--r--src/libcryptobox/cryptobox.c27
-rw-r--r--src/libcryptobox/cryptobox.h19
-rw-r--r--src/libutil/util.c10
-rw-r--r--src/rspamadm/pw.c4
-rw-r--r--src/rspamd.h11
8 files changed, 81 insertions, 24 deletions
diff --git a/src/controller.c b/src/controller.c
index f3e21730e..542f197c3 100644
--- a/src/controller.c
+++ b/src/controller.c
@@ -174,8 +174,9 @@ rspamd_is_encrypted_password (const gchar *password,
{
const gchar *start, *end;
gint64 id;
- gsize size;
+ gsize size, i;
gboolean ret = FALSE;
+ const struct rspamd_controller_pbkdf *p;
if (password[0] == '$') {
/* Parse id */
@@ -192,11 +193,18 @@ rspamd_is_encrypted_password (const gchar *password,
gchar *endptr;
id = strtoul (start, &endptr, 10);
- if ((endptr == NULL || *endptr == *end) && id == RSPAMD_PBKDF_ID_V1) {
- ret = TRUE;
+ if ((endptr == NULL || *endptr == *end)) {
+ for (i = 0; i < RSPAMD_PBKDF_ID_MAX - 1; i ++) {
+ p = &pbkdf_list[i];
+
+ if (p->id == id) {
+ ret = TRUE;
+ if (pbkdf != NULL) {
+ *pbkdf = &pbkdf_list[0];
+ }
- if (pbkdf != NULL) {
- *pbkdf = &pbkdf_list[0];
+ break;
+ }
}
}
}
@@ -298,7 +306,8 @@ rspamd_check_encrypted_password (struct rspamd_controller_worker_ctx *ctx,
local_key = g_alloca (pbkdf->key_len);
rspamd_cryptobox_pbkdf (password->begin, password->len,
salt_decoded, salt_len,
- local_key, pbkdf->key_len, pbkdf->rounds);
+ local_key, pbkdf->key_len, pbkdf->complexity,
+ pbkdf->type);
if (!rspamd_constant_memcmp (key_decoded, local_key, pbkdf->key_len)) {
msg_info_ctx ("incorrect or absent password has been specified");
diff --git a/src/libcryptobox/catena/catena.c b/src/libcryptobox/catena/catena.c
index c7f21637f..29950dd6e 100644
--- a/src/libcryptobox/catena/catena.c
+++ b/src/libcryptobox/catena/catena.c
@@ -346,7 +346,8 @@ Flap (const uint8_t x[H_LEN], const uint8_t lambda, const uint8_t garlic,
g_free (tmp);
}
-static int __Catena(const uint8_t *pwd, const uint32_t pwdlen,
+static int
+__Catena (const uint8_t *pwd, const uint32_t pwdlen,
const uint8_t *salt, const uint8_t saltlen, const uint8_t *data,
const uint32_t datalen, const uint8_t lambda, const uint8_t min_garlic,
const uint8_t garlic, const uint8_t hashlen, const uint8_t client,
@@ -402,7 +403,7 @@ static int __Catena(const uint8_t *pwd, const uint32_t pwdlen,
/***************************************************/
int
-catena (uint8_t *pwd, const uint32_t pwdlen, const uint8_t *salt,
+catena (const uint8_t *pwd, const uint32_t pwdlen, const uint8_t *salt,
const uint8_t saltlen, const uint8_t *data, const uint32_t datalen,
const uint8_t lambda, const uint8_t min_garlic, const uint8_t garlic,
const uint8_t hashlen, uint8_t *hash)
@@ -413,12 +414,12 @@ catena (uint8_t *pwd, const uint32_t pwdlen, const uint8_t *salt,
}
int
-simple_catena (uint8_t *pwd, const uint32_t pwdlen,
+simple_catena (const uint8_t *pwd, const uint32_t pwdlen,
const uint8_t *salt, const uint8_t saltlen,
const uint8_t *data, const uint32_t datalen,
uint8_t hash[H_LEN])
{
- return __Catena(pwd, pwdlen, salt, saltlen, data, datalen,
+ return __Catena (pwd, pwdlen, salt, saltlen, data, datalen,
LAMBDA, MIN_GARLIC, GARLIC, H_LEN,
REGULAR, PASSWORD_HASHING_MODE, hash);
}
diff --git a/src/libcryptobox/catena/catena.h b/src/libcryptobox/catena/catena.h
index 6624a54ec..56da560ea 100644
--- a/src/libcryptobox/catena/catena.h
+++ b/src/libcryptobox/catena/catena.h
@@ -25,7 +25,7 @@
#define CATENA_HLEN 64
int
-catena (uint8_t *pwd, const uint32_t pwdlen,
+catena (const uint8_t *pwd, const uint32_t pwdlen,
const uint8_t *salt, const uint8_t saltlen,
const uint8_t *data, const uint32_t datalen,
const uint8_t lambda, const uint8_t min_garlic,
@@ -42,7 +42,7 @@ catena (uint8_t *pwd, const uint32_t pwdlen,
* @param hash output hash
* @return 0 if hash is generated, -1 in case of error
*/
-int simple_catena(uint8_t *pwd, const uint32_t pwdlen,
+int simple_catena (const uint8_t *pwd, const uint32_t pwdlen,
const uint8_t *salt, const uint8_t saltlen,
const uint8_t *data, const uint32_t datalen,
uint8_t hash[CATENA_HLEN]);
diff --git a/src/libcryptobox/cryptobox.c b/src/libcryptobox/cryptobox.c
index 22860695a..1680f1848 100644
--- a/src/libcryptobox/cryptobox.c
+++ b/src/libcryptobox/cryptobox.c
@@ -1200,8 +1200,8 @@ rspamd_cryptobox_siphash (unsigned char *out, const unsigned char *in,
* Password-Based Key Derivation Function 2 (PKCS #5 v2.0).
* Code based on IEEE Std 802.11-2007, Annex H.4.2.
*/
-gboolean
-rspamd_cryptobox_pbkdf (const char *pass, gsize pass_len,
+static gboolean
+rspamd_cryptobox_pbkdf2 (const char *pass, gsize pass_len,
const guint8 *salt, gsize salt_len, guint8 *key, gsize key_len,
unsigned int rounds)
{
@@ -1253,6 +1253,29 @@ rspamd_cryptobox_pbkdf (const char *pass, gsize pass_len,
return TRUE;
}
+gboolean
+rspamd_cryptobox_pbkdf (const char *pass, gsize pass_len,
+ const guint8 *salt, gsize salt_len, guint8 *key, gsize key_len,
+ unsigned int complexity, enum rspamd_cryptobox_pbkdf_type type)
+{
+ gboolean ret = FALSE;
+
+ switch (type) {
+ case RSPAMD_CRYPTOBOX_CATENA:
+ if (catena (pass, pass_len, salt, salt_len, "rspamd", 6,
+ 4, complexity, complexity, key_len, key) == 0) {
+ ret = TRUE;
+ }
+ break;
+ case RSPAMD_CRYPTOBOX_PBKDF2:
+ default:
+ ret = rspamd_cryptobox_pbkdf2 (pass, pass_len, salt, salt_len, key,
+ key_len, complexity);
+ break;
+ }
+
+ return ret;
+}
guint
rspamd_cryptobox_pk_bytes (enum rspamd_cryptobox_mode mode)
diff --git a/src/libcryptobox/cryptobox.h b/src/libcryptobox/cryptobox.h
index fffbc098b..9631bd8d0 100644
--- a/src/libcryptobox/cryptobox.h
+++ b/src/libcryptobox/cryptobox.h
@@ -229,20 +229,29 @@ void rspamd_cryptobox_siphash (unsigned char *out, const unsigned char *in,
unsigned long long inlen,
const rspamd_sipkey_t k);
+enum rspamd_cryptobox_pbkdf_type {
+ RSPAMD_CRYPTOBOX_PBKDF2 = 0,
+ RSPAMD_CRYPTOBOX_CATENA
+};
+
+
/**
- * Derive key from password using PKCS#5 and HMAC-blake2
+ * Derive key from password using the specified algorithm
* @param pass input password
* @param pass_len length of the password
* @param salt input salt
* @param salt_len length of salt
* @param key output key
* @param key_len size of the key
- * @param rounds number of rounds (should be reasonably high)
+ * @param complexity empiric number of complexity (rounds for pbkdf2 and garlic for catena)
* @return TRUE in case of success and FALSE if failed
*/
-gboolean rspamd_cryptobox_pbkdf(const char *pass, gsize pass_len,
- const guint8 *salt, gsize salt_len, guint8 *key, gsize key_len,
- unsigned int rounds);
+gboolean rspamd_cryptobox_pbkdf (const char *pass, gsize pass_len,
+ const guint8 *salt, gsize salt_len,
+ guint8 *key, gsize key_len,
+ unsigned int complexity,
+ enum rspamd_cryptobox_pbkdf_type type);
+
/**
* Real size of rspamd cryptobox public key
diff --git a/src/libutil/util.c b/src/libutil/util.c
index 7a649508e..4120849a3 100644
--- a/src/libutil/util.c
+++ b/src/libutil/util.c
@@ -77,8 +77,16 @@
const struct rspamd_controller_pbkdf pbkdf_list[] = {
{
+ .type = RSPAMD_CRYPTOBOX_PBKDF2,
.id = RSPAMD_PBKDF_ID_V1,
- .rounds = 16000,
+ .complexity = 16000,
+ .salt_len = 20,
+ .key_len = rspamd_cryptobox_HASHBYTES / 2
+ },
+ {
+ .type = RSPAMD_CRYPTOBOX_CATENA,
+ .id = RSPAMD_PBKDF_ID_V2,
+ .complexity = 10,
.salt_len = 20,
.key_len = rspamd_cryptobox_HASHBYTES / 2
}
diff --git a/src/rspamadm/pw.c b/src/rspamadm/pw.c
index b11b671f7..ff0185024 100644
--- a/src/rspamadm/pw.c
+++ b/src/rspamadm/pw.c
@@ -98,7 +98,7 @@ rspamadm_pw_encrypt (void)
ottery_rand_bytes (salt, pbkdf->salt_len);
/* Derive key */
rspamd_cryptobox_pbkdf (password, strlen (password),
- salt, pbkdf->salt_len, key, pbkdf->key_len, pbkdf->rounds);
+ salt, pbkdf->salt_len, key, pbkdf->key_len, pbkdf->complexity);
encoded_salt = rspamd_encode_base32 (salt, pbkdf->salt_len);
encoded_key = rspamd_encode_base32 (key, pbkdf->key_len);
@@ -213,7 +213,7 @@ rspamadm_pw_check (void)
local_key = g_alloca (pbkdf->key_len);
rspamd_cryptobox_pbkdf (test_password, plen,
salt_decoded, salt_len,
- local_key, pbkdf->key_len, pbkdf->rounds);
+ local_key, pbkdf->key_len, pbkdf->complexity);
rspamd_explicit_memzero (test_password, plen);
if (!rspamd_constant_memcmp (key_decoded, local_key, pbkdf->key_len)) {
diff --git a/src/rspamd.h b/src/rspamd.h
index a677f02c7..52838a950 100644
--- a/src/rspamd.h
+++ b/src/rspamd.h
@@ -85,8 +85,9 @@ struct rspamd_worker_signal_handler {
};
struct rspamd_controller_pbkdf {
+ enum rspamd_cryptobox_pbkdf_type type;
gint id;
- guint rounds;
+ guint complexity;
gsize salt_len;
gsize key_len;
};
@@ -291,9 +292,15 @@ void register_custom_controller_command (const gchar *name,
gboolean privilleged,
gboolean require_message);
-#define RSPAMD_PBKDF_ID_V1 1
+enum rspamd_pbkdf_version_id {
+ RSPAMD_PBKDF_ID_V1 = 1,
+ RSPAMD_PBKDF_ID_V2= 2,
+ RSPAMD_PBKDF_ID_MAX
+};
+
extern const struct rspamd_controller_pbkdf pbkdf_list[];
+
#endif
/*