Page MenuHome GnuPG

Draft: Kleopatra: ADSK shown as "unknown recipient"
Testing, 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.

ebo changed the task status from Open to Testing.Mon, Oct 20, 3:16 PM
ebo moved this task from WIP to QA on the gpd5x board.

We need to check what the current status here is. This has been in the 5.0 Betas for a while, so testing with 5.0-Beta369 will work

timegrid added a subscriber: timegrid.

Not sure, if my test covers all cases (especially regarding cache): encrypted for alice with several ADSKs (local/card, v4/v5, several algos, 1 unknown = not in keyring).

  • If the cert associated with the adsk is in keyring, the userid of this cert is shown.
  • The number of unknown recipients (cert not in keyring) is shown at the end.

Makes sense to me. Possible optimizations:

  • I might want to know the fingerprints of those unknown recipients to search for them (in the audit log I can't see, which of those fingerprints are unknown immediately)
  • The cert used for decryption could be listed first

C:\Users\g10\Desktop\testdata\adsk>gpg -K --with-subkey-fingerprint
[keyboxd]
---------
sec#  brainpoolP256r1 2025-10-24 [SC] [verfällt: 2028-10-24]
      5165F54D94B78BA83124A941D04A01B757E7E9F6
uid        [ unbekannt ] kyber <kyber@gnupg.test>
ssb   ky768_bp256 2025-10-24 [E] [verfällt: 2028-10-24]
      AAA831ADAABE791A3CA726DCAF1A77E92FFA7679C9C8251CB6694272C324237C

sec>  brainpoolP256r1 2025-10-24 [SC] [verfällt: 2028-10-24]
      BD1E9A3CCE7E7A2B4DCBB00D32E828058AED0653
      Kartenseriennr. = 0005 00009D59
uid        [ ultimativ ] card <card@gnupg.test>
ssb>  brainpoolP256r1 2025-10-24 [A] [verfällt: 2028-10-24]
      11376E4C88DB263930B563C8CFDA7FE11E34BD98
      Kartenseriennr. = 0005 00009D59
ssb>  brainpoolP256r1 2025-10-24 [E] [verfällt: 2028-10-24]
      A81DDE96B9F69D8786FADE198C89699A226DEF36
      Kartenseriennr. = 0005 00009D59

sec   ed25519 2025-10-24 [SC] [verfällt: 2028-10-24]
      FB3CD56641FA71402AD90B4C841FFCE98B51002C
uid        [ ultimativ ] alice <alice@gnupg.test>
ssb   cv25519 2025-10-24 [E] [verfällt: 2028-10-24]
      93DBB5B1505125AAF13C44A99EBD0A42566EFD84
ssb   ky768_bp256 2025-10-24 [R] [verfällt: 2028-10-24]
      AAA831ADAABE791A3CA726DCAF1A77E92FFA7679C9C8251CB6694272C324237C
ssb#  cv25519 2025-10-24 [R] [verfällt: 2028-10-24]
      86E82E250744656FEA9CCCE66BF1CF390E9742F1
ssb#  cv25519 2025-10-24 [R] [verfällt: 2028-10-24]
      0644712042E8A2DC9D668ECD9712BEBB2F569F9D
ssb#  cv448 2025-10-24 [R] [verfällt: 2028-10-24]
      295934553092E92EA0EEC0264860D641416E1002F4E92C67DC9D297275F6C496
ssb#  cv25519 2025-10-24 [R] [verfällt: 2028-10-24]
      1A93A0C3C5ED11BE8D900D76E88107C3D395E1B3
ssb>  brainpoolP256r1 2025-10-24 [R] [verfällt: 2028-10-24]
      A81DDE96B9F69D8786FADE198C89699A226DEF36
      Kartenseriennr. = 0005 00009D59
C:\Users\g10\Desktop\testdata\adsk>gpg -k --with-subkey-fingerprint
[keyboxd]
---------
pub   brainpoolP256r1 2025-10-24 [SC] [verfällt: 2028-10-24]
      5165F54D94B78BA83124A941D04A01B757E7E9F6
uid        [ unbekannt ] kyber <kyber@gnupg.test>
sub   ky768_bp256 2025-10-24 [E] [verfällt: 2028-10-24]
      AAA831ADAABE791A3CA726DCAF1A77E92FFA7679C9C8251CB6694272C324237C

pub   ed25519 2025-10-24 [SC] [verfällt: 2028-10-24]
      60B03BDF5FFEFF6F99C8A85DC9CDF62B5815E30B
uid        [ unbekannt ] charlie <charlie@gnupg.test>
sub   cv25519 2025-10-24 [E] [verfällt: 2028-10-24]
      86E82E250744656FEA9CCCE66BF1CF390E9742F1

pub   ed25519 2025-10-24 [SC] [verfällt: 2028-10-24]
      B1EB4C812A73F59BFDE37DD37DE19444D71E691A
uid        [ unbekannt ] bob <bob@gnupg.test>
sub   cv25519 2025-10-24 [E] [verfällt: 2028-10-24]
      0644712042E8A2DC9D668ECD9712BEBB2F569F9D

pub   brainpoolP256r1 2025-10-24 [SC] [verfällt: 2028-10-24]
      BD1E9A3CCE7E7A2B4DCBB00D32E828058AED0653
uid        [ ultimativ ] card <card@gnupg.test>
sub   brainpoolP256r1 2025-10-24 [A] [verfällt: 2028-10-24]
      11376E4C88DB263930B563C8CFDA7FE11E34BD98
sub   brainpoolP256r1 2025-10-24 [E] [verfällt: 2028-10-24]
      A81DDE96B9F69D8786FADE198C89699A226DEF36

pub   ed448 2025-10-24 [SC] [verfällt: 2028-10-24]
      C333FACB6611A188D13C29DAD038898C1277909236160BA7F54B92CEB7382607
uid        [ unbekannt ] curve448 <curve448@gnupg.test>
sub   cv448 2025-10-24 [E] [verfällt: 2028-10-24]
      295934553092E92EA0EEC0264860D641416E1002F4E92C67DC9D297275F6C496

pub   ed25519 2025-10-24 [SC] [verfällt: 2028-10-24]
      FB3CD56641FA71402AD90B4C841FFCE98B51002C
uid        [ ultimativ ] alice <alice@gnupg.test>
sub   cv25519 2025-10-24 [E] [verfällt: 2028-10-24]
      93DBB5B1505125AAF13C44A99EBD0A42566EFD84
sub   ky768_bp256 2025-10-24 [R] [verfällt: 2028-10-24]
      AAA831ADAABE791A3CA726DCAF1A77E92FFA7679C9C8251CB6694272C324237C
sub   cv25519 2025-10-24 [R] [verfällt: 2028-10-24]
      86E82E250744656FEA9CCCE66BF1CF390E9742F1
sub   cv25519 2025-10-24 [R] [verfällt: 2028-10-24]
      0644712042E8A2DC9D668ECD9712BEBB2F569F9D
sub   cv448 2025-10-24 [R] [verfällt: 2028-10-24]
      295934553092E92EA0EEC0264860D641416E1002F4E92C67DC9D297275F6C496
sub   cv25519 2025-10-24 [R] [verfällt: 2028-10-24]
      1A93A0C3C5ED11BE8D900D76E88107C3D395E1B3
sub   brainpoolP256r1 2025-10-24 [R] [verfällt: 2028-10-24]
      A81DDE96B9F69D8786FADE198C89699A226DEF36
  • I might want to know the fingerprints of those unknown recipients to search for them (in the audit log I can't see, which of those fingerprints are unknown immediately)

My main point here is, that users might be unsettled by the fact, that some unknown entity is able to read their encrypted communication. A better way to communicate the reason and/or pointers to resolve it might be desirable.

Well, in the audit log the output of gpg is shown, nothing Kleo can do there, I believe.
But we need to talk about what still needs to be / can be implemented on the Kleo side.

ebo renamed this task from Kleopatra: ADSK shown as "unknown recipient" to Draft: Kleopatra: ADSK shown as "unknown recipient".Wed, Oct 29, 4:02 PM