Exception thrown when dual-signing is configured

Bug #1901569 reported by pgnd
12
This bug affects 2 people
Affects Status Importance Assigned to Milestone
dkimpy-milter
Invalid
Undecided
Unassigned

Bug Description

with

 pip show dkimpy-milter dkimpy pymilter pynacl | egrep "Name:|Version:"
  Name: dkimpy-milter
  Version: 1.2.2
  Name: dkimpy
  Version: 1.0.5
  Name: pymilter
  Version: 1.0.4
  Name: PyNaCl
  Version: 1.4.0

 python v3.8.6
 lsb_release -rd
  Description: Fedora release 32 (Thirty Two)
  Release: 32

i've dknewkey-generated both rsa & ed25519 keys, and pushed to nameserver.
(i've also tried 'openssl' key generation ... results, as below, are the same in both cases)

with dkimpy-config

 ...
 KeyTable /etc/dkimpy-milter/key_table_rsa
 #KeyTableEd25519 /etc/dkimpy-milter/key_table_ed25519
 ...

where

 cat /etc/dkimpy-milter/signing_table
  *@example.net dkim-2a072a271a930868._domainkey.example.net

 cat key_table_ed25519
  dkim-2a072a271a930868._domainkey.example.net example.net:dkim-2a072a271a930868:/srv/dkim/dkim.example.net.ed25519.key.pem

 cat key_table_rsa
  dkim-2a072a271a930868._domainkey.example.net example.net:dkim-2a072a271a930868:/srv/dkim/dkim.example.net.rsa.key.pem

checking,

 dig @1.1.1.1 TXT selector._domainkey.example.net +short
  dkim-2a072a271a930868._domainkey.example.net.
  "v=DKIM1; k=ed25519; p=0cU7XIzvq3Y3UZOwiXho3cp9ggwoudPY9T93AniWWiJ=;"
  "v=DKIM1; k=rsa; h=sha256; s=email; t=s;" "p=MIIB...qK" "uC3KM...CAE" "PB2s...JaS" "3lyD...IdF" "Nde3...N3o+" "0R8T3...lkg" "rQIDAQAB;"

outbound mail's rsa-signed

 Oct 26 09:00:30 mx.example.com dkimpy-milter[62259]: connect from int.mx.example.com at ('10.0.1.127', 35709) EXTERNAL
 Oct 26 09:00:30 mx.example.com dkimpy-milter[62259]: mail from: <email address hidden> ('SIZE=952', 'BODY=8BITMIME')
 Oct 26 09:00:30 mx.example.com dkimpy-milter[62259]: From: test _ <email address hidden>
 Oct 26 09:00:30 mx.example.com dkimpy-milter[62259]: 4CKfgf1gS2z2P: rsa-sha256 DKIM signature added (s=dkim-2a072a271a930868 d=example.net)

and verifies/passes all checks.
rsa signing works in any/all cases.

enabling dual-signing,

 ...
 KeyTable /etc/dkimpy-milter/key_table_rsa
- #KeyTableEd25519 /etc/dkimpy-milter/key_table_ed25519
+ KeyTableEd25519 /etc/dkimpy-milter/key_table_ed25519
 ...

outbound signing appears to succeed for rsa, bug fails for subsequent/additional ed25519 signing,

 " sign_dkim: The seed must be exactly 32 bytes long"

logs,

 Oct 26 09:01:27 mx.example.com dkimpy-milter[65442]: connect from int.mx.example.com at ('10.0.1.127', 38713) EXTERNAL
 Oct 26 09:01:27 mx.example.com dkimpy-milter[65442]: mail from: <email address hidden> ('SIZE=952', 'BODY=8BITMIME')
 Oct 26 09:01:27 mx.example.com dkimpy-milter[65442]: From: test _ <email address hidden>
 Oct 26 09:01:27 mx.example.com dkimpy-milter[65442]: 4CKfhl4qzhz2P: rsa-sha256 DKIM signature added (s=dkim-2a072a271a930868 d=example.net)
 Oct 26 09:01:27 mx.example.com dkimpy-milter[65442]: sign_dkim: The seed must be exactly 32 bytes long
 Oct 26 09:01:27 mx.example.com dkimpy-milter[65442]: Traceback (most recent call last):
 Oct 26 09:01:27 mx.example.com dkimpy-milter[65442]: File "/usr/lib64/python3.8/site-packages/Milter/__init__.py", line 772, in <lambda>
                milter.set_eom_callback(lambda ctx: ctx.getpriv().eom())
 Oct 26 09:01:27 mx.example.com dkimpy-milter[65442]: File "/usr/local/lib/python3.8/site-packages/dkimpy_milter/__init__.py", line 198, in eom
                self.sign_dkim(txt)
 Oct 26 09:01:27 mx.example.com dkimpy-milter[65442]: File "/usr/local/lib/python3.8/site-packages/dkimpy_milter/__init__.py", line 335, in sign_dkim
                h = d.sign(codecs.encode(self.selectorEd25519, 'ascii'), codecs.encode(self.fdomain, 'ascii'),
 Oct 26 09:01:27 mx.example.com dkimpy-milter[65442]: File "/usr/local/lib/python3.8/site-packages/dkim/__init__.py", line 832, in sign
                pk = nacl.signing.SigningKey(privkey, encoder=nacl.encoding.Base64Encoder)
 Oct 26 09:01:27 mx.example.com dkimpy-milter[65442]: File "/usr/local/lib64/python3.8/site-packages/nacl/signing.py", line 153, in __init__
                raise exc.ValueError(
 Oct 26 09:01:27 mx.example.com dkimpy-milter[65442]: nacl.exceptions.ValueError: The seed must be exactly 32 bytes long

Revision history for this message
Ike Johnson-Woods (notactuallyterry) wrote (last edit ):

Same results on arch when trying to sign both rsa and ed25519.
When rsa is commented out, ed25519 signs perfectly fine, and vice versa.

Name: dkimpy-milter
Version: 1.2.2
Name: dkimpy
Version: 1.0.5
Name: pymilter
Version: 1.0.4
Name: PyNaCl
Version: 1.4.0

sign_dkim: The seed must be exactly 32 bytes long
Traceback (most recent call last):
Traceback (most recent call last):
  File "/usr/lib/python3.9/site-packages/Milter/__init__.py", line 772, in <lambda>
                                                milter.set_eom_callback(lambda ctx: ctx.getpriv().eom())
  File "/usr/lib/python3.9/site-packages/Milter/__init__.py", line 772, in <lambda>
    milter.set_eom_callback(lambda ctx: ctx.getpriv().eom())
  File "/usr/lib/python3.9/site-packages/dkimpy_milter/__init__.py", line 198, in eom
                                                self.sign_dkim(txt)
  File "/usr/lib/python3.9/site-packages/dkimpy_milter/__init__.py", line 198, in eom
    self.sign_dkim(txt)
  File "/usr/lib/python3.9/site-packages/dkimpy_milter/__init__.py", line 335, in sign_dkim
                                                h = d.sign(codecs.encode(self.selectorEd25519, 'ascii'), codecs.encode(self.fdomain, 'ascii'),
  File "/usr/lib/python3.9/site-packages/dkimpy_milter/__init__.py", line 335, in sign_dkim
    h = d.sign(codecs.encode(self.selectorEd25519, 'ascii'), codecs.encode(self.fdomain, 'ascii'),
  File "/usr/lib/python3.9/site-packages/dkim/__init__.py", line 832, in sign
                                                pk = nacl.signing.SigningKey(privkey, encoder=nacl.encoding.Base64Encoder)
  File "/usr/lib/python3.9/site-packages/dkim/__init__.py", line 832, in sign
    pk = nacl.signing.SigningKey(privkey, encoder=nacl.encoding.Base64Encoder)
  File "/usr/lib/python3.9/site-packages/nacl/signing.py", line 153, in __init__
                                                raise exc.ValueError(
  File "/usr/lib/python3.9/site-packages/nacl/signing.py", line 153, in __init__
    raise exc.ValueError(
nacl.exceptions.ValueError: The seed must be exactly 32 bytes long
nacl.exceptions.ValueError: The seed must be exactly 32 bytes long

no longer affects: archlinux
summary: - ed25519 signing ERROR: "sign_dkim: The seed must be exactly 32 bytes
- long"
+ Exception thrown when dual-signing is configured
Revision history for this message
pgnd (pgnd) wrote :

dual signing is still an issue here.

with

 pip show dkimpy-milter dkimpy pymilter pynacl | egrep "Name:|Version:"

  Name: dkimpy-milter
  Version: 1.2.2
  Name: dkimpy
  Version: 1.0.5
  Name: pymilter
  Version: 1.0.5
  Name: PyNaCl
  Version: 1.4.0

 python -V
  Python 3.10.0

 lsb_release -rd
  Description: Fedora release 35 (Thirty Five)
  Release: 35

and dual-signing enabled

 ...
 KeyTable /etc/dkimpy-milter/key_table_rsa
 KeyTableEd25519 /etc/dkimpy-milter/key_table_ed25519
 ...

dual signing still fails with

 dkimpy-milter[7609]: sign_dkim: The seed must be exactly 32 bytes long
 dkimpy-milter[7609]: Traceback (most recent call last):
 dkimpy-milter[7609]: File "/usr/lib64/python3.10/site-packages/Milter/__init__.py", line 855, in <lambda>#012 milter.set_eom_callback(lambda ctx: ctx.getpriv().eom())
 dkimpy-milter[7609]: Traceback (most recent call last):
 dkimpy-milter[7609]: File "/usr/lib64/python3.10/site-packages/Milter/__init__.py", line 855, in <lambda>
 dkimpy-milter[7609]: milter.set_eom_callback(lambda ctx: ctx.getpriv().eom())
 dkimpy-milter[7609]: File "/usr/lib/python3.10/site-packages/dkimpy_milter/__init__.py", line 198, in eom
 dkimpy-milter[7609]: self.sign_dkim(txt)
 dkimpy-milter[7609]: File "/usr/lib/python3.10/site-packages/dkimpy_milter/__init__.py", line 335, in sign_dkim
 dkimpy-milter[7609]: h = d.sign(codecs.encode(self.selectorEd25519, 'ascii'), codecs.encode(self.fdomain, 'ascii'),
 dkimpy-milter[7609]: File "/usr/lib/python3.10/site-packages/dkim/__init__.py", line 832, in sign
 dkimpy-milter[7609]: pk = nacl.signing.SigningKey(privkey, encoder=nacl.encoding.Base64Encoder)
 dkimpy-milter[7609]: File "/usr/lib64/python3.10/site-packages/nacl/signing.py", line 153, in __init__
 dkimpy-milter[7609]: raise exc.ValueError(
 dkimpy-milter[7609]: nacl.exceptions.ValueError: The seed must be exactly 32 bytes long
 dkimpy-milter[7609]: File "/usr/lib/python3.10/site-packages/dkimpy_milter/__init__.py", line 198, in eom#012 self.sign_dkim(txt)
 dkimpy-milter[7609]: File "/usr/lib/python3.10/site-packages/dkimpy_milter/__init__.py", line 335, in sign_dkim#012 h = d.sign(codecs.encode(self.selectorEd25519, 'ascii'), codecs.encode(self.fdomain, 'ascii'),
 dkimpy-milter[7609]: File "/usr/lib/python3.10/site-packages/dkim/__init__.py", line 832, in sign#012 pk = nacl.signing.SigningKey(privkey, encoder=nacl.encoding.Base64Encoder)
 dkimpy-milter[7609]: File "/usr/lib64/python3.10/site-packages/nacl/signing.py", line 153, in __init__#012 raise exc.ValueError(
 dkimpy-milter[7609]: nacl.exceptions.ValueError: The seed must be exactly 32 bytes long

Revision history for this message
Scott Kitterman (kitterman) wrote :

From the original bug text:

 cat key_table_ed25519
  dkim-2a072a271a930868._domainkey.example.net example.net:dkim-2a072a271a930868:/srv/dkim/dkim.example.net.ed25519.key.pem

Is that what you're using? For dkimpy (and thus dkimpy-milter) the ed25119 keys aren't .pem. If that's accurate and it's a .pem file it won't work because it's not the right format.

Revision history for this message
pgnd (pgnd) wrote :

yes, that's the _extension_.

i'm aware of

 src/dkimpy-milter/README.md
  There is no standardized non-binary representation for Ed25519 private keys,
  so in order to generate Ed25519 keys for dkimpy-milter, dkimpy specific tools
  must be used to be compatible. The same dknewkey script support Ed25519:

   dknewkey --ktype ed25519 anothernewkey

  will provide both the private key file (.key suffix) and a file with the DKIM
  public key record to be published DNS (.dns suffix). Ed25519 keys do not have
  variable bit lengths.

and used that generator accordingly.

in my deploy scripts, i renamed the xxx.key to xxx.key.pem, for consistency.

didn't think that naming would matter, and clearly missed that it's not actually .pem to begin with.

a self-inflicted wound!

i'll get that cleaned-up & see ...

Revision history for this message
Scott Kitterman (kitterman) wrote : Re: [Bug 1901569] Re: Exception thrown when dual-signing is configured

On Tuesday, November 23, 2021 5:19:46 PM EST you wrote:
> yes, that's the _extension_.
>
> i'm aware of
>
> src/dkimpy-milter/README.md
> There is no standardized non-binary representation for Ed25519 private
> keys, so in order to generate Ed25519 keys for dkimpy-milter, dkimpy
> specific tools must be used to be compatible. The same dknewkey script
> support Ed25519:
>
> dknewkey --ktype ed25519 anothernewkey
>
> will provide both the private key file (.key suffix) and a file with the
> DKIM public key record to be published DNS (.dns suffix). Ed25519 keys do
> not have variable bit lengths.
>
> and used that generator accordingly.
>
> in my deploy scripts, i renamed the xxx.key to xxx.key.pem, for
> consistency.
>
> didn't think that naming would matter, and clearly missed that it's not
> actually .pem to begin with.
>
> a self-inflicted wound!
>
> i'll get that cleaned-up & see ...

OK, If it's not really a pem file, just has the extension, then that should be
fine.

For some reason dkimpy is not liking your private key. That's what that error
indicates. If you set up for ed25119 only and not RSA do you get the same
error?

Revision history for this message
pgnd (pgnd) wrote :
Download full text (8.9 KiB)

pebkac. got outbound signing apparently sorted.

with

 key_table_ed25519
  dkim-b2aXXXXXXXXXX44f-name.example.com example.com:dkim-b2aXXXXXXXXXX44f-ed25519:/etc/dkimpy-milter/sec/dkim.1637753119.1635724800.1651968000.example.com.ed25519.key

 key_table_rsa
  dkim-b2aXXXXXXXXXX44f-name.example.com example.com:dkim-b2aXXXXXXXXXX44f-rsa:/etc/dkimpy-milter/sec/dkim.1637753119.1635724800.1651968000.example.com.rsa.key.pem

 signing_table
  *@example.com dkim-b2aXXXXXXXXXX44f-name.example.com

verifying, my local data

 dig +short TXT dkim-b2aXXXXXXXXXX44f-ed25519._domainkey.example.com
  "v=DKIM1; k=ed25519; p=h6tXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXtZQ=
;"

 dig +short TXT dkim-b2aXXXXXXXXXX44f-rsa._domainkey.example.com
  "v=DKIM1; k=rsa; h=sha256; s=email; t=s;" "p=MIIXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" "XXXXXQAB
;"

& matches propagated,

 dig +short TXT dkim-b2aXXXXXXXXXX44f-ed25519._domainkey.example.com @1.1.1.1
  "v=DKIM1; k=ed25519; p=h6tXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXtZQ=
;"

 dig +short TXT dkim-b2aXXXXXXXXXX44f-rsa._domainkey.example.com @1.1.1.1
  "v=DKIM1; k=rsa; h=sha256; s=email; t=s;" "p=MIIXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" "XXXXXQAB
;"

now, @ outbound log, dkimpy-milter appears happy,

 2021-11-24T06:46:51.507842-05:00 mx dkimpy-milter[7121]: 4HzfP73128z3N: rsa-sha256 DKIM signature added (s=dkim-b2aXXXXXXXXXX44f-rsa d=example.com)
 2021-11-24T06:46:51.508123-05:00 mx dkimpy-milter[7121]: 4HzfP73128z3N: ed25519-sha256 DKIM signature added (s=dkim-b2aXXXXXXXXXX44f-ed25519 d=example.com)

verifying, this rfc

 A New Cryptographic Signature Method for DomainKeys Identified Mail (DKIM)
 https://datatracker.ietf.org/doc/html/rfc8463

states

 https://datatracker.ietf.org/doc/html/rfc8463#section-5

  5. Choice and Strength of Keys and Algorithms

     Section 3.3 of [RFC6376] describes DKIM's hash and signature
     algorithms. It is updated as follows:

     Signers SHOULD implement and verifiers MUST implement the Ed25519-SHA256 algorithm.
                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

checking,

(1) headers, rec'd @ fastmail --> "unsupported algorithm ed25519-sha256"

 Authentication-Results: mx6.messagingengine.com;
    dkim=invalid (unsupported algorithm ed25519-sha256, 0-bit key)
      header.d=example.com <email address hidden>
      header.b=orr2iQuy header.a=- header.s=dkim-b2aXXXXXXXXXX44f-ed25519
      x-bits=0;
    dkim=pass (2048-bit rsa key sha256) heade...

Read more...

Revision history for this message
Scott Kitterman (kitterman) wrote :

RFC 8463 support is still somewhat spotty. I've been signing email from my domains with both RSA and ed25119 since before we finished the RFC and haven't noticed any negative effects from doing so (there's an RFC 6376 DKIM requirement to ignore signatures with unknown algorithms that everyone seems to follow).

I'm going to close this as invalid then. If you have any documentation improvement suggests to help the next person along avoid problems, please reopen the bug and provide specifics. Thanks.

Changed in dkimpy-milter:
status: New → Invalid
Revision history for this message
Scott Kitterman (kitterman) wrote :

I've also added code to catch this error and provide a better error message for the next dkimpy release:

https://git.launchpad.net/dkimpy/commit/?id=6dcaaac7123cd3d703e4e2f3c06ddbe1b51ce555

Revision history for this message
pgnd (pgnd) wrote :

> there's an RFC 6376 DKIM requirement to ignore signatures with unknown algorithms that everyone seems to follow

that's helpful to know

> I'm going to close this as invalid then.

+1

> If you have any documentation improvement suggests to help the next person along avoid problems, please reopen the bug and provide specifics

mostly, just this^ above, for me anyway. in particular, that you "haven't noticed any negative effects from doing so", despite the missing support for ed25519 at some of the 'usual suspects' ...

for those interested,

 https://dkimvalidator.com/

correctly supports/verifies ed25519 dkim sigs

for a dkimpy-milter dual-signed msg,

 2021-11-25T09:15:31.451275-05:00 mx dkimpy-milter[7121]: 4C4A3ea4G1z4D: rsa-sha256 DKIM signature added (s=dkim-bXXXXXXXXX-rsa d=example.com)
 2021-11-25T09:15:31.464613-05:00 mx dkimpy-milter[7121]: 4C4A3ea4G1z4D: ed25519-sha256 DKIM signature added (s=dkim-bXXXXXXXXX-ed25519 d=example.com)

@ dkimvalidator, ed25519 -- as expected if present & valid -- takes precedence.
verifier result,

 DKIM Information:

 DKIM Signature

 Message contains this DKIM Signature:
!! DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed;
  d=example.com; <email address hidden>; q=dns/txt;
  s=dkim-bXXXXXXXXX-ed25519; t=1637852967; h=message-id : date :
  reply-to : from : to : subject : content-type :
  content-transfer-encoding : from;
  bh=ab...;
  b=cD...
  i1...
 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
  d=example.com; <email address hidden>; q=dns/txt;
  s=dkim-bXXXXXXXXX-rsa; t=1637852967; h=message-id : date :
  reply-to : from : to : subject : content-type :
  content-transfer-encoding : from;
  bh=ab...;
  b=Y3...

 Signature Information:
 v= Version: 1
!! a= Algorithm: ed25519-sha256
 c= Method: relaxed/relaxed
 d= Domain: example.com
 s= Selector: dkim-bXXXXXXXXX-ed25519
 q= Protocol: dns/txt
 bh= ab...
 h= Signed Headers: message-id : date :
  reply-to : from : to : subject : content-type :
  content-transfer-encoding : from
 b= Data: cD...
  i1...
 Public Key DNS Lookup

!! Building DNS Query for dkim-bXXXXXXXXX-ed25519._domainkey.example.com
!! Retrieved this publickey from DNS: v=DKIM1; k=ed25519; p=h6...=;
 Validating Signature

!! result = pass
 Details:

Revision history for this message
Ike Johnson-Woods (notactuallyterry) wrote :

This error still occurs with dual-signing configured without a signing table, like so:

KeyFile /mnt/data/config/dkim/rsa.key
Selector c5s-rsa

KeyFileEd25519 /mnt/data/config/dkim/ed25519.key
SelectorEd25519 c5s-ed

Is this sort of configuration supported, or would you recommend just migrating to signing tables?

Revision history for this message
Scott Kitterman (kitterman) wrote :

It is supported and works for me. That's almost exactly what I use:

Domain kitterman.com
KeyFile /etc/mail/dkim/201903r.key
Selector 201903r
KeyFileEd25519 /etc/mail/dkim/201903e.key
SelectorEd25519 201903e

What's the exact error you're getting?

Revision history for this message
pgnd (pgnd) wrote :

> RFC 8463 support is still somewhat spotty.

just fyi: response from Fastmail's authentication_milter proj,

"ed25519 support needs to be added to Mail::DKIM first, it's on the to do list, but there are many things above it."

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.