From 4569510b51d6e950ceb10493f80bee77a2ef204c Mon Sep 17 00:00:00 2001 From: Max Tropets Date: Thu, 19 Mar 2026 10:28:37 +0000 Subject: [PATCH] Simplify COSE OpenSSL interface --- native/rust/cose_openssl/src/cose.rs | 519 ++++++++++----------------- native/rust/cose_openssl/src/lib.rs | 4 +- 2 files changed, 181 insertions(+), 342 deletions(-) diff --git a/native/rust/cose_openssl/src/cose.rs b/native/rust/cose_openssl/src/cose.rs index c4105f48..57417511 100644 --- a/native/rust/cose_openssl/src/cose.rs +++ b/native/rust/cose_openssl/src/cose.rs @@ -31,49 +31,6 @@ fn cose_alg(key: &EvpKey) -> Result { } } -/// Parse a COSE_Sign1 envelope and return (phdr_bytes, payload, signature). -fn parse_cose_sign1( - envelope: &[u8], -) -> Result<(Vec, CborValue, CborValue), String> { - let parsed = CborValue::from_bytes(envelope)?; - - let inner = match parsed { - CborValue::Tagged { tag, payload } if tag == COSE_SIGN1_TAG => *payload, - CborValue::Tagged { tag, .. } => { - return Err(format!( - "Wrong COSE tag: expected {COSE_SIGN1_TAG}, got {tag}" - )); - } - _ => return Err("Expected COSE_Sign1 tagged item".to_string()), - }; - - let items = match inner { - CborValue::Array(items) => items, - _ => { - return Err("Expected COSE_Sign1 array inside tag".to_string()); - } - }; - - if items.len() != 4 { - return Err("COSE_Sign1 array length is not 4".to_string()); - } - - let mut items = items.into_iter(); - let phdr = items.next().unwrap(); - let _uhdr = items.next().unwrap(); - let payload = items.next().unwrap(); - let signature = items.next().unwrap(); - - let phdr_bytes = match phdr { - CborValue::ByteString(b) => b, - _ => { - return Err("Protected header is not a byte string".to_string()); - } - }; - - Ok((phdr_bytes, payload, signature)) -} - /// Insert alg(1) into a CborValue map, return error if already exists. fn insert_alg_value( key: &EvpKey, @@ -109,7 +66,7 @@ fn sig_structure(phdr: &[u8], payload: &[u8]) -> Result, String> { .to_bytes() } -/// Produce a COSE_Sign1 envelope from CborValue headers. +/// Produce a COSE_Sign1 envelope. pub fn cose_sign1( key: &EvpKey, phdr: CborValue, @@ -148,106 +105,10 @@ pub fn cose_sign1( envelope.to_bytes() } -/// Produce a COSE_Sign1 envelope from pre-encoded CBOR bytes. -pub fn cose_sign1_encoded( - key: &EvpKey, - phdr: &[u8], - uhdr: &[u8], - payload: &[u8], - detached: bool, -) -> Result, String> { - let phdr_value = CborValue::from_bytes(phdr)?; - let uhdr_value = CborValue::from_bytes(uhdr)?; - cose_sign1(key, phdr_value, uhdr_value, payload, detached) -} - -/// Check that the algorithm encoded in the phdr is compatible with the key. -/// For RSA keys, any PS* algorithm is accepted (returns the alg value). -/// For other keys, exact match is required. -fn check_phdr_alg(key: &EvpKey, phdr_bytes: &[u8]) -> Result { - let parsed = CborValue::from_bytes(phdr_bytes)?; - - let alg = parsed - .map_at_int(COSE_HEADER_ALG) - .map_err(|_| "Algorithm not found in protected header".to_string())?; - - let alg_val = match alg { - CborValue::Int(v) => *v, - _ => { - return Err( - "Algorithm value in protected header is not an integer" - .to_string(), - ); - } - }; - - match &key.typ { - KeyType::RSA(_) => { - // Accept any PS* algorithm with any RSA key. - rsa_pss_md_for_cose_alg(alg_val)?; - Ok(alg_val) - } - _ => { - let expected = cose_alg(key)?; - if alg_val == expected { - Ok(alg_val) - } else { - Err("Algorithm mismatch between protected header and key" - .to_string()) - } - } - } -} - -/// Verify a COSE_Sign1 envelope. If `payload` is `Some`, it is used -/// as the detached payload; otherwise the embedded payload is used. +/// Verify a COSE_Sign1 from pre-parsed components. The caller supplies +/// the serialized protected header, payload, fixed-size signature (all +/// as byte slices), and the COSE algorithm integer (e.g. -7 for ES256). pub fn cose_verify1( - key: &EvpKey, - envelope: &[u8], - payload: Option<&[u8]>, -) -> Result { - let (phdr_bytes, cose_payload, cose_sig) = parse_cose_sign1(envelope)?; - - let header_alg = check_phdr_alg(key, &phdr_bytes)?; - - let actual_payload = match payload { - Some(p) => p.to_vec(), - None => match cose_payload { - CborValue::ByteString(b) => b, - _ => { - return Err("Embedded payload is not a byte string".to_string()); - } - }, - }; - - let sig = match cose_sig { - CborValue::ByteString(b) => b, - _ => return Err("Signature is not a byte string".to_string()), - }; - - let sig = match &key.typ { - KeyType::EC(_) => ecdsa_fixed_to_der(&sig, key.ec_field_size()?)?, - KeyType::RSA(_) => sig, - #[cfg(feature = "pqc")] - KeyType::MLDSA(_) => sig, - }; - - let tbs = sig_structure(&phdr_bytes, &actual_payload)?; - - match &key.typ { - KeyType::RSA(_) => { - let md = rsa_pss_md_for_cose_alg(header_alg)?; - crate::verify::verify_with_md(key, &sig, &tbs, md) - } - _ => crate::verify::verify(key, &sig, &tbs), - } -} - -/// Verify a COSE_Sign1 from pre-parsed components, skipping all CBOR -/// parsing. The caller supplies the serialized protected header, the -/// payload, the fixed-size signature, and the COSE algorithm integer -/// (e.g. -7 for ES256) which is checked against `key`. -pub fn cose_verify1_decoded( key: &EvpKey, alg: i64, phdr: &[u8], @@ -300,11 +161,37 @@ mod tests { const TEST_PHDR: &str = "A319018B020FA3061A698B72820173736572766963652E6578616D706C652E636F6D02706C65646765722E7369676E6174757265666363662E7631A1647478696465322E313334"; - #[test] - fn test_parse_cose() { - let in_str = "d284588da50138220458406661363331386532666561643537313035326231383230393236653865653531313030623630633161383239393362333031353133383561623334343237303019018b020fa3061a698b72820173736572766963652e6578616d706c652e636f6d02706c65646765722e7369676e6174757265666363662e7631a1647478696465322e313334a119018ca12081590100a2018358204208b5b5378c253f49641ab2edb58b557c75cdbb85ae9327930362c84ebba694784963653a322e3133333a3066646666336265663338346237383231316363336434306463363333663336383364353963643930303864613037653030623266356464323734613365633758200000000000000000000000000000000000000000000000000000000000000000028382f5582081980abb4e161b2f3d306c185ef9f7ce84cf5a3b0c8978da82e049d761adfd0082f55820610e8b89721667f99305e7ce4befe0b3b393821a3f72713f89961ebc7e81de6382f55820cbe0d3307b00aa9f324e29c8fb26508404af81044c7adcd4f5b41043d92aff23f6586005784bfccce87452a35a0cd14df5ed8a38c8937f63fb6b522fb94a1551c0e061893bb35fba1fa6fea322b080a14c0894c3864bf4e76df04ffb0f7c350366f91c0d522652d8fa3ebad6ba0270b48e43a065312c759d8bc9a413d4270d5ba86182"; - let v = hex_decode(in_str); - let (_phdr, _payload, _sig) = parse_cose_sign1(&v).unwrap(); + /// Helper: sign then verify via the new APIs. + fn sign_and_verify(key_type: KeyType) { + let key = EvpKey::new(key_type).unwrap(); + let phdr_bytes = hex_decode(TEST_PHDR); + let phdr = CborValue::from_bytes(&phdr_bytes).unwrap(); + let uhdr = CborValue::Map(vec![]); + let payload = b"Good boy..."; + + let envelope = cose_sign1(&key, phdr, uhdr, payload, false).unwrap(); + + // Parse envelope to extract raw components for cose_verify1. + let parsed = CborValue::from_bytes(&envelope).unwrap(); + let inner = match parsed { + CborValue::Tagged { payload, .. } => *payload, + _ => panic!("not tagged"), + }; + let items = match inner { + CborValue::Array(v) => v, + _ => panic!("not array"), + }; + let phdr_raw = match &items[0] { + CborValue::ByteString(b) => b.clone(), + _ => panic!("phdr not bstr"), + }; + let sig_raw = match &items[3] { + CborValue::ByteString(b) => b.clone(), + _ => panic!("sig not bstr"), + }; + + let alg = cose_alg(&key).unwrap(); + assert!(cose_verify1(&key, alg, &phdr_raw, payload, &sig_raw).unwrap()); } #[test] @@ -314,64 +201,25 @@ mod tests { let phdr = CborValue::from_bytes(&phdr_bytes).unwrap(); let phdr_with_alg = insert_alg_value(&key, phdr).unwrap(); - // Verify alg is present. let alg = phdr_with_alg.map_at_int(COSE_HEADER_ALG).unwrap(); assert_eq!(alg, &CborValue::Int(cose_alg(&key).unwrap())); - // Inserting again must fail. assert!(insert_alg_value(&key, phdr_with_alg).is_err()); } - fn sign_verify_cose_encoded(key_type: KeyType) { - let key = EvpKey::new(key_type).unwrap(); - let phdr = hex_decode(TEST_PHDR); - let uhdr = b"\xa0"; // empty map - let payload = b"Good boy..."; - - let envelope = - cose_sign1_encoded(&key, &phdr, uhdr, payload, false).unwrap(); - assert!(cose_verify1(&key, &envelope, None).unwrap()); - } - - fn sign_verify_cose(key_type: KeyType) { - let key = EvpKey::new(key_type).unwrap(); - let phdr_bytes = hex_decode(TEST_PHDR); - let phdr = CborValue::from_bytes(&phdr_bytes).unwrap(); - let uhdr = CborValue::Map(vec![]); // empty map - let payload = b"Good boy..."; - - let envelope = cose_sign1(&key, phdr, uhdr, payload, false).unwrap(); - assert!(cose_verify1(&key, &envelope, None).unwrap()); - } - #[test] fn cose_ec_p256() { - sign_verify_cose(KeyType::EC(WhichEC::P256)); + sign_and_verify(KeyType::EC(WhichEC::P256)); } #[test] fn cose_ec_p384() { - sign_verify_cose(KeyType::EC(WhichEC::P384)); + sign_and_verify(KeyType::EC(WhichEC::P384)); } #[test] fn cose_ec_p521() { - sign_verify_cose(KeyType::EC(WhichEC::P521)); - } - - #[test] - fn cose_encoded_ec_p256() { - sign_verify_cose_encoded(KeyType::EC(WhichEC::P256)); - } - - #[test] - fn cose_encoded_ec_p384() { - sign_verify_cose_encoded(KeyType::EC(WhichEC::P384)); - } - - #[test] - fn cose_encoded_ec_p521() { - sign_verify_cose_encoded(KeyType::EC(WhichEC::P521)); + sign_and_verify(KeyType::EC(WhichEC::P521)); } #[test] @@ -384,90 +232,43 @@ mod tests { let envelope = cose_sign1(&key, phdr, uhdr, payload, true).unwrap(); - // Verify with the detached payload supplied externally. - assert!(cose_verify1(&key, &envelope, Some(payload)).unwrap()); - - // Verify without supplying the payload must fail. - assert!(cose_verify1(&key, &envelope, None).is_err()); - } - - #[test] - fn cose_detached_payload_encoded() { - let key = EvpKey::new(KeyType::EC(WhichEC::P256)).unwrap(); - let phdr = hex_decode(TEST_PHDR); - let uhdr = b"\xa0"; // empty map - let payload = b"Good boy..."; - - let envelope = - cose_sign1_encoded(&key, &phdr, uhdr, payload, true).unwrap(); - - // Verify with the detached payload supplied externally. - assert!(cose_verify1(&key, &envelope, Some(payload)).unwrap()); - - // Verify without supplying the payload must fail. - assert!(cose_verify1(&key, &envelope, None).is_err()); - } - - fn sign_and_verify_raw(key_type: KeyType) { - let key = EvpKey::new(key_type).unwrap(); - let phdr_bytes = hex_decode(TEST_PHDR); - let phdr = CborValue::from_bytes(&phdr_bytes).unwrap(); - let uhdr = CborValue::Map(vec![]); - let payload = b"verify1_raw test"; - - let envelope = cose_sign1(&key, phdr, uhdr, payload, false).unwrap(); - - // Parse the envelope to extract raw components. - let (phdr_raw, cose_payload, cose_sig) = - parse_cose_sign1(&envelope).unwrap(); - let sig = match cose_sig { - CborValue::ByteString(b) => b, - _ => panic!("sig not bstr"), + let parsed = CborValue::from_bytes(&envelope).unwrap(); + let inner = match parsed { + CborValue::Tagged { payload, .. } => *payload, + _ => panic!("not tagged"), }; - let embedded_payload = match cose_payload { - CborValue::ByteString(b) => b, - _ => panic!("payload not bstr"), + let items = match inner { + CborValue::Array(v) => v, + _ => panic!("not array"), + }; + let phdr_raw = match &items[0] { + CborValue::ByteString(b) => b.clone(), + _ => panic!("phdr not bstr"), + }; + let sig_raw = match &items[3] { + CborValue::ByteString(b) => b.clone(), + _ => panic!("sig not bstr"), }; - let alg = cose_alg(&key).unwrap(); - assert!( - cose_verify1_decoded(&key, alg, &phdr_raw, &embedded_payload, &sig) - .unwrap() - ); - } - - #[test] - fn cose_verify1_raw_p256() { - sign_and_verify_raw(KeyType::EC(WhichEC::P256)); - } - - #[test] - fn cose_verify1_raw_p384() { - sign_and_verify_raw(KeyType::EC(WhichEC::P384)); - } + assert_eq!(items[2], CborValue::Simple(CBOR_SIMPLE_VALUE_NULL)); - #[test] - fn cose_verify1_raw_p521() { - sign_and_verify_raw(KeyType::EC(WhichEC::P521)); + let alg = cose_alg(&key).unwrap(); + assert!(cose_verify1(&key, alg, &phdr_raw, payload, &sig_raw).unwrap()); } #[test] - fn cose_verify1_raw_wrong_alg() { + fn cose_verify1_wrong_alg() { let key = EvpKey::new(KeyType::EC(WhichEC::P256)).unwrap(); - // Pass a wrong algorithm id. - assert!(cose_verify1_decoded(&key, -35, b"", b"", b"").is_err()); + assert!(cose_verify1(&key, -35, b"", b"", b"").is_err()); } #[test] fn cose_with_der_imported_key() { - // Create key pair let original_key = EvpKey::new(KeyType::EC(WhichEC::P384)).unwrap(); - // Export private key to DER and reimport for signing let priv_der = original_key.to_der_private().unwrap(); let signing_key = EvpKey::from_der_private(&priv_der).unwrap(); - // Export public key DER and reimport for verification let pub_der = original_key.to_der_public().unwrap(); let verification_key = EvpKey::from_der_public(&pub_der).unwrap(); @@ -476,38 +277,47 @@ mod tests { let uhdr = CborValue::Map(vec![]); let payload = b"test with DER-imported key"; - // Sign with DER-reimported private key let envelope = cose_sign1(&signing_key, phdr, uhdr, payload, false).unwrap(); - // Verify with DER-imported public key - assert!(cose_verify1(&verification_key, &envelope, None).unwrap()); - } - - fn sign_verify_cose_rsa(key_type: KeyType) { - let key = EvpKey::new(key_type).unwrap(); - let phdr_bytes = hex_decode(TEST_PHDR); - let phdr = CborValue::from_bytes(&phdr_bytes).unwrap(); - let uhdr = CborValue::Map(vec![]); - let payload = b"RSA PSS test"; + let parsed = CborValue::from_bytes(&envelope).unwrap(); + let inner = match parsed { + CborValue::Tagged { payload, .. } => *payload, + _ => panic!("not tagged"), + }; + let items = match inner { + CborValue::Array(v) => v, + _ => panic!("not array"), + }; + let phdr_raw = match &items[0] { + CborValue::ByteString(b) => b.clone(), + _ => panic!("phdr not bstr"), + }; + let sig_raw = match &items[3] { + CborValue::ByteString(b) => b.clone(), + _ => panic!("sig not bstr"), + }; - let envelope = cose_sign1(&key, phdr, uhdr, payload, false).unwrap(); - assert!(cose_verify1(&key, &envelope, None).unwrap()); + let alg = cose_alg(&verification_key).unwrap(); + assert!( + cose_verify1(&verification_key, alg, &phdr_raw, payload, &sig_raw) + .unwrap() + ); } #[test] fn cose_rsa_ps256() { - sign_verify_cose_rsa(KeyType::RSA(WhichRSA::PS256)); + sign_and_verify(KeyType::RSA(WhichRSA::PS256)); } #[test] fn cose_rsa_ps384() { - sign_verify_cose_rsa(KeyType::RSA(WhichRSA::PS384)); + sign_and_verify(KeyType::RSA(WhichRSA::PS384)); } #[test] fn cose_rsa_ps512() { - sign_verify_cose_rsa(KeyType::RSA(WhichRSA::PS512)); + sign_and_verify(KeyType::RSA(WhichRSA::PS512)); } #[test] @@ -527,7 +337,30 @@ mod tests { let envelope = cose_sign1(&signing_key, phdr, uhdr, payload, false).unwrap(); - assert!(cose_verify1(&verification_key, &envelope, None).unwrap()); + + let parsed = CborValue::from_bytes(&envelope).unwrap(); + let inner = match parsed { + CborValue::Tagged { payload, .. } => *payload, + _ => panic!("not tagged"), + }; + let items = match inner { + CborValue::Array(v) => v, + _ => panic!("not array"), + }; + let phdr_raw = match &items[0] { + CborValue::ByteString(b) => b.clone(), + _ => panic!("phdr not bstr"), + }; + let sig_raw = match &items[3] { + CborValue::ByteString(b) => b.clone(), + _ => panic!("sig not bstr"), + }; + + let alg = cose_alg(&verification_key).unwrap(); + assert!( + cose_verify1(&verification_key, alg, &phdr_raw, payload, &sig_raw) + .unwrap() + ); } #[test] @@ -539,36 +372,27 @@ mod tests { let payload = b"RSA detached"; let envelope = cose_sign1(&key, phdr, uhdr, payload, true).unwrap(); - assert!(cose_verify1(&key, &envelope, Some(payload)).unwrap()); - assert!(cose_verify1(&key, &envelope, None).is_err()); - } - - #[test] - fn cose_verify1_decoded_rsa() { - let key = EvpKey::new(KeyType::RSA(WhichRSA::PS256)).unwrap(); - let phdr_bytes = hex_decode(TEST_PHDR); - let phdr = CborValue::from_bytes(&phdr_bytes).unwrap(); - let uhdr = CborValue::Map(vec![]); - let payload = b"RSA decoded verify"; - - let envelope = cose_sign1(&key, phdr, uhdr, payload, false).unwrap(); - let (phdr_raw, cose_payload, cose_sig) = - parse_cose_sign1(&envelope).unwrap(); - let sig = match cose_sig { - CborValue::ByteString(b) => b, - _ => panic!("sig not bstr"), + let parsed = CborValue::from_bytes(&envelope).unwrap(); + let inner = match parsed { + CborValue::Tagged { payload, .. } => *payload, + _ => panic!("not tagged"), }; - let embedded_payload = match cose_payload { - CborValue::ByteString(b) => b, - _ => panic!("payload not bstr"), + let items = match inner { + CborValue::Array(v) => v, + _ => panic!("not array"), + }; + let phdr_raw = match &items[0] { + CborValue::ByteString(b) => b.clone(), + _ => panic!("phdr not bstr"), + }; + let sig_raw = match &items[3] { + CborValue::ByteString(b) => b.clone(), + _ => panic!("sig not bstr"), }; let alg = cose_alg(&key).unwrap(); - assert!( - cose_verify1_decoded(&key, alg, &phdr_raw, &embedded_payload, &sig) - .unwrap() - ); + assert!(cose_verify1(&key, alg, &phdr_raw, payload, &sig_raw).unwrap()); } /// Sign with a PS256 key (2048-bit RSA) but use SHA-384 (PS384 @@ -597,47 +421,41 @@ mod tests { let md = rsa_pss_md_for_cose_alg(-38).unwrap(); let sig = crate::sign::sign_with_md(&key, &tbs, md).unwrap(); - // Assemble the COSE_Sign1 envelope. - let envelope = CborValue::Tagged { - tag: COSE_SIGN1_TAG, - payload: Box::new(CborValue::Array(vec![ - CborValue::ByteString(phdr_ser), - CborValue::Map(vec![]), - CborValue::ByteString(payload.to_vec()), - CborValue::ByteString(sig), - ])), - } - .to_bytes() - .unwrap(); - - // Verify — header says PS384 so SHA-384 is used. - assert!(cose_verify1(&key, &envelope, None).unwrap()); + // Verify with PS384 alg. + assert!(cose_verify1(&key, -38, &phdr_ser, payload, &sig).unwrap()); } + /// Verify that a &[u8] payload is stored directly in the envelope + /// bstr without double-encoding as bstr(bstr(...)). #[test] - fn cose_verify1_rejects_trailing_bytes() { + fn cose_sign1_no_double_encoding() { let key = EvpKey::new(KeyType::EC(WhichEC::P256)).unwrap(); let phdr_bytes = hex_decode(TEST_PHDR); let phdr = CborValue::from_bytes(&phdr_bytes).unwrap(); let uhdr = CborValue::Map(vec![]); - let payload = b"Good boy..."; + let payload = b"test payload"; let envelope = cose_sign1(&key, phdr, uhdr, payload, false).unwrap(); - // Sanity: valid envelope verifies. - assert!(cose_verify1(&key, &envelope, None).unwrap()); - - // Append a redundant trailing byte. - let mut bad_envelope = envelope.clone(); - bad_envelope.push(0x00); - - // Verification of the envelope with trailing bytes should fail - // (either return an error or reject the signature). - let result = cose_verify1(&key, &bad_envelope, None); - assert!( - result.is_err(), - "Expected error with trailing byte, got: {:?}", - result, + let parsed = CborValue::from_bytes(&envelope).unwrap(); + let inner = match parsed { + CborValue::Tagged { payload, .. } => *payload, + _ => panic!("not tagged"), + }; + let items = match inner { + CborValue::Array(v) => v, + _ => panic!("not array"), + }; + let payload_in_envelope = match &items[2] { + CborValue::ByteString(b) => b.clone(), + _ => panic!("payload not bstr"), + }; + // The envelope payload must equal the raw data, not a + // CBOR-encoded bstr wrapping it. + assert_eq!( + payload_in_envelope, + payload.to_vec(), + "payload double-encoded as bstr(bstr(...))" ); } @@ -646,28 +464,25 @@ mod tests { use super::*; #[test] fn cose_mldsa44() { - sign_verify_cose(KeyType::MLDSA(WhichMLDSA::P44)); + sign_and_verify(KeyType::MLDSA(WhichMLDSA::P44)); } #[test] fn cose_mldsa65() { - sign_verify_cose(KeyType::MLDSA(WhichMLDSA::P65)); + sign_and_verify(KeyType::MLDSA(WhichMLDSA::P65)); } #[test] fn cose_mldsa87() { - sign_verify_cose(KeyType::MLDSA(WhichMLDSA::P87)); + sign_and_verify(KeyType::MLDSA(WhichMLDSA::P87)); } #[test] fn cose_mldsa_with_der_imported_key() { - // Create ML-DSA key pair let original_key = EvpKey::new(KeyType::MLDSA(WhichMLDSA::P65)).unwrap(); - // Export private key to DER and reimport for signing let priv_der = original_key.to_der_private().unwrap(); let signing_key = EvpKey::from_der_private(&priv_der).unwrap(); - // Export public key DER and reimport for verification let pub_der = original_key.to_der_public().unwrap(); let verification_key = EvpKey::from_der_public(&pub_der).unwrap(); @@ -676,12 +491,38 @@ mod tests { let uhdr = CborValue::Map(vec![]); let payload = b"ML-DSA with DER-imported key"; - // Sign with DER-reimported private key let envelope = cose_sign1(&signing_key, phdr, uhdr, payload, false).unwrap(); - // Verify with DER-imported public key - assert!(cose_verify1(&verification_key, &envelope, None).unwrap()); + let parsed = CborValue::from_bytes(&envelope).unwrap(); + let inner = match parsed { + CborValue::Tagged { payload, .. } => *payload, + _ => panic!("not tagged"), + }; + let items = match inner { + CborValue::Array(v) => v, + _ => panic!("not array"), + }; + let phdr_raw = match &items[0] { + CborValue::ByteString(b) => b.clone(), + _ => panic!("phdr not bstr"), + }; + let sig_raw = match &items[3] { + CborValue::ByteString(b) => b.clone(), + _ => panic!("sig not bstr"), + }; + + let alg = cose_alg(&verification_key).unwrap(); + assert!( + cose_verify1( + &verification_key, + alg, + &phdr_raw, + payload, + &sig_raw + ) + .unwrap() + ); } } } diff --git a/native/rust/cose_openssl/src/lib.rs b/native/rust/cose_openssl/src/lib.rs index 740a87bd..ede1c5eb 100644 --- a/native/rust/cose_openssl/src/lib.rs +++ b/native/rust/cose_openssl/src/lib.rs @@ -5,9 +5,7 @@ mod sign; mod verify; pub use cbor::CborValue; -pub use cose::{ - cose_sign1, cose_sign1_encoded, cose_verify1, cose_verify1_decoded, -}; +pub use cose::{cose_sign1, cose_verify1}; pub use ossl_wrappers::{EvpKey, KeyType, WhichEC, WhichRSA}; #[cfg(feature = "pqc")]