Skip to content

Commit

Permalink
refactor: rewrite AAD and key providers, simplify API
Browse files Browse the repository at this point in the history
  • Loading branch information
pulsastrix committed Jul 19, 2024
1 parent 7a699ed commit 5910133
Show file tree
Hide file tree
Showing 22 changed files with 1,048 additions and 935 deletions.
9 changes: 7 additions & 2 deletions src/error/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use core::any::type_name;
use core::fmt::{Display, Formatter};

use ciborium::value::Value;
use coset::{Algorithm, CoseError, CoseKey, KeyOperation, KeyType, Label};
use coset::{Algorithm, CoseError, CoseKey, CoseRecipient, KeyOperation, KeyType, Label};
use strum_macros::IntoStaticStr;

use {alloc::format, alloc::string::String, alloc::string::ToString};
Expand Down Expand Up @@ -264,7 +264,7 @@ where
/// headers or the key itself).
NoAlgorithmDeterminable,
/// The provided key does not support the given operation.
KeyOperationNotPermitted(BTreeSet<KeyOperation>, KeyOperation),
KeyOperationNotPermitted(BTreeSet<KeyOperation>, BTreeSet<KeyOperation>),
/// Key in given curve must be in different format.
KeyTypeCurveMismatch(KeyType, EllipticCurve),
/// Provided algorithm requires a different key type.
Expand Down Expand Up @@ -296,6 +296,11 @@ where
/// In the latter case, the error field will contain a list of all attempted keys and the
/// corresponding error.
NoMatchingKeyFound(Vec<(CoseKey, CoseCipherError<T>)>),
/// TODO docs
NoDecryptableRecipientFound(
Vec<(CoseRecipient, Vec<(CoseKey, CoseCipherError<T>)>)>,
Vec<(CoseKey, CoseCipherError<T>)>,
),
/// A different error has occurred. Details are provided in the contained error.
Other(T),
}
Expand Down
102 changes: 51 additions & 51 deletions src/token/cose/encrypted/encrypt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,28 +57,28 @@ pub trait CoseEncryptBuilderExt: Sized {
/// # Examples
///
/// TODO
fn try_encrypt<B: CoseEncryptCipher, CKP: CoseKeyProvider, CAP: CoseAadProvider>(
fn try_encrypt<B: CoseEncryptCipher, CKP: CoseKeyProvider, CAP: CoseAadProvider + ?Sized>(
self,
backend: &mut B,
key_provider: &mut CKP,
try_all_keys: bool,
key_provider: &CKP,

protected: Option<Header>,
unprotected: Option<Header>,
payload: &[u8],
external_aad: &mut CAP,
external_aad: CAP,
) -> Result<Self, CoseCipherError<B::Error>>;
}

impl CoseEncryptBuilderExt for CoseEncryptBuilder {
fn try_encrypt<B: CoseEncryptCipher, CKP: CoseKeyProvider, CAP: CoseAadProvider>(
fn try_encrypt<B: CoseEncryptCipher, CKP: CoseKeyProvider, CAP: CoseAadProvider + ?Sized>(
self,
backend: &mut B,
key_provider: &mut CKP,
try_all_keys: bool,
key_provider: &CKP,

protected: Option<Header>,
unprotected: Option<Header>,
payload: &[u8],
external_aad: &mut CAP,
external_aad: CAP,
) -> Result<Self, CoseCipherError<B::Error>> {
let mut builder = self;
if let Some(protected) = &protected {
Expand All @@ -89,18 +89,19 @@ impl CoseEncryptBuilderExt for CoseEncryptBuilder {
}
builder.try_create_ciphertext(
payload,
external_aad.lookup_aad(
Some(EncryptionContext::CoseEncrypt),
protected.as_ref(),
unprotected.as_ref(),
),
external_aad
.lookup_aad(
Some(EncryptionContext::CoseEncrypt),
protected.as_ref(),
unprotected.as_ref(),
)
.unwrap_or(&[] as &[u8]),
|plaintext, aad| {
encrypted::try_encrypt(
backend,
key_provider,
protected.as_ref(),
unprotected.as_ref(),
try_all_keys,
plaintext,
aad,
)
Expand Down Expand Up @@ -151,12 +152,12 @@ pub trait CoseEncryptExt {
/// # Examples
///
/// TODO
fn try_decrypt<B: CoseEncryptCipher, CKP: CoseKeyProvider, CAP: CoseAadProvider>(
fn try_decrypt<B: CoseEncryptCipher, CKP: CoseKeyProvider, CAP: CoseAadProvider + ?Sized>(
&self,
backend: &mut B,
key_provider: &mut CKP,
try_all_keys: bool,
external_aad: &mut CAP,
key_provider: &CKP,

external_aad: CAP,
) -> Result<Vec<u8>, CoseCipherError<B::Error>>;

/// Attempts to decrypt the payload contained in this object using a cryptographic backend,
Expand Down Expand Up @@ -199,39 +200,39 @@ pub trait CoseEncryptExt {
fn try_decrypt_with_recipients<
B: CoseKeyDistributionCipher + CoseEncryptCipher,
CKP: CoseKeyProvider,
CAP: CoseAadProvider,
CAP: CoseAadProvider + ?Sized,
>(
&self,
backend: &mut B,
key_provider: &mut CKP,
try_all_keys: bool,
external_aad: &mut CAP,
key_provider: &CKP,

external_aad: CAP,
) -> Result<Vec<u8>, CoseCipherError<B::Error>>;
}

impl CoseEncryptExt for CoseEncrypt {
fn try_decrypt<B: CoseEncryptCipher, CKP: CoseKeyProvider, CAP: CoseAadProvider>(
fn try_decrypt<B: CoseEncryptCipher, CKP: CoseKeyProvider, CAP: CoseAadProvider + ?Sized>(
&self,
backend: &mut B,
key_provider: &mut CKP,
try_all_keys: bool,
external_aad: &mut CAP,
key_provider: &CKP,

external_aad: CAP,
) -> Result<Vec<u8>, CoseCipherError<B::Error>> {
let backend = Rc::new(RefCell::new(backend));
let key_provider = Rc::new(RefCell::new(key_provider));
self.decrypt(
external_aad.lookup_aad(
Some(EncryptionContext::CoseEncrypt),
Some(&self.protected.header),
Some(&self.unprotected),
),
external_aad
.lookup_aad(
Some(EncryptionContext::CoseEncrypt),
Some(&self.protected.header),
Some(&self.unprotected),
)
.unwrap_or(&[] as &[u8]),
|ciphertext, aad| {
try_decrypt(
&backend,
&key_provider,
backend,
key_provider,
&self.protected.header,
&self.unprotected,
try_all_keys,
ciphertext,
aad,
)
Expand All @@ -242,36 +243,35 @@ impl CoseEncryptExt for CoseEncrypt {
fn try_decrypt_with_recipients<
B: CoseKeyDistributionCipher + CoseEncryptCipher,
CKP: CoseKeyProvider,
CAP: CoseAadProvider,
CAP: CoseAadProvider + ?Sized,
>(
&self,
backend: &mut B,
key_provider: &mut CKP,
try_all_keys: bool,
external_aad: &mut CAP,
key_provider: &CKP,
external_aad: CAP,
) -> Result<Vec<u8>, CoseCipherError<B::Error>> {
let backend = Rc::new(RefCell::new(backend));
let key_provider = Rc::new(RefCell::new(key_provider));
let mut nested_recipient_key_provider = CoseNestedRecipientSearchContext::new(
let nested_recipient_key_provider = CoseNestedRecipientSearchContext::new(
&self.recipients,
Rc::clone(&backend),
Rc::clone(&key_provider),
try_all_keys,
key_provider,
&external_aad,
struct_to_recipient_context(EncryptionContext::CoseEncrypt),
);
self.decrypt(
external_aad.lookup_aad(
Some(EncryptionContext::CoseEncrypt),
Some(&self.protected.header),
Some(&self.unprotected),
),
external_aad
.lookup_aad(
Some(EncryptionContext::CoseEncrypt),
Some(&self.protected.header),
Some(&self.unprotected),
)
.unwrap_or(&[] as &[u8]),
|ciphertext, aad| {
try_decrypt(
&backend,
&Rc::new(RefCell::new(&mut nested_recipient_key_provider)),
backend,
&nested_recipient_key_provider,
&self.protected.header,
&self.unprotected,
true,
ciphertext,
aad,
)
Expand Down
16 changes: 7 additions & 9 deletions src/token/cose/encrypted/encrypt/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ impl<B: CoseCipher + CoseEncryptCipher + CoseKeyDistributionCipher> CoseStructTe
if recipient.alg == Some(coset::Algorithm::Assigned(Algorithm::Direct))
|| determine_algorithm::<Infallible>(
None,
recipient.unprotected.as_ref(),
recipient.protected.as_ref(),
recipient.unprotected.as_ref(),
) == Ok(coset::iana::Algorithm::Direct)
{
enc_key = recipient.key.clone();
Expand All @@ -83,13 +83,12 @@ impl<B: CoseCipher + CoseEncryptCipher + CoseKeyDistributionCipher> CoseStructTe
recipient_struct_builder = recipient_struct_builder
.try_encrypt(
backend,
&mut &recipient.key,
true,
&recipient.key,
EncryptionContext::EncRecipient,
recipient.protected.clone(),
recipient.unprotected.clone(),
parsed_key.k,
&mut (&[] as &[u8]),
&[] as &[u8],
)
.expect("unable to create CoseRecipient structure");
}
Expand All @@ -98,12 +97,11 @@ impl<B: CoseCipher + CoseEncryptCipher + CoseKeyDistributionCipher> CoseStructTe
.add_recipient(recipient_struct_builder.build())
.try_encrypt(
backend,
&mut &enc_key,
false,
&enc_key,
encrypt_cfg.protected.clone(),
Some(unprotected),
&case.input.plaintext.clone().into_bytes(),
&mut encrypt_cfg.external.as_slice(),
encrypt_cfg.external.as_slice(),
)
.expect("unable to encrypt Encrypt object")
.build()
Expand Down Expand Up @@ -139,9 +137,9 @@ impl<B: CoseCipher + CoseEncryptCipher + CoseKeyDistributionCipher> CoseStructTe
key_with_alg
})
.collect();
let mut aad = test_case.external.as_slice();
let aad = test_case.external.as_slice();

let verify_result = self.try_decrypt_with_recipients(backend, &mut &keys, false, &mut aad);
let verify_result = self.try_decrypt_with_recipients(backend, &keys, aad);

if case.fail {
verify_result.expect_err("invalid token was successfully verified");
Expand Down
63 changes: 32 additions & 31 deletions src/token/cose/encrypted/encrypt0/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,38 +48,38 @@ pub trait CoseEncrypt0Ext {
/// # Examples
///
/// TODO
fn try_decrypt<B: CoseEncryptCipher, CKP: CoseKeyProvider, CAP: CoseAadProvider>(
fn try_decrypt<B: CoseEncryptCipher, CKP: CoseKeyProvider, CAP: CoseAadProvider + ?Sized>(
&self,
backend: &mut B,
key_provider: &mut CKP,
try_all_keys: bool,
external_aad: &mut CAP,
key_provider: &CKP,

external_aad: CAP,
) -> Result<Vec<u8>, CoseCipherError<B::Error>>;
}

impl CoseEncrypt0Ext for CoseEncrypt0 {
fn try_decrypt<B: CoseEncryptCipher, CKP: CoseKeyProvider, CAP: CoseAadProvider>(
fn try_decrypt<B: CoseEncryptCipher, CKP: CoseKeyProvider, CAP: CoseAadProvider + ?Sized>(
&self,
backend: &mut B,
key_provider: &mut CKP,
try_all_keys: bool,
external_aad: &mut CAP,
key_provider: &CKP,

external_aad: CAP,
) -> Result<Vec<u8>, CoseCipherError<B::Error>> {
let backend = Rc::new(RefCell::new(backend));
let key_provider = Rc::new(RefCell::new(key_provider));
self.decrypt(
external_aad.lookup_aad(
Some(EncryptionContext::CoseEncrypt0),
Some(&self.protected.header),
Some(&self.unprotected),
),
external_aad
.lookup_aad(
Some(EncryptionContext::CoseEncrypt0),
Some(&self.protected.header),
Some(&self.unprotected),
)
.unwrap_or(&[] as &[u8]),
|ciphertext, aad| {
encrypted::try_decrypt(
&backend,
&key_provider,
backend,
key_provider,
&self.protected.header,
&self.unprotected,
try_all_keys,
ciphertext,
aad,
)
Expand Down Expand Up @@ -125,28 +125,28 @@ pub trait CoseEncrypt0BuilderExt: Sized {
/// # Examples
///
/// TODO
fn try_encrypt<B: CoseEncryptCipher, CKP: CoseKeyProvider, CAP: CoseAadProvider>(
fn try_encrypt<B: CoseEncryptCipher, CKP: CoseKeyProvider, CAP: CoseAadProvider + ?Sized>(
self,
backend: &mut B,
key_provider: &mut CKP,
try_all_keys: bool,
key_provider: &CKP,

protected: Option<Header>,
unprotected: Option<Header>,
payload: &[u8],
external_aad: &mut CAP,
external_aad: CAP,
) -> Result<Self, CoseCipherError<B::Error>>;
}

impl CoseEncrypt0BuilderExt for CoseEncrypt0Builder {
fn try_encrypt<B: CoseEncryptCipher, CKP: CoseKeyProvider, CAP: CoseAadProvider>(
fn try_encrypt<B: CoseEncryptCipher, CKP: CoseKeyProvider, CAP: CoseAadProvider + ?Sized>(
self,
backend: &mut B,
key_provider: &mut CKP,
try_all_keys: bool,
key_provider: &CKP,

protected: Option<Header>,
unprotected: Option<Header>,
payload: &[u8],
external_aad: &mut CAP,
external_aad: CAP,
) -> Result<Self, CoseCipherError<B::Error>> {
let mut builder = self;
if let Some(protected) = &protected {
Expand All @@ -157,18 +157,19 @@ impl CoseEncrypt0BuilderExt for CoseEncrypt0Builder {
}
builder.try_create_ciphertext(
payload,
external_aad.lookup_aad(
Some(EncryptionContext::CoseEncrypt0),
protected.as_ref(),
unprotected.as_ref(),
),
external_aad
.lookup_aad(
Some(EncryptionContext::CoseEncrypt0),
protected.as_ref(),
unprotected.as_ref(),
)
.unwrap_or(&[] as &[u8]),
|plaintext, aad| {
encrypted::try_encrypt(
backend,
key_provider,
protected.as_ref(),
unprotected.as_ref(),
try_all_keys,
plaintext,
aad,
)
Expand Down
Loading

0 comments on commit 5910133

Please sign in to comment.