Page MenuHome GnuPG

Kleopatra: ADSK shown as "unknown recipient"
Open, NormalPublic

Description

Starting point: Key "Alice" with ADSK subkey. (The public key to which the ADSK belongs is in the keyring.)

Encrypt a file to Alice.

Decrypt it again. The info shown is recipients Alice + unknown. Audit log shows Alice as the recipient twice with the keyIDs for both encryption resp. ADSK subkeys:

How would it be correct? Show Alice twice as recipient, both times with the KeyID of the primary key?

Edit 2024-10-16:

As suggested by Tobias finding, part of the time the same decryption displays the second recipient:

Edit 2024-11-05:

It was decided that the owner of the ADSK key should be listed as the second recipient, if possible, which it is in the case described above.
And the listing should consistently always show the same info, of course.
For details see https://dev.gnupg.org/T7334#193396

Details

External Link
https://invent.kde.org/pim/libkleo/-/merge_requests/150
Version
gpg4win-Beta-50

Event Timeline

Yes. I think that Kleo does not yet fully support the R-flag indicating an ADSK.

Is this R-flag part of the status logging, i.e. do we need to add handling for this in gpgme?

We have this data already. The problem on kleopatra's side is that in the key cache, we add the ADSK subkey for each key that has it as an ADSK, causing a somewhat broken index and ultimately the problem seen here.

@werner: Looking at the audit log ebo sent, gpg itself also seems to make errors about which certificate the ADSK actually belongs to

What is wrong in your opinion?

Both subkeys belong to Alice from gpg's point of view, which is technically true, the ADSK is an offline subkey.
But stating it like this without additional info may be confusing for users.

Both subkeys belong to Alice from gpg's point of view

yes, but in practice, the ADSK belongs to a different certificate and allows that certificate to decrypt the data. I would find it strange to then omit that information entirely or list alice as the recipient twice, when alice might not even be the holder of the ADSK's private key

(for completeness: with my patch, kleopatra lists all "normal" recipients and the certificate the subkey "actually belongs to", if it's known. if it's unknown, it's listed as an unknown recipient. If we want a different behavior, the patch is of course not applicable anymore)

TobiasFella set External Link to https://invent.kde.org/pim/libkleo/-/merge_requests/150.Oct 14 2024, 3:12 PM

Thinking about this some more, I don't think we can anything different from what's done in my patch:

  • (as far as i know) we don't have a way of knowing whether the data was encrypted to a certain recipient as an ADSK or because the sender actively chose to encrypt for them
  • Consider the following setup:
    • Certificates alice and bob; with alice having bob's encryption key as an ADSK
    • Someone encrypts a file for bob only
    • Kleopatra will currently show the data as being encrypted for alice

In case of an unknown encryption subkey we could check if it's the ADSK of a known recipient and then display something like

Unknown ADSK for "Some key with ADSK <with-adsk@example.net>"

instead of

unknown recipient

Not sure if it's worth spending time on this. In any case, this would be a new ticket.

It is not of the recipient's business to know which certificate also uses a subkey. For all the user needs to know that it is a subkey which belongs to a primary key. In this regard this is not different from a shared encryption subkey as used by many sites for role addresses. For a subkey the user id of its primary should always been show.

Summarizing out-of-band discussion (please correct where i remember things wrong):

  • There's not always a perfect mapping from Subkey to certificate (as I mentioned in my last comment); in situations where one of the resulting certificates contains the key as an ADSK and the other as a normal encryption key, the latter should be preferred (effectively done in the linked MR)
  • Figure out which recipients are ADSKs (by checking the certificates of the known recipients, as suggested by Ingo) and show them separately / summarized

For a subkey the user id of its primary should always been show.

But what is "its primary key"? It seems that gpg considers the key with the attached ADSK to be "its primary key" (see gpg's log output in the attached screenshot) which makes "its" ambiguous.

There is no such concept of a primary keyblock for a subkey. Using the same subkey for several primary keys is non frequent but nevertheless seen use-case. Thus this behaviour is not ADSK specific. I would suggest to first search the keyblock used for decryption to get the name of another subkey - only if that is not found search the keyring for that subkey and thus the primary key and its user id.

werner triaged this task as Normal priority.Oct 15 2024, 9:52 AM

I don't think gpg/gpgsm tell gpgme "the keyblock used for decryption". They simply log all public keys used for encryption via STATUS_ENC_TO in the order the packets appear in the encrypted file.

Edit: gpg emits STATUS_NO_SECKEY which gpgme stores in the status field for the recipients. But I'm not sure if we can simply assume that the first recipient without error in the status field was used for decryption because gpg skips recipients with wrong pubkey_algo (in get_session_key) without setting a result for the recipients.

My last comment makes things look more complicated than they are.

If Kleopatra cannot find a certificate for a recipient (sub)key in the key cache then it could check if any of the known recipient certificates (starting with the own certificates) has an ADSK (or simply a subkey; it does not need to be an ADSK) matching the unknown recipient (sub)key.

It's not exactly what Werner proposed (i.e. to first check the certificate that was used for decryption), but it can be implemented with little effort and without any changes in gpg and gpgme.

ebo updated the task description. (Show Details)
ebo moved this task from Backlog to WIP on the gpd5x board.

As discussed today let's use the following heuristic:

  • If we find a certificate for the recipient (sub)key in the key cache (ignoring ADSK subkeys) then list this certificate as recipient.
  • Else: If we find a single certificate for the recipient (sub)key in the key cache (including ADSK subkeys) then list this certificate as recipient.
  • Else: In a second pass, check if any of the already known recipient certificates has a(n ADSK) subkey matching the unknown recipient (sub)key. In this case list this recipient again (so that formatRecipientsDetails doesn't assume an unknown recipient).
  • Else: Count the recipient as unknown.

I guess this means we need to add the ADSK subkeys again to the subkey index. Moreover, formatRecipientsDetails should deduplicate the list of recipients.