DKIM: add support for the SubjectPublicKeyInfo wrapped form of pubkey
authorJeremy Harris <jgh146exb@wizmail.org>
Fri, 13 Apr 2018 10:51:50 +0000 (11:51 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Fri, 13 Apr 2018 10:51:50 +0000 (11:51 +0100)
doc/doc-docbook/spec.xfpt
doc/doc-txt/ChangeLog
src/src/pdkim/pdkim.c
test/dnszones-src/db.test.ex
test/log/4540
test/scripts/4540-DKIM-Ed25519/4540

index d8f1573..a35a8bf 100644 (file)
@@ -39067,6 +39067,11 @@ To produce the required public key value for a DNS record:
 openssl pkey -outform DER -pubout -in dkim_ed25519.private | tail -c +13 | base64
 certtool --load_privkey=dkim_ed25519.private --pubkey_info --outder | tail -c +13 | base64
 .endd
+
+Note that the format
+of Ed25519 keys in DNS has not yet been decided; this release supports
+both of the leading candidates at this time, a future release will
+probably drop support for whichever proposal loses
 .wen
 
 .option dkim_hash smtp string&!! sha256
index 9fc4663..83a37d5 100644 (file)
@@ -206,6 +206,10 @@ JH/37 Bug 2255: Revert the disable of the OpenSSL session caching.  This
 PP/03 Add util/renew-opendmarc-tlds.sh script for safe renewal of public
       suffix list.
 
+JH/38 DKIM: accept Ed25519 pubkeys in SubjectPublicKeyInfo-wrapped form,
+      since the IETF WG has not yet settled on that versus the original
+      "bare" representation.
+
 
 Exim version 4.90
 -----------------
index 149cff8..5688c78 100644 (file)
@@ -80,7 +80,7 @@ const pdkim_hashtype pdkim_hashes[] = {
 const uschar * pdkim_keytypes[] = {
   [KEYTYPE_RSA] =      US"rsa",
 #ifdef SIGN_HAVE_ED25519
-  [KEYTYPE_ED25519] =  US"ed25519",            /* Works for 3.6.0 GnuTLS */
+  [KEYTYPE_ED25519] =  US"ed25519",            /* Works for 3.6.0 GnuTLS, OpenSSL 1.1.1 */
 #endif
 
 #ifdef notyet_EC_dkim_extensions       /* https://tools.ietf.org/html/draft-srose-dkim-ecc-00 */
@@ -1336,6 +1336,28 @@ return string_from_gstring(hdr);
 
 /* -------------------------------------------------------------------------- */
 
+/* According to draft-ietf-dcrup-dkim-crypto-07 "keys are 256 bits" (referring
+to DNS, hence the pubkey).  Check for more than 32 bytes; if so assume the
+alternate possible representation (still) being discussed: a
+SubjectPublickeyInfo wrapped key - and drop all but the trailing 32-bytes (it
+should be a DER, with exactly 12 leading bytes - but we could accept a BER also,
+which could be any size).  We still rely on the crypto library for checking for
+undersize.
+
+When the RFC is published this should be re-addressed. */
+
+static void
+check_bare_ed25519_pubkey(pdkim_pubkey * p)
+{
+int excess = p->key.len - 32;
+if (excess > 0)
+  {
+  DEBUG(D_acl) debug_printf("PDKIM: unexpected pubkey len %lu\n", p->key.len);
+  p->key.data += excess; p->key.len = 32;
+  }
+}
+
+
 static pdkim_pubkey *
 pdkim_key_from_dns(pdkim_ctx * ctx, pdkim_signature * sig, ev_ctx * vctx,
   const uschar ** errstr)
@@ -1408,6 +1430,9 @@ if (sig->keytype < 0)
   }
 k_ok:
 
+if (sig->keytype == KEYTYPE_ED25519)
+  check_bare_ed25519_pubkey(p);
+
 if ((*errstr = exim_dkim_verify_init(&p->key,
            sig->keytype == KEYTYPE_ED25519 ? KEYFMT_ED25519_BARE : KEYFMT_DER,
            vctx)))
index b8abd28..492ee5d 100644 (file)
@@ -556,9 +556,15 @@ sel2._domainkey TXT "v=DKIM1; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXRFf+VhT+
 ; EC signing, using Ed25519
 ; - needs GnuTLS 3.6.0 (fedora rawhide has that)
 ;           certtool --generate-privkey --key-type=ed25519 --outfile=dkim_ed25519.private
-;           ../src/util/ed25519_privkey_pem_to_pubkey_raw_b64 dkim_ed25519.private
+;          certtool --load_privkey=dkim_ed25519.private --pubkey_info --outder | tail -c +13 | base64
 
 sed._domainkey TXT "v=DKIM1; k=ed25519; p=sPs07Vu29FpHT/80UXUcYHFOHifD4o2ZlP2+XUh9g6E="
 
+; version of the above wrapped in SubjectPublicKeyInfo, in case the WG plumps in that direction
+;      certtool --load_privkey=aux-fixed/dkim/dkim_ed25519.private --pubkey_info
+;       (and grab the b64 content from between the pem headers)
+
+sedw._domainkey TXT "v=DKIM1; k=ed25519; p=MCowBQYDK2VwAyEAsPs07Vu29FpHT/80UXUcYHFOHifD4o2ZlP2+XUh9g6E="
+
 
 ; End
index 5803946..7d0c92b 100644 (file)
@@ -5,9 +5,13 @@
 1999-03-02 09:44:33 10HmaX-0005vi-00 DKIM: d=test.ex s=sed c=relaxed/relaxed a=ed25519-sha256 b=512 [verification succeeded]
 1999-03-02 09:44:33 10HmaX-0005vi-00 Authentication-Results: myhost.test.ex;\n dkim=pass header.d=test.ex header.s=sed header.a=ed25519-sha256
 1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss DKIM=test.ex id=E10HmaY-0005vi-00@myhost.test.ex
-1999-03-02 09:44:33 10HmaZ-0005vi-00 signer: kitterman.org bits: 512
-1999-03-02 09:44:33 10HmaZ-0005vi-00 DKIM: d=kitterman.org s=ed25519 c=relaxed/simple a=ed25519-sha256 b=512 i=@kitterman.org t=1517847601 [verification succeeded]
-1999-03-02 09:44:33 10HmaZ-0005vi-00 signer: @kitterman.org bits: 512
-1999-03-02 09:44:33 10HmaZ-0005vi-00 DKIM: d=kitterman.org s=ed25519 c=relaxed/simple a=ed25519-sha256 b=512 i=@kitterman.org t=1517847601 [verification succeeded]
-1999-03-02 09:44:33 10HmaZ-0005vi-00 Authentication-Results: myhost.test.ex;\n dkim=pass header.d=kitterman.org header.i=@kitterman.org header.s=ed25519 header.a=ed25519-sha256
-1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss DKIM=kitterman.org id=example@example.com
+1999-03-02 09:44:33 10HmaZ-0005vi-00 signer: test.ex bits: 512
+1999-03-02 09:44:33 10HmaZ-0005vi-00 DKIM: d=test.ex s=sedw c=relaxed/relaxed a=ed25519-sha256 b=512 [verification succeeded]
+1999-03-02 09:44:33 10HmaZ-0005vi-00 Authentication-Results: myhost.test.ex;\n dkim=pass header.d=test.ex header.s=sedw header.a=ed25519-sha256
+1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss DKIM=test.ex id=E10HmaY-0005vi-00@myhost.test.ex
+1999-03-02 09:44:33 10HmbA-0005vi-00 signer: kitterman.org bits: 512
+1999-03-02 09:44:33 10HmbA-0005vi-00 DKIM: d=kitterman.org s=ed25519 c=relaxed/simple a=ed25519-sha256 b=512 i=@kitterman.org t=1517847601 [verification succeeded]
+1999-03-02 09:44:33 10HmbA-0005vi-00 signer: @kitterman.org bits: 512
+1999-03-02 09:44:33 10HmbA-0005vi-00 DKIM: d=kitterman.org s=ed25519 c=relaxed/simple a=ed25519-sha256 b=512 i=@kitterman.org t=1517847601 [verification succeeded]
+1999-03-02 09:44:33 10HmbA-0005vi-00 Authentication-Results: myhost.test.ex;\n dkim=pass header.d=kitterman.org header.i=@kitterman.org header.s=ed25519 header.a=ed25519-sha256
+1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss DKIM=kitterman.org id=example@example.com
index 0be08ea..504676e 100644 (file)
@@ -6,7 +6,7 @@ exim -DSERVER=server -bd -oX PORT_D
 # This should pass, only Mail::DKIM::Signer does not handle ed25519-sha256 yet
 #
 # Mail original (will be)in aux-fixed/4500.msg1.txt
-# Sig generated by: perl aux-fixed/dkim/sign.pl --algorithm=ed255190sha256 \
+# Sig (would be) generated by: perl aux-fixed/dkim/sign.pl --algorithm=ed255190sha256 \
 #                      --method=simple/simple < aux-fixed/4500.msg1.txt
 #
 # TODO - until we have that we can only test internal consistency,
@@ -44,6 +44,40 @@ QUIT
 ****
 #
 #
+# Duplicate of the above, but referencing a pubkey in "wrapped-in-SubjectPublicKeyInfo"
+# format.  Should pass also.
+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=ed25519-sha256; q=dns/txt; c=relaxed/relaxed; d=test.ex
+ ; s=sedw; h=From:To:Subject; bh=/Ab0giHZitYQbDhFszoqQRUkgqueaX9zatJttIU/plc=;
+ b=g0aVl5sI4fFLWDwXj9SnLgENXg2u8H8kKgK5/bXBZ7DKAImkm2+4tRzz1UOveu/Navis53Bg/C
+ 9nPxsspzb/Dg==;
+Received: from jgh by myhost.test.ex with local (Exim x.yz)
+       envelope-from <jgh@myhost.test.ex>)
+        1dtXln-0000YP-Hb
+        a@test.ex; Sun, 17 Sep 2017 12:29:51 +0100
+From: nobody@example.com
+Message-Id: <E1dtXln-0000YP-Hb@myhost.test.ex>
+Sender: CALLER_NAME <jgh@myhost.test.ex>
+Date: Sun, 17 Sep 2017 12:29:51 +0100
+
+content
+.
+??? 250
+QUIT
+??? 221
+****
+#
+#
+
 # This should pass, an independently-generated sample from Scott Kitterman.
 # I don't want to retain this longterm as it hits an external DNS record,
 # not under the testsuite.