DKIM: $dkim_key_length visibility variable. Bug 1311
authorJeremy Harris <jgh146exb@wizmail.org>
Tue, 1 Dec 2015 00:01:33 +0000 (00:01 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Tue, 1 Dec 2015 19:39:53 +0000 (19:39 +0000)
17 files changed:
doc/doc-docbook/spec.xfpt
doc/doc-txt/ChangeLog
doc/doc-txt/NewStuff
src/src/dkim.c
src/src/expand.c
src/src/globals.c
src/src/globals.h
src/src/pdkim/pdkim.c
test/aux-fixed/dkim/dkim512.private [new file with mode: 0644]
test/aux-fixed/dkim/sign.pl
test/confs/4500
test/dnszones-src/db.test.ex
test/log/4500
test/log/4501
test/log/4502
test/scripts/4500-Domain-Keys-Identified-Mail/4500
test/scripts/4500-Domain-Keys-Identified-Mail/REQUIRES [new file with mode: 0644]

index af41e44..289ba65 100644 (file)
@@ -11417,7 +11417,8 @@ see section &<<SECTdemimecond>>&.
        &$dkim_key_nosubdomains$& &&&
        &$dkim_key_srvtype$& &&&
        &$dkim_key_granularity$& &&&
-       &$dkim_key_notes$&
+       &$dkim_key_notes$& &&&
+       &$dkim_key_length$&
 These variables are only available within the DKIM ACL.
 For details see chapter &<<CHAPdkim>>&.
 
@@ -37962,6 +37963,8 @@ Key granularity (tag g=) from the key record. Defaults to "*" if not specified
 in the key record.
 .vitem &%$dkim_key_notes%&
 Notes from the key record (tag n=).
+.vitem &%$dkim_key_length%&
+Number of bits in the key.
 .endlist
 
 In addition, two ACL conditions are provided:
index a199a8d..2062399 100644 (file)
@@ -109,6 +109,9 @@ JH/21 Bug 1720: Add support for priority groups and weighted-random proxy
       "pri" and "weight".  Note that the previous implicit priority given by the
       list order is no longer honoured.
 
+JH/22 Bugs 963, 1721: Fix some corner cases in message body canonicalisation
+      for DKIM processing.
+
 
 Exim version 4.86
 -----------------
index 7e530ce..7385212 100644 (file)
@@ -26,6 +26,8 @@ Version 4.87
 
  5. New "-bP config" support, to dump the effective configuration.
 
+ 6. New $dkim_key_length variable.
+
 
 Version 4.86
 ------------
index 6bae641..2d4af50 100644 (file)
@@ -127,12 +127,14 @@ for (sig = dkim_signatures; sig; sig = sig->next)
   /* Log a line for each signature */
 
   uschar *logmsg = string_append(NULL, &size, &ptr, 5,
-       string_sprintf("d=%s s=%s c=%s/%s a=%s ",
+       string_sprintf("d=%s s=%s c=%s/%s a=%s b=%d ",
              sig->domain,
              sig->selector,
              sig->canon_headers == PDKIM_CANON_SIMPLE ?  "simple" : "relaxed",
              sig->canon_body == PDKIM_CANON_SIMPLE ?  "simple" : "relaxed",
-             sig->algo == PDKIM_ALGO_RSA_SHA256 ?  "rsa-sha256" : "rsa-sha1"),
+             sig->algo == PDKIM_ALGO_RSA_SHA256 ?  "rsa-sha256" : "rsa-sha1",
+             sig->sigdata_len * 8
+             ),
 
        sig->identity ? string_sprintf("i=%s ", sig->identity) : US"",
        sig->created > 0 ? string_sprintf("t=%lu ", sig->created) : US"",
@@ -256,6 +258,7 @@ for (sig = dkim_signatures; sig; sig = sig->next)
 
     dkim_signing_domain = US sig->domain;
     dkim_signing_selector = US sig->selector;
+    dkim_key_length = sig->sigdata_len * 8;
     return;
     }
 }
index 90ffe78..bd16f49 100644 (file)
@@ -493,6 +493,7 @@ static var_entry var_table[] = {
   { "dkim_headernames",    vtype_dkim,        (void *)DKIM_HEADERNAMES },
   { "dkim_identity",       vtype_dkim,        (void *)DKIM_IDENTITY },
   { "dkim_key_granularity",vtype_dkim,        (void *)DKIM_KEY_GRANULARITY },
+  { "dkim_key_length",     vtype_int,         &dkim_key_length },
   { "dkim_key_nosubdomains",vtype_dkim,       (void *)DKIM_NOSUBDOMAINS },
   { "dkim_key_notes",      vtype_dkim,        (void *)DKIM_KEY_NOTES },
   { "dkim_key_srvtype",    vtype_dkim,        (void *)DKIM_KEY_SRVTYPE },
index 5dd0b13..eea84d3 100644 (file)
@@ -637,13 +637,14 @@ BOOL    disable_ipv6           = FALSE;
 BOOL    disable_logging        = FALSE;
 
 #ifndef DISABLE_DKIM
+BOOL    dkim_collect_input       = FALSE;
 uschar *dkim_cur_signer          = NULL;
+BOOL    dkim_disable_verify      = FALSE;
+int     dkim_key_length          = 0;
 uschar *dkim_signers             = NULL;
 uschar *dkim_signing_domain      = NULL;
 uschar *dkim_signing_selector    = NULL;
 uschar *dkim_verify_signers      = US"$dkim_signers";
-BOOL    dkim_collect_input       = FALSE;
-BOOL    dkim_disable_verify      = FALSE;
 #endif
 #ifdef EXPERIMENTAL_DMARC
 BOOL    dmarc_has_been_checked  = FALSE;
index 6aaa4e0..fed0495 100644 (file)
@@ -374,13 +374,14 @@ extern BOOL    disable_ipv6;           /* Don't do any IPv6 things */
 extern BOOL    disable_logging;        /* Disables log writing when TRUE */
 
 #ifndef DISABLE_DKIM
+extern BOOL    dkim_collect_input;     /* Runtime flag that tracks wether SMTP input is fed to DKIM validation */
 extern uschar *dkim_cur_signer;        /* Expansion variable, holds the current "signer" domain or identity during a acl_smtp_dkim run */
+extern BOOL    dkim_disable_verify;    /* Set via ACL control statement. When set, DKIM verification is disabled for the current message */
+extern int     dkim_key_length;        /* Expansion variable, length of signing key in bits */
 extern uschar *dkim_signers;           /* Expansion variable, holds colon-separated list of domains and identities that have signed a message */
 extern uschar *dkim_signing_domain;    /* Expansion variable, domain used for signing a message. */
 extern uschar *dkim_signing_selector;  /* Expansion variable, selector used for signing a message. */
 extern uschar *dkim_verify_signers;    /* Colon-separated list of domains for each of which we call the DKIM ACL */
-extern BOOL    dkim_collect_input;     /* Runtime flag that tracks wether SMTP input is fed to DKIM validation */
-extern BOOL    dkim_disable_verify;    /* Set via ACL control statement. When set, DKIM verification is disabled for the current message */
 #endif
 #ifdef EXPERIMENTAL_DMARC
 extern BOOL    dmarc_has_been_checked; /* Global variable to check if test has been called yet */
index 4b48664..825a2f9 100644 (file)
@@ -141,22 +141,22 @@ for (i = 0; i<len; i++)
   const int c = p[i];
   switch (c)
     {
-    case ' ' : fprintf(stream,"{SP}"); break;
-    case '\t': fprintf(stream,"{TB}"); break;
-    case '\r': fprintf(stream,"{CR}"); break;
-    case '\n': fprintf(stream,"{LF}"); break;
-    case '{' : fprintf(stream,"{BO}"); break;
-    case '}' : fprintf(stream,"{BC}"); break;
+    case ' ' : fprintf(stream, "{SP}"); break;
+    case '\t': fprintf(stream, "{TB}"); break;
+    case '\r': fprintf(stream, "{CR}"); break;
+    case '\n': fprintf(stream, "{LF}"); break;
+    case '{' : fprintf(stream, "{BO}"); break;
+    case '}' : fprintf(stream, "{BC}"); break;
     default:
       if ( (c < 32) || (c > 127) )
-       fprintf(stream,"{%02x}",c);
+       fprintf(stream, "{%02x}", c);
       else
-       fputc(c,stream);
+       fputc(c, stream);
       break;
     }
   }
 if (lf)
-  fputc('\n',stream);
+  fputc('\n', stream);
 }
 
 void
@@ -168,10 +168,10 @@ const unsigned char *p = (const unsigned char *)data;
 for (i =0 ; i<len; i++)
   {
   const int c = p[i];
-  fprintf(stream,"%02x",c);
+  fprintf(stream, "%02x", c);
   }
 if (lf)
-  fputc('\n',stream);
+  fputc('\n', stream);
 }
 #endif
 
@@ -184,7 +184,7 @@ pdkim_append_stringlist(pdkim_stringlist *base, char *str)
 pdkim_stringlist *new_entry = malloc(sizeof(pdkim_stringlist));
 
 if (!new_entry) return NULL;
-memset(new_entry,0,sizeof(pdkim_stringlist));
+memset(new_entry, 0, sizeof(pdkim_stringlist));
 if (!(new_entry->value = strdup(str))) return NULL;
 if (base)
   {
@@ -203,7 +203,7 @@ pdkim_prepend_stringlist(pdkim_stringlist *base, char *str)
 pdkim_stringlist *new_entry = malloc(sizeof(pdkim_stringlist));
 
 if (!new_entry) return NULL;
-memset(new_entry,0,sizeof(pdkim_stringlist));
+memset(new_entry, 0, sizeof(pdkim_stringlist));
 if (!(new_entry->value = strdup(str))) return NULL;
 if (base)
   new_entry->next = base;
@@ -221,7 +221,7 @@ unsigned int len = cstr ? strlen(cstr) : 0;
 pdkim_str *p = malloc(sizeof(pdkim_str));
 
 if (!p) return NULL;
-memset(p,0,sizeof(pdkim_str));
+memset(p, 0, sizeof(pdkim_str));
 if (!(p->str = malloc(len+1)))
   {
   free(p);
@@ -230,7 +230,7 @@ if (!(p->str = malloc(len+1)))
 p->allocated = len+1;
 p->len = len;
 if (cstr)
-  strcpy(p->str,cstr);
+  strcpy(p->str, cstr);
 else
   p->str[p->len] = '\0';
 return p;
@@ -265,8 +265,8 @@ char *
 pdkim_numcat(pdkim_str *str, unsigned long num)
 {
 char minibuf[20];
-snprintf(minibuf,20,"%lu",num);
-return pdkim_strcat(str,minibuf);
+snprintf(minibuf, 20, "%lu", num);
+return pdkim_strcat(str, minibuf);
 }
 
 char *
@@ -402,14 +402,14 @@ char *q;
 int rc = PDKIM_FAIL;
 
 /* Get header name */
-char *hcolon = strchr(header,':');
+char *hcolon = strchr(header, ':');
 
 if (!hcolon) return rc; /* This isn't a header */
 
 if (!(hname = malloc((hcolon-header)+1)))
   return PDKIM_ERR_OOM;
-memset(hname,0,(hcolon-header)+1);
-strncpy(hname,header,(hcolon-header));
+memset(hname, 0, (hcolon-header)+1);
+strncpy(hname, header, (hcolon-header));
 
 /* Copy tick-off list locally, so we can punch zeroes into it */
 if (!(lcopy = strdup(tick)))
@@ -418,12 +418,12 @@ if (!(lcopy = strdup(tick)))
   return PDKIM_ERR_OOM;
   }
 p = lcopy;
-q = strchr(p,':');
+q = strchr(p, ':');
 while (q)
   {
   *q = '\0';
 
-  if (strcasecmp(p,hname) == 0)
+  if (strcasecmp(p, hname) == 0)
     {
     rc = PDKIM_OK;
     /* Invalidate header name instance in tick-off list */
@@ -432,10 +432,10 @@ while (q)
     }
 
   p = q+1;
-  q = strchr(p,':');
+  q = strchr(p, ':');
   }
 
-if (strcasecmp(p,hname) == 0)
+if (strcasecmp(p, hname) == 0)
   {
   rc = PDKIM_OK;
   /* Invalidate header name instance in tick-off list */
@@ -496,7 +496,7 @@ for (p = header; *p != '\0'; p++)
 if (q > relaxed && q[-1] == ' ') q--; /* Squash eventual trailing SP */
 *q = '\0';
 
-if (crlf) strcat(relaxed,"\r\n");
+if (crlf) strcat(relaxed, "\r\n");
 return relaxed;
 }
 
@@ -614,7 +614,7 @@ pdkim_signature *
 pdkim_parse_sig_header(pdkim_ctx *ctx, char *raw_hdr)
 {
 pdkim_signature *sig ;
-char *p,*q;
+char *p, *q;
 pdkim_str *cur_tag = NULL;
 pdkim_str *cur_val = NULL;
 BOOL past_hname = FALSE;
@@ -623,7 +623,7 @@ int where = PDKIM_HDR_LIMBO;
 int i;
 
 if (!(sig = malloc(sizeof(pdkim_signature)))) return NULL;
-memset(sig,0,sizeof(pdkim_signature));
+memset(sig, 0, sizeof(pdkim_signature));
 sig->bodylength = -1;
 
 if (!(sig->rawsig_no_b_val = malloc(strlen(raw_hdr)+1)))
@@ -806,6 +806,8 @@ if (ctx->debug_stream)
                   sig->rawsig_no_b_val,
                   strlen(sig->rawsig_no_b_val), 1);
   fprintf(ctx->debug_stream,
+         "PDKIM >> Sig size: %4d bits\n", sig->sigdata_len*8);
+  fprintf(ctx->debug_stream,
          "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
   }
 #endif
@@ -837,7 +839,7 @@ pdkim_str *cur_val = NULL;
 int where = PDKIM_HDR_LIMBO;
 
 if (!(pub = malloc(sizeof(pdkim_pubkey)))) return NULL;
-memset(pub,0,sizeof(pdkim_pubkey));
+memset(pub, 0, sizeof(pdkim_pubkey));
 
 for (p = raw_record; ; p++)
   {
@@ -910,8 +912,8 @@ for (p = raw_record; ; p++)
          case 's':
            pub->srvtype = strdup(cur_val->str); break;
          case 't':
-           if (strchr(cur_val->str,'y') != NULL) pub->testing = 1;
-           if (strchr(cur_val->str,'s') != NULL) pub->no_subdomaining = 1;
+           if (strchr(cur_val->str, 'y') != NULL) pub->testing = 1;
+           if (strchr(cur_val->str, 's') != NULL) pub->no_subdomaining = 1;
            break;
          default:
 #ifdef PDKIM_DEBUG
@@ -1012,9 +1014,9 @@ while (sig)
   if (canon_len > 0)
     {
     if (sig->algo == PDKIM_ALGO_RSA_SHA1)
-      sha1_update(sig->sha1_body,(unsigned char *)canon_data,canon_len);
+      sha1_update(sig->sha1_body, (unsigned char *)canon_data, canon_len);
     else
-      sha2_update(sig->sha2_body,(unsigned char *)canon_data,canon_len);
+      sha2_update(sig->sha2_body, (unsigned char *)canon_data, canon_len);
 
     sig->signed_body_bytes += canon_len;
 #ifdef PDKIM_DEBUG
@@ -1044,9 +1046,9 @@ while (sig)
   unsigned char bh[32]; /* SHA-256 = 32 Bytes,  SHA-1 = 20 Bytes */
 
   if (sig->algo == PDKIM_ALGO_RSA_SHA1)
-    sha1_finish(sig->sha1_body,bh);
+    sha1_finish(sig->sha1_body, bh);
   else
-    sha2_finish(sig->sha2_body,bh);
+    sha2_finish(sig->sha2_body, bh);
 
 #ifdef PDKIM_DEBUG
   if (ctx->debug_stream)
@@ -1055,7 +1057,7 @@ while (sig)
       sig->domain, sig->signed_body_bytes);
     fprintf(ctx->debug_stream, "PDKIM [%s] bh  computed: ", sig->domain);
     pdkim_hexprint(ctx->debug_stream, (char *)bh,
-                  (sig->algo == PDKIM_ALGO_RSA_SHA1)?20:32,1);
+                  (sig->algo == PDKIM_ALGO_RSA_SHA1)?20:32, 1);
     }
 #endif
 
@@ -1094,7 +1096,7 @@ while (sig)
         {
        fprintf(ctx->debug_stream, "PDKIM [%s] bh signature: ", sig->domain);
        pdkim_hexprint(ctx->debug_stream, sig->bodyhash,
-                        (sig->algo == PDKIM_ALGO_RSA_SHA1)?20:32,1);
+                        (sig->algo == PDKIM_ALGO_RSA_SHA1)?20:32, 1);
        fprintf(ctx->debug_stream, "PDKIM [%s] Body hash did NOT verify\n",
                sig->domain);
        }
@@ -1137,7 +1139,7 @@ if (ctx->input_mode == PDKIM_INPUT_SMTP)
     if (  ctx->sig && ctx->sig->canon_body == PDKIM_CANON_SIMPLE
        && ctx->num_buffered_crlf > 0
        )
-      pdkim_update_bodyhash(ctx, "\r\n",2);
+      pdkim_update_bodyhash(ctx, "\r\n", 2);
 
     ctx->seen_eod = 1;
     goto BAIL;
@@ -1256,11 +1258,11 @@ if (ctx->mode == PDKIM_MODE_VERIFY)
        last_sig->next = new_sig;
        }
       }
-    else
 #ifdef PDKIM_DEBUG
+    else
       if (ctx->debug_stream)
         {
-       fprintf(ctx->debug_stream,"Error while parsing signature header\n");
+       fprintf(ctx->debug_stream, "Error while parsing signature header\n");
        fprintf(ctx->debug_stream,
          "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
        }
@@ -1272,8 +1274,7 @@ if (ctx->mode == PDKIM_MODE_VERIFY)
     {
     pdkim_stringlist *list;
 
-    if (!(list = pdkim_prepend_stringlist(ctx->headers,
-                                   ctx->cur_header->str)))
+    if (!(list = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->str)))
       return PDKIM_ERR_OOM;
     ctx->headers = list;
     }
@@ -1421,7 +1422,7 @@ while (l>77)
     {
     size_t sl = strlen(intro);
 
-    pdkim_strncat(str, intro,sl);
+    pdkim_strncat(str, intro, sl);
     *col += sl;
     l -= sl;
     intro = NULL; /* only want this once */
@@ -1432,7 +1433,7 @@ while (l>77)
     size_t sl = strlen(payload);
     size_t chomp = *col+sl < 77 ? sl : 78-*col;
 
-    pdkim_strncat(str, payload,chomp);
+    pdkim_strncat(str, payload, chomp);
     *col += chomp;
     payload += chomp;
     l -= chomp-1;
@@ -1503,14 +1504,13 @@ if (!(base64_bh = pdkim_encode_base64(sig->bodyhash, sig->bodyhash_len)))
 col = strlen(hdr->str);
 
 /* Required and static bits */
-if (
-      pdkim_headcat(&col,hdr,";","a=",pdkim_algos[sig->algo]) &&
-      pdkim_headcat(&col,hdr,";","q=",pdkim_querymethods[sig->querymethod])  &&
-       pdkim_strcat(canon_all,"/")                           &&
-       pdkim_strcat(canon_all,pdkim_canons[sig->canon_body]) &&
-      pdkim_headcat(&col,hdr,";","c=",canon_all->str)         &&
-      pdkim_headcat(&col,hdr,";","d=",sig->domain)            &&
-      pdkim_headcat(&col,hdr,";","s=",sig->selector)
+if (  pdkim_headcat(&col, hdr, ";", "a=", pdkim_algos[sig->algo])
+   && pdkim_headcat(&col, hdr, ";", "q=", pdkim_querymethods[sig->querymethod])
+   && pdkim_strcat(canon_all, "/")
+   && pdkim_strcat(canon_all, pdkim_canons[sig->canon_body])
+   && pdkim_headcat(&col, hdr, ";", "c=", canon_all->str)
+   && pdkim_headcat(&col, hdr, ";", "d=", sig->domain)
+   && pdkim_headcat(&col, hdr, ";", "s=", sig->selector)
    )
   {
   /* list of eader names can be split between items. */
@@ -1523,18 +1523,18 @@ if (
     if (!n) goto BAIL;
     while (*n)
       {
-      char *c = strchr(n,':');
+      char *c = strchr(n, ':');
 
       if (c) *c ='\0';
 
       if (!i)
-       if (!pdkim_headcat(&col,hdr,NULL,NULL,":"))
+       if (!pdkim_headcat(&col, hdr, NULL, NULL, ":"))
          {
          free(f);
          goto BAIL;
          }
 
-      if (!pdkim_headcat(&col,hdr,s,i,n))
+      if (!pdkim_headcat(&col, hdr, s, i, n))
        {
        free(f);
        goto BAIL;
@@ -1562,7 +1562,7 @@ if (
     {
     char minibuf[20];
 
-    snprintf(minibuf,20,"%lu",sig->created);
+    snprintf(minibuf, 20, "%lu", sig->created);
     if(!pdkim_headcat(&col, hdr, ";", "t=", minibuf))
       goto BAIL;
   }
@@ -1571,7 +1571,7 @@ if (
     {
     char minibuf[20];
 
-    snprintf(minibuf,20,"%lu",sig->expires);
+    snprintf(minibuf, 20, "%lu", sig->expires);
     if(!pdkim_headcat(&col, hdr, ";", "x=", minibuf))
       goto BAIL;
     }
@@ -1580,7 +1580,7 @@ if (
     {
     char minibuf[20];
 
-    snprintf(minibuf,20,"%lu",sig->bodylength);
+    snprintf(minibuf, 20, "%lu", sig->bodylength);
     if(!pdkim_headcat(&col, hdr, ";", "l=", minibuf))
       goto BAIL;
     }
@@ -1598,7 +1598,7 @@ if (
       goto BAIL;
 
   /* add trailing semicolon: I'm not sure if this is actually needed */
-  if (!pdkim_headcat(&col,hdr,NULL,";",""))
+  if (!pdkim_headcat(&col, hdr, NULL, ";", ""))
     goto BAIL;
   }
 
@@ -1667,7 +1667,7 @@ while (sig)
   if (sig->algo == PDKIM_ALGO_RSA_SHA1)
     sha1_starts(&sha1_headers);
   else
-    sha2_starts(&sha2_headers,0);
+    sha2_starts(&sha2_headers, 0);
 
 #ifdef PDKIM_DEBUG
   if (ctx->debug_stream)
@@ -1687,14 +1687,14 @@ while (sig)
       {
       char *rh = NULL;
       /* Collect header names (Note: colon presence is guaranteed here) */
-      char *q = strchr(p->value,':');
+      char *q = strchr(p->value, ':');
 
       if (!(pdkim_strncat(headernames, p->value,
                        (q-(p->value)) + (p->next ? 1 : 0))))
        return PDKIM_ERR_OOM;
 
       rh = sig->canon_headers == PDKIM_CANON_RELAXED
-       ? pdkim_relax_header(p->value,1) /* cook header for relaxed canon */
+       ? pdkim_relax_header(p->value, 1) /* cook header for relaxed canon */
        : strdup(p->value);              /* just copy it for simple canon */
       if (!rh)
        return PDKIM_ERR_OOM;
@@ -1731,28 +1731,28 @@ while (sig)
 
     while(1)
       {
-      if ((q = strchr(p,':')))
+      if ((q = strchr(p, ':')))
        *q = '\0';
 
       for (hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
        if (  hdrs->tag == 0
-          && strncasecmp(hdrs->value,p,strlen(p)) == 0
+          && strncasecmp(hdrs->value, p, strlen(p)) == 0
           && (hdrs->value)[strlen(p)] == ':'
           )
          {
          char *rh;
 
          rh = sig->canon_headers == PDKIM_CANON_RELAXED
-           ? pdkim_relax_header(hdrs->value,1)  /* cook header for relaxed canon */
+           ? pdkim_relax_header(hdrs->value, 1) /* cook header for relaxed canon */
            : strdup(hdrs->value);               /* just copy it for simple canon */
          if (!rh)
            return PDKIM_ERR_OOM;
 
          /* Feed header to the hash algorithm */
          if (sig->algo == PDKIM_ALGO_RSA_SHA1)
-           sha1_update(&(sha1_headers), (unsigned char *)rh, strlen(rh));
+           sha1_update(&sha1_headers, (unsigned char *)rh, strlen(rh));
          else
-           sha2_update(&(sha2_headers), (unsigned char *)rh, strlen(rh));
+           sha2_update(&sha2_headers, (unsigned char *)rh, strlen(rh));
 
 #ifdef PDKIM_DEBUG
          if (ctx->debug_stream)
@@ -1819,8 +1819,8 @@ while (sig)
   /* Finalize header hash */
   if (sig->algo == PDKIM_ALGO_RSA_SHA1)
     {
-    sha1_update(&(sha1_headers), (unsigned char *)sig_hdr, strlen(sig_hdr));
-    sha1_finish(&(sha1_headers), (unsigned char *)headerhash);
+    sha1_update(&sha1_headers, (unsigned char *)sig_hdr, strlen(sig_hdr));
+    sha1_finish(&sha1_headers, (unsigned char *)headerhash);
 
 #ifdef PDKIM_DEBUG
     if (ctx->debug_stream)
@@ -1832,8 +1832,8 @@ while (sig)
     }
   else
     {
-    sha2_update(&(sha2_headers), (unsigned char *)sig_hdr, strlen(sig_hdr));
-    sha2_finish(&(sha2_headers), (unsigned char *)headerhash);
+    sha2_update(&sha2_headers, (unsigned char *)sig_hdr, strlen(sig_hdr));
+    sha2_finish(&sha2_headers, (unsigned char *)headerhash);
 
 #ifdef PDKIM_DEBUG
     if (ctx->debug_stream)
@@ -1880,7 +1880,7 @@ while (sig)
       }
 #endif
 
-    if (!(sig->signature_header = pdkim_create_header(ctx->sig,1)))
+    if (!(sig->signature_header = pdkim_create_header(ctx->sig, 1)))
       return PDKIM_ERR_OOM;
     }
 
@@ -1904,9 +1904,9 @@ while (sig)
     memset(dns_txt_reply, 0, PDKIM_DNS_TXT_MAX_RECLEN);
     memset(dns_txt_name , 0, PDKIM_DNS_TXT_MAX_NAMELEN);
 
-    if (snprintf(dns_txt_name,PDKIM_DNS_TXT_MAX_NAMELEN,
+    if (snprintf(dns_txt_name, PDKIM_DNS_TXT_MAX_NAMELEN,
                 "%s._domainkey.%s.",
-                sig->selector,sig->domain) >= PDKIM_DNS_TXT_MAX_NAMELEN)
+                sig->selector, sig->domain) >= PDKIM_DNS_TXT_MAX_NAMELEN)
       {
       sig->verify_status =      PDKIM_VERIFY_INVALID;
       sig->verify_ext_status =  PDKIM_VERIFY_INVALID_BUFFER_SIZE;
@@ -1926,12 +1926,12 @@ while (sig)
       {
       fprintf(ctx->debug_stream,
              "PDKIM >> Parsing public key record >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
-      fprintf(ctx->debug_stream," Raw record: ");
+      fprintf(ctx->debug_stream, " Raw record: ");
       pdkim_quoteprint(ctx->debug_stream, dns_txt_reply, strlen(dns_txt_reply), 1);
       }
 #endif
 
-    if (!(sig->pubkey = pdkim_parse_pubkey_record(ctx,dns_txt_reply)))
+    if (!(sig->pubkey = pdkim_parse_pubkey_record(ctx, dns_txt_reply)))
       {
       sig->verify_status =      PDKIM_VERIFY_INVALID;
       sig->verify_ext_status =  PDKIM_VERIFY_INVALID_PUBKEY_PARSING;
@@ -1939,7 +1939,7 @@ while (sig)
 #ifdef PDKIM_DEBUG
       if (ctx->debug_stream)
         {
-       fprintf(ctx->debug_stream," Error while parsing public key record\n");
+       fprintf(ctx->debug_stream, " Error while parsing public key record\n");
        fprintf(ctx->debug_stream,
          "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
        }
@@ -2020,7 +2020,7 @@ pdkim_ctx *ctx = malloc(sizeof(pdkim_ctx));
 
 if (!ctx)
   return NULL;
-memset(ctx,0,sizeof(pdkim_ctx));
+memset(ctx, 0, sizeof(pdkim_ctx));
 
 if (!(ctx->linebuf = malloc(PDKIM_MAX_BODY_LINE_LEN)))
   {
@@ -2049,7 +2049,7 @@ if (!domain || !selector || !rsa_privkey)
 
 if (!(ctx = malloc(sizeof(pdkim_ctx))))
   return NULL;
-memset(ctx,0,sizeof(pdkim_ctx));
+memset(ctx, 0, sizeof(pdkim_ctx));
 
 if (!(ctx->linebuf = malloc(PDKIM_MAX_BODY_LINE_LEN)))
   {
@@ -2063,7 +2063,7 @@ if (!(sig = malloc(sizeof(pdkim_signature))))
   free(ctx);
   return NULL;
   }
-memset(sig,0,sizeof(pdkim_signature));
+memset(sig, 0, sizeof(pdkim_signature));
 
 sig->bodylength = -1;
 
@@ -2084,7 +2084,7 @@ sha1_starts(ctx->sig->sha1_body);
 
 if (!(ctx->sig->sha2_body = malloc(sizeof(sha2_context))))
   goto BAIL;
-sha2_starts(ctx->sig->sha2_body,0);
+sha2_starts(ctx->sig->sha2_body, 0);
 
 return ctx;
 
diff --git a/test/aux-fixed/dkim/dkim512.private b/test/aux-fixed/dkim/dkim512.private
new file mode 100644 (file)
index 0000000..159852b
--- /dev/null
@@ -0,0 +1,9 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBOAIBAAJBAL6eAQxd9didJ0/+05iDwJOqT6ly826Vi8aGPecsBiYK5/tAT97f
+xXk+dPWMZp9kQxtknEzYjYjAydzf+HQ2yJMCAwEAAQI/d+Dmx+BPvOsYzjZ03HX/
+pt51OxwP/HwQa8oBJGGLfGBJbxdKZoqZu1srifgA9o25x3YrSjfK9zrUgdqJEZRp
+AiEA5hUWdth65YX8dNMs93lsV0YkXdYzZ6Yxw6xyBAmpMh8CIQDUFtrIV8EYwgjq
+Ck0Un4RXbZleqOljmvhK+t7IBJsjDQIgGSMEqUdNZfYVds37g64IYCCRqI7WXuSR
+W0djzX0gtxECIEpwQxWyByoDYFGUj/0/B5oP85aPvmqhR6g5aNvXEgQ5AiBFgvNg
+ecXPBzNb52PZWOwH/DyuYE4agI2zLTmTsDJ09Q==
+-----END RSA PRIVATE KEY-----
index 1c2a872..6220015 100644 (file)
@@ -2,10 +2,15 @@ use Mail::DKIM::Signer;
 use Mail::DKIM::TextWrap;  #recommended
 use Getopt::Long;
 
+# default option values
 my $method = "simple/simple";
+my $selector = "sel";
+my $keyfile = "aux-fixed/dkim/dkim.private";
 
 GetOptions(
        "method=s" => \$method,
+       "selector=s" => \$selector,
+       "keyfile=s" => \$keyfile,
 );
 
 # create a signer object
@@ -13,8 +18,8 @@ my $dkim = Mail::DKIM::Signer->new(
                   Algorithm => "rsa-sha1",
                   Method => $method,
                   Domain => "test.ex",
-                  Selector => "sel",
-                  KeyFile => "aux-fixed/dkim/dkim.private",
+                  Selector => $selector,
+                  KeyFile => $keyfile,
              );
 
 # read an email and pass it into the signer, one line at a time
index e452bc0..cb98407 100644 (file)
@@ -14,6 +14,7 @@ tls_advertise_hosts =
 # ----- Main settings -----
 
 acl_smtp_rcpt = accept
+acl_smtp_dkim = accept logwrite = signer: $dkim_cur_signer bits: $dkim_key_length
 
 queue_only
 queue_run_in_order
index 6b8a531..07e3c0e 100644 (file)
@@ -460,7 +460,11 @@ DELAY=1500 delay1500 A HOSTIPV4
 ;  openssl genrsa -out aux-fixed/dkim/dkim.private 1024
 ;  openssl rsa -in aux-fixed/dkim/dkim.private -out /dev/stdout -pubout -outform PEM
 ;
+; Another, 512-bit (with a Notes field)
+;
 sel._domainkey TXT "v=DKIM1; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXRFf+VhT+lCgFhhSkinZKcFNeRzjYdW8vT29Rbb3NadvTFwAd+cVLPFwZL8H5tUD/7JbUPqNTCPxmpgIL+V5T4tEZMorHatvvUM2qfcpQ45IfsZ+YdhbIiAslHCpy4xNxIR3zylgqRUF4+Dtsaqy3a5LhwMiKCLrnzhXk1F1hxwIDAQAB"
 
+ses._domainkey TXT "v=DKIM1; n=halfkilo; p=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL6eAQxd9didJ0/+05iDwJOqT6ly826Vi8aGPecsBiYK5/tAT97fxXk+dPWMZp9kQxtknEzYjYjAydzf+HQ2yJMCAwEAAQ=="
+
 
 ; End
index 5ab02f3..4787e64 100644 (file)
@@ -1,5 +1,9 @@
 
 ******** SERVER ********
 1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
-1999-03-02 09:44:33 10HmaX-0005vi-00 DKIM: d=test.ex s=sel c=simple/simple a=rsa-sha1 [verification succeeded]
+1999-03-02 09:44:33 10HmaX-0005vi-00 DKIM: d=test.ex s=sel c=simple/simple a=rsa-sha1 b=1024 [verification succeeded]
+1999-03-02 09:44:33 10HmaX-0005vi-00 signer: test.ex bits: 1024
 1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss id=qwerty1234@disco-zombie.net
+1999-03-02 09:44:33 10HmaY-0005vi-00 DKIM: d=test.ex s=ses c=simple/simple a=rsa-sha1 b=512 [verification succeeded]
+1999-03-02 09:44:33 10HmaY-0005vi-00 signer: test.ex bits: 512
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss id=qwerty1234@disco-zombie.net
index 2234176..153f6f2 100644 (file)
@@ -1,7 +1,9 @@
 
 ******** SERVER ********
 1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
-1999-03-02 09:44:33 10HmaX-0005vi-00 DKIM: d=test.ex s=sel c=simple/simple a=rsa-sha1 [verification succeeded]
+1999-03-02 09:44:33 10HmaX-0005vi-00 DKIM: d=test.ex s=sel c=simple/simple a=rsa-sha1 b=1024 [verification succeeded]
+1999-03-02 09:44:33 10HmaX-0005vi-00 signer: test.ex bits: 1024
 1999-03-02 09:44:33 10HmaX-0005vi-00 <= pass@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss id=qwerty1234@disco-zombie.net
-1999-03-02 09:44:33 10HmaY-0005vi-00 DKIM: d=test.ex s=sel c=simple/simple a=rsa-sha1 [verification failed - body hash mismatch (body probably modified in transit)]
+1999-03-02 09:44:33 10HmaY-0005vi-00 DKIM: d=test.ex s=sel c=simple/simple a=rsa-sha1 b=1024 [verification failed - body hash mismatch (body probably modified in transit)]
+1999-03-02 09:44:33 10HmaY-0005vi-00 signer: test.ex bits: 1024
 1999-03-02 09:44:33 10HmaY-0005vi-00 <= fail@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss id=qwerty1234@disco-zombie.net
index eff4be0..8745884 100644 (file)
@@ -1,7 +1,9 @@
 
 ******** SERVER ********
 1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
-1999-03-02 09:44:33 10HmaX-0005vi-00 DKIM: d=test.ex s=sel c=relaxed/relaxed a=rsa-sha1 [verification succeeded]
+1999-03-02 09:44:33 10HmaX-0005vi-00 DKIM: d=test.ex s=sel c=relaxed/relaxed a=rsa-sha1 b=1024 [verification succeeded]
+1999-03-02 09:44:33 10HmaX-0005vi-00 signer: test.ex bits: 1024
 1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss id=564CFC9B.1040905@yahoo.com
-1999-03-02 09:44:33 10HmaY-0005vi-00 DKIM: d=test.ex s=sel c=relaxed/simple a=rsa-sha1 [verification succeeded]
+1999-03-02 09:44:33 10HmaY-0005vi-00 DKIM: d=test.ex s=sel c=relaxed/simple a=rsa-sha1 b=1024 [verification succeeded]
+1999-03-02 09:44:33 10HmaY-0005vi-00 signer: test.ex bits: 1024
 1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss
index 1dea022..b352893 100644 (file)
@@ -5,7 +5,7 @@ exim -DSERVER=server -bd -oX PORT_D
 #
 # This should pass.
 # Mail original in aux-fixed/4500.msg1.txt
-# Sig generatd by: perl aux-fixed/dkim/sign.pl --method=simple/simple < aux-fixed/4500.msg1.txt
+# Sig generated by: perl aux-fixed/dkim/sign.pl --method=simple/simple < aux-fixed/4500.msg1.txt
 client 127.0.0.1 PORT_D
 ??? 220
 HELO xxx
@@ -34,6 +34,38 @@ QUIT
 ??? 221
 ****
 #
+# This should pass.
+# Mail original in aux-fixed/4500.msg1.txt
+# Sig generated by: perl aux-fixed/dkim/sign.pl --method=simple/simple --selector=ses \
+#                      --keyfile=aux-fixed/dkim/dkim512.private < aux-fixed/4500.msg1.txt
+client 127.0.0.1 PORT_D
+??? 220
+HELO xxx
+??? 250
+MAIL FROM:<CALLER@bloggs.com>
+??? 250
+RCPT TO:<a@test.ex>
+??? 250
+DATA
+??? 354
+DKIM-Signature: v=1; a=rsa-sha1; c=simple/simple; d=test.ex; h=from:to
+       :date:message-id:subject; s=ses; bh=OB9dZVu7+5/ufs3TH9leIcEpXSo=; b=
+       cIErF1eueIT9AU4qG54FyT3yrlVDDM7RZnuU6fWTevZpAuMqhYcRO8tU3U4vtKWB
+       +I2vd+F1gzqCzBcRtfLhZg==
+From: mrgus@text.ex
+To: bakawolf@yahoo.com
+Date: Thu, 19 Nov 2015 17:00:07 -0700
+Message-ID: <qwerty1234@disco-zombie.net>
+Subject: simple test
+
+This is a simple test.
+.
+??? 250
+QUIT
+??? 221
+****
+#
+#
 killdaemon
 no_stdout_check
 no_msglog_check
diff --git a/test/scripts/4500-Domain-Keys-Identified-Mail/REQUIRES b/test/scripts/4500-Domain-Keys-Identified-Mail/REQUIRES
new file mode 100644 (file)
index 0000000..ec7e42a
--- /dev/null
@@ -0,0 +1 @@
+support DKIM