Open Bug 1884337 Opened 5 months ago Updated 2 months ago

Forward compatibility: Allow permissive import of OpenPGP certificates with Subkeys with Unknown Public Key Algorithms

Categories

(MailNews Core :: Security: OpenPGP, enhancement)

enhancement

Tracking

(Not tracked)

People

(Reporter: johannes.roth, Unassigned)

References

(Depends on 1 open bug, )

Details

(Whiteboard: See comment 12)

Attachments

(1 file)

Steps to reproduce:

New public-key algorithms are being specified for OpenPGP:

  1. In the Crypto Refresh https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-13 the algorithms X25519/X448/Ed25519/Ed448 are added (ids 25-28)

  2. In the PQC draft https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-pqc ML-KEM-based algorithms are added with the intent to be usable as subkeys with v4 certificates.

In order to maximize the compatibility, Thunderbird should be able to process certificates with subkeys with unknown public-key-algorithm identifiers. I want to point out, that new algorithms may be standardized at any time, so it's not only a problem with the Crypto Refresh or the PQC draft and it would be generally good to be compatible in such cases. It allows new OpenPGP standards to rely on this mechanism to provide backwards compatibility.

RNP offers the permissive flag (RNP_LOAD_SAVE_PERMISSIVE) which will ignore all subkeys that cannot be correctly parsed. Thunderbird makes use of it already to some extent. However, it seems to be inconsistently implemented at the moment.

I did a small experiment: When attaching an OpenPGP v4 certificate with EdDSA (primary) + ECDH (sub) + a PQC key (sub) to a message, Thunderbird offers the receiver of the message (at least) two ways of importing this key.

  1. Click on the OpenPGP button that appears in the top-right corner at the end of the Subject field when viewing the mail. Here, the UI says that the message claims that the public key is contained and asks if the user wants to import it. Doing so results in an error.

  2. Import the certificate via "Tools -> OpenPGP Key Manager -> File -> Import Public Key(s) From File". Now the import fails but it is asked if the user wants to try it again with only the parts that can be correctly parsed. Here, RNP's permissive flag is set for the second try. The import succeeds by ignoring the subkey with the unknown algorithm.

My conclusion is:
First, Thunderbird needs to be updated such that the behaviour is more consistent.
Second, it might be worthwhile to consider an alternative approach to the current behaviour of retrying the import with the permissive flag. This will confuse users and make it look like a bug ("Why does Thunderbird complain and then it works anyway?"). So I propose to import OpenPGP certificates with unknown subkey algorithms by default by simply ignoring them (and giving a non-confusing message to the user).

Component: Security → Security: OpenPGP
Product: Thunderbird → MailNews Core

If Thunderbird always set RNP_LOAD_SAVE_PERMISSIVE when importinging any keys, can we think of any side effects?

Will RNP always ignore key attributes that it cannot process, or could it result in new runtime failures?

(In reply to Kai Engert (:KaiE:) from comment #1)

If Thunderbird always set RNP_LOAD_SAVE_PERMISSIVE when importinging any keys, can we think of any side effects?

Will RNP always ignore key attributes that it cannot process, or could it result in new runtime failures?

Kai,
This option is designed exactly for this purpose - to ignore packets which RNP cannot parse. Which sort of failures do you mention?

(In reply to Nickolay Olshevsky from comment #2)

This option is designed exactly for this purpose - to ignore packets which RNP cannot parse. Which sort of failures do you mention?

For example, that the key might be supported for listing, but e.g. not being usable as a recipient encryption certificate.

Could the presence of packets (that RNP cannot parse) allow importing, but prevent using for encryption?
That could potentially introduce new failures modes that Thunderbird doesn't handle yet.

I think it would be best if I were able to test keys with that attributes.

If we learn that the presence of such packets doesn't do any harm, we could consider to always use that flag in Thunderbird when importing.

(In reply to Kai Engert (:KaiE:) from comment #3)

(In reply to Nickolay Olshevsky from comment #2)

This option is designed exactly for this purpose - to ignore packets which RNP cannot parse. Which sort of failures do you mention?

For example, that the key might be supported for listing, but e.g. not being usable as a recipient encryption certificate.

If key (as well as signature) packet is not supported (unknown algorithm, format, whatever else) then it will be completely dropped from the input stream and ignored in permissive mode.

Could the presence of packets (that RNP cannot parse) allow importing, but prevent using for encryption?

Nope.

That could potentially introduce new failures modes that Thunderbird doesn't handle yet.
I think it would be best if I were able to test keys with that attributes.

Keys with unknown algorithms or damaged structure are already being tested in RNP CI and proven to work correctly. Once PQC v4 key artifacts are available we could at them to test suite as well. You may also simulate this case by editing keys in hex editor (feel free to contact me if you need a help with that).

Thanks for the explanation.

I'll run with a local Thunderbird build for a few days with "always permissive" to perform some testing.
If things are well, I'll consider setting it by default.

Status: UNCONFIRMED → NEW
Ever confirmed: true
Summary: Increase OpenPGP Compatibility for Certificates with Subkeys with Unknown Public Key Algorithms → Forward compatibility: Allow import of OpenPGP certificates with Subkeys with Unknown Public Key Algorithms

Just some more brainstorming:

Can we think any reason why it would be preferable to limit permissive mode to public keys?

In other words, is it fine to import secret keys in permissive mode, or should we still be strict when importing secret keys?

(Hmm, it would be challenging to exclude secret keys actually. Someone could have already imported the public key, and then attempt to restore the secret key from a backup.)

Nickolay, I found one behavior difference, which was detected by TB's automated test.

When importing a v5 secret key using rnp_import_keys, the success value 0 is returned - but no key is imported.

When not using the permissive flag, then rnp_import_keys returns a failure code.

Kai,
Yeah, RNP_SUCCESS is returned if no keys are imported in this case, and this could be checked via the results JSON.

I've experimented using one of the experimental keys distributed with the initial gnupg 2.6 beta versions
(from https://lists.gnupg.org/pipermail/gnupg-devel/2024-April/035533.html )

It includes sample keys, which use a v4 primary key, a v5 subkey, and v4 binding signatures.

If I enable the permissive import mode, then RNP accepts to import that key.

This means, the permissive mode isn't limited to unknown algorithms, it also allows unsupported subkeys.

I'm not yet convinced we're ready to generally enable this flag.

I'm worried that importing partially unsupported keys can confuse the user by introducing new failure modes.

For example, with the example keys I mentioned in comment 11, if we gracefully allow the import of that key, the user will get the impression that a key has been imported fine. However, current TB version will not find a usable encryption subkey and consequently cannot use it for exchanging encrypted messages.

This could confuse users. They might import, even verify the correspondent's fingerprint, mark the keys as accepted, but still not being able to use it.

I think we should take some more time, prior to considering to import this mode.

As I understand it, the future versions of RNP will introduce a new API that can be used to obtain the version number of a key (and I assume that will work for subkeys, too).

It might be better to wait for that API. And once it's available, maybe TB should perform several checks when trying to import a key. If could check whether the key contains a full set of usable/supported keys. Maybe if that condition is satisfied, then it might be acceptable to ignore additional unknown/unsable keys.

It might also be necessary to more actively guide the user, when trying to import such a partially supported key. For example, by warning the user about unsupported keys, or possibly by telling the user that the key isn't really usable to TB. In that scenario, TB might offer the user to extend the key with additional subkeys, to MAKE it usable in TB.

So lots of room for improvement in a future version, but risk of confusion without having that.

I suggest to keep this bug open and reconsider the request at a future time, possibly after more assistance (as explained above in this comment) has been implemented.

At this time, I prefer to say "no" to this suggestion.

Summary: Forward compatibility: Allow import of OpenPGP certificates with Subkeys with Unknown Public Key Algorithms → Forward compatibility: Allow permissive import of OpenPGP certificates with Subkeys with Unknown Public Key Algorithms
Depends on: 1893950
Whiteboard: See comment 12

(In reply to Kai Engert (:KaiE:) from comment #6)

Can we think any reason why it would be preferable to limit permissive mode to public keys?

In other words, is it fine to import secret keys in permissive mode, or should we still be strict when importing secret keys?

If you do end up setting this flag, I think it would indeed be best to only do so for public keys, if possible.

For secret keys, the risk is that someone might receive an email encrypted with one of the unsupported subkeys, which then wouldn't be decryptable (which would be confusing if the key was imported successfully).

That being said, for public keys, there's no such risk, and - as long as the key can be used for encryption, e.g. using another (supported) subkey - I think it should be fine to allow importing it. One way this could be checked (without any new APIs) is by doing a trial encryption, for example.

Kai, i agree with you that the semantics of RNP_LOAD_SAVE_PERMISSIVE may not be exactly what Thunderbird wants. Rather than trying to figure out how to hold the RNP tooling "correctly", it might make more sense initially to think about what Thunderbird actually wants. Then we can ask RNP for something concretely useful, if the current mechanisms don't match the desired outcomes.

I think Daniel Huigens' point in comment #14 is pretty insightful; What Thunderbird cares about is functionality, not about versions or subpackets or whatever. Gratuitous rejection of certificates where the functionality is actually possible could make Thunderbird a blocker for OpenPGP ecosystem evolution. It's also important to remember that functionality tests for certificates may yield different outcomes at different times. For example a certificate's encryption-capable subkey could expire (or be revoked) in between runs.

I also note that the usability concerns that Kai rightfully cares about are relevant even when no unsupported packets or subpackets or version numbers are present. For example, some software developers use signing-only certificate to both release software, and to write status notes to public mailing lists. While Thunderbird couldn't use such a certificate to encrypt mail to that developer, it would also be a shame to reject such a certificate out of hand -- that would limit the ability to verify signatures.

So, what functionality to test for? There are two main things that Thunderbird presumably cares about for any given certificate: being able to verify signatures, and being able to encrypt. How would Thunderbird want to test for them? what kinds of answers would Thunderbird want to get from a library? for example:

  • can safely i encrypt a message to this certificate?
  • can i verify a signature from this certificate?
  • will i be able to encrypt a message to this certificate in a month? (or some other cadence?)
  • will i be able to verify a signature from this certificate in a month? (or some other cadence?)
  • is this certificate internally bound to a given identity in ways that i can automatically validate?
  • …?

None of these questions suggest that dropping a certificate entirely because some part of the certificate is unknown is a necessarily a useful thing for usability. What are the ways that Thunderbird would want to react to some of the more "negative" answers to these questions? For example, what should Thunderbird do/how should Thunderbird behave if it finds a signing-only certificate? What should thunderbird do when encrypting a message to a certificate that it knows will expire tomorrow?

Thank you for your thoughts, that's very helpful.

I'm not sure it's ideal to ask RNP to implement exactly what Thunderbird needs.
I might make mistakes in what I define, and regret choices later, and what's best to do could be influenced by changes in the ecosystem.

I still think I don't want to blindly import anything that permissive mode allows.

I don't want to reject signing-only certificates or encryption certificates, I agree those could be useful.

Also, because Thunderbird allows (optional) permissive import (with an easy confirmation click in the past, which is still possible in the future, albeit having to set an additional pref to allow it, see bug 1829881),
I cannot claim that I want to solve all problems at import time. Some users might have already have such certifcates imported, so whatever smart behavior gets invented to happen at import time in the future, must also cover certificates that are already imported in one way or the other.

So my primary argument remains, I prefer to avoid that people get into trouble, or are confused, by unknowingly importing certificates with problematic or unexpected properties.

So, I think what I really want is this:

When importing a certificate, I want to inspect it. I want to check if it makes sense. If it makes sense and seems usable for the intended purpose, I might be willing to import it in permissive mode, despite some attributes we don't fully understand.

Let me be more specific:

On import, we could check whether the key has any key (primary or subkey) for the signing usage. If we see that, we should assume the cert is intended to be used for signing. Based on that, we should require that at least one key is present that can be used for signing, with a supported algorithm. If yes, we can accept additional signing keys that we don't understand.

Same strategy for encryption. If at least one encryption subkey is present, make sure there's at least one subkey there that's usable by us.

Regarding the concern that a key could become unusable because it expires or gets revoked. I think I'm ok to tolerate that risk, because that risk applies to any keys we already have. It also means that the correspondent has a simple way to fix it, if they want to, by extending the validity.

So, I think it's fine to limit the above checks to finding a key that is usable at the current time.
Even if a key is expected to expire tomorrow. I think that's still fine. The user might have a need to send a message today. If the key is usable, let's allow to use it.

How can this be implemented?

I think it can be implemented using the tools we already have available.

Thunderbird already uses a two-phase strategy when importing a new key. In a first step, we always import the incoming keys into an isolated temporary space, and we set the permissive flag for that step. That allows us to always get a listing of the incoming data, and tell the user about it. (And if the user agrees to import, we might then run into a failure, when not importing permissive.)

Thunderbird could perform the "does the key seem usable for our purposes at this time" check, as explained above.

If this test passes, we always set the permissive import flag, and carry along all the extra stuff that we don't understand (yet).

If the test fails, we still reject importing. (Unless the users sets the new pref from bug 1829881, and tells TB interactively to import the key anyway.)

At this time, however, I would like to always reject unknown (new) key versions (v5, v6), whenever they are present, until I have a better plan what to do about them.

What do you think?

You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: