ffi: add rnp_uid_get_photo() for Photo ID read support (#13) - #2430
Open
ronaldtse wants to merge 3 commits into
Open
ffi: add rnp_uid_get_photo() for Photo ID read support (#13)#2430ronaldtse wants to merge 3 commits into
ronaldtse wants to merge 3 commits into
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #2430 +/- ##
==========================================
+ Coverage 85.44% 85.47% +0.02%
==========================================
Files 125 125
Lines 22962 23028 +66
==========================================
+ Hits 19620 19683 +63
- Misses 3342 3345 +3 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
ronaldtse
force-pushed
the
photo-id-support
branch
from
August 1, 2026 08:23
e03ea3d to
15e6050
Compare
ronaldtse
force-pushed
the
photo-id-support
branch
from
August 10, 2026 02:09
15e6050 to
b4d0768
Compare
ronaldtse
force-pushed
the
photo-id-support
branch
3 times, most recently
from
August 22, 2026 05:25
b879067 to
1e845f9
Compare
ronaldtse
force-pushed
the
photo-id-support
branch
from
August 29, 2026 01:42
1e845f9 to
fe2253f
Compare
7 tasks
Foundation for issue #1947 (Photo ID support). Adds an FFI function that parses the User Attribute packet body (RFC 4880 §5.12 / RFC 9580 §5.13) and returns just the image bytes plus its detected format (JPEG or PNG), saving callers from having to implement the subpacket length decoding and image-header walk themselves. The UserAttr packet was already loaded and stored as a UID with type RNP_USER_ATTR; this PR adds the typed photo accessor on top. Image format is detected from the bytes' magic header (FF D8 FF for JPEG, 89 50 4E 47 for PNG), not from the UserAttr header's format byte, since real-world keys frequently leave the format byte at 0 even when the data is a valid JPEG. Out of scope (follow-up PRs): - rnp_key_add_photo() to attach a new photo to a key - CLI --show-photo flag - Negative tests with crafted malformed UserAttr bodies - Photo ID display in --list-keys output
…ollow-up) The FFI test only exercises one fixture (the JPEG round-trip), so codecov shows the parser's edge cases uncovered. Adds test_parse_photo_attribute in cipher.cpp that calls the C++ API directly with crafted UserAttr bodies to cover: - JPEG happy path - PNG happy path (different magic-byte detection branch) - Unknown image format (still returns bytes, format = Unknown) - Empty body - Non-image subpacket type (must skip past) - Header length 0 (must reject — RFC requires >= 16) - Image too small to magic-check (< 3 bytes) - 5-byte subpacket length form (b0 == 255) - Partial-length encoding (b0 in 224-254) — must reject - Multiple subpackets where the first is non-image and the second contains the photo
Main's lint now runs the clang-format 11.1.0 binary (a6b0b99); these files were formatted under the previous 11.0.x pin and drifted.
ronaldtse
force-pushed
the
photo-id-support
branch
from
August 30, 2026 20:37
fe2253f to
a9b409b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Foundation for issue #1947 (Photo ID support). Adds an FFI function that parses the User Attribute packet body and returns just the image bytes plus the detected format, so callers don't have to implement the subpacket length decoding and image-header walk themselves.
What's in this PR
include/rnp/rnp.h: new constantsRNP_PHOTO_FORMAT_{UNKNOWN,JPEG,PNG}and new FFI functionrnp_uid_get_photo(uid, &format, &data, &size)with thorough Doxygen.src/lib/userid.{hpp,cpp}: new helperrnp::parse_photo_attribute(uid_body, image, format)that walks the variable-length subpacket prefix, finds the first Image Attribute subpacket (type 1), and returns its image bytes plus detected format. The image header length byte counts itself (RFC 4880 §5.12.1 / RFC 9580 §5.13.1), so the remaining header bytes to skip arehdr_len - 1, nothdr_len. Format is detected from magic bytes (JPEG: FF D8 FF, PNG: 89 50 4E 47), not from the UserAttr header's format byte — real-world keys frequently leave that byte at 0 even when the image data is a valid JPEG.src/lib/rnp.cpp: FFI implementation. ReturnsRNP_ERROR_BAD_PARAMETERSif the UID is not a User Attribute packet,RNP_ERROR_BAD_STATEif the UserAttr body is malformed or contains no image subpacket.src/tests/ffi.cpp: extends the existingtest_ffi_load_userattrto exercise the new API: asserts the photo UID returns JPEG bytes with the correct magic header, and that callingrnp_uid_get_photo()on a non-photo UID is rejected.Why
The "gpg can, rnp can't" feature gap is most visible to end users — Thunderbird users with photo IDs on their keys see them silently dropped when their keyring is read by rnp. The UserAttr packet was already loaded as an opaque UID with
type=RNP_USER_ATTRand the raw bytes retrievable viarnp_uid_get_data(), but parsing those bytes was the caller's job. This PR makes the common case (a JPEG photo) one FFI call.Out of scope (follow-up PRs)
rnp_key_add_photo()to attach a new photo to a key (needs serialiser work)--show-photoflag,[photo]indicator in--list-keysTest plan
test_ffi_load_userattr(extended) passes: verifies JPEG magic, JPEG format constant, rejection of non-photo UIDdata/test_stream_key_load/ecc-25519-photo-pub.asc— image bytes form a valid JPEG (starts withFF D8 FF E0, ends withFF D9)test_ffi_add_userid,test_ffi_key_userid_dump_has_no_special_chars,test_ffi_key_dump_edge_cases