diff --git a/native/rust/cose_openssl/Cargo.toml b/native/rust/cose_openssl/Cargo.toml index 6486a635..7ab661ea 100644 --- a/native/rust/cose_openssl/Cargo.toml +++ b/native/rust/cose_openssl/Cargo.toml @@ -14,5 +14,5 @@ warnings = "deny" [dependencies] openssl-sys = "0.9" -cborrs = { git = "https://github.com/project-everest/everparse.git", tag = "v2026.02.25" } -cborrs-nondet = { git = "https://github.com/project-everest/everparse.git", tag = "v2026.02.25" } +cborrs = { git = "https://github.com/project-everest/everparse.git", rev = "f4cd5ffa183edd5cc824d66588012bcf8d0bdccd" } # v2026.02.25 +cborrs-nondet = { git = "https://github.com/project-everest/everparse.git", rev = "f4cd5ffa183edd5cc824d66588012bcf8d0bdccd" } # v2026.02.25 diff --git a/native/rust/cose_openssl/src/cbor.rs b/native/rust/cose_openssl/src/cbor.rs index 9cc70922..ba6c3850 100644 --- a/native/rust/cose_openssl/src/cbor.rs +++ b/native/rust/cose_openssl/src/cbor.rs @@ -287,6 +287,28 @@ fn serialize_det(item: CborDet) -> Result, String> { Ok(buf) } +/// A CBOR item that borrows its data, for zero-copy serialization. +pub enum CborSlice<'a> { + TextStr(&'a str), + ByteStr(&'a [u8]), +} + +/// Serialize a CBOR array of borrowed items without intermediate copies. +pub fn serialize_array(items: &[CborSlice<'_>]) -> Result, String> { + let mut raw: Vec> = items + .iter() + .map(|item| match item { + CborSlice::TextStr(s) => cbor_det_mk_text_string(s) + .ok_or("Failed to make CBOR text string".to_string()), + CborSlice::ByteStr(b) => cbor_det_mk_byte_string(b) + .ok_or("Failed to make CBOR byte string".to_string()), + }) + .collect::>()?; + let array = cbor_det_mk_array(&mut raw) + .ok_or("Failed to build CBOR array".to_string())?; + serialize_det(array) +} + impl std::fmt::Debug for CborValue { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { diff --git a/native/rust/cose_openssl/src/cose.rs b/native/rust/cose_openssl/src/cose.rs index 57417511..5ea1ce31 100644 --- a/native/rust/cose_openssl/src/cose.rs +++ b/native/rust/cose_openssl/src/cose.rs @@ -1,4 +1,4 @@ -use crate::cbor::CborValue; +use crate::cbor::{CborSlice, CborValue, serialize_array}; use crate::ossl_wrappers::{ EvpKey, KeyType, WhichEC, WhichRSA, ecdsa_der_to_fixed, ecdsa_fixed_to_der, rsa_pss_md_for_cose_alg, @@ -56,14 +56,18 @@ fn insert_alg_value( /// To-be-signed (TBS). /// https://www.rfc-editor.org/rfc/rfc9052.html#section-4.4. +/// +/// Uses `serialize_array` with borrowed slices to avoid copying +/// `phdr` and `payload` into intermediate `Vec`s. These can +/// be large (payload especially), so we serialize directly from +/// the caller's buffers. fn sig_structure(phdr: &[u8], payload: &[u8]) -> Result, String> { - CborValue::Array(vec![ - CborValue::TextString(SIG_STRUCTURE1_CONTEXT.to_string()), - CborValue::ByteString(phdr.to_vec()), - CborValue::ByteString(vec![]), - CborValue::ByteString(payload.to_vec()), + serialize_array(&[ + CborSlice::TextStr(SIG_STRUCTURE1_CONTEXT), + CborSlice::ByteStr(phdr), + CborSlice::ByteStr(&[]), + CborSlice::ByteStr(payload), ]) - .to_bytes() } /// Produce a COSE_Sign1 envelope. diff --git a/native/rust/cose_openssl/src/sign.rs b/native/rust/cose_openssl/src/sign.rs index 69b7ce9f..32020189 100644 --- a/native/rust/cose_openssl/src/sign.rs +++ b/native/rust/cose_openssl/src/sign.rs @@ -33,7 +33,7 @@ fn sign_with_ctx( msg.len(), ); if res != 1 { - return Err(format!("Failed to signature size, err: {}", res)); + return Err(format!("Failed to get signature size, err: {}", res)); } let mut sig = vec![0u8; sig_size];