Merge ~mirespace/ubuntu/+source/libmail-dkim-perl:reverting-upstream-debian-ed25519-noble-proposed into ubuntu/+source/libmail-dkim-perl:ubuntu/devel

Proposed by Miriam España Acebal
Status: Rejected
Rejected by: Andreas Hasenack
Proposed branch: ~mirespace/ubuntu/+source/libmail-dkim-perl:reverting-upstream-debian-ed25519-noble-proposed
Merge into: ubuntu/+source/libmail-dkim-perl:ubuntu/devel
Diff against target: 1764 lines (+1689/-3)
9 files modified
debian/changelog (+9/-0)
debian/control (+2/-3)
debian/patches/0001-Revert-Ed25519-Add-test-for-missing-public-key.patch (+94/-0)
debian/patches/0002-Revert-Refactor-and-cleanup-some-ed25519-code.patch (+496/-0)
debian/patches/0003-Revert-set-rsa-ed25519-type.patch (+84/-0)
debian/patches/0004-Revert-added-ed25519-signing-support.patch (+327/-0)
debian/patches/0005-Revert-added-support-for-verifying-Ed25519-signature.patch (+578/-0)
debian/patches/0006-Revert-Debian-support-for-ed25519.patch (+93/-0)
debian/patches/series (+6/-0)
Reviewer Review Type Date Requested Status
Andreas Hasenack Disapprove
Ubuntu Sponsors Pending
Canonical Server Reporter Pending
Review via email: mp+460681@code.launchpad.net

Description of the change

Hi team,

I'm dropping lybcriptx-perl support (dependencies and related upstream commits) to avoid a component mismatched situation temporarily while packaging New libcrypt-openssl-ed25519-perl package [1]. I'll update the Releases Notes for Noble once this change is accepted.

The patches correspond to this PR in upstream:

https://github.com/fastmail/mail-dkim/pull/18/commits

but, looking into the complete history, you can find these commits where added to a branch created by the maintainer and called "ed25519" which includes two more commits:

https://github.com/fastmail/mail-dkim/commits/ed25519/

The 0006-Revert-*.patch is for undoing the changes related to ed25519 (only those) added by Debian when upgrading the package to version 1.20230630 ( commit message New upstream version 1.20230630) :

https://salsa.debian.org/perl-team/modules/packages/libmail-dkim-perl/-/commit/876974a2c45f2d3ac1c71a4b43b70055fba66f4f

The changes in the code are only adding the use of ed25519, not affecting the use from other third packages of the existing rsa-sha256 algorithm, making a distinction between 'rsa' or 'ed25519' for selecting the correct algorithm.

PPA for this is:

ppa:mirespace/libmail-dkim-perl-no-libcryptx-perl
https://launchpad.net/~mirespace/+archive/ubuntu/libmail-dkim-perl-no-libcryptx-perl

Test passed locally:
autopkgtest [13:55:19]: @@@@@@@@@@@@@@@@@@@@ summary
autodep8-perl-build-deps PASS
autodep8-perl PASS (superficial)
autodep8-perl-recommends PASS (superficial)

Also, they ran in the infra with good results (i386 not passing is known):

https://autopkgtest.ubuntu.com/results/autopkgtest-noble-mirespace-libmail-dkim-perl-no-libcryptx-perl/?format=plain

 ✅ libmail-dkim-perl on noble for amd64 @ 19.02.24 08:59:17
      • Log: https://autopkgtest.ubuntu.com/results/autopkgtest-noble-mirespace-libmail-dkim-perl-no-libcryptx-perl/noble/amd64/libm/libmail-dkim-perl/20240219_085917_d304c@/log.gz

 ✅ libmail-dkim-perl on noble for arm64 @ 19.02.24 09:35:18
      • Log: https://autopkgtest.ubuntu.com/results/autopkgtest-noble-mirespace-libmail-dkim-perl-no-libcryptx-perl/noble/arm64/libm/libmail-dkim-perl/20240219_093518_1a71a@/log.gz

 ✅ libmail-dkim-perl on noble for armhf @ 19.02.24 09:04:19
      • Log: https://autopkgtest.ubuntu.com/results/autopkgtest-noble-mirespace-libmail-dkim-perl-no-libcryptx-perl/noble/armhf/libm/libmail-dkim-perl/20240219_090419_1fb9a@/log.gz

✅ libmail-dkim-perl on noble for ppc64el @ 19.02.24 09:01:02
      • Log: https://autopkgtest.ubuntu.com/results/autopkgtest-noble-mirespace-libmail-dkim-perl-no-libcryptx-perl/noble/ppc64el/libm/libmail-dkim-perl/20240219_090102_81f0d@/log.gz

✅ libmail-dkim-perl on noble for s390x @ 19.02.24 09:19:56
      • Log: https://autopkgtest.ubuntu.com/results/autopkgtest-noble-mirespace-libmail-dkim-perl-no-libcryptx-perl/noble/s390x/libm/libmail-dkim-perl/20240219_091956_7991c@/log.gz

And all building tests passed:

All tests successful.
Files=19, Tests=455, 2 wallclock secs ( 0.08 usr 0.05 sys + 1.43 cusr 0.40 csys = 1.96 CPU)
Result: PASS

Checking spamassassin's tests again this libmail-dkim-perl was also OK:

$ autopkgtest -U -s --add-apt-source="deb [trusted=yes] https://ppa.launchpadcontent.net/mirespace/libmail-dkim-perl-no-libcryptx-perl/ubuntu noble main" spamassassin -- qemu /media/miriam/extension/Images/autopkgtest-noble-amd64.img

[...]
autopkgtest [16:51:09]: @@@@@@@@@@@@@@@@@@@@ summary
spamassassin.nospam PASS
spamassassin.spam PASS
daemon PASS

And looking into the building tests of spamassassin, the dkim test is disabled because it could be flaky due to network issues. But, I manually disabled the net verification (commenting line 19 in t/dkim.t) and I launched the test with the libmail-dkim-perl package proposed here:

All tests successful.
Files=1, Tests=258, 16 wallclock secs ( 0.03 usr 0.02 sys + 3.82 cusr 0.15 csys = 4.02 CPU)
Result: PASS

Complete log at https://pastebin.ubuntu.com/p/gjGdCrB9hF/

Package installed :

root@Nspamassasin-dkim-no-cryptx:~/spamassassin# dpkg -l libmail-dkim-perl | grep dkim
ii libmail-dkim-perl 1.20240124-1ubuntu1+ppa1 all module to cryptographically identify the sender of email

without libcryptx-perl:

root@Nspamassasin-dkim-no-cryptx:~/spamassassin# apt-cache policy libcryptx-perl
libcryptx-perl:
  Installed: (none)
  Candidate: 0.080-2build1
  Version table:
     0.080-2build1 500
        500 http://archive.ubuntu.com/ubuntu noble/universe amd64 Packages

Please, review and sponsor if LGTY. Thanks in advance (also, for your time reviewing this)!

[1] https://bugs.launchpad.net/ubuntu/+source/libcryptx-perl/+bug/2046154/comments/6

To post a comment you must log in.
Revision history for this message
Andreas Hasenack (ahasenack) wrote (last edit ):

I still have to go over this in more detail, but my first question (and sorry if I missed the answer somewhere), is about the reverse dependencies of libmail-dkim-perl:
$ apt-cache rdepends libmail-dkim-perl
libmail-dkim-perl
Reverse Depends:
  sympa
  amavisd-new
  libmail-dmarc-perl
  spamassassin

What about sympa and amavisd-new, do they indirectly rely on libcryptx-perl, or specifically, on the ed25519 code? Did you also rebuild these reverse dependencies, and their tests?

Revision history for this message
Miriam España Acebal (mirespace) wrote :

Hi Andreas!

> I still have to go over this in more detail, but my first question (and sorry
> if I missed the answer somewhere)

Nothing to be sorry about... Maybe I missed this question in the standup :$.

> What about sympa and amavisd-new, do they indirectly rely on libcryptx-perl,
> or specifically, on the ed25519 code? Did you also rebuild these reverse
> dependencies, and their tests?

Good point (as ever) ! I'm on it with the tests and checking the code of those reverse dependencies to look for Mail::Dkim inclusions and calls to any removed code in this MP.

I'll go back to you with the conclusions... thanks Andreas!

Revision history for this message
Miriam España Acebal (mirespace) wrote (last edit ):
Download full text (6.0 KiB)

TL;DR: Checking that amavisd-new or sympa still work ok when dropping this change: OK

All tested against the package in the ppa.

A. Code Insights: No one of the packages calls directly or indirectly the added (and removed here) code.

In both cases, an 'ack ed25519' search doesn't return anything.

Files modified by these MP are

lib/Mail/DKIM/Signature.pm
lib/Mail/DKIM/Verifier.pm
 -- > Modified functions
       _check_and_verify_signature → private, called by finish_body
lib/Mail/DKIM/PublicKey.pm
lib/Mail/DKIM/Algorithm/ed25519_sha256.pm

A.1. Sympa:

sympa
-------------
❯ ack Mail::DKIM::Signature
❯ ack Mail::DKIM::PublicKey
❯ ack Mail::DKIM::Verifier
cpanfile
182:recommends 'Mail::DKIM::Verifier', '>= 0.37';
272:feature 'Mail::DKIM::Verifier', 'Required in order to use DKIM features (both for signature verification and signature insertion).' => sub {
273: requires 'Mail::DKIM::Verifier', '>= 0.37';

src/lib/Sympa/Message.pm
648: eval 'use Mail::DKIM::Verifier';
655: return unless $Mail::DKIM::Verifier::VERSION;
668: unless ($dkim = Mail::DKIM::Verifier->new()) {
669: $log->syslog('err', 'Could not create Mail::DKIM::Verifier');

Checking Algorithm used is rsa:

❯ ack -C2 Algorithm
src/lib/Sympa/Message.pm
502- # create a signer object
503- my $dkim = Mail::DKIM::Signer->new(
504: Algorithm => "rsa-sha256",
505- Method => "relaxed",
506- Domain => $dkim_d,
--
600- # create a signer object
601- my $arc = Mail::DKIM::ARC::Signer->new(
602: Algorithm => "rsa-sha256",
603- Chain => $arc_cv,
604- SrvId => $arc_srvid,

A.2. amavisd-new:

amavisd-new
-------------------

❯ ack Mail::DKIM::Signature
lib/Amavis/Tools.pm
116: $dkim->add_signature( Mail::DKIM::Signature->new(

lib/Amavis/DKIM.pm
27:use Mail::DKIM::Signature;
336:# returning them as a list of Mail::DKIM::Signature objects
694: $dkim->add_signature( Mail::DKIM::Signature->new(
838: # map a Mail::DKIM::Signature result into an RFC 7601 result value
❯ ack Mail::DKIM::PublicKey
❯ ack Mail::DKIM::Verifier
lib/Amavis.pm
900: Net::Patricia Net::LDAP Mail::SpamAssassin Mail::DKIM::Verifier
6221: if (!defined $dns_resolver && Mail::DKIM::Verifier->VERSION >= 0.40) {
6223: # of Mail::DKIM::Verifier; this avoids repeating initializations
6254: $dkim_verifier = Mail::DKIM::Verifier->new;

lib/Amavis/SpamControl/SpamAssassin.pm
123: push(@modules, qw(Mail::DKIM Mail::DKIM::Verifier Net::DNS::Resolver))

lib/Amavis/Tools.pm
139: my $dkim_verifier = Mail::DKIM::Verifier->new;
140: $dkim_verifier or die "Could not create a Mail::DKIM::Verifier object";

lib/Amavis/DKIM.pm
24:use Mail::DKIM::Verifier 0.31;

Checking Algorithm used is rsa:

❯ ack -C2 Algorithm
lib/Amavis/Tools.pm
116- $dkim->add_signature( Mail::DKIM::Signature->new(
117- Selector => $selector_ace, Domain => $domain_ace,
118: Method => 'simple/simple', Algorithm => 'rsa-sha256',
119- Timestamp => int($now), Expiration => int($now)+24*3600, Key => $key,
120- )); under;

lib/Amavis/DKIM.pm
299-
300-# a CustomSigner callback routine passed to Mail::DKIM in place of a key;
301:# the ro...

Read more...

Revision history for this message
Andreas Hasenack (ahasenack) wrote :

So I'm looking at this, and here are my concerns:

a) complex delta
These patches look like they will be hard to carry forward. Even though we are unlikely to see big changes in noble SRUs, and there they should be more maintainable, this is delta that will be hard to maintain post-noble.

b) we are making a big change to a package
Ed25519 was announced by upstream as part of the 1.20230630 release. Except, in Ubuntu, it's not. configure-like and other version checks might be assuming that after this version, Ed25519 support is there for granted. But not in Ubuntu. In other words, we are deviating quite harshly from upstream and removing a feature they added more than a year ago. Granted, most good such checks will look for the actual feature being present, and not just a version number, but still.

c) there is no guarantee that we will benefit from this work
For this to be complete, we still need the MIR LP: #2023971 to be complete. It's currently in the security review queue, and it might come out from there as a +1 or a -1.

We currently have these versions in noble:

 libmail-dkim-perl | 1.20230212-1 | noble | source
 libmail-dkim-perl | 1.20240124-1 | noble-proposed | source

The upstream change that added Ed25519 support is in 1.20230630, which mean it's *NOT* in noble release at the moment, only noble-proposed.

I propose that we kick out 1.20240124-1 from noble-proposed, and keep the one in noble-release. We can either add this package to the sync-blocklist[1], or upload a no-change rebuild with an ubuntu suffix to block it from syncing that way. I seem to remember there was a discussion on a suitable suffix for such changes, something like adding "maysync" or similar. We can find that, I think it was used recently in an MP in the server team even, for dns root data?

Yes:

 dns-root-data | 2023112702~willsync1 | noble | source, all

But maybe for now, just before FF, we should add a block to it, just to be safe. Although, if we do nothing, it will just stay in proposed without migrating...

Now, if there is something in newer libmail-dkim-perl that we want, maybe the plan above doesn't work so well. Or we could cherry-pick what we want that is in newer versions only.

So, what do you think?

1. https://code.launchpad.net/~ubuntu-archive/+git/sync-blocklist

review: Needs Information
Revision history for this message
Miriam España Acebal (mirespace) wrote :

Thanks Andreas!

It makes perfect sense for a user to trust that a new package version will come with all the features announced upstream.... thanks for bringing up this point.

I checked spamassassin versions and we are in 4.0.0 since Mantic, so new features that can come in -proposed libmail-dkim-perl version are not in use yet:

 spamassassin | 3.4.6-1ubuntu0.22.04.1 | jammy-updates | source, all
 spamassassin | 4.0.0-7ubuntu1 | mantic | source, all
 spamassassin | 4.0.0-8ubuntu1 | noble | source, all

for libmail-dmar-perl is the same case:

 libmail-dmarc-perl | 1.20230215-1 | mantic/universe | source, all
 libmail-dmarc-perl | 1.20230215-1 | noble/universe | source, all

Only for the records, the changes that come with the dkim -proposed version are:

1.20240124 2024-01-24 UTC
  * ARC: Return fail for any ARC set with an instance number greater than 50.
    This brings ARC verification in line with DKIM verification limits.

1.20230911 2023-09-11 UTC
  * Option to add custom tags to generated ARC signatures and seals

1.20230630 2023-06-30 UTC
  * Add support for Ed25519 signature types
    Thanks to Matthäus Wander @mwander
  * Option to add custom tags to generated signatures

So I'm okay with adding libmail-dkim-perl to the sync-blocklist.

Revision history for this message
Andreas Hasenack (ahasenack) wrote :

Ok, the "maysync" or "willsync" ideas don't apply here, because the version in noble is way lower then debian unstable:

1.20230212-1 vs 1.20240124-1

Also, the sync blocklist is meant for more permanent blocks, and I don't think we will want to block this package forever.

So my suggestion is, if we all agree on this plan, to:

- remove libmail-dkim-perl 1.20240124-1 from noble-proposed
- prepare and upload libmail-dkim-perl 1.20230212-1ubuntu1 with no changes. The "ubuntu1" suffix will block it from syncing

Revision history for this message
Miriam España Acebal (mirespace) wrote :

MP for blocking is here: https://code.launchpad.net/~mirespace/+git/sync-blocklist/+merge/461273
(I didn't say anything in #ubuntu-release yet; I am waiting for comments from Christian)

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

Thanks Andreas, this really is a much more maintainable approach to this.
The current version as it is not too old but would get the rest of the stack resolved.
I'd be ok on either sync-blockist or delta to avoid a sync.

I'm already +0.99 on this, but let me ask one crucial question though...

The intent originally was to add back Ed25519 once we managed to create a wrapper we'd trust.
But if we now hold back 1.20240124-1, we'd have a much bigger change to "later add Ed25519".
As we'd then need to go to "at least 1.20230630 for the general infrastructure and then adopt it to use the alternative library for that encryption.

So we'd buy an easier current time, for a more complex future.

Yet OTOH the success, acceptance and all that of the to be created wrapper isn't entirely certain.
We are not taking away anything, it is already without Ed25519, no loss on upgrade. We'd just have that feature later.

And while intention is well meant - there still is the chance we need to decide later, "yeah Ed25519 will only be added in 24.10 but not backported".

With that in mind I'm adding another +0.01 for not spending effort now which might end up being totally different than we thought.

Objections after I forced that thought to be present in your mind?

Revision history for this message
Miriam España Acebal (mirespace) wrote :

Hi Andreas, Christian:

Adding here the third scenario (blocking by suffix):

https://code.launchpad.net/~mirespace/ubuntu/+source/libmail-dkim-perl/+git/libmail-dkim-perl/+merge/461344

As the sync-blocklist MP.

Both are in WIP, but ready. If I'm OOO after the decision on this is taken, feel free to mark Needs Review and Approve/Reject depending on the taken decision.

About the complexity in the long-term: how feasible would it be to upgrade to a new version of this package with new features in noble as LTS? It sounds like we would need a SRU exception for only once... Oh, I forgot Robie's comment (https://bugs.launchpad.net/ubuntu/+source/libcryptx-perl/+bug/2046154/comments/7)... so, at the end, What will the way more compatible to do the SRU to noble later?

1- This MP, removing all the patches and restoring the dependency in d/control as SRU?
2- removing the package from sync-blocklist, and doing a "sync-SRU"?
3- removing the suffix as SRU-change, and sync automatically in MM and "SRU-sync" to noble?

I don't know if a sync to a GA LTS can be done, hence my questions.

Revision history for this message
Andreas Hasenack (ahasenack) wrote :
Download full text (3.3 KiB)

> About the complexity in the long-term: how feasible would it be to upgrade to a new version of this
> package with new features

We don't have to upgrade, we can patch the ed25519 support in. Basically the revert of you patches here.

It's still a new feature, of course, and one could argue it's a delta as complicated as the one here dropping the patches. So updating the version might be less risky. Both scenarios, however, will require an FFe for noble. Personally, I would prefer upgrading to 1.20240124-1 when the time comes.

So let's think about the scenarios:

a) Proceed as planned with this MP, which means:
- remove Ed25519 support from src:libmail-dkim-perl now, and upload
- that will make src:libmail-dkim-perl migrate
- feature freeze happens without Ed25519 support

Then:
- fingers crossed that security ACKs MIR LP: #2023971 for src:libmail-dmarc-perl
- the Ed25519 perl+openssl wrapper happens, passes NEW review, goes into noble
- we restore Ed25519 support in src:libmail-dkim-perl by dropping these patches, get an FFe, upload to noble
- change src:spamassassin to again recommend (instead of suggest) bin:libmail-dmarc-perl (its MIR was supposedly accepted above)

b) Revert to src:libmail-dkim-perl 1.20230212 in noble, without Ed25519 support
- remove src:libmail-dkim-perl 1.20240124-1 from noble-proposed
- upload src:libmail-dkim-perl 1.20230212-1ubuntu to block syncs
- feature freeze happens without Ed25519 support

Then:
- fingers crossed that security ACKs MIR LP: #2023971 for src:libmail-dmarc-perl
- the Ed25519 perl+openssl wrapper happens, passes NEW review, goes into noble
- we restore Ed25519 support in src:libmail-dkim-perl. Either updating to 1.20240124, or patching Ed25519 in taken from the 1.20230630 version. FFe required
- change src:spamassassin to again recommend (instead of suggest) bin:libmail-dmarc-perl (its MIR was supposedly accepted above)

So.

If all goes to plan, in *both* cases we will need a FFe for src:libmail-dkim-perl with the Ed25519 feature put back, either via a patch, or a version bump to at least 1.20230630, or preferably (just because it's the sync from debian) 1.20240124-1.

If something fails along the way (MIR is not granted for src:libmail-dmarc-perl, or the new openssl ed25519 perl wrapper doesn't happen in time, or is not reviewed in NEW in time, etc), then we have differences.

In the failed (a) case, we will have in noble a src:libmail-dkim-perl package with Ed25519 patched out. That delta is unlikely to apply cleanly on version upgrades, but that shouldn't happen in noble SRUs. This has the "unexpected" feeling (to me) of a newer version of a package with a feature dropped by us as a delta. If we manage to unfail things after noble was released, an SRU would just remove that patch, and by that, add a new feature.

In the failed (b) case, we will have in noble a normal src:libmail-dkim-perl package, just behind debian, without Ed25519. After we "unfail" this, the SRU would be to add a feature by either adding ed25519 via patches, or bumping the version. This might be psychological, but personally I feel that removing patches has less risk than adding them, or bumping the version.

If we...

Read more...

Revision history for this message
Andreas Hasenack (ahasenack) wrote :

Let's take a look at the patches, while we are at it (inline).

Revision history for this message
Andreas Hasenack (ahasenack) wrote :

Oh, and after looking more closely at the reverts, and I think I haven't mentioned this before: there is risk in us missing something in these reverts, or later, miss something if we decide to patch ed25519 back in (instead of bumping the version).

Revision history for this message
Miriam España Acebal (mirespace) wrote :

I understand completely that the patches way could be more risky and are ugly/tedious/horrible/madness to inspection.

(ofi) I did the patches 1-5 with git format-patch -5 HEAD from marcbrashaw/ed25519 (upstream/ed25519) branch, I didn't do it manually

Revision history for this message
Andreas Hasenack (ahasenack) wrote :

We decided to go with (b) and drop[1] libmail-dkim-perl 1.20240124-1 from noble-proposed.

1. https://bugs.launchpad.net/ubuntu/+source/libmail-dkim-perl/+bug/2055198

Revision history for this message
Andreas Hasenack (ahasenack) :
review: Disapprove

Unmerged commits

4844d33... by Miriam España Acebal

changelog

e23ee2c... by Miriam España Acebal

update-maintainer

9b1b276... by Miriam España Acebal

d/control: Dropping libcryptc-perl dependency.

f5552de... by Miriam España Acebal

d/p/0006-Revert-*.patch: Reverting changes applied by debian to support ed25519

959e0c1... by Miriam España Acebal

d/patches/*-Revert-*.patch: Dropping ed25519 support while replacing
    using of libcryptx-perl as dependency. Reverting upstream changes.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/debian/changelog b/debian/changelog
index 4a792c5..edafb42 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,12 @@
1libmail-dkim-perl (1.20240124-1ubuntu1) noble; urgency=medium
2
3 * d/patches/*-Revert-*.patch: Drop ed25519 support while replacing
4 the use of libcryptx-perl as dependency. Revert upstream and debian
5 changes due to that (LP: #2046154).
6 * d/control: Drop libcryptx-perl dependency.
7
8 -- Miriam España Acebal <miriam.espana@canonical.com> Fri, 16 Feb 2024 13:20:59 +0100
9
1libmail-dkim-perl (1.20240124-1) unstable; urgency=medium10libmail-dkim-perl (1.20240124-1) unstable; urgency=medium
211
3 * Team upload.12 * Team upload.
diff --git a/debian/control b/debian/control
index 9c1240c..9bf4a65 100644
--- a/debian/control
+++ b/debian/control
@@ -1,12 +1,12 @@
1Source: libmail-dkim-perl1Source: libmail-dkim-perl
2Maintainer: Debian Perl Group <pkg-perl-maintainers@lists.alioth.debian.org>2Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
3XSBC-Original-Maintainer: Debian Perl Group <pkg-perl-maintainers@lists.alioth.debian.org>
3Uploaders: Magnus Holmgren <holmgren@debian.org>4Uploaders: Magnus Holmgren <holmgren@debian.org>
4Section: perl5Section: perl
5Testsuite: autopkgtest-pkg-perl6Testsuite: autopkgtest-pkg-perl
6Priority: optional7Priority: optional
7Build-Depends: debhelper-compat (= 13)8Build-Depends: debhelper-compat (= 13)
8Build-Depends-Indep: libcrypt-openssl-rsa-perl <!nocheck>,9Build-Depends-Indep: libcrypt-openssl-rsa-perl <!nocheck>,
9 libcryptx-perl <!nocheck>,
10 libdigest-sha-perl <!nocheck>,10 libdigest-sha-perl <!nocheck>,
11 liberror-perl <!nocheck>,11 liberror-perl <!nocheck>,
12 libmail-authenticationresults-perl <!nocheck>,12 libmail-authenticationresults-perl <!nocheck>,
@@ -27,7 +27,6 @@ Architecture: all
27Depends: ${misc:Depends},27Depends: ${misc:Depends},
28 ${perl:Depends},28 ${perl:Depends},
29 libcrypt-openssl-rsa-perl,29 libcrypt-openssl-rsa-perl,
30 libcryptx-perl,
31 libdigest-sha-perl,30 libdigest-sha-perl,
32 liberror-perl,31 liberror-perl,
33 libgetopt-long-descriptive-perl,32 libgetopt-long-descriptive-perl,
diff --git a/debian/patches/0001-Revert-Ed25519-Add-test-for-missing-public-key.patch b/debian/patches/0001-Revert-Ed25519-Add-test-for-missing-public-key.patch
34new file mode 10064433new file mode 100644
index 0000000..71b97c9
--- /dev/null
+++ b/debian/patches/0001-Revert-Ed25519-Add-test-for-missing-public-key.patch
@@ -0,0 +1,94 @@
1From d7cd937e612f44d8862999f4a8894384ac8eb8c1 Mon Sep 17 00:00:00 2001
2From: Miriam Espana Acebal <miriam.espana@canonical.com>
3Date: Fri, 16 Feb 2024 13:11:48 +0100
4Subject: [PATCH 1/5] Revert "Ed25519: Add test for missing public key"
5
6This reverts commit 1d37a260ec2090aaccb3bbe6bb668d7ca1569836.
7---
8 t/FAKE_DNS.dat | 1 -
9 t/corpus/badkey4_ed25519.txt | 16 ----------------
10 t/corpus/badkey5_ed25519.txt | 16 ----------------
11 t/verifier.t | 4 +---
12 4 files changed, 1 insertion(+), 36 deletions(-)
13 delete mode 100644 t/corpus/badkey4_ed25519.txt
14 delete mode 100644 t/corpus/badkey5_ed25519.txt
15
16diff --git a/t/FAKE_DNS.dat b/t/FAKE_DNS.dat
17index 602c13b..22e24da 100644
18--- a/t/FAKE_DNS.dat
19+++ b/t/FAKE_DNS.dat
20@@ -25,5 +25,4 @@ nonexistent._domainkey.messiah.edu NXDOMAIN
21 test3._domainkey.blackhole.messiah.edu ~~Query timed out~~
22 test3._domainkey.blackhole2.messiah.edu ~~SERVFAIL~~
23 2023-05-ed25519._domainkey.wander.science v=DKIM1; k=ed25519; p=pP+YUyRjAvKha4Oc49KAY703oLUS1NLMEuGD3IHMKww=
24-2023-05-ed25519-empty._domainkey.wander.science ""
25 invalid._domainkey.wander.science v=DKIM1; k=ed25519; p=MCowBQYDK2VwAyEA3SUqa9UbfciWkk7tlcJ9P1VD5pXAasg0JUn/OgjVbKE=
26diff --git a/t/corpus/badkey4_ed25519.txt b/t/corpus/badkey4_ed25519.txt
27deleted file mode 100644
28index 4693bc2..0000000
29--- a/t/corpus/badkey4_ed25519.txt
30+++ /dev/null
31@@ -1,16 +0,0 @@
32-DKIM-Signature: v=1; a=ed25519-sha256; q=dns/txt; c=relaxed/relaxed;
33- d=wander.science; s=2023-05-ed25519-does-not-exist; h=Subject:Content-Transfer-Encoding:
34- Content-Type:From:To:MIME-Version:Date:Message-ID:In-Reply-To:Cc:References:
35- Sender:Reply-To; bh=P//FppzGgSSJDjYgpnZ255T9+DxXvu14MiedTEyE5UY=; b=85mI8hH/s
36- TYf2w8vAF3BKeRs/7EMD8yGrrekJNcoZ8LxDd3RnpejvsG43I6vryFIx6xFmVSx65+zmxXu9/kvDg
37- ==;
38-Message-ID: <505c05af-3dd2-be13-df41-464353251933@wander.science>
39-Date: Wed, 10 May 2023 21:54:21 +0200
40-MIME-Version: 1.0
41-To: echo@mail.town
42-From: mail@wander.science
43-Content-Type: text/plain; charset=UTF-8; format=flowed
44-Content-Transfer-Encoding: 7bit
45-Subject: Test ed25519
46-
47-This is an elliptic test, with a missing key.
48diff --git a/t/corpus/badkey5_ed25519.txt b/t/corpus/badkey5_ed25519.txt
49deleted file mode 100644
50index f60f504..0000000
51--- a/t/corpus/badkey5_ed25519.txt
52+++ /dev/null
53@@ -1,16 +0,0 @@
54-DKIM-Signature: v=1; a=ed25519-sha256; q=dns/txt; c=relaxed/relaxed;
55- d=wander.science; s=2023-05-ed25519-empty; h=Subject:Content-Transfer-Encoding:
56- Content-Type:From:To:MIME-Version:Date:Message-ID:In-Reply-To:Cc:References:
57- Sender:Reply-To; bh=P//FppzGgSSJDjYgpnZ255T9+DxXvu14MiedTEyE5UY=; b=85mI8hH/s
58- TYf2w8vAF3BKeRs/7EMD8yGrrekJNcoZ8LxDd3RnpejvsG43I6vryFIx6xFmVSx65+zmxXu9/kvDg
59- ==;
60-Message-ID: <505c05af-3dd2-be13-df41-464353251933@wander.science>
61-Date: Wed, 10 May 2023 21:54:21 +0200
62-MIME-Version: 1.0
63-To: echo@mail.town
64-From: mail@wander.science
65-Content-Type: text/plain; charset=UTF-8; format=flowed
66-Content-Transfer-Encoding: 7bit
67-Subject: Test ed25519
68-
69-This is an elliptic test, with a missing key.
70diff --git a/t/verifier.t b/t/verifier.t
71index 3f802c9..90320d4 100755
72--- a/t/verifier.t
73+++ b/t/verifier.t
74@@ -2,7 +2,7 @@
75
76 use strict;
77 use warnings;
78-use Test::More tests => 111;
79+use Test::More tests => 109;
80
81 use Mail::DKIM::Verifier;
82
83@@ -167,8 +167,6 @@ test_email( "goodkey_ed25519.txt", "pass" );
84 test_email( "badkey1_ed25519.txt", "invalid" ); # key has invalid length
85 test_email( "badkey2_ed25519.txt", "fail" ); # header modified
86 test_email( "badkey3_ed25519.txt", "fail" ); # body modified
87-test_email( "badkey4_ed25519.txt", "invalid" ); # missing key
88-test_email( "badkey5_ed25519.txt", "invalid" ); # empty key
89
90 sub read_file {
91 my $srcfile = shift;
92--
932.40.1
94
diff --git a/debian/patches/0002-Revert-Refactor-and-cleanup-some-ed25519-code.patch b/debian/patches/0002-Revert-Refactor-and-cleanup-some-ed25519-code.patch
0new file mode 10064495new file mode 100644
index 0000000..10aeb9d
--- /dev/null
+++ b/debian/patches/0002-Revert-Refactor-and-cleanup-some-ed25519-code.patch
@@ -0,0 +1,496 @@
1From 3d65013b6cc172343354bfa33e59330b9b44ee57 Mon Sep 17 00:00:00 2001
2From: Miriam Espana Acebal <miriam.espana@canonical.com>
3Date: Fri, 16 Feb 2024 13:15:07 +0100
4Subject: [PATCH 2/5] Revert "Refactor and cleanup some ed25519 code"
5
6This reverts commit 86f65f4e6d7b99e759de2ea23c56e16b5e76ab15.
7---
8 Changes | 2 -
9 lib/Mail/DKIM/Algorithm/ed25519_sha256.pm | 4 +-
10 lib/Mail/DKIM/PrivateKey.pm | 161 ++++++++++----------
11 lib/Mail/DKIM/PublicKey.pm | 175 ++++++++++------------
12 4 files changed, 163 insertions(+), 179 deletions(-)
13
14diff --git a/Changes b/Changes
15index f898dc5..39b645a 100644
16--- a/Changes
17+++ b/Changes
18@@ -8,8 +8,6 @@ This file summarizes what's changed between releases of Mail-DKIM.
19 * Option to add custom tags to generated ARC signatures and seals
20
21 1.20230630 2023-06-30 UTC
22- * Add support for Ed25519 signature types
23- Thanks to Matthäus Wander @mwander
24 * Option to add custom tags to generated signatures
25
26 1.20230212 2023-02-12 UTC
27diff --git a/lib/Mail/DKIM/Algorithm/ed25519_sha256.pm b/lib/Mail/DKIM/Algorithm/ed25519_sha256.pm
28index 9a4a2f3..d97deeb 100644
29--- a/lib/Mail/DKIM/Algorithm/ed25519_sha256.pm
30+++ b/lib/Mail/DKIM/Algorithm/ed25519_sha256.pm
31@@ -1,8 +1,8 @@
32 package Mail::DKIM::Algorithm::ed25519_sha256;
33 use strict;
34 use warnings;
35-our $VERSION = '1.20240124'; # VERSION
36-# ABSTRACT: ed25519 sha256 algorithm class
37+# VERSION
38+# ABSTRACT: edd2519 sha256 algorithm class
39
40 # Copyright 2005-2006 Messiah College. All rights reserved.
41 # Jason Long <jlong@messiah.edu>
42diff --git a/lib/Mail/DKIM/PrivateKey.pm b/lib/Mail/DKIM/PrivateKey.pm
43index af08573..1a9526d 100644
44--- a/lib/Mail/DKIM/PrivateKey.pm
45+++ b/lib/Mail/DKIM/PrivateKey.pm
46@@ -15,8 +15,6 @@ our $VERSION = '1.20240124'; # VERSION
47 use base 'Mail::DKIM::Key';
48 use Carp;
49 *calculate_EM = \&Mail::DKIM::Key::calculate_EM;
50-use Crypt::OpenSSL::RSA;
51-use Crypt::PK::Ed25519;
52
53
54 sub load {
55@@ -53,86 +51,88 @@ sub load {
56 }
57
58
59-sub _convert_rsa {
60+sub convert {
61 my $self = shift;
62
63- # have to PKCS1ify the privkey because openssl is too finicky...
64- my $pkcs = "-----BEGIN RSA PRIVATE KEY-----\n";
65-
66- for ( my $i = 0 ; $i < length $self->data ; $i += 64 ) {
67- $pkcs .= substr $self->data, $i, 64;
68- $pkcs .= "\n";
69+ # Use different libs subject to key type.
70+ if ( $self->{'TYPE'} eq 'rsa' ) {
71+ use Crypt::OpenSSL::RSA;
72+ }
73+ elsif ( $self->{'TYPE'} eq 'ed25519' ) {
74+ use Crypt::PK::Ed25519;
75 }
76
77- $pkcs .= "-----END RSA PRIVATE KEY-----\n";
78+ $self->data
79+ or return;
80+
81+ if ( $self->{'TYPE'} eq 'rsa' ) {
82+
83+ # have to PKCS1ify the privkey because openssl is too finicky...
84+ my $pkcs = "-----BEGIN RSA PRIVATE KEY-----\n";
85+
86+ for ( my $i = 0 ; $i < length $self->data ; $i += 64 ) {
87+ $pkcs .= substr $self->data, $i, 64;
88+ $pkcs .= "\n";
89+ }
90+
91+ $pkcs .= "-----END RSA PRIVATE KEY-----\n";
92
93- my $cork;
94+ my $cork;
95
96- eval {
97- local $SIG{__DIE__};
98- $cork = new_private_key Crypt::OpenSSL::RSA($pkcs);
99- 1
100- } || do {
101+ eval {
102+ local $SIG{__DIE__};
103+ $cork = new_private_key Crypt::OpenSSL::RSA($pkcs);
104+ 1
105+ } || do {
106 $self->errorstr($@);
107 return;
108- };
109+ };
110
111- $cork
112- or return;
113+ $cork
114+ or return;
115
116- # segfaults on my machine
117- # $cork->check_key or
118- # return;
119+ # segfaults on my machine
120+ # $cork->check_key or
121+ # return;
122
123- $self->cork($cork);
124- return 1;
125-}
126+ $self->cork($cork);
127
128-sub _convert_ed25519 {
129- my $self = shift;
130- my $cork;
131+ }
132+ elsif ( $self->{'TYPE'} eq 'ed25519' ) {
133+ my $cork;
134
135- eval {
136- local $SIG{__DIE__};
137- $cork = new Crypt::PK::Ed25519;
138+ eval {
139+ local $SIG{__DIE__};
140+ $cork = new Crypt::PK::Ed25519;
141
142- # Prepend/append with PEM boilerplate
143- my $pem = "-----BEGIN ED25519 PRIVATE KEY-----\n";
144- $pem .= $self->data;
145- $pem .= "\n";
146- $pem .= "-----END ED25519 PRIVATE KEY-----\n";
147+ # Prepend/append with PEM boilerplate
148+ my $pem = "-----BEGIN ED25519 PRIVATE KEY-----\n";
149+ $pem .= $self->data;
150+ $pem .= "\n";
151+ $pem .= "-----END ED25519 PRIVATE KEY-----\n";
152
153- # Pass PEM text buffer
154- $cork->import_key(\$pem)
155- or die 'failed to load Ed25519 private key';
156+ # Pass PEM text buffer
157+ $cork->import_key(\$pem)
158+ or die 'failed to load Ed25519 private key';
159
160- # Alternatively, import_raw_key() could be used,
161- # but requires the 32-byte key, which must be extracted
162- # from the ASN.1 structure first.
163+ # Alternatively, import_raw_key() could be used,
164+ # but requires the 32-byte key, which must be extracted
165+ # from the ASN.1 structure first.
166
167- 1
168- } || do {
169- $self->errorstr($@);
170- return;
171- };
172+ 1
173+ } || do {
174+ $self->errorstr($@);
175+ return;
176+ };
177
178- $cork
179- or return;
180+ $cork
181+ or return;
182
183- $self->cork($cork);
184- return 1;
185-}
186+ $self->cork($cork);
187
188-sub convert {
189- my $self = shift;
190-
191- $self->data
192- or return;
193+ }
194
195- return $self->_convert_rsa if $self->{TYPE} eq 'rsa';
196- return $self->_convert_ed25519 if $self->{TYPE} eq 'ed25519';
197- self->errorstr('unsupported key type');
198- return;
199+ return 1;
200 }
201
202 #deprecated
203@@ -151,36 +151,31 @@ sub sign_sha1_digest {
204 }
205
206
207-sub _sign_digest_rsa {
208+sub sign_digest {
209 my $self = shift;
210 my ( $digest_algorithm, $digest ) = @_;
211
212- my $rsa_priv = $self->cork;
213- $rsa_priv->use_no_padding;
214- my $k = $rsa_priv->size;
215- my $EM = calculate_EM( $digest_algorithm, $digest, $k );
216- return $rsa_priv->decrypt($EM);
217-}
218+ if ( $self->{'TYPE'} eq 'rsa') {
219
220-sub _sign_digest_ed25519 {
221- my $self = shift;
222- my ( $digest_algorithm, $digest ) = @_;
223+ my $rsa_priv = $self->cork;
224+ $rsa_priv->use_no_padding;
225+
226+ my $k = $rsa_priv->size;
227+ my $EM = calculate_EM( $digest_algorithm, $digest, $k );
228+ return $rsa_priv->decrypt($EM);
229
230- my $ed = $self->cork;
231- if ( !$ed ) {
232- $@ = $@ ne '' ? "Ed25519 failed: $@" : 'Ed25519 unknown problem';
233- die;
234 }
235- return $ed->sign_message($digest);
236-}
237+ elsif ( $self->{'TYPE'} eq 'ed25519' ) {
238
239-sub sign_digest {
240- my $self = shift;
241- my ( $digest_algorithm, $digest ) = @_;
242+ my $ed = $self->cork;
243+ if ( !$ed ) {
244+ $@ = $@ ne '' ? "Ed25519 failed: $@" : 'Ed25519 unknown problem';
245+ die;
246+ }
247
248- return $self->_sign_digest_rsa($digest_algorithm, $digest) if $self->{TYPE} eq 'rsa';
249- return $self->_sign_digest_ed25519($digest_algorithm, $digest) if $self->{TYPE} eq 'ed25519';
250- die 'unsupported key type';
251+ return $ed->sign_message($digest);
252+
253+ }
254 }
255
256 __END__
257diff --git a/lib/Mail/DKIM/PublicKey.pm b/lib/Mail/DKIM/PublicKey.pm
258index bbae0e7..bd45aeb 100644
259--- a/lib/Mail/DKIM/PublicKey.pm
260+++ b/lib/Mail/DKIM/PublicKey.pm
261@@ -14,9 +14,6 @@ our $VERSION = '1.20240124'; # VERSION
262 use base ( 'Mail::DKIM::KeyValueList', 'Mail::DKIM::Key' );
263 *calculate_EM = \&Mail::DKIM::Key::calculate_EM;
264
265-use Crypt::OpenSSL::RSA;
266-use Crypt::PK::Ed25519;
267-use MIME::Base64;
268 use Mail::DKIM::DNS;
269
270 sub new {
271@@ -102,7 +99,7 @@ sub fetch_async {
272 my $self = $class->parse($strn);
273 $self->{Selector} = $prms{'Selector'};
274 $self->{Domain} = $prms{'Domain'};
275- $self->{TYPE} = $self->get_tag('k') || 'rsa';
276+ $self->{TYPE} = ( $self->get_tag('k') or 'rsa' );
277 $self->check;
278
279 return $on_success->($self);
280@@ -284,54 +281,57 @@ sub check_hash_algorithm {
281 # Create an OpenSSL public key object from the Base64-encoded data
282 # found in this public key's DNS record. The OpenSSL object is saved
283 # in the "cork" property.
284-sub _convert_rsa {
285+sub convert {
286 my $self = shift;
287- # have to PKCS1ify the pubkey because openssl is too finicky...
288- my $cert = "-----BEGIN PUBLIC KEY-----\n";
289
290- for ( my $i = 0 ; $i < length $self->data ; $i += 64 ) {
291- $cert .= substr $self->data, $i, 64;
292- $cert .= "\n";
293+ # Use different libs subject to k= tag.
294+ # Without k= tag, default to RSA to maintain prior behavior
295+ my $k = ( $self->get_tag('k') or 'rsa' );
296+ if ( $k eq 'rsa' ) {
297+ use Crypt::OpenSSL::RSA;
298+ }
299+ elsif ( $k eq 'ed25519' ) {
300+ use Crypt::PK::Ed25519;
301+ use MIME::Base64;
302 }
303
304- $cert .= "-----END PUBLIC KEY-----\n";
305+ $self->data
306+ or return;
307
308- my $cork = Crypt::OpenSSL::RSA->new_public_key($cert)
309- or die 'unable to generate public key object';
310+ if ( $k eq 'rsa' ) {
311+ # have to PKCS1ify the pubkey because openssl is too finicky...
312+ my $cert = "-----BEGIN PUBLIC KEY-----\n";
313
314- # segfaults on my machine
315- # $cork->check_key or
316- # return;
317+ for ( my $i = 0 ; $i < length $self->data ; $i += 64 ) {
318+ $cert .= substr $self->data, $i, 64;
319+ $cert .= "\n";
320+ }
321
322- $self->cork($cork);
323- return 1;
324-}
325+ $cert .= "-----END PUBLIC KEY-----\n";
326
327-sub _convert_ed25519 {
328- my $self = shift;
329- my $cork = Crypt::PK::Ed25519->new
330- or die 'unable to generate Ed25519 public key object';
331+ my $cork = Crypt::OpenSSL::RSA->new_public_key($cert)
332+ or die 'unable to generate public key object';
333
334- my $keybin = decode_base64($self->data);
335- $cork->import_key_raw($keybin, 'public')
336- or die 'failed to load Ed25519 public key';
337+ # segfaults on my machine
338+ # $cork->check_key or
339+ # return;
340
341- $self->cork($cork);
342- return 1;
343-}
344+ $self->cork($cork);
345
346-sub convert {
347- my $self = shift;
348+ }
349+ elsif ( $k eq 'ed25519' ) {
350+ my $cork = Crypt::PK::Ed25519->new
351+ or die 'unable to generate Ed25519 public key object';
352
353- my $k_tag = $self->get_tag('k');
354- $k_tag = 'rsa' unless defined $k_tag;
355+ my $keybin = decode_base64($self->data);
356+ $cork->import_key_raw($keybin, 'public')
357+ or die 'failed to load Ed25519 public key';
358
359- $self->data
360- or return;
361+ $self->cork($cork);
362+
363+ }
364
365- return $self->_convert_rsa if $k_tag eq 'rsa';
366- return $self->_convert_ed25519 if $k_tag eq 'ed25519';
367- die 'unsupported key type';
368+ return 1;
369 }
370
371 sub verify {
372@@ -436,76 +436,67 @@ sub verify_sha1_digest {
373 return $self->verify_digest( 'SHA-1', $digest, $signature );
374 }
375
376-sub _verify_digest_rsa {
377+# verify_digest() - returns true if the digest verifies, false otherwise
378+#
379+# if false, $@ is set to a description of the problem
380+#
381+sub verify_digest {
382 my $self = shift;
383 my ( $digest_algorithm, $digest, $signature ) = @_;
384
385- my $rsa_pub = $self->cork;
386- if ( !$rsa_pub ) {
387- $@ = $@ ne '' ? "RSA failed: $@" : 'RSA unknown problem';
388- $@ .= ", s=$self->{Selector} d=$self->{Domain}";
389- return;
390- }
391-
392- $rsa_pub->use_no_padding;
393- my $verify_result = $rsa_pub->encrypt($signature);
394+ my $k_tag = $self->get_tag('k') || 'rsa';
395
396- my $k = $rsa_pub->size;
397- my $expected = calculate_EM( $digest_algorithm, $digest, $k );
398- return 1 if ( $verify_result eq $expected );
399+ if ($k_tag eq 'rsa') {
400+ my $rsa_pub = $self->cork;
401+ if ( !$rsa_pub ) {
402+ $@ = $@ ne '' ? "RSA failed: $@" : 'RSA unknown problem';
403+ $@ .= ", s=$self->{Selector} d=$self->{Domain}";
404+ return;
405+ }
406
407- # well, the RSA verification failed; I wonder if the RSA signing
408- # was performed on a different digest value? I think we can check...
409+ $rsa_pub->use_no_padding;
410+ my $verify_result = $rsa_pub->encrypt($signature);
411
412- # basically, if the $verify_result has the same prefix as $expected,
413- # then only the digest was different
414+ my $k = $rsa_pub->size;
415+ my $expected = calculate_EM( $digest_algorithm, $digest, $k );
416+ return 1 if ( $verify_result eq $expected );
417
418- my $digest_len = length $digest;
419- my $prefix_len = length($expected) - $digest_len;
420- if (
421- substr( $verify_result, 0, $prefix_len ) eq
422- substr( $expected, 0, $prefix_len ) )
423- {
424- $@ = 'message has been altered';
425- return;
426- }
427+ # well, the RSA verification failed; I wonder if the RSA signing
428+ # was performed on a different digest value? I think we can check...
429
430- $@ = 'bad RSA signature';
431- return;
432-}
433+ # basically, if the $verify_result has the same prefix as $expected,
434+ # then only the digest was different
435
436-sub _verify_digest_ed25519 {
437- my $self = shift;
438- my ( $digest_algorithm, $digest, $signature ) = @_;
439+ my $digest_len = length $digest;
440+ my $prefix_len = length($expected) - $digest_len;
441+ if (
442+ substr( $verify_result, 0, $prefix_len ) eq
443+ substr( $expected, 0, $prefix_len ) )
444+ {
445+ $@ = 'message has been altered';
446+ return;
447+ }
448
449- my $ed = $self->cork;
450- if ( !$ed ) {
451- $@ = $@ ne '' ? "Ed25519 failed: $@" : 'Ed25519 unknown problem';
452- $@ .= ", s=$self->{Selector} d=$self->{Domain}";
453+ $@ = 'bad RSA signature';
454 return;
455- }
456
457- my $verify_result = $ed->verify_message($signature, $digest);
458- return $verify_result if ($verify_result == 1);
459+ } elsif ($k_tag eq 'ed25519') {
460
461- $@ = 'bad Ed25519 signature';
462- return;
463-}
464+ my $ed = $self->cork;
465+ if ( !$ed ) {
466+ $@ = $@ ne '' ? "Ed25519 failed: $@" : 'Ed25519 unknown problem';
467+ $@ .= ", s=$self->{Selector} d=$self->{Domain}";
468+ return;
469+ }
470
471-# verify_digest() - returns true if the digest verifies, false otherwise
472-#
473-# if false, $@ is set to a description of the problem
474-#
475-sub verify_digest {
476- my $self = shift;
477- my ( $digest_algorithm, $digest, $signature ) = @_;
478+ my $verify_result = $ed->verify_message($signature, $digest);
479+ return $verify_result if ($verify_result == 1);
480
481- my $k_tag = $self->get_tag('k') || 'rsa';
482+ $@ = 'bad Ed25519 signature';
483+ return;
484+
485+ }
486
487- return $self->_verify_digest_rsa($digest_algorithm, $digest, $signature) if $k_tag eq 'rsa';
488- return $self->_verify_digest_ed25519($digest_algorithm, $digest, $signature) if $k_tag eq 'ed25519';
489- $@ = 'unsupported key type';
490- return;
491 }
492
493 1;
494--
4952.40.1
496
diff --git a/debian/patches/0003-Revert-set-rsa-ed25519-type.patch b/debian/patches/0003-Revert-set-rsa-ed25519-type.patch
0new file mode 100644497new file mode 100644
index 0000000..8e8ded8
--- /dev/null
+++ b/debian/patches/0003-Revert-set-rsa-ed25519-type.patch
@@ -0,0 +1,84 @@
1From 7f8a91d1c8643967907843e45ee75ca0ae5a2157 Mon Sep 17 00:00:00 2001
2From: Miriam Espana Acebal <miriam.espana@canonical.com>
3Date: Fri, 16 Feb 2024 13:15:15 +0100
4Subject: [PATCH 3/5] Revert "set rsa/ed25519 type"
5
6This reverts commit d146356d5f0ec41f796cc40f0db76ba400efe12a.
7---
8 lib/Mail/DKIM/PrivateKey.pm | 2 +-
9 lib/Mail/DKIM/PublicKey.pm | 6 ++----
10 lib/Mail/DKIM/Signer.pm | 6 +-----
11 3 files changed, 4 insertions(+), 10 deletions(-)
12
13diff --git a/lib/Mail/DKIM/PrivateKey.pm b/lib/Mail/DKIM/PrivateKey.pm
14index 1a9526d..ad98dd2 100644
15--- a/lib/Mail/DKIM/PrivateKey.pm
16+++ b/lib/Mail/DKIM/PrivateKey.pm
17@@ -165,7 +165,7 @@ sub sign_digest {
18 return $rsa_priv->decrypt($EM);
19
20 }
21- elsif ( $self->{'TYPE'} eq 'ed25519' ) {
22+ elsif ( $self->{'TYPE'} eq 'ed25519') {
23
24 my $ed = $self->cork;
25 if ( !$ed ) {
26diff --git a/lib/Mail/DKIM/PublicKey.pm b/lib/Mail/DKIM/PublicKey.pm
27index bd45aeb..dce1736 100644
28--- a/lib/Mail/DKIM/PublicKey.pm
29+++ b/lib/Mail/DKIM/PublicKey.pm
30@@ -25,7 +25,7 @@ sub new {
31 $self->{'GRAN'} = $prms{'Granularity'};
32 $self->{'NOTE'} = $prms{'Note'};
33 $self->{'TEST'} = $prms{'Testing'};
34- $self->{'TYPE'} = ( $prms{'Type'} or 'rsa' );
35+ #$self->{'TYPE'} = ( $prms{'Type'} or 'rsa' ); # unused
36 $self->{'DATA'} = $prms{'Data'};
37
38 bless $self, $type;
39@@ -99,9 +99,7 @@ sub fetch_async {
40 my $self = $class->parse($strn);
41 $self->{Selector} = $prms{'Selector'};
42 $self->{Domain} = $prms{'Domain'};
43- $self->{TYPE} = ( $self->get_tag('k') or 'rsa' );
44 $self->check;
45-
46 return $on_success->($self);
47 };
48
49@@ -286,7 +284,7 @@ sub convert {
50
51 # Use different libs subject to k= tag.
52 # Without k= tag, default to RSA to maintain prior behavior
53- my $k = ( $self->get_tag('k') or 'rsa' );
54+ my $k = $self->get_tag('k') || 'rsa';
55 if ( $k eq 'rsa' ) {
56 use Crypt::OpenSSL::RSA;
57 }
58diff --git a/lib/Mail/DKIM/Signer.pm b/lib/Mail/DKIM/Signer.pm
59index 7aebced..24b5285 100644
60--- a/lib/Mail/DKIM/Signer.pm
61+++ b/lib/Mail/DKIM/Signer.pm
62@@ -185,9 +185,6 @@ sub finish_body {
63 # finished canonicalizing
64 $algorithm->finish_body;
65
66- my $type = 'rsa'; # default
67- $type = 'ed25519' if ( $self->{'Algorithm'} =~ /^ed25519/ );
68-
69 # load the private key file if necessary
70 my $signature = $algorithm->signature;
71 my $key =
72@@ -196,8 +193,7 @@ sub finish_body {
73 || $self->{Key}
74 || $self->{KeyFile};
75 if ( defined($key) && !ref($key) ) {
76- $key = Mail::DKIM::PrivateKey->load( File => $key,
77- Type => $type );
78+ $key = Mail::DKIM::PrivateKey->load( File => $key );
79 }
80 $key
81 or die "no key available to sign with\n";
82--
832.40.1
84
diff --git a/debian/patches/0004-Revert-added-ed25519-signing-support.patch b/debian/patches/0004-Revert-added-ed25519-signing-support.patch
0new file mode 10064485new file mode 100644
index 0000000..7966790
--- /dev/null
+++ b/debian/patches/0004-Revert-added-ed25519-signing-support.patch
@@ -0,0 +1,327 @@
1From 74064a137e63c028a815eb24dcd8b52c616a08bc Mon Sep 17 00:00:00 2001
2From: Miriam Espana Acebal <miriam.espana@canonical.com>
3Date: Fri, 16 Feb 2024 13:15:23 +0100
4Subject: [PATCH 4/5] Revert "added ed25519 signing support."
5
6This reverts commit edd9897ee9208f41035f311d5b8443a5513a6037.
7---
8 lib/Mail/DKIM/PrivateKey.pm | 114 +++++++++---------------------------
9 lib/Mail/DKIM/PublicKey.pm | 12 ++--
10 lib/Mail/DKIM/Signer.pm | 16 ++---
11 t/signer.t | 54 +----------------
12 t/test.ed.key | 3 -
13 5 files changed, 38 insertions(+), 161 deletions(-)
14 delete mode 100644 t/test.ed.key
15
16diff --git a/lib/Mail/DKIM/PrivateKey.pm b/lib/Mail/DKIM/PrivateKey.pm
17index ad98dd2..261f866 100644
18--- a/lib/Mail/DKIM/PrivateKey.pm
19+++ b/lib/Mail/DKIM/PrivateKey.pm
20@@ -52,85 +52,42 @@ sub load {
21
22
23 sub convert {
24- my $self = shift;
25+ use Crypt::OpenSSL::RSA;
26
27- # Use different libs subject to key type.
28- if ( $self->{'TYPE'} eq 'rsa' ) {
29- use Crypt::OpenSSL::RSA;
30- }
31- elsif ( $self->{'TYPE'} eq 'ed25519' ) {
32- use Crypt::PK::Ed25519;
33- }
34+ my $self = shift;
35
36 $self->data
37 or return;
38
39- if ( $self->{'TYPE'} eq 'rsa' ) {
40-
41- # have to PKCS1ify the privkey because openssl is too finicky...
42- my $pkcs = "-----BEGIN RSA PRIVATE KEY-----\n";
43-
44- for ( my $i = 0 ; $i < length $self->data ; $i += 64 ) {
45- $pkcs .= substr $self->data, $i, 64;
46- $pkcs .= "\n";
47- }
48-
49- $pkcs .= "-----END RSA PRIVATE KEY-----\n";
50-
51- my $cork;
52-
53- eval {
54- local $SIG{__DIE__};
55- $cork = new_private_key Crypt::OpenSSL::RSA($pkcs);
56- 1
57- } || do {
58- $self->errorstr($@);
59- return;
60- };
61-
62- $cork
63- or return;
64-
65- # segfaults on my machine
66- # $cork->check_key or
67- # return;
68-
69- $self->cork($cork);
70+ # have to PKCS1ify the privkey because openssl is too finicky...
71+ my $pkcs = "-----BEGIN RSA PRIVATE KEY-----\n";
72
73+ for ( my $i = 0 ; $i < length $self->data ; $i += 64 ) {
74+ $pkcs .= substr $self->data, $i, 64;
75+ $pkcs .= "\n";
76 }
77- elsif ( $self->{'TYPE'} eq 'ed25519' ) {
78- my $cork;
79
80- eval {
81- local $SIG{__DIE__};
82- $cork = new Crypt::PK::Ed25519;
83+ $pkcs .= "-----END RSA PRIVATE KEY-----\n";
84
85- # Prepend/append with PEM boilerplate
86- my $pem = "-----BEGIN ED25519 PRIVATE KEY-----\n";
87- $pem .= $self->data;
88- $pem .= "\n";
89- $pem .= "-----END ED25519 PRIVATE KEY-----\n";
90+ my $cork;
91
92- # Pass PEM text buffer
93- $cork->import_key(\$pem)
94- or die 'failed to load Ed25519 private key';
95+ eval {
96+ local $SIG{__DIE__};
97+ $cork = new_private_key Crypt::OpenSSL::RSA($pkcs);
98+ 1
99+ } || do {
100+ $self->errorstr($@);
101+ return;
102+ };
103
104- # Alternatively, import_raw_key() could be used,
105- # but requires the 32-byte key, which must be extracted
106- # from the ASN.1 structure first.
107-
108- 1
109- } || do {
110- $self->errorstr($@);
111- return;
112- };
113-
114- $cork
115- or return;
116+ $cork
117+ or return;
118
119- $self->cork($cork);
120+ # segfaults on my machine
121+ # $cork->check_key or
122+ # return;
123
124- }
125+ $self->cork($cork);
126
127 return 1;
128 }
129@@ -155,27 +112,12 @@ sub sign_digest {
130 my $self = shift;
131 my ( $digest_algorithm, $digest ) = @_;
132
133- if ( $self->{'TYPE'} eq 'rsa') {
134-
135- my $rsa_priv = $self->cork;
136- $rsa_priv->use_no_padding;
137-
138- my $k = $rsa_priv->size;
139- my $EM = calculate_EM( $digest_algorithm, $digest, $k );
140- return $rsa_priv->decrypt($EM);
141+ my $rsa_priv = $self->cork;
142+ $rsa_priv->use_no_padding;
143
144- }
145- elsif ( $self->{'TYPE'} eq 'ed25519') {
146-
147- my $ed = $self->cork;
148- if ( !$ed ) {
149- $@ = $@ ne '' ? "Ed25519 failed: $@" : 'Ed25519 unknown problem';
150- die;
151- }
152-
153- return $ed->sign_message($digest);
154-
155- }
156+ my $k = $rsa_priv->size;
157+ my $EM = calculate_EM( $digest_algorithm, $digest, $k );
158+ return $rsa_priv->decrypt($EM);
159 }
160
161 __END__
162diff --git a/lib/Mail/DKIM/PublicKey.pm b/lib/Mail/DKIM/PublicKey.pm
163index dce1736..b7b2a49 100644
164--- a/lib/Mail/DKIM/PublicKey.pm
165+++ b/lib/Mail/DKIM/PublicKey.pm
166@@ -285,10 +285,9 @@ sub convert {
167 # Use different libs subject to k= tag.
168 # Without k= tag, default to RSA to maintain prior behavior
169 my $k = $self->get_tag('k') || 'rsa';
170- if ( $k eq 'rsa' ) {
171+ if ($k eq 'rsa') {
172 use Crypt::OpenSSL::RSA;
173- }
174- elsif ( $k eq 'ed25519' ) {
175+ } elsif ($k eq 'ed25519') {
176 use Crypt::PK::Ed25519;
177 use MIME::Base64;
178 }
179@@ -296,7 +295,7 @@ sub convert {
180 $self->data
181 or return;
182
183- if ( $k eq 'rsa' ) {
184+ if ($k eq 'rsa') {
185 # have to PKCS1ify the pubkey because openssl is too finicky...
186 my $cert = "-----BEGIN PUBLIC KEY-----\n";
187
188@@ -316,8 +315,7 @@ sub convert {
189
190 $self->cork($cork);
191
192- }
193- elsif ( $k eq 'ed25519' ) {
194+ } elsif ($k eq 'ed25519') {
195 my $cork = Crypt::PK::Ed25519->new
196 or die 'unable to generate Ed25519 public key object';
197
198@@ -492,9 +490,7 @@ sub verify_digest {
199
200 $@ = 'bad Ed25519 signature';
201 return;
202-
203 }
204-
205 }
206
207 1;
208diff --git a/lib/Mail/DKIM/Signer.pm b/lib/Mail/DKIM/Signer.pm
209index 24b5285..b1d751a 100644
210--- a/lib/Mail/DKIM/Signer.pm
211+++ b/lib/Mail/DKIM/Signer.pm
212@@ -61,21 +61,16 @@ sub init {
213 my $self = shift;
214 $self->SUPER::init;
215
216+ if ( defined $self->{KeyFile} ) {
217+ $self->{Key} ||=
218+ Mail::DKIM::PrivateKey->load( File => $self->{KeyFile} );
219+ }
220+
221 unless ( $self->{'Algorithm'} ) {
222
223 # use default algorithm
224 $self->{'Algorithm'} = 'rsa-sha1';
225 }
226-
227- my $type = 'rsa'; # default
228- $type = 'ed25519' if ( $self->{'Algorithm'} =~ /^ed25519/ );
229-
230- if ( defined $self->{KeyFile} ) {
231- $self->{Key} ||=
232- Mail::DKIM::PrivateKey->load( File => $self->{KeyFile},
233- Type => $type );
234- }
235-
236 unless ( $self->{'Method'} ) {
237
238 # use default canonicalization method
239@@ -91,7 +86,6 @@ sub init {
240 # use default selector
241 $self->{'Selector'} = 'unknown';
242 }
243-
244 }
245
246 sub finish_header {
247diff --git a/t/signer.t b/t/signer.t
248index 7cc4738..203a671 100755
249--- a/t/signer.t
250+++ b/t/signer.t
251@@ -2,7 +2,7 @@
252
253 use strict;
254 use warnings;
255-use Test::Simple tests => 35;
256+use Test::Simple tests => 31;
257
258 use Mail::DKIM::Signer;
259
260@@ -238,55 +238,3 @@ END_OF_SAMPLE
261 ok( $sigstr =~ /subject/i, "subject was signed" );
262 ok( $sigstr =~ /from/i, "from was signed" );
263 }
264-
265-{
266- my $EXPECTED_RE = qr/4goHxydMueA3ev5toKlGLc7sUrwPG/;
267-
268- my $tdir = -f "t/test.ed.key" ? "t" : ".";
269- my $keyfile = "$tdir/test.ed.key";
270- my $dkim = Mail::DKIM::Signer->new(
271- Algorithm => "ed25519-sha256",
272- Method => "relaxed",
273- Domain => "example.org",
274- Selector => "test",
275- KeyFile => $keyfile
276- );
277- ok( $dkim, "new() works" );
278-
279- my $sample_email = <<END_OF_SAMPLE;
280-From: alice <alice\@example.org>
281-Date: Wed, 12 May 2023 14:00:00 +0200
282-Subject: ed25519
283-
284-this is an elliptic test.
285-END_OF_SAMPLE
286- $sample_email =~ s/\n/\015\012/gs;
287-
288- $dkim->PRINT($sample_email);
289- $dkim->CLOSE;
290-
291- my $signature = $dkim->signature;
292- ok( $signature, "signature() works" );
293-
294- print "# signature=" . $signature->as_string . "\n";
295- ok( $signature->as_string =~ /$EXPECTED_RE/, "got expected signature value" );
296-
297- # Modify sample email and sign again
298-
299- $sample_email =~ s/Wed, 12/Tue, 11/;
300- $dkim = Mail::DKIM::Signer->new(
301- Algorithm => "ed25519-sha256",
302- Method => "relaxed",
303- Domain => "example.org",
304- Selector => "test",
305- KeyFile => $keyfile
306- );
307- $dkim->PRINT($sample_email);
308- $dkim->CLOSE;
309-
310- $signature = $dkim->signature;
311-
312- print "# signature=" . $signature->as_string . "\n";
313- ok( $signature->as_string !~ /$EXPECTED_RE/, "got expected signature mismatch" );
314-
315-}
316diff --git a/t/test.ed.key b/t/test.ed.key
317deleted file mode 100644
318index 8e3a9d3..0000000
319--- a/t/test.ed.key
320+++ /dev/null
321@@ -1,3 +0,0 @@
322------BEGIN PRIVATE KEY-----
323-MC4CAQAwBQYDK2VwBCIEIBNq8eB74GQ0uhob9AKDiQFK2vPZy3Rpqw6ec66p3A+m
324------END PRIVATE KEY-----
325--
3262.40.1
327
diff --git a/debian/patches/0005-Revert-added-support-for-verifying-Ed25519-signature.patch b/debian/patches/0005-Revert-added-support-for-verifying-Ed25519-signature.patch
0new file mode 100644328new file mode 100644
index 0000000..5f2b978
--- /dev/null
+++ b/debian/patches/0005-Revert-added-support-for-verifying-Ed25519-signature.patch
@@ -0,0 +1,578 @@
1From 007bf781b0efd2f9f41cd6c259ad02fb488337c6 Mon Sep 17 00:00:00 2001
2From: Miriam Espana Acebal <miriam.espana@canonical.com>
3Date: Fri, 16 Feb 2024 13:17:00 +0100
4Subject: [PATCH 5/5] Revert "added support for *verifying* Ed25519 signatures
5 (depends on Crypt::PK::Ed25519)."
6
7This reverts commit 3aa592be9bff03672e229a7e70abef0a5b302ce7.
8---
9 HACKING.DKIM | 9 +-
10 README.md | 1 -
11 lib/Mail/DKIM/Algorithm/ed25519_sha256.pm | 121 ---------------------
12 lib/Mail/DKIM/PublicKey.pm | 127 +++++++---------------
13 lib/Mail/DKIM/Signature.pm | 11 +-
14 lib/Mail/DKIM/Verifier.pm | 17 +--
15 t/FAKE_DNS.dat | 2 -
16 t/corpus/badkey1_ed25519.txt | 16 ---
17 t/corpus/badkey2_ed25519.txt | 16 ---
18 t/corpus/badkey3_ed25519.txt | 16 ---
19 t/corpus/goodkey_ed25519.txt | 16 ---
20 t/verifier.t | 8 +-
21 12 files changed, 57 insertions(+), 303 deletions(-)
22 delete mode 100644 lib/Mail/DKIM/Algorithm/ed25519_sha256.pm
23 delete mode 100644 t/corpus/badkey1_ed25519.txt
24 delete mode 100644 t/corpus/badkey2_ed25519.txt
25 delete mode 100644 t/corpus/badkey3_ed25519.txt
26 delete mode 100644 t/corpus/goodkey_ed25519.txt
27
28diff --git a/HACKING.DKIM b/HACKING.DKIM
29index 9d8354a..e21ab49 100644
30--- a/HACKING.DKIM
31+++ b/HACKING.DKIM
32@@ -30,18 +30,11 @@ New version - update version numbers in these files:
33 New algorithm:
34 create new algorithm class by copying and editing
35 lib/Mail/DKIM/Algorithm/rsa_sha1.pm
36- edit lib/Mail/DKIM/Signature.pm:
37+ edit lib/Mail/DKIM/Common.pm:
38 get_algorithm_class() - add a check for your new algorithm and return
39 the name of your new algorithm class
40 add a "use" line at the top of this file so that your algorithm class
41 gets imported
42- if the new algorithm uses a different key type (k=), also edit
43- lib/Mail/DKIM/PublicKey.pm:
44- check()
45- convert()
46- verify_digest()
47- lib/Mail/DKIM/Verifier.pm:
48- _check_and_verify_signature()
49
50 --
51
52diff --git a/README.md b/README.md
53index 5b937a9..cf1dd52 100644
54--- a/README.md
55+++ b/README.md
56@@ -30,7 +30,6 @@ DEPENDENCIES
57 This module requires these other modules and libraries:
58
59 Crypt::OpenSSL::RSA
60- Crypt::PK::Ed25519
61 Digest::SHA
62 Mail::Address (part of the MailTools package)
63 MIME::Base64
64diff --git a/lib/Mail/DKIM/Algorithm/ed25519_sha256.pm b/lib/Mail/DKIM/Algorithm/ed25519_sha256.pm
65deleted file mode 100644
66index d97deeb..0000000
67--- a/lib/Mail/DKIM/Algorithm/ed25519_sha256.pm
68+++ /dev/null
69@@ -1,121 +0,0 @@
70-package Mail::DKIM::Algorithm::ed25519_sha256;
71-use strict;
72-use warnings;
73-# VERSION
74-# ABSTRACT: edd2519 sha256 algorithm class
75-
76-# Copyright 2005-2006 Messiah College. All rights reserved.
77-# Jason Long <jlong@messiah.edu>
78-
79-# Copyright (c) 2004 Anthony D. Urso. All rights reserved.
80-# This program is free software; you can redistribute it and/or
81-# modify it under the same terms as Perl itself.
82-
83-use base 'Mail::DKIM::Algorithm::Base';
84-use Carp;
85-use MIME::Base64;
86-use Digest::SHA;
87-
88-sub init_digests {
89- my $self = shift;
90-
91- # initialize a SHA-256 Digest
92- $self->{header_digest} = new Digest::SHA(256);
93- $self->{body_digest} = new Digest::SHA(256);
94-}
95-
96-sub sign {
97- my $self = shift;
98- croak 'wrong number of arguments' unless ( @_ == 1 );
99- my ($private_key) = @_;
100-
101- my $digest = $self->{header_digest}->digest;
102- my $signature = $private_key->sign_digest( 'SHA-256', $digest );
103-
104- return encode_base64( $signature, '' );
105-}
106-
107-sub verify {
108- my $self = shift;
109- croak 'wrong number of arguments' unless ( @_ == 0 );
110-
111- my $base64 = $self->signature->data;
112- my $public_key = $self->signature->get_public_key;
113-
114- my $digest = $self->{header_digest}->digest;
115- my $sig = decode_base64($base64);
116-
117- return unless $public_key->verify_digest( 'SHA-256', $digest, $sig );
118- return $self->check_body_hash;
119-}
120-
121-sub wants_pre_signature_headers {
122- return 1;
123-}
124-
125-1;
126-
127-__END__
128-
129-=pod
130-
131-=encoding UTF-8
132-
133-=head1 NAME
134-
135-Mail::DKIM::Algorithm::ed25519_sha256 - ed25519 sha256 algorithm class
136-
137-=head1 VERSION
138-
139-version 1.20240124
140-
141-=head1 AUTHORS
142-
143-=over 4
144-
145-=item *
146-
147-Jason Long <jason@long.name>
148-
149-=item *
150-
151-Marc Bradshaw <marc@marcbradshaw.net>
152-
153-=item *
154-
155-Bron Gondwana <brong@fastmailteam.com> (ARC)
156-
157-=back
158-
159-=head1 THANKS
160-
161-Work on ensuring that this module passes the ARC test suite was
162-generously sponsored by Valimail (https://www.valimail.com/)
163-
164-=head1 COPYRIGHT AND LICENSE
165-
166-=over 4
167-
168-=item *
169-
170-Copyright (C) 2013 by Messiah College
171-
172-=item *
173-
174-Copyright (C) 2010 by Jason Long
175-
176-=item *
177-
178-Copyright (C) 2017 by Standcore LLC
179-
180-=item *
181-
182-Copyright (C) 2020 by FastMail Pty Ltd
183-
184-=back
185-
186-This library is free software; you can redistribute it and/or modify
187-it under the same terms as Perl itself, either Perl version 5.8.6 or,
188-at your option, any later version of Perl 5 you may have available.
189-
190-=cut
191diff --git a/lib/Mail/DKIM/PublicKey.pm b/lib/Mail/DKIM/PublicKey.pm
192index b7b2a49..0080c67 100644
193--- a/lib/Mail/DKIM/PublicKey.pm
194+++ b/lib/Mail/DKIM/PublicKey.pm
195@@ -25,7 +25,7 @@ sub new {
196 $self->{'GRAN'} = $prms{'Granularity'};
197 $self->{'NOTE'} = $prms{'Note'};
198 $self->{'TEST'} = $prms{'Testing'};
199- #$self->{'TYPE'} = ( $prms{'Type'} or 'rsa' ); # unused
200+ $self->{'TYPE'} = ( $prms{'Type'} or 'rsa' );
201 $self->{'DATA'} = $prms{'Data'};
202
203 bless $self, $type;
204@@ -130,7 +130,7 @@ sub check {
205
206 # check key type
207 if ( my $k = $self->get_tag('k') ) {
208- unless ( $k eq 'rsa' || $k eq 'ed25519' ) {
209+ unless ( $k eq 'rsa' ) {
210 die "unsupported key type\n";
211 }
212 }
213@@ -162,9 +162,6 @@ sub check {
214 elsif ( $E =~ /^(panic:.*?) at / ) {
215 $E = "OpenSSL $1";
216 }
217- elsif ( $E =~ /^FATAL: (.*) at / ) {
218- $E = "Ed25519 $1";
219- }
220 die "$E\n";
221 };
222
223@@ -280,52 +277,31 @@ sub check_hash_algorithm {
224 # found in this public key's DNS record. The OpenSSL object is saved
225 # in the "cork" property.
226 sub convert {
227- my $self = shift;
228+ use Crypt::OpenSSL::RSA;
229
230- # Use different libs subject to k= tag.
231- # Without k= tag, default to RSA to maintain prior behavior
232- my $k = $self->get_tag('k') || 'rsa';
233- if ($k eq 'rsa') {
234- use Crypt::OpenSSL::RSA;
235- } elsif ($k eq 'ed25519') {
236- use Crypt::PK::Ed25519;
237- use MIME::Base64;
238- }
239+ my $self = shift;
240
241 $self->data
242 or return;
243
244- if ($k eq 'rsa') {
245- # have to PKCS1ify the pubkey because openssl is too finicky...
246- my $cert = "-----BEGIN PUBLIC KEY-----\n";
247-
248- for ( my $i = 0 ; $i < length $self->data ; $i += 64 ) {
249- $cert .= substr $self->data, $i, 64;
250- $cert .= "\n";
251- }
252-
253- $cert .= "-----END PUBLIC KEY-----\n";
254-
255- my $cork = Crypt::OpenSSL::RSA->new_public_key($cert)
256- or die 'unable to generate public key object';
257+ # have to PKCS1ify the pubkey because openssl is too finicky...
258+ my $cert = "-----BEGIN PUBLIC KEY-----\n";
259
260- # segfaults on my machine
261- # $cork->check_key or
262- # return;
263-
264- $self->cork($cork);
265+ for ( my $i = 0 ; $i < length $self->data ; $i += 64 ) {
266+ $cert .= substr $self->data, $i, 64;
267+ $cert .= "\n";
268+ }
269
270- } elsif ($k eq 'ed25519') {
271- my $cork = Crypt::PK::Ed25519->new
272- or die 'unable to generate Ed25519 public key object';
273+ $cert .= "-----END PUBLIC KEY-----\n";
274
275- my $keybin = decode_base64($self->data);
276- $cork->import_key_raw($keybin, 'public')
277- or die 'failed to load Ed25519 public key';
278+ my $cork = Crypt::OpenSSL::RSA->new_public_key($cert)
279+ or die 'unable to generate public key object';
280
281- $self->cork($cork);
282+ # segfaults on my machine
283+ # $cork->check_key or
284+ # return;
285
286- }
287+ $self->cork($cork);
288
289 return 1;
290 }
291@@ -440,57 +416,38 @@ sub verify_digest {
292 my $self = shift;
293 my ( $digest_algorithm, $digest, $signature ) = @_;
294
295- my $k_tag = $self->get_tag('k') || 'rsa';
296-
297- if ($k_tag eq 'rsa') {
298- my $rsa_pub = $self->cork;
299- if ( !$rsa_pub ) {
300- $@ = $@ ne '' ? "RSA failed: $@" : 'RSA unknown problem';
301- $@ .= ", s=$self->{Selector} d=$self->{Domain}";
302- return;
303- }
304-
305- $rsa_pub->use_no_padding;
306- my $verify_result = $rsa_pub->encrypt($signature);
307-
308- my $k = $rsa_pub->size;
309- my $expected = calculate_EM( $digest_algorithm, $digest, $k );
310- return 1 if ( $verify_result eq $expected );
311-
312- # well, the RSA verification failed; I wonder if the RSA signing
313- # was performed on a different digest value? I think we can check...
314-
315- # basically, if the $verify_result has the same prefix as $expected,
316- # then only the digest was different
317-
318- my $digest_len = length $digest;
319- my $prefix_len = length($expected) - $digest_len;
320- if (
321- substr( $verify_result, 0, $prefix_len ) eq
322- substr( $expected, 0, $prefix_len ) )
323- {
324- $@ = 'message has been altered';
325- return;
326- }
327-
328- $@ = 'bad RSA signature';
329+ my $rsa_pub = $self->cork;
330+ if ( !$rsa_pub ) {
331+ $@ = $@ ne '' ? "RSA failed: $@" : 'RSA unknown problem';
332+ $@ .= ", s=$self->{Selector} d=$self->{Domain}";
333 return;
334+ }
335
336- } elsif ($k_tag eq 'ed25519') {
337+ $rsa_pub->use_no_padding;
338+ my $verify_result = $rsa_pub->encrypt($signature);
339
340- my $ed = $self->cork;
341- if ( !$ed ) {
342- $@ = $@ ne '' ? "Ed25519 failed: $@" : 'Ed25519 unknown problem';
343- $@ .= ", s=$self->{Selector} d=$self->{Domain}";
344- return;
345- }
346+ my $k = $rsa_pub->size;
347+ my $expected = calculate_EM( $digest_algorithm, $digest, $k );
348+ return 1 if ( $verify_result eq $expected );
349
350- my $verify_result = $ed->verify_message($signature, $digest);
351- return $verify_result if ($verify_result == 1);
352+ # well, the RSA verification failed; I wonder if the RSA signing
353+ # was performed on a different digest value? I think we can check...
354
355- $@ = 'bad Ed25519 signature';
356+ # basically, if the $verify_result has the same prefix as $expected,
357+ # then only the digest was different
358+
359+ my $digest_len = length $digest;
360+ my $prefix_len = length($expected) - $digest_len;
361+ if (
362+ substr( $verify_result, 0, $prefix_len ) eq
363+ substr( $expected, 0, $prefix_len ) )
364+ {
365+ $@ = 'message has been altered';
366 return;
367 }
368+
369+ $@ = 'bad RSA signature';
370+ return;
371 }
372
373 1;
374diff --git a/lib/Mail/DKIM/Signature.pm b/lib/Mail/DKIM/Signature.pm
375index 7beb5e9..0504329 100644
376--- a/lib/Mail/DKIM/Signature.pm
377+++ b/lib/Mail/DKIM/Signature.pm
378@@ -14,7 +14,6 @@ our $VERSION = '1.20240124'; # VERSION
379 use Mail::DKIM::PublicKey;
380 use Mail::DKIM::Algorithm::rsa_sha1;
381 use Mail::DKIM::Algorithm::rsa_sha256;
382-use Mail::DKIM::Algorithm::ed25519_sha256;
383
384 use base 'Mail::DKIM::KeyValueList';
385 use Carp;
386@@ -83,6 +82,14 @@ sub wantheader {
387 return;
388 }
389
390+=head2 algorithm() - get or set the algorithm (a=) field
391+
392+The algorithm used to generate the signature. Should be either "rsa-sha1",
393+an RSA-signed SHA-1 digest, or "rsa-sha256", an RSA-signed SHA-256 digest.
394+
395+See also hash_algorithm().
396+
397+=cut
398
399 sub algorithm {
400 my $self = shift;
401@@ -343,7 +350,6 @@ sub get_algorithm_class {
402 my $class =
403 $algorithm eq 'rsa-sha1' ? 'Mail::DKIM::Algorithm::rsa_sha1'
404 : $algorithm eq 'rsa-sha256' ? 'Mail::DKIM::Algorithm::rsa_sha256'
405- : $algorithm eq 'ed25519-sha256' ? 'Mail::DKIM::Algorithm::ed25519_sha256'
406 : undef;
407 return $class;
408 }
409@@ -426,7 +432,6 @@ sub hash_algorithm {
410 return
411 $algorithm eq 'rsa-sha1' ? 'sha1'
412 : $algorithm eq 'rsa-sha256' ? 'sha256'
413- : $algorithm eq 'ed25519-sha256' ? 'sha256'
414 : undef;
415 }
416
417diff --git a/lib/Mail/DKIM/Verifier.pm b/lib/Mail/DKIM/Verifier.pm
418index 8dfa65b..c1ca743 100644
419--- a/lib/Mail/DKIM/Verifier.pm
420+++ b/lib/Mail/DKIM/Verifier.pm
421@@ -348,15 +348,11 @@ sub _check_and_verify_signature {
422 return ( 'invalid', $self->{signature_reject_reason} );
423 }
424
425- # special handling for RSA signatures
426- my $k = $pkey->get_tag('k') || 'rsa';
427- if ($k eq 'rsa') {
428- # make sure key is big enough
429- my $keysize = $pkey->cork->size * 8; # in bits
430- if ( $keysize < 1024 && $self->{Strict} ) {
431- $self->{signature_reject_reason} = "Key length $keysize too short";
432- return ( 'fail', $self->{signature_reject_reason} );
433- }
434+ # make sure key is big enough
435+ my $keysize = $pkey->cork->size * 8; # in bits
436+ if ( $keysize < 1024 && $self->{Strict} ) {
437+ $self->{signature_reject_reason} = "Key length $keysize too short";
438+ return ( 'fail', $self->{signature_reject_reason} );
439 }
440
441 # verify signature
442@@ -377,9 +373,6 @@ sub _check_and_verify_signature {
443 elsif ( $E =~ /^(panic:.*?) at / ) {
444 $E = "OpenSSL $1";
445 }
446- elsif ( $E =~ /^FATAL: (.*) at / ) {
447- $E = "Ed25519 $1";
448- }
449 $result = 'fail';
450 $details = $E;
451 };
452diff --git a/t/FAKE_DNS.dat b/t/FAKE_DNS.dat
453index 22e24da..e1683da 100644
454--- a/t/FAKE_DNS.dat
455+++ b/t/FAKE_DNS.dat
456@@ -24,5 +24,3 @@ foo._domainkey.vmt2.cis.att.net v=DKIM1; k=rsa; n=send%20comments%20to%20tony%4
457 nonexistent._domainkey.messiah.edu NXDOMAIN
458 test3._domainkey.blackhole.messiah.edu ~~Query timed out~~
459 test3._domainkey.blackhole2.messiah.edu ~~SERVFAIL~~
460-2023-05-ed25519._domainkey.wander.science v=DKIM1; k=ed25519; p=pP+YUyRjAvKha4Oc49KAY703oLUS1NLMEuGD3IHMKww=
461-invalid._domainkey.wander.science v=DKIM1; k=ed25519; p=MCowBQYDK2VwAyEA3SUqa9UbfciWkk7tlcJ9P1VD5pXAasg0JUn/OgjVbKE=
462diff --git a/t/corpus/badkey1_ed25519.txt b/t/corpus/badkey1_ed25519.txt
463deleted file mode 100644
464index 48dca6c..0000000
465--- a/t/corpus/badkey1_ed25519.txt
466+++ /dev/null
467@@ -1,16 +0,0 @@
468-DKIM-Signature: v=1; a=ed25519-sha256; q=dns/txt; c=relaxed/relaxed;
469- d=wander.science; s=invalid; h=Subject:Content-Transfer-Encoding:
470- Content-Type:From:To:MIME-Version:Date:Message-ID:In-Reply-To:Cc:References:
471- Sender:Reply-To; bh=P//FppzGgSSJDjYgpnZ255T9+DxXvu14MiedTEyE5UY=; b=85mI8hH/s
472- TYf2w8vAF3BKeRs/7EMD8yGrrekJNcoZ8LxDd3RnpejvsG43I6vryFIx6xFmVSx65+zmxXu9/kvDg
473- ==;
474-Message-ID: <505c05af-3dd2-be13-df41-464353251933@wander.science>
475-Date: Wed, 10 May 2023 21:54:21 +0200
476-MIME-Version: 1.0
477-To: echo@mail.town
478-From: mail@wander.science
479-Content-Type: text/plain; charset=UTF-8; format=flowed
480-Content-Transfer-Encoding: 7bit
481-Subject: Test ed25519
482-
483-The public key is invalid (wrong key length).
484diff --git a/t/corpus/badkey2_ed25519.txt b/t/corpus/badkey2_ed25519.txt
485deleted file mode 100644
486index bbb0d6b..0000000
487--- a/t/corpus/badkey2_ed25519.txt
488+++ /dev/null
489@@ -1,16 +0,0 @@
490-DKIM-Signature: v=1; a=ed25519-sha256; q=dns/txt; c=relaxed/relaxed;
491- d=wander.science; s=2023-05-ed25519; h=Subject:Content-Transfer-Encoding:
492- Content-Type:From:To:MIME-Version:Date:Message-ID:In-Reply-To:Cc:References:
493- Sender:Reply-To; bh=P//FppzGgSSJDjYgpnZ255T9+DxXvu14MiedTEyE5UY=; b=85mI8hH/s
494- TYf2w8vAF3BKeRs/7EMD8yGrrekJNcoZ8LxDd3RnpejvsG43I6vryFIx6xFmVSx65+zmxXu9/kvDg
495- ==;
496-Message-ID: <505c05af-3dd2-be13-df41-464353251933@wander.science>
497-Date: Wed, 10 May 2023 21:54:21 +0200
498-MIME-Version: 1.0
499-To: echo@mail.town
500-From: mail@wander.science
501-Content-Type: text/plain; charset=UTF-8; format=flowed
502-Content-Transfer-Encoding: 7bit
503-Subject: Test ed25519 wrong signature - subject modified
504-
505-This is an elliptic test.
506diff --git a/t/corpus/badkey3_ed25519.txt b/t/corpus/badkey3_ed25519.txt
507deleted file mode 100644
508index 02ea252..0000000
509--- a/t/corpus/badkey3_ed25519.txt
510+++ /dev/null
511@@ -1,16 +0,0 @@
512-DKIM-Signature: v=1; a=ed25519-sha256; q=dns/txt; c=relaxed/relaxed;
513- d=wander.science; s=2023-05-ed25519; h=Subject:Content-Transfer-Encoding:
514- Content-Type:From:To:MIME-Version:Date:Message-ID:In-Reply-To:Cc:References:
515- Sender:Reply-To; bh=P//FppzGgSSJDjYgpnZ255T9+DxXvu14MiedTEyE5UY=; b=85mI8hH/s
516- TYf2w8vAF3BKeRs/7EMD8yGrrekJNcoZ8LxDd3RnpejvsG43I6vryFIx6xFmVSx65+zmxXu9/kvDg
517- ==;
518-Message-ID: <505c05af-3dd2-be13-df41-464353251933@wander.science>
519-Date: Wed, 10 May 2023 21:54:21 +0200
520-MIME-Version: 1.0
521-To: echo@mail.town
522-From: mail@wander.science
523-Content-Type: text/plain; charset=UTF-8; format=flowed
524-Content-Transfer-Encoding: 7bit
525-Subject: Test ed25519
526-
527-Signature invalid - body modified.
528diff --git a/t/corpus/goodkey_ed25519.txt b/t/corpus/goodkey_ed25519.txt
529deleted file mode 100644
530index 42c2eb3..0000000
531--- a/t/corpus/goodkey_ed25519.txt
532+++ /dev/null
533@@ -1,16 +0,0 @@
534-DKIM-Signature: v=1; a=ed25519-sha256; q=dns/txt; c=relaxed/relaxed;
535- d=wander.science; s=2023-05-ed25519; h=Subject:Content-Transfer-Encoding:
536- Content-Type:From:To:MIME-Version:Date:Message-ID:In-Reply-To:Cc:References:
537- Sender:Reply-To; bh=P//FppzGgSSJDjYgpnZ255T9+DxXvu14MiedTEyE5UY=; b=85mI8hH/s
538- TYf2w8vAF3BKeRs/7EMD8yGrrekJNcoZ8LxDd3RnpejvsG43I6vryFIx6xFmVSx65+zmxXu9/kvDg
539- ==;
540-Message-ID: <505c05af-3dd2-be13-df41-464353251933@wander.science>
541-Date: Wed, 10 May 2023 21:54:21 +0200
542-MIME-Version: 1.0
543-To: echo@mail.town
544-From: mail@wander.science
545-Content-Type: text/plain; charset=UTF-8; format=flowed
546-Content-Transfer-Encoding: 7bit
547-Subject: Test ed25519
548-
549-This is an elliptic test.
550diff --git a/t/verifier.t b/t/verifier.t
551index 90320d4..b1b1e28 100755
552--- a/t/verifier.t
553+++ b/t/verifier.t
554@@ -2,7 +2,7 @@
555
556 use strict;
557 use warnings;
558-use Test::More tests => 109;
559+use Test::More tests => 105;
560
561 use Mail::DKIM::Verifier;
562
563@@ -162,12 +162,6 @@ test_email( "badkey_15.txt", "invalid" ); # dns error (SERVFAIL)
564 ok( $dkim->result_detail =~ /public key/, "detail mentions public key" );
565 ok( $dkim->result_detail =~ /dns.*SERVFAIL/i, "type of dns failure" );
566
567-# test ed25519
568-test_email( "goodkey_ed25519.txt", "pass" );
569-test_email( "badkey1_ed25519.txt", "invalid" ); # key has invalid length
570-test_email( "badkey2_ed25519.txt", "fail" ); # header modified
571-test_email( "badkey3_ed25519.txt", "fail" ); # body modified
572-
573 sub read_file {
574 my $srcfile = shift;
575 open my $fh, "<", $srcfile
576--
5772.40.1
578
diff --git a/debian/patches/0006-Revert-Debian-support-for-ed25519.patch b/debian/patches/0006-Revert-Debian-support-for-ed25519.patch
0new file mode 100644579new file mode 100644
index 0000000..1ae3d6d
--- /dev/null
+++ b/debian/patches/0006-Revert-Debian-support-for-ed25519.patch
@@ -0,0 +1,93 @@
1From 2ff36de8102d340f4b2f25fc538891049af1692b Mon Sep 17 00:00:00 2001
2From: Miriam Espana Acebal <miriam.espana@canonical.com>
3Date: Thu, 15 Feb 2024 16:50:10 +0100
4Subject: [PATCH] Revert-Debian-support-for-ed25519
5
6Reverting partially commit b0358e44077951cabd3f27ad99473ef3bd778e67 from Debian,
7just removing perl dependencies and files related to ed25519 in 1.20230630-1.
8---
9 MANIFEST | 7 -------
10 META.json | 1 -
11 META.yml | 1 -
12 Makefile.PL | 2 --
13 4 files changed, 11 deletions(-)
14
15diff --git a/MANIFEST b/MANIFEST
16index edf3b5f..067c052 100644
17--- a/MANIFEST
18+++ b/MANIFEST
19@@ -23,7 +23,6 @@ lib/Mail/DKIM/ARC/Signer.pm
20 lib/Mail/DKIM/ARC/Verifier.pm
21 lib/Mail/DKIM/Algorithm/Base.pm
22 lib/Mail/DKIM/Algorithm/dk_rsa_sha1.pm
23-lib/Mail/DKIM/Algorithm/ed25519_sha256.pm
24 lib/Mail/DKIM/Algorithm/rsa_sha1.pm
25 lib/Mail/DKIM/Algorithm/rsa_sha256.pm
26 lib/Mail/DKIM/AuthorDomainPolicy.pm
27@@ -83,11 +82,6 @@ t/corpus/bad_dk_5.txt
28 t/corpus/bad_ietf01_1.txt
29 t/corpus/bad_ietf01_2.txt
30 t/corpus/bad_ietf01_3.txt
31-t/corpus/badkey1_ed25519.txt
32-t/corpus/badkey2_ed25519.txt
33-t/corpus/badkey3_ed25519.txt
34-t/corpus/badkey4_ed25519.txt
35-t/corpus/badkey5_ed25519.txt
36 t/corpus/badkey_1.txt
37 t/corpus/badkey_10.txt
38 t/corpus/badkey_11.txt
39@@ -133,7 +127,6 @@ t/corpus/goodkey_1.txt
40 t/corpus/goodkey_2.txt
41 t/corpus/goodkey_3.txt
42 t/corpus/goodkey_4.txt
43-t/corpus/goodkey_ed25519.txt
44 t/corpus/ignore_1.txt
45 t/corpus/ignore_2.txt
46 t/corpus/ignore_3.txt
47diff --git a/META.json b/META.json
48index 0491f11..557b36e 100644
49--- a/META.json
50+++ b/META.json
51@@ -31,7 +31,6 @@
52 "requires" : {
53 "Carp" : "0",
54 "Crypt::OpenSSL::RSA" : "0",
55- "Crypt::PK::Ed25519" : "0",
56 "Digest::SHA" : "0",
57 "MIME::Base64" : "0",
58 "Mail::Address" : "0",
59diff --git a/META.yml b/META.yml
60index 9a226c5..240ba76 100644
61--- a/META.yml
62+++ b/META.yml
63@@ -24,7 +24,6 @@ name: Mail-DKIM
64 requires:
65 Carp: '0'
66 Crypt::OpenSSL::RSA: '0'
67- Crypt::PK::Ed25519: '0'
68 Digest::SHA: '0'
69 MIME::Base64: '0'
70 Mail::Address: '0'
71diff --git a/Makefile.PL b/Makefile.PL
72index d36be4e..43ab54e 100644
73--- a/Makefile.PL
74+++ b/Makefile.PL
75@@ -19,7 +19,6 @@ my %WriteMakefileArgs = (
76 "PREREQ_PM" => {
77 "Carp" => 0,
78 "Crypt::OpenSSL::RSA" => 0,
79- "Crypt::PK::Ed25519" => 0,
80 "Digest::SHA" => 0,
81 "MIME::Base64" => 0,
82 "Mail::Address" => 0,
83@@ -50,7 +49,6 @@ my %WriteMakefileArgs = (
84 my %FallbackPrereqs = (
85 "Carp" => 0,
86 "Crypt::OpenSSL::RSA" => 0,
87- "Crypt::PK::Ed25519" => 0,
88 "Data::Dumper" => 0,
89 "Digest::SHA" => 0,
90 "MIME::Base64" => 0,
91--
922.40.1
93
diff --git a/debian/patches/series b/debian/patches/series
0new file mode 10064494new file mode 100644
index 0000000..6e5e0f9
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1,6 @@
10001-Revert-Ed25519-Add-test-for-missing-public-key.patch
20002-Revert-Refactor-and-cleanup-some-ed25519-code.patch
30003-Revert-set-rsa-ed25519-type.patch
40004-Revert-added-ed25519-signing-support.patch
50005-Revert-added-support-for-verifying-Ed25519-signature.patch
60006-Revert-Debian-support-for-ed25519.patch

Subscribers

People subscribed via source and target branches