Skip to content
Permalink
Browse files
Merge pull request #2739 from McKayJT/dkim-sign-ed25519
[Feature] Add ed25519 and multiple signature support
  • Loading branch information
vstakhov committed Feb 4, 2019
2 parents f897271 + 161184e commit 9e11c03379029b306a886ce2ba8beadb37790ba2
@@ -58,10 +58,17 @@ dkim_signing {
# Domain specific settings
#domain {
# example.com {
# # Private key path
# path = "/var/lib/rspamd/dkim/example.key";
# # Selector
# selector = "ds";
# selectors [
# { # Private key path
# path = "/var/lib/rspamd/dkim/example.key";
# # Selector
# selector = "ds";
# },
# { # multiple dkim signature
# path = "/var/lib/rspamd/dkim/eddsa.key";
# selector = "eddsa";
# }
# ]
# }
#}

@@ -22,21 +22,57 @@ local lua_util = require "lua_util"
local rspamd_util = require "rspamd_util"
local logger = require "rspamd_logger"

local function check_violation(N, task, domain, selector)
local function check_violation(N, task, domain)
-- Check for DKIM_REJECT
local sym_check = 'R_DKIM_REJECT'

if N == 'arc' then sym_check = 'ARC_REJECT' end
if task:has_symbol(sym_check) then
local sym = task:get_symbol(sym_check)
logger.infox(task, 'skip signing for %s:%s: violation %s found: %s',
domain, selector, sym_check, sym.options)
logger.infox(task, 'skip signing for %s: violation %s found: %s',
domain, sym_check, sym.options)
return false
end

return true
end

local function insert_or_update_prop(N, task, p, prop, origin, data)
if #p == 0 then
local k = {}
k[prop] = data
table.insert(p, k)
lua_util.debugm(N, task, 'add %s "%s" using %s', prop, data, origin)
else
for _, k in ipairs(p) do
if not k[prop] then
k[prop] = data
lua_util.debugm(N, task, 'set %s to "%s" using %s', prop, data, origin)
end
end
end
end

local function get_mempool_selectors(N, task)
local p = {}
local key_var = "dkim_key"
local selector_var = "dkim_selector"
if N == "arc" then
key_var = "arc_key"
selector_var = "arc_selector"
end

p.key = task:get_mempool():get_variable(key_var)
p.selector = task:get_mempool():get_variable(selector_var)

if (not p.key or not p.selector) then
return false, {}
end

lua_util.debugm(N, task, 'override selector and key to %s:%s', p.key, p.selector)
return true, p
end

local function parse_dkim_http_headers(N, task, settings)
-- Configure headers
local headers = {
@@ -66,11 +102,14 @@ local function parse_dkim_http_headers(N, task, settings)
end
end

return true,{
rawkey = tostring(key),
local p = {}
local k = {
domain = tostring(domain),
selector = tostring(selector)
rawkey = tostring(key),
selector = tostring(selector),
}
table.insert(p, k)
return true, p
end

lua_util.debugm(N, task, 'no sign header %s', headers.sign_header)
@@ -214,76 +253,71 @@ local function prepare_dkim_signing(N, task, settings)
local p = {}

if settings.domain[dkim_domain] then
p.selector = settings.domain[dkim_domain].selector
p.key = settings.domain[dkim_domain].path
end

if not p.key and p.selector then
local key_var = "dkim_key"
local selector_var = "dkim_selector"
if N == "arc" then
key_var = "arc_key"
selector_var = "arc_selector"
-- support old style selector/paths
if settings.domain[dkim_domain].selector or
settings.domain[dkim_domain].path then
local k = {}
k.selector = settings.domain[dkim_domain].selector
k.key = settings.domain[dkim_domain].path
table.insert(p, k)
end

p.key = task:get_mempool():get_variable(key_var)
local selector_override = task:get_mempool():get_variable(selector_var)

if selector_override then
p.selector = selector_override
for _, s in ipairs((settings.domain[dkim_domain].selectors or {})) do
lua_util.debugm(N, task, 'adding selector: %1', s)
local k = {}
k.selector = s.selector
k.key = s.path
table.insert(p, k)
end
end

if (not p.key or not p.selector) and (not (settings.try_fallback or
settings.use_redis or settings.selector_map
or settings.path_map)) then
lua_util.debugm(N, task, 'dkim unconfigured and fallback disabled')
return false,{}
if #p == 0 then
local ret, k = get_mempool_selectors(N, task)
if ret then
table.insert(p, k)
lua_util.debugm(N, task, 'using mempool selector %s with key %s',
k.selector, k.key)
end

lua_util.debugm(N, task, 'override selector and key to %s:%s', p.key, p.selector)
end

if not p.selector and settings.selector_map then
if settings.selector_map then
local data = settings.selector_map:get_key(dkim_domain)
if data then
p.selector = data
lua_util.debugm(N, task, 'override selector to "%s" using selector_map', p.selector)
elseif not settings.try_fallback then
lua_util.debugm(N, task, 'no selector for %s', dkim_domain)
return false,{}
insert_or_update_prop(N, task, p, 'selector', 'selector_map', data)
else
lua_util.debugm(N, task, 'no selector in map for %s', dkim_domain)
end
end

if not p.key and settings.path_map then
if settings.path_map then
local data = settings.path_map:get_key(dkim_domain)
if data then
p.key = data
lua_util.debugm(N, task, 'override key to "%s" using path_map', p.key)
elseif not settings.try_fallback then
lua_util.debugm(N, task, 'no key for %s', dkim_domain)
return false,{}
insert_or_update_prop(N, task, p, 'key', 'path_map', data)
else
lua_util.debugm(N, task, 'no key in map for %s', dkim_domain)
end
end

if not p.key then
if not settings.use_redis then
p.key = settings.path
lua_util.debugm(N, task, 'use default key "%s" from path', p.key)
end
if #p == 0 and not settings.try_fallback then
lua_util.debugm(N, task, 'dkim unconfigured and fallback disabled')
return false,{}
end

if not p.selector then
p.selector = settings.selector
lua_util.debugm(N, task, 'use default selector "%s"', p.selector)
if not settings.use_redis then
insert_or_update_prop(N, task, p, 'key',
'default path', settings.path)
end

insert_or_update_prop(N, task, p, 'selector',
'default selector', settings.selector)

if settings.check_violation then
if not check_violation(N, task, p.domain, p.selector) then
if not check_violation(N, task, p.domain) then
return false,{}
end
end

p.domain = dkim_domain
insert_or_update_prop(N, task, p, 'domain', 'dkim_domain',
dkim_domain)

return true,p
end
@@ -887,7 +887,15 @@ rspamc_symbols_output (FILE *out, ucl_object_t *obj)
}
}

PRINT_PROTOCOL_STRING ("dkim-signature", "DKIM-Signature");
elt = ucl_object_lookup (obj, "dkim-signature");
if (elt && elt->type == UCL_STRING) {
rspamd_fprintf (out, "DKIM-Signature: %s\n", ucl_object_tostring (elt));
} else if (elt && elt->type == UCL_ARRAY) {
mit = NULL;
while ((cmesg = ucl_object_iterate (elt, &mit, true)) != NULL) {
rspamd_fprintf (out, "DKIM-Signature: %s\n", ucl_object_tostring (cmesg));
}
}

elt = ucl_object_lookup (obj, "profile");

@@ -1372,11 +1380,16 @@ rspamc_mime_output (FILE *out, ucl_object_t *result, GString *input,
g_string_free (folded_symbuf, TRUE);
g_string_free (symbuf, TRUE);

if (ucl_object_lookup (result, "dkim-signature")) {
res = ucl_object_lookup (result, "dkim-signature");
if (res && res->type == UCL_STRING) {
rspamd_printf_gstring (added_headers, "DKIM-Signature: %s%s",
ucl_object_tostring (
ucl_object_lookup (result, "dkim-signature")),
line_end);
ucl_object_tostring (res), line_end);
} else if (res && res->type == UCL_ARRAY) {
it = NULL;
while ((cur = ucl_object_iterate (res, &it, true)) != NULL) {
rspamd_printf_gstring (added_headers, "DKIM-Signature: %s%s",
ucl_object_tostring (cur), line_end);
}
}

if (json || raw || compact) {
@@ -26,6 +26,7 @@ typedef struct ed25519_impl_s {
const char *desc;

void (*keypair) (unsigned char *pk, unsigned char *sk);
void (*seed_keypair) (unsigned char *pk, unsigned char *sk, unsigned char *seed);
void (*sign) (unsigned char *sig, size_t *siglen_p,
const unsigned char *m, size_t mlen,
const unsigned char *sk);
@@ -37,6 +38,7 @@ typedef struct ed25519_impl_s {

#define ED25519_DECLARE(ext) \
void ed_keypair_##ext(unsigned char *pk, unsigned char *sk); \
void ed_seed_keypair_##ext(unsigned char *pk, unsigned char *sk, unsigned char *seed); \
void ed_sign_##ext(unsigned char *sig, size_t *siglen_p, \
const unsigned char *m, size_t mlen, \
const unsigned char *sk); \
@@ -46,7 +48,7 @@ typedef struct ed25519_impl_s {
const unsigned char *pk)

#define ED25519_IMPL(cpuflags, desc, ext) \
{(cpuflags), desc, ed_keypair_##ext, ed_sign_##ext, ed_verify_##ext}
{(cpuflags), desc, ed_keypair_##ext, ed_seed_keypair_##ext, ed_sign_##ext, ed_verify_##ext}

ED25519_DECLARE(ref);
#define ED25519_REF ED25519_IMPL(0, "ref", ref)
@@ -78,6 +80,12 @@ ed25519_load (void)
return ed25519_opt->desc;
}

void
ed25519_seed_keypair (unsigned char *pk, unsigned char *sk, unsigned char *seed)
{
ed25519_opt->seed_keypair (pk, sk, seed);
}

void
ed25519_keypair (unsigned char *pk, unsigned char *sk)
{
@@ -22,6 +22,7 @@

const char* ed25519_load (void);
void ed25519_keypair (unsigned char *pk, unsigned char *sk);
void ed25519_seed_keypair (unsigned char *pk, unsigned char *sk, unsigned char *seed);
void ed25519_sign (unsigned char *sig, size_t *siglen_p,
const unsigned char *m, size_t mlen,
const unsigned char *sk);
@@ -23,7 +23,7 @@
#include "ottery.h"
#include <openssl/evp.h> /* SHA512 */

static int
int
ed_seed_keypair_ref (unsigned char *pk, unsigned char *sk,
const unsigned char *seed)
{

0 comments on commit 9e11c03

Please sign in to comment.