feat(native): signing, validation & DID layer with zero-copy architecture#186
Merged
JeromySt merged 12 commits intousers/jstatia/native_ports_finalfrom Apr 2, 2026
Merged
Conversation
…ture Layer 3 staged merge from native_ports onto native_ports_final. ## Zero-Copy Architecture Single-allocation parsing: CoseSign1Message wraps one Arc<[u8]> and all fields (headers, payload, signature) are Range<usize> into that buffer. - CoseData::from_arc_range() — sub-view into parent buffer (0 alloc) - parse_from_shared() / parse_from_arc_slice() — parse nested messages (e.g. receipts) sharing the parent's Arc with zero allocation - ArcSlice::arc() / range() — expose backing buffer for downstream sharing - LazyHeaderMap — deferred parsing via OnceLock, zero-copy ArcSlice/ArcStr values reference the parent buffer - extract_receipts() returns Vec<ArcSlice> (no data copy) - merge_receipts() deduplicates via HashSet<ArcSlice> (no byte copying) ## Message Lifecycle (Composing → Signed) - MessageState enum tracks mutability: Signed messages lock protected headers, payload, and signature - set_unprotected_header() / remove_unprotected_header() — only mutation allowed post-signing, sets dirty flag - encode() fast-path: clean signed messages return backing bytes directly - encode_and_persist() — re-serializes and updates backing buffer - CoseSign1Builder::sign_to_message() — produces Signed message directly ## New Crates Signing: cose_sign1_signing, cose_sign1_factories, cose_sign1_headers Validation: cose_sign1_validation, cose_sign1_validation_primitives, cose_sign1_validation_test_utils DID: did_x509 FFI: 7 C-ABI projection crates for all above ## Handle-Based FFI (zero-copy across boundary) 15 new _to_message FFI functions return CoseSign1MessageHandle instead of copied byte buffers. C/C++ callers borrow data via accessor functions: - cose_sign1_message_as_bytes() → *const u8 into Rust Arc - cose_sign1_message_payload/signature/protected_bytes() → borrowed ## C++ Projections (thin RAII, no allocations) - ByteView struct replaces std::vector<uint8_t> for all byte accessors - CoseSign1Builder::Sign() returns CoseSign1Message (RAII handle) - Validator::Validate(const CoseSign1Message&) borrows message bytes - CryptoProvider::SignerFromPem() / VerifierFromPem() — PEM key support ## PEM Key Support Added across Rust → FFI → C++ layers: - EvpSigner::from_pem() / EvpVerifier::from_pem() - cose_crypto_openssl_signer_from_pem() / verifier_from_pem() - CryptoProvider::SignerFromPem(string/vector overloads) ## Coverage 5,681 tests, 0 failures. Line coverage: 90.34% (gate: 90%). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2f71aee to
bbded5b
Compare
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
bbded5b to
96be233
Compare
… tests - Add nightly Rust toolchain step to native-c-cpp CI job so coverage(off) attributes are properly activated during ASAN coverage collection - Remove redundant RUSTFLAGS --cfg coverage_nightly (cargo-llvm-cov sets it automatically on nightly) - Add 45 tests for _to_message FFI functions in signing core FFI - Add 33 tests for _to_message FFI functions in factories FFI - Total: 78 new tests covering previously untested _to_message variants Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Create minimal placeholder headers for certificates.h, mst.h, and azure_key_vault.h so the C smoke test can compile. The actual extension pack functions are gated behind #ifdef macros and are not yet implemented in this layer. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Fix rustfmt import ordering in factories_to_message_tests.rs - Guard trust plan compilation in C smoke test on having at least one extension pack (certificates, MST, or AKV) since compile_or fails with zero plans Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ility The BundledTrustPlan tests call compile_or() which fails when zero extension packs contribute default plans. Gate these tests on having at least one pack (certificates, MST, or AKV) available. Fixes C and C++ smoke test failures when extension packs are not built. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Fix unsound 'static lifetimes in FFI handle casts — use bounded <'a> lifetime parameters matching the primitives FFI pattern. Affects signing, factories, DID, and headers FFI crates (12 functions). - Add missing cose_sign1_message_as_bytes() declaration to C header. - Add validate_arc() / validate_arc_async() zero-copy overloads that accept Arc<CoseSign1Message> to avoid cloning in the validation path. - Eliminate header double-clone in FFI sign path — move fields out of the consumed BuilderInner instead of cloning. - Move options.additional_data instead of cloning in factory sign path. - Fix DID x509 FFI string ownership: change out params from *const to *mut c_char to correctly express ownership transfer, removing const_cast from C++ wrapper. - Document vector-returning factory methods noting zero-copy ToMessage alternatives. 5806 tests pass, 0 failures. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add cose_sign1_builder_consume_protected/unprotected FFI functions that move (not clone) header maps into the builder - Add C header declarations and C++ ConsumeProtected/ConsumeUnprotected RAII wrappers with HeaderMap::release() ownership transfer - Remove unnecessary .to_string()/.clone() allocations in DID x509 parser error paths (8 sites) and percent_encoding (use std::mem::take) - Add PartialEq derive to CwtClaims for whole-struct roundtrip assertions - Add round_trip_full_claims_struct_equality test covering all fields - Add module-level doc comments with architecture diagrams to signing and validation core lib.rs - Add @see cross-references from vector-returning factory methods to their zero-copy ToMessage alternatives in C++ headers - Add 7 new tests for consume FFI functions (success + null safety) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
New instruction files codifying the design principles, review criteria, migration patterns, and testing standards established during the signing and validation layer port: - zero-copy-design.instructions.md: No-allocation architecture patterns, Arc-based sharing, consume-vs-set FFI, known trade-offs checklist - code-review-standards.instructions.md: 5-dimension review grading (A-F), anti-patterns catalog, coverage exclusion policy - migration-playbook.instructions.md: V2 C# to Rust porting guide, phase tracker, trait mapping, async/config/DI translation patterns - testing-standards.instructions.md: FFI lifecycle tests, null safety, roundtrip tests, parallel safety, coverage targets and exclusions Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.
Layer 3 staged merge from native_ports onto native_ports_final.
Zero-Copy Architecture
Single-allocation parsing: CoseSign1Message wraps one Arc<[u8]> and all fields (headers, payload, signature) are Range into that buffer.
Message Lifecycle (Composing → Signed)
New Crates
Signing: cose_sign1_signing, cose_sign1_factories, cose_sign1_headers Validation: cose_sign1_validation, cose_sign1_validation_primitives,
cose_sign1_validation_test_utils
DID: did_x509
FFI: 7 C-ABI projection crates for all above
Handle-Based FFI (zero-copy across boundary)
15 new _to_message FFI functions return CoseSign1MessageHandle instead of copied byte buffers. C/C++ callers borrow data via accessor functions:
C++ Projections (thin RAII, no allocations)
PEM Key Support
Added across Rust → FFI → C++ layers:
Coverage
5,681 tests, 0 failures. Line coverage: 90.34% (gate: 90%).