#![allow(missing_docs)]
use core::ptr::NonNull;
use wolfcose::{
sign1_into, sign1_to_vec, sign_into, verify1, verify_sign, Algorithm, CoseKey, CoseKeyBuilder,
Encrypt0Builder, EncryptBuilder, Error, Mac0Builder, MacBuilder, PayloadMode, Recipient,
Sign1Builder, SignBuilder, Signature,
};
const PAYLOAD: &[u8] = b"secured drone payload";
const AAD: &[u8] = b"drone-protocol/v1:test";
const IV: [u8; 12] = *b"unique-iv-01";
fn aes_key() -> CoseKey {
CoseKeyBuilder::symmetric([0x11; 16])
.algorithm(Algorithm::A128GCM)
.kid(b"aes")
.build()
.unwrap()
}
fn mac_key() -> CoseKey {
CoseKeyBuilder::symmetric([0x22; 32])
.algorithm(Algorithm::HMAC256)
.kid(b"mac")
.build()
.unwrap()
}
#[test]
fn builders_report_missing_required_inputs() {
let key = aes_key();
let mut out = [0; 256];
assert_eq!(
Encrypt0Builder::default().encrypt_into(&mut out),
Err(Error::InvalidArgument)
);
assert_eq!(
Encrypt0Builder::new().encrypt_into(&mut out),
Err(Error::InvalidArgument)
);
assert_eq!(
Encrypt0Builder::new()
.key(&key)
.algorithm(Algorithm::A128GCM)
.iv(&IV)
.payload(PayloadMode::Detached(PAYLOAD))
.encrypt_into(&mut out),
Err(Error::InvalidArgument)
);
let mac_key = mac_key();
assert_eq!(
Mac0Builder::default().mac_into(&mut out),
Err(Error::InvalidArgument)
);
assert_eq!(
Mac0Builder::new().mac_into(&mut out),
Err(Error::InvalidArgument)
);
assert_eq!(
MacBuilder::default().mac_into(&mut out),
Err(Error::InvalidArgument)
);
assert_eq!(
MacBuilder::new().mac_into(&mut out),
Err(Error::InvalidArgument)
);
assert_eq!(
EncryptBuilder::new()
.recipient(Recipient::new(Algorithm::DIRECT, &key))
.algorithm(Algorithm::A128GCM)
.iv(&IV)
.payload(PayloadMode::Detached(PAYLOAD))
.encrypt_to_vec(),
Err(Error::InvalidArgument)
);
assert_eq!(
Mac0Builder::new()
.key(&mac_key)
.algorithm(Algorithm::HMAC256)
.verify(b"not-a-cose-message", None),
Err(Error::CborType)
);
let mut sign1_builder = Sign1Builder::default()
.key(&key)
.algorithm(Algorithm::ES256)
.kid(b"sig")
.external_aad(AAD)
.scratch_len(1024)
.rng(NonNull::dangling())
.payload(PayloadMode::Attached(PAYLOAD));
assert!(sign1_builder.sign_into(&mut out).is_err());
assert!(sign1_builder.sign_to_vec().is_err());
assert_eq!(
Sign1Builder::new().sign_into(&mut out),
Err(Error::InvalidArgument)
);
assert_eq!(
Sign1Builder::new()
.key(&key)
.algorithm(Algorithm::ES256)
.payload(PayloadMode::Attached(PAYLOAD))
.verify(b"not-a-cose-message", None),
Err(Error::CborType)
);
assert_eq!(
SignBuilder::default().sign_into(&mut out),
Err(Error::InvalidArgument)
);
assert_eq!(
SignBuilder::new().sign_into(&mut out),
Err(Error::InvalidArgument)
);
assert_eq!(
SignBuilder::new().verify(&key, 0, b"not-a-cose-message", None),
Err(Error::CborType)
);
let mut scratch = [0; 1024];
assert!(sign1_into(
&key,
Algorithm::ES256,
Some(b"sig"),
PayloadMode::Attached(PAYLOAD),
AAD,
&mut scratch,
&mut out,
None
)
.is_err());
assert!(sign1_to_vec(
&key,
Algorithm::ES256,
Some(b"sig"),
PayloadMode::Detached(PAYLOAD),
AAD,
&mut scratch,
None
)
.is_err());
let signer = Signature::new(Algorithm::ES256, &key).with_kid(b"sig");
let mut sign_builder = SignBuilder::new()
.signer(Signature::new(Algorithm::ES256, &key).with_kid(b"sig"))
.external_aad(AAD)
.rng(NonNull::dangling())
.payload(PayloadMode::Attached(PAYLOAD));
assert!(sign_builder.sign_into(&mut out).is_err());
assert!(sign_builder.sign_to_vec().is_err());
assert!(sign_into(
&[signer],
PayloadMode::Attached(PAYLOAD),
AAD,
&mut scratch,
&mut out,
None
)
.is_err());
assert_eq!(
verify1(&key, b"not-a-cose-message", None, AAD, &mut scratch),
Err(Error::CborType)
);
assert_eq!(
verify_sign(&key, 0, b"not-a-cose-message", None, AAD, &mut scratch),
Err(Error::CborType)
);
let mut detached_encrypt = EncryptBuilder::default()
.recipient(Recipient::new(Algorithm::DIRECT, &key))
.algorithm(Algorithm::A128GCM)
.iv(&IV)
.external_aad(AAD)
.rng(NonNull::dangling())
.payload(PayloadMode::Detached(PAYLOAD));
match detached_encrypt.encrypt_into(&mut out) {
Ok(message) => assert!(!message.is_empty()),
Err(Error::Unsupported) => {}
Err(error) => panic!("unexpected detached encrypt builder error: {error:?}"),
}
assert_eq!(
detached_encrypt.encrypt_to_vec(),
Err(Error::InvalidArgument)
);
assert_eq!(
Encrypt0Builder::new()
.key(&key)
.algorithm(Algorithm::A128GCM)
.iv(&IV)
.payload(PayloadMode::Attached(PAYLOAD))
.encrypt_detached_into(&mut out, &mut [0; 128]),
Err(Error::InvalidArgument)
);
let mut mac_builder = MacBuilder::default()
.recipient(Recipient::new(Algorithm::DIRECT, &mac_key))
.algorithm(Algorithm::HMAC256)
.external_aad(AAD)
.payload(PayloadMode::Detached(PAYLOAD));
let detached_mac = mac_builder.mac_to_vec().unwrap();
assert_eq!(
mac_builder
.verify(
&Recipient::new(Algorithm::DIRECT, &mac_key),
0,
&detached_mac,
Some(PAYLOAD)
)
.unwrap()
.payload,
None
);
}