Skip to content

Conversation

mtrmac
Copy link
Contributor

@mtrmac mtrmac commented Jul 16, 2025

  • Make the semantics of the input parameter more strict, and reject ambiguities
  • Then avoid unnecessary loops / vectors
  • Don't ignore errors parsing data
  • Match sq in looking for usable keys

This works against the basic tests in c/image, but I suppose this should have good test coverage — marking as draft for now, filing for early discussion / review.

@mtrmac
Copy link
Contributor Author

mtrmac commented Jul 16, 2025

Attempts to address containers/image#2569 (comment) and containers/image#2569 (comment) .

if certs.len() != 1 {
// This should not happen, lookup_by_cert documentation says
// > The caller may assume that looking up a fingerprint returns at
// > most one certificate.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to distinguish the cases where no certs are found or multiple certs are returned? Something like:

if certs.is_empty() {
  return Err(...);
}
// At most one cert should be returned by lookup_by_cert, when searched with a fingerprint
assert!(certs.len() == 1);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn’t test that, but lookup_by_cert not finding anything should fail with StoreError::NotFound already; that’s one of the failures the with_context()? above is supposed to be handling.

So, here I think len() ≥ 1.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, len() > 1 is not an indication of a program bug that would merit an assert at this point — the input is parsed as KeyHandle, which is not only a full fingerprint, but also a key ID, and key IDs are short enough to be possibly ambiguous. So, it is ~legitimately possible for the lookup to return multiple results.

(At the c/image level, the API is named WithKeyFingerprint and it’s undocumented that it also accepts short key IDs. That’s really a bug in c/image option validation; it might still be an option for podman-sequoia to turn the key_handle parameter into a key_fingerprint parameter, and then this could be an assert.)


Compare also the “For gpgme, allow lookup by user ID? grep_userid, or what is the compatible semantics?” FIXME: the pre-existing simple signing API names the parameter “fingerprint” but allows it to match, as gpgme does, against the user ID, including an email address. I don’t really want such a loose matching in the Sequoia API — I think adding extra methods for various lookup mechanisms is better.)

.with_context(|| format!("Parsing certificate for {key_handle}"))?;

let mut key: Option<sequoia_keystore::Key> = None;
let mut rejected_key_errors: Vec<String> = vec![];
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might have suggested it before, but I would collect errors as a dedicated error type (you can define it easily with thiserror).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of the values of rejected_key_errors currently get concatenated into a single string that is returned back to Go.

And the Go client, at this moment, doesn’t really need any more granularity: this package does not provide any API to inspect a key, list subkeys, or anything else that would allow the Go client to somehow process the errors or to make decisions based on them. All of that is potentially interesting and could be built for other users, but it’s not something I’m likely to be working on for c/image.


Alternatively, it would be interesting to not just use a single string for localization purposes. Conceptually, I would very much like software to talk my language, but in the container ecosystem as is, everything is English everywhere. Similarly, providing structured errors to build a nice GUI — even if this failure case ever were something a GUI designer would choose to prioritize — is limited by c/image error reporting all using just a Go error (~string provider) type.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Late thought — I’d really argue that a higher-level key choice feature (or even, a higher-level “create a streaming signature from a streaming input” feature?) should exist in Sequoia-PGP, not in callers like this.

Right now, https://docs.rs/sequoia-openpgp/latest/sequoia_openpgp/cert/amalgamation/key/index.html#selecting-keys documents what needs to be done, but it’s an amount of code to copy&paste.

mtrmac added 7 commits August 5, 2025 15:51
Should not change (test) behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This matches (sq sign --signer), and per documentation:
> The caller may assume that looking up a fingerprint returns at most one certificate.

means we don't have to worry about ambiguities _if_ the input
is a fingerprint.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This is both needed for correctness, and it simplifies the code.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
The ultimate result should be the same value, but the former
does an extra check on the primary binding signature.

Also, this matches what (sq sign) does.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
Match what (sq sign) does.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This means we can terminate early as soon as we find a usable
key (and stop noting failures that are known to not matter),
and avoid some vectors / copies / complexity.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
... and the C binding.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
@mtrmac
Copy link
Contributor Author

mtrmac commented Aug 5, 2025

Now ready for review.

@mtrmac mtrmac marked this pull request as ready for review August 5, 2025 17:49
mtrmac added 2 commits August 5, 2025 23:28
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
Copy link
Owner

@ueno ueno left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, my comments are mostly nit-picks, and functionality-wise, this looks fine. Let's merge it now.

@ueno ueno merged commit f63a605 into ueno:main Aug 15, 2025
2 checks passed
@mtrmac mtrmac deleted the sign branch August 18, 2025 16:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants