#define DKIM_PARAM_TIMESTAMP 9 /* t */
#define DKIM_PARAM_EXPIRATION 10 /* x */
#define DKIM_PARAM_COPIEDHDRS 11 /* z */
-#define DKIM_PARAM_BODYHASH 12 /* bh */
+#define DKIM_PARAM_BODYHASH 12 /* bh */
#define DKIM_PARAM_BODYLENGTH 13 /* l */
+#define DKIM_PARAM_IDX 14 /* i */
/* Signature methods */
#define DKIM_SIGN_UNKNOWN (-2) /* unknown method */
G_STRFUNC, \
__VA_ARGS__)
-
-
struct rspamd_dkim_common_ctx {
rspamd_mempool_t *pool;
gsize len;
GPtrArray *hlist;
EVP_MD_CTX *headers_hash;
EVP_MD_CTX *body_hash;
+ enum rspamd_dkim_type type;
+ guint idx;
};
struct rspamd_dkim_context_s {
const gchar *param,
gsize len,
GError **err);
+static gboolean rspamd_dkim_parse_idx (rspamd_dkim_context_t * ctx,
+ const gchar *param,
+ gsize len,
+ GError **err);
static const dkim_parse_param_f parser_funcs[] = {
[DKIM_PARAM_EXPIRATION] = rspamd_dkim_parse_expiration,
[DKIM_PARAM_COPIEDHDRS] = rspamd_dkim_parse_ignore,
[DKIM_PARAM_BODYHASH] = rspamd_dkim_parse_bodyhash,
- [DKIM_PARAM_BODYLENGTH] = rspamd_dkim_parse_bodylength
+ [DKIM_PARAM_BODYLENGTH] = rspamd_dkim_parse_bodylength,
+ [DKIM_PARAM_IDX] = rspamd_dkim_parse_idx,
};
#define DKIM_ERROR dkim_error_quark ()
return TRUE;
}
+static gboolean
+rspamd_dkim_parse_idx (rspamd_dkim_context_t * ctx,
+ const gchar *param,
+ gsize len,
+ GError **err)
+{
+ gulong val;
+
+ if (!rspamd_strtoul (param, len, &val)) {
+ g_set_error (err,
+ DKIM_ERROR,
+ DKIM_SIGERROR_INVALID_L,
+ "invalid ARC idx");
+ return FALSE;
+ }
+ ctx->common.idx = val;
+
+ return TRUE;
+}
+
/**
* Create new dkim context from signature
* @param sig message's signature
*/
rspamd_dkim_context_t *
rspamd_create_dkim_context (const gchar *sig,
- rspamd_mempool_t *pool,
- guint time_jitter,
- GError **err)
+ rspamd_mempool_t *pool,
+ guint time_jitter,
+ enum rspamd_dkim_type type,
+ GError **err)
{
const gchar *p, *c, *tag = NULL, *end;
gsize taglen;
ctx->common.body_canon_type = DKIM_CANON_DEFAULT;
ctx->sig_alg = DKIM_SIGN_UNKNOWN;
ctx->common.pool = pool;
+ ctx->common.type = type;
/* A simple state machine of parsing tags */
state = DKIM_STATE_SKIP_SPACES;
next_state = DKIM_STATE_TAG;
param = DKIM_PARAM_HDRLIST;
break;
case 'i':
- param = DKIM_PARAM_IDENTITY;
+ if (type == RSPAMD_DKIM_NORMAL) {
+ param = DKIM_PARAM_IDENTITY;
+ }
+ else {
+ param = DKIM_PARAM_IDX;
+ }
break;
case 'l':
param = DKIM_PARAM_BODYLENGTH;
gint headers_canon,
gint body_canon,
const gchar *headers,
+ enum rspamd_dkim_type type,
GError **err)
{
rspamd_dkim_sign_context_t *nctx;
nctx->common.pool = task->task_pool;
nctx->common.header_canon_type = headers_canon;
nctx->common.body_canon_type = body_canon;
+ nctx->common.type = type;
if (!rspamd_dkim_parse_hdrlist_common (&nctx->common, headers, strlen (headers),
err)) {
rspamd_dkim_sign (struct rspamd_task *task,
const gchar *selector, const gchar *domain,
time_t expire, gsize len,
+ guint idx,
rspamd_dkim_sign_context_t *ctx)
{
GString *hdr;
RSPAMD_DKIM_SIGN_KEY_DER
};
+enum rspamd_dkim_type {
+ RSPAMD_DKIM_NORMAL,
+ RSPAMD_DKIM_ARC_SIG,
+ RSPAMD_DKIM_ARC_SEAL
+};
+
/* Err MUST be freed if it is not NULL, key is allocated by slice allocator */
typedef void (*dkim_key_handler_f)(rspamd_dkim_key_t *key, gsize keylen,
rspamd_dkim_context_t *ctx, gpointer ud, GError *err);
* @return new context or NULL
*/
rspamd_dkim_context_t * rspamd_create_dkim_context (const gchar *sig,
- rspamd_mempool_t *pool,
- guint time_jitter,
- GError **err);
+ rspamd_mempool_t *pool,
+ guint time_jitter,
+ enum rspamd_dkim_type type,
+ GError **err);
/**
* Create new dkim context for making a signature
gint headers_canon,
gint body_canon,
const gchar *dkim_headers,
+ enum rspamd_dkim_type type,
GError **err);
/**
GString* rspamd_dkim_sign (struct rspamd_task *task,
const gchar *selector, const gchar *domain,
time_t expire, gsize len,
+ guint idx,
rspamd_dkim_sign_context_t *ctx);
rspamd_dkim_key_t * rspamd_dkim_key_ref (rspamd_dkim_key_t *k);
ctx = rspamd_create_dkim_sign_context (task, dkim_key,
DKIM_CANON_RELAXED, DKIM_CANON_RELAXED,
- headers, &err);
+ headers, RSPAMD_DKIM_NORMAL, &err);
if (ctx == NULL) {
msg_err_task ("cannot create sign context: %e",
return 1;
}
- hdr = rspamd_dkim_sign (task, selector, domain, 0, 0, ctx);
+ hdr = rspamd_dkim_sign (task, selector, domain, 0, 0, 0, ctx);
if (hdr) {
ctx = rspamd_create_dkim_context (rh->decoded,
task->task_pool,
dkim_module_ctx->time_jitter,
+ RSPAMD_DKIM_NORMAL,
&err);
if (ctx == NULL) {
ctx = rspamd_create_dkim_sign_context (task, dkim_key,
DKIM_CANON_RELAXED, DKIM_CANON_RELAXED,
- dkim_module_ctx->sign_headers, &err);
+ dkim_module_ctx->sign_headers,
+ RSPAMD_DKIM_NORMAL,
+ &err);
if (ctx == NULL) {
msg_err_task ("cannot create sign context: %e",
return;
}
- hdr = rspamd_dkim_sign (task, selector, domain, 0, 0, ctx);
+ hdr = rspamd_dkim_sign (task, selector, domain, 0, 0, 0, ctx);
if (hdr) {
rspamd_mempool_set_variable (task->task_pool,
ctx = rspamd_create_dkim_context (sig,
task->task_pool,
dkim_module_ctx->time_jitter,
+ RSPAMD_DKIM_NORMAL,
&err);
if (ctx == NULL) {