commit ea07b60: [Minor] Move DKIM keys load to DKIM common code

Vsevolod Stakhov vsevolod at highsecure.ru
Mon Feb 11 17:28:07 UTC 2019


Author: Vsevolod Stakhov
Date: 2019-02-11 14:21:29 +0000
URL: https://github.com/rspamd/rspamd/commit/ea07b601a62c68334e27a93c7b35e47e7fd16001

[Minor] Move DKIM keys load to DKIM common code

---
 src/libserver/dkim.c     | 96 +++++++++++++++++++++++++++++++++++++++-------
 src/plugins/dkim_check.c | 99 +++++++-----------------------------------------
 2 files changed, 96 insertions(+), 99 deletions(-)

diff --git a/src/libserver/dkim.c b/src/libserver/dkim.c
index bbaa6b90f..2a66146ed 100644
--- a/src/libserver/dkim.c
+++ b/src/libserver/dkim.c
@@ -2604,29 +2604,83 @@ rspamd_dkim_get_dns_key (rspamd_dkim_context_t *ctx)
 	return NULL;
 }
 
+#define PEM_SIG "-----BEGIN"
+
 rspamd_dkim_sign_key_t*
 rspamd_dkim_sign_key_load (const gchar *key, gsize len,
 		enum rspamd_dkim_key_format type,
 		GError **err)
 {
+	guchar *map = NULL, *tmp = NULL;
+	gsize maplen;
 	rspamd_dkim_sign_key_t *nkey;
 	time_t mtime = time (NULL);
 
-	switch (type) {
-		case RSPAMD_DKIM_KEY_PEM:
-			/* fallthrough */
-		case RSPAMD_DKIM_KEY_RAW:
-			break;
-		default:
-			g_set_error (err, dkim_error_quark (), DKIM_SIGERROR_KEYFAIL,
-					"invalid key type to load: %d", type);
-			return NULL;
+	if (type < 0 || type > RSPAMD_DKIM_KEY_UNKNOWN || len == 0 || key == NULL) {
+		g_set_error (err, dkim_error_quark (), DKIM_SIGERROR_KEYFAIL,
+				"invalid key type to load: %d", type);
+		return NULL;
 	}
 
 	nkey = g_malloc0 (sizeof (*nkey));
 	nkey->mtime = mtime;
 
-	msg_debug_dkim_taskless ("got public key with length %d and type %d", len, type);
+	msg_debug_dkim_taskless ("got public key with length %d and type %d",
+			len, type);
+
+	/* Load key file if needed */
+	if (type == RSPAMD_DKIM_KEY_FILE) {
+		struct stat st;
+
+		if (stat (key, &st) != 0) {
+			g_set_error (err, dkim_error_quark (), DKIM_SIGERROR_KEYFAIL,
+					"cannot stat key file: '%s' %s", key, strerror (errno));
+
+			return NULL;
+		}
+
+		nkey->mtime = st.st_mtime;
+		map = rspamd_file_xmap (key, PROT_READ, &maplen, TRUE);
+
+		if (map == NULL) {
+			g_set_error (err, dkim_error_quark (), DKIM_SIGERROR_KEYFAIL,
+					"cannot map key file: '%s' %s", key, strerror (errno));
+
+			return NULL;
+		}
+
+		key = map;
+		len = maplen;
+
+		if (maplen > sizeof (PEM_SIG) &&
+			strncmp (map, PEM_SIG, sizeof (PEM_SIG) - 1) == 0) {
+			type = RSPAMD_DKIM_KEY_PEM;
+		}
+		else if (rspamd_cryptobox_base64_is_valid (map, maplen)) {
+			type = RSPAMD_DKIM_KEY_BASE64;
+		}
+		else {
+			type = RSPAMD_DKIM_KEY_RAW;
+		}
+	}
+
+	if (type == RSPAMD_DKIM_KEY_UNKNOWN) {
+		if (len > sizeof (PEM_SIG) &&
+			memcmp (key, PEM_SIG, sizeof (PEM_SIG) - 1) == 0) {
+			type = RSPAMD_DKIM_KEY_PEM;
+		}
+		else {
+			type = RSPAMD_DKIM_KEY_RAW;
+		}
+	}
+
+	if (type == RSPAMD_DKIM_KEY_BASE64) {
+		type = RSPAMD_DKIM_KEY_RAW;
+		tmp = g_malloc (len);
+		rspamd_cryptobox_base64_decode (key, len, tmp, &len);
+		key = tmp;
+	}
+
 	if (type == RSPAMD_DKIM_KEY_RAW && len == 32) {
 		unsigned char pk[32];
 		nkey->type = RSPAMD_DKIM_KEY_EDDSA;
@@ -2645,8 +2699,9 @@ rspamd_dkim_sign_key_load (const gchar *key, gsize len,
 						ERR_error_string (ERR_get_error (), NULL));
 
 				rspamd_dkim_sign_key_free (nkey);
+				nkey = NULL;
 
-				return NULL;
+				goto end;
 			}
 		}
 		else {
@@ -2655,8 +2710,9 @@ rspamd_dkim_sign_key_load (const gchar *key, gsize len,
 						"cannot parse pem private key: %s",
 						ERR_error_string (ERR_get_error (), NULL));
 				rspamd_dkim_sign_key_free (nkey);
+				nkey = NULL;
 
-				return NULL;
+				goto end;
 			}
 
 		}
@@ -2667,17 +2723,31 @@ rspamd_dkim_sign_key_load (const gchar *key, gsize len,
 					DKIM_SIGERROR_KEYFAIL,
 					"cannot extract rsa key from evp key");
 			rspamd_dkim_sign_key_free (nkey);
+			nkey = NULL;
 
-			return NULL;
+			goto end;
 		}
 		nkey->type = RSPAMD_DKIM_KEY_RSA;
 	}
 
 	REF_INIT_RETAIN (nkey, rspamd_dkim_sign_key_free);
 
+end:
+
+	if (map != NULL) {
+		munmap (map, maplen);
+	}
+
+	if (tmp != NULL) {
+		rspamd_explicit_memzero (tmp, len);
+		g_free (tmp);
+	}
+
 	return nkey;
 }
 
+#undef PEM_SIG
+
 gboolean
 rspamd_dkim_sign_key_maybe_invalidate (rspamd_dkim_sign_key_t *key, time_t mtime)
 {
diff --git a/src/plugins/dkim_check.c b/src/plugins/dkim_check.c
index 278a8e1e1..bb66e5ccc 100644
--- a/src/plugins/dkim_check.c
+++ b/src/plugins/dkim_check.c
@@ -641,58 +641,23 @@ dkim_module_config (struct rspamd_config *cfg)
 	return res;
 }
 
-/**
- * helper to see if valid base64, minus newline
- */
-static gboolean
-is_valid_base64(const uint8_t *in, size_t len) {
-	int i;
-	if (in[len - 1] == '\n')
-		len--;
-	if (in[len - 1] == '\r')
-		len--;
-	if (len % 4 != 0)
-		return FALSE;
-
-	if (in[len - 1] == '=')
-		len--;
-	if (in[len - 1] == '=')
-		len--;
-
-	for (i = 0; i < len; i++) {
-		if ('a' <= in[i] && in[i] <= 'z')
-			continue;
-		if ('A' <= in[i] && in[i] <= 'Z')
-			continue;
-		if ('0' <= in[i] && in[i] <= '9')
-			continue;
-		if (in[i] == '/')
-			continue;
-		if (in[i] == '+')
-			continue;
-		return FALSE;
-	}
-	return TRUE;
-}
 
-
-#define PEM_SIG "-----BEGIN"
 /**
  * Grab a private key from the cache
  * or from the key content provided
  */
 rspamd_dkim_sign_key_t *
-dkim_module_load_key_format (struct rspamd_task *task, struct dkim_ctx *dkim_module_ctx,
-		const gchar *key, gsize keylen, enum rspamd_dkim_key_format key_format)
+dkim_module_load_key_format (struct rspamd_task *task,
+							 struct dkim_ctx *dkim_module_ctx,
+							 const gchar *key, gsize keylen,
+							 enum rspamd_dkim_key_format key_format)
 
 {
 	guchar h[rspamd_cryptobox_HASHBYTES],
 			hex_hash[rspamd_cryptobox_HASHBYTES * 2 + 1];
 	rspamd_dkim_sign_key_t *ret;
 	GError *err = NULL;
-	gpointer map = NULL, tmp = NULL;
 	struct stat st;
-	ssize_t maplen;
 
 	memset (hex_hash, 0, sizeof (hex_hash));
 	rspamd_cryptobox_hash (h, key, keylen, NULL, 0);
@@ -706,16 +671,19 @@ dkim_module_load_key_format (struct rspamd_task *task, struct dkim_ctx *dkim_mod
 	 */
 	if (key_format == RSPAMD_DKIM_KEY_UNKNOWN &&
 		(key[0] == '.' || key[0] == '/')) {
-		if (!is_valid_base64 (key, keylen))
+		if (!rspamd_cryptobox_base64_is_valid (key, keylen)) {
 			key_format = RSPAMD_DKIM_KEY_FILE;
+		}
 	}
 
 	if (ret != NULL && key_format == RSPAMD_DKIM_KEY_FILE) {
 		msg_debug_task("checking for stale file key");
+
 		if (stat (key, &st) != 0) {
 			msg_err_task("cannot stat key file: %s", strerror (errno));
 			return NULL;
 		}
+
 		if (rspamd_dkim_sign_key_maybe_invalidate (ret, st.st_mtime)) {
 			msg_debug_task("removing stale file key");
 			/*
@@ -729,43 +697,8 @@ dkim_module_load_key_format (struct rspamd_task *task, struct dkim_ctx *dkim_mod
 	}
 
 	/* found key; done */
-	if (ret != NULL)
+	if (ret != NULL) {
 		return ret;
-
-	if (key_format == RSPAMD_DKIM_KEY_FILE) {
-		if (stat (key, &st) != 0) {
-			msg_err_task("cannot stat key file: %s", strerror (errno));
-			return NULL;
-		}
-		map = rspamd_file_xmap (key, PROT_READ, &maplen, TRUE);
-		if (map == NULL) {
-			msg_err_task("cannot open key file \'%s\'", key);
-			return NULL;
-		}
-		key = map;
-		keylen = maplen;
-		if (maplen > sizeof (PEM_SIG) &&
-				strncmp (map, PEM_SIG, sizeof (PEM_SIG) - 1) == 0) {
-			key_format = RSPAMD_DKIM_KEY_PEM;
-		} else if (is_valid_base64 ((uint8_t *)map, maplen)) {
-			key_format = RSPAMD_DKIM_KEY_BASE64;
-		} else {
-			key_format = RSPAMD_DKIM_KEY_RAW;
-		}
-	}
-	if (key_format == RSPAMD_DKIM_KEY_UNKNOWN) {
-		if (keylen > sizeof (PEM_SIG) &&
-				strncmp (key, PEM_SIG, sizeof (PEM_SIG) - 1) == 0) {
-			key_format = RSPAMD_DKIM_KEY_PEM;
-		} else {
-			key_format = RSPAMD_DKIM_KEY_RAW;
-		}
-	}
-	if (key_format == RSPAMD_DKIM_KEY_BASE64) {
-		key_format = RSPAMD_DKIM_KEY_RAW;
-		tmp = g_malloc (keylen);
-		rspamd_cryptobox_base64_decode (key, keylen, tmp, &keylen);
-		key = tmp;
 	}
 
 	ret = rspamd_dkim_sign_key_load (key, keylen, key_format, &err);
@@ -779,16 +712,8 @@ dkim_module_load_key_format (struct rspamd_task *task, struct dkim_ctx *dkim_mod
 				g_strdup (hex_hash), ret, time (NULL), 0);
 	}
 
-	if (map != NULL)
-		munmap (map, maplen);
-	if (tmp != NULL) {
-		rspamd_explicit_memzero (tmp, keylen);
-		g_free (tmp);
-	}
-
 	return ret;
 }
-#undef PEM_SIG
 
 static gint
 lua_dkim_sign_handler (lua_State *L)
@@ -844,10 +769,12 @@ lua_dkim_sign_handler (lua_State *L)
 	if (key) {
 		dkim_key = dkim_module_load_key_format (task, dkim_module_ctx, key,
 				keylen, RSPAMD_DKIM_KEY_UNKNOWN);
-	} else if(rawkey) {
+	}
+	else if(rawkey) {
 		dkim_key = dkim_module_load_key_format (task, dkim_module_ctx, rawkey,
 				rawlen, RSPAMD_DKIM_KEY_UNKNOWN);
-	} else {
+	}
+	else {
 		msg_err_task ("neither key nor rawkey are specified");
 		lua_pushboolean (L, FALSE);
 


More information about the Commits mailing list