Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 99 additions & 2 deletions native/rust/cose_openssl/src/cose.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,10 @@ mod tests {
let alg = phdr_with_alg.map_at_int(COSE_HEADER_ALG).unwrap();
assert_eq!(alg, &CborValue::Int(cose_alg(&key).unwrap()));

assert!(insert_alg_value(&key, phdr_with_alg).is_err());
assert_eq!(
insert_alg_value(&key, phdr_with_alg).unwrap_err(),
"Algorithm already set in protected header"
);
}

#[test]
Expand Down Expand Up @@ -263,7 +266,10 @@ mod tests {
#[test]
fn cose_verify1_wrong_alg() {
let key = EvpKey::new(KeyType::EC(WhichEC::P256)).unwrap();
assert!(cose_verify1(&key, -35, b"", b"", b"").is_err());
assert_eq!(
cose_verify1(&key, -35, b"", b"", b"").unwrap_err(),
"Algorithm mismatch between supplied alg and key"
);
}

#[test]
Expand Down Expand Up @@ -463,6 +469,97 @@ mod tests {
);
}

// ---------------------------------------------------------------
// Negative tests: error propagation through cose_sign1/cose_verify1
// ---------------------------------------------------------------

#[test]
fn cose_sign1_rejects_non_map_phdr() {
let key = EvpKey::new(KeyType::EC(WhichEC::P256)).unwrap();
assert_eq!(
cose_sign1(
&key,
CborValue::Int(0),
CborValue::Map(vec![]),
b"msg",
false
)
.unwrap_err(),
"Protected header is not a CBOR map"
);
}

#[test]
fn cose_sign1_rejects_duplicate_alg() {
let key = EvpKey::new(KeyType::EC(WhichEC::P256)).unwrap();
let phdr = CborValue::Map(vec![(
CborValue::Int(COSE_HEADER_ALG),
CborValue::Int(-7),
)]);
assert_eq!(
cose_sign1(&key, phdr, CborValue::Map(vec![]), b"msg", false)
.unwrap_err(),
"Algorithm already set in protected header"
);
}

#[test]
fn cose_sign1_propagates_ossl_sign_error() {
// Null key triggers EVP_DigestSignInit failure.
let null_key = EvpKey {
key: std::ptr::null_mut(),
typ: KeyType::EC(WhichEC::P256),
};
let err = cose_sign1(
&null_key,
CborValue::Map(vec![]),
CborValue::Map(vec![]),
b"msg",
false,
)
.unwrap_err();
assert!(
err.starts_with("EVP_DigestSignInit returned 0: error:"),
"unexpected error: {err}"
);
}

#[test]
fn cose_verify1_wrong_rsa_alg() {
let key = EvpKey::new(KeyType::RSA(WhichRSA::PS256)).unwrap();
assert_eq!(
cose_verify1(&key, -7, b"", b"", b"").unwrap_err(),
"-7 is not a COSE RSA-PSS algorithm"
);
}

#[test]
fn cose_verify1_ec_sig_wrong_length() {
let key = EvpKey::new(KeyType::EC(WhichEC::P256)).unwrap();
let pub_der = key.to_der_public().unwrap();
let pub_key = EvpKey::from_der_public(&pub_der).unwrap();
// P-256 expects 64 byte fixed sig, pass 3 bytes.
assert_eq!(
cose_verify1(&pub_key, -7, b"", b"", &[0u8; 3]).unwrap_err(),
"Expected 64 byte ECDSA signature, got 3"
);
}

#[test]
fn cose_verify1_propagates_ossl_verify_error() {
// Null key triggers EVP_DigestVerifyInit failure.
let null_key = EvpKey {
key: std::ptr::null_mut(),
typ: KeyType::RSA(WhichRSA::PS256),
};
let err =
cose_verify1(&null_key, -37, b"", b"", &[0u8; 256]).unwrap_err();
assert!(
err.starts_with("EVP_DigestVerifyInit returned 0: error:"),
"unexpected error: {err}"
);
}

#[cfg(feature = "pqc")]
mod pqc_tests {
use super::*;
Expand Down
Loading
Loading