From bcf60c5e8d5b842cb3676fa4cf06eb0b44808e5d Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Fri, 19 Dec 2025 11:54:03 +0000 Subject: [PATCH] Tweak tests for more code coverage --- src/common/tests.rs | 18 +++++++++++++++++- src/encrypt/tests.rs | 23 +++++++++++++++++++++++ src/key/tests.rs | 15 +++++++++------ src/mac/tests.rs | 18 ++++++++++++++++++ src/util/mod.rs | 2 +- 5 files changed, 68 insertions(+), 8 deletions(-) diff --git a/src/common/tests.rs b/src/common/tests.rs index 8dbda7d..4e93805 100644 --- a/src/common/tests.rs +++ b/src/common/tests.rs @@ -20,7 +20,7 @@ use alloc::{borrow::ToOwned, format, vec}; use core::cmp::Ordering; #[test] -fn test_error_convert() { +fn test_ser_error_convert() { let e = CoseError::from(crate::cbor::ser::Error::::Value( "error message lost".to_owned(), )); @@ -33,6 +33,21 @@ fn test_error_convert() { } } +#[test] +fn test_de_error_convert() { + // Instances of `cbor::de::Error` get embedded into the `DecodeFailed` variant. + let tests = [ + || cbor::de::Error::RecursionLimitExceeded, + || cbor::de::Error::Semantic(None, "err".to_owned()), + || cbor::de::Error::Syntax(42), + ]; + for err_gen in tests { + let got = CoseError::from(err_gen()); + let want = CoseError::DecodeFailed(err_gen()); + assert_eq!(format!("{got:?}"), format!("{want}")); + } +} + #[test] fn test_label_encode() { let tests = [ @@ -183,6 +198,7 @@ fn test_label_decode_fail() { #[test] fn test_registered_label_encode() { let tests = [ + (RegisteredLabel::from(iana::Algorithm::A192GCM), "02"), (RegisteredLabel::Assigned(iana::Algorithm::A192GCM), "02"), (RegisteredLabel::Assigned(iana::Algorithm::EdDSA), "27"), (RegisteredLabel::Text("abc".to_owned()), "63616263"), diff --git a/src/encrypt/tests.rs b/src/encrypt/tests.rs index f0378bf..a507174 100644 --- a/src/encrypt/tests.rs +++ b/src/encrypt/tests.rs @@ -864,6 +864,29 @@ fn test_cose_recipient_decrypt_invalid_context() { let external_aad = b"This is the external aad"; let cipher = FakeCipher {}; + let recipient = CoseRecipientBuilder::new() + .create_ciphertext( + EncryptionContext::EncRecipient, + pt, + external_aad, + |pt, aad| cipher.encrypt(pt, aad).unwrap(), + ) + .build(); + + // Can't use a non-recipient context. + #[allow(deprecated)] + let _result = recipient.decrypt(EncryptionContext::CoseEncrypt, external_aad, |ct, aad| { + cipher.decrypt(ct, aad) + }); +} + +#[test] +#[should_panic] +fn test_cose_recipient_decrypt_ciphertext_invalid_context() { + let pt = b"This is the plaintext"; + let external_aad = b"This is the external aad"; + let cipher = FakeCipher {}; + let recipient = CoseRecipientBuilder::new() .create_ciphertext( EncryptionContext::EncRecipient, diff --git a/src/key/tests.rs b/src/key/tests.rs index 2957aff..5ead5f7 100644 --- a/src/key/tests.rs +++ b/src/key/tests.rs @@ -16,7 +16,7 @@ use super::*; use crate::{cbor::value::Value, iana, util::expect_err, CborOrdering, CborSerializable}; -use alloc::{borrow::ToOwned, string::ToString, vec}; +use alloc::{borrow::ToOwned, format, string::ToString, vec}; #[test] fn test_cose_key_encode() { @@ -302,6 +302,8 @@ fn test_new_ec2_pub_key_sec1_octet_string_errors() { ]; for (i, (got, want)) in tests.iter().enumerate() { assert_eq!(got, want, "case {i}"); + assert!(!format!("{got}").is_empty()); + assert!(!format!("{got:?}").is_empty()); } } @@ -1149,10 +1151,11 @@ fn test_key_to_sec1_octet_string() { ), ]; for (i, (key, want)) in tests.iter().enumerate() { - assert_eq!( - key.to_sec1_octet_string().map(hex::encode), - want.map(str::to_string), - "case {i}" - ); + let got = key.to_sec1_octet_string().map(hex::encode); + assert_eq!(got, want.map(str::to_string), "case {i}"); + if let Err(e) = got { + assert!(!format!("{e}").is_empty()); + assert!(!format!("{e:?}").is_empty()); + } } } diff --git a/src/mac/tests.rs b/src/mac/tests.rs index 26016d7..e229287 100644 --- a/src/mac/tests.rs +++ b/src/mac/tests.rs @@ -796,3 +796,21 @@ fn test_cose_mac0_verify_tag_no_payload() { #[allow(deprecated)] let _result = mac.verify_tag(external_aad, |tag, data| tagger.verify(tag, data)); } + +#[test] +fn test_cose_mac0_verify_payload_tag_no_payload() { + let tagger = FakeMac {}; + let external_aad = b"This is the external aad"; + let mut mac = CoseMac0Builder::new() + .protected(HeaderBuilder::new().key_id(b"11".to_vec()).build()) + .payload(b"This is the data".to_vec()) + .create_tag(external_aad, |data| tagger.compute(data)) + .build(); + + mac.payload = None; + // Trying to verify with no payload emits an error. + let result = mac.verify_payload_tag(external_aad, no_payload_err, |tag, data| { + tagger.verify(tag, data) + }); + assert_eq!(result, Err(no_payload_err())); +} diff --git a/src/util/mod.rs b/src/util/mod.rs index 6da9bf4..c0f46e9 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -38,7 +38,7 @@ pub(crate) fn cbor_type_error(value: &Value, want: &'static str) -> Result Value::Tag(_, _) => "tag", Value::Array(_) => "array", Value::Map(_) => "map", - _ => "other", + _ => "other", // unhittable: `Value` marked as non-exhaustive }; Err(CoseError::UnexpectedItem(got, want)) }