From 70bac8dddb4987a0dce551d1e4ede53e1fd3c9af Mon Sep 17 00:00:00 2001 From: Hugo Hakim Damer Date: Tue, 27 Aug 2024 21:53:23 +0200 Subject: [PATCH 1/4] refactor: create cose utilities module, move header_util.rs there --- src/error/mod.rs | 2 +- src/token/cose/aad.rs | 2 +- src/token/cose/crypto_impl/openssl.rs | 2 +- src/token/cose/encrypted/encrypt/tests.rs | 4 ++-- src/token/cose/encrypted/encrypt0/tests.rs | 2 +- src/token/cose/encrypted/mod.rs | 12 ++++++------ src/token/cose/maced/mac/tests.rs | 2 +- src/token/cose/maced/mac0/tests.rs | 2 +- src/token/cose/maced/mod.rs | 6 +++--- src/token/cose/mod.rs | 4 ++-- src/token/cose/recipient/mod.rs | 7 ++++--- src/token/cose/signed/mod.rs | 6 +++--- src/token/cose/{header_util.rs => util/header.rs} | 0 src/token/cose/util/mod.rs | 3 +++ src/token/cose/util/ops.rs | 0 src/token/cose/util/symm.rs | 0 src/token/mod.rs | 2 +- 17 files changed, 30 insertions(+), 26 deletions(-) rename src/token/cose/{header_util.rs => util/header.rs} (100%) create mode 100644 src/token/cose/util/mod.rs create mode 100644 src/token/cose/util/ops.rs create mode 100644 src/token/cose/util/symm.rs diff --git a/src/error/mod.rs b/src/error/mod.rs index 8405c8b..d2db256 100644 --- a/src/error/mod.rs +++ b/src/error/mod.rs @@ -24,7 +24,7 @@ use strum_macros::IntoStaticStr; use {alloc::format, alloc::string::String, alloc::string::ToString}; -use crate::token::cose::HeaderParam; +use crate::token::cose::header::HeaderParam; use crate::token::cose::{EllipticCurve, KeyParam}; use core::{marker::PhantomData, num::TryFromIntError}; diff --git a/src/token/cose/aad.rs b/src/token/cose/aad.rs index ec55647..7bbba4e 100644 --- a/src/token/cose/aad.rs +++ b/src/token/cose/aad.rs @@ -1,4 +1,4 @@ -use crate::token::cose::determine_header_param; +use crate::token::cose::util::header::determine_header_param; use alloc::collections::BTreeMap; use coset::{EncryptionContext, Header}; diff --git a/src/token/cose/crypto_impl/openssl.rs b/src/token/cose/crypto_impl/openssl.rs index 7057bda..e527314 100644 --- a/src/token/cose/crypto_impl/openssl.rs +++ b/src/token/cose/crypto_impl/openssl.rs @@ -27,7 +27,7 @@ use strum_macros::Display; use crate::error::CoseCipherError; use crate::token::cose::encrypted::{EncryptCryptoBackend, AES_GCM_TAG_LEN}; -use crate::token::cose::header_util::HeaderParam; +use crate::token::cose::header::HeaderParam; use crate::token::cose::key::{CoseEc2Key, CoseSymmetricKey, EllipticCurve}; use crate::token::cose::maced::MacCryptoBackend; use crate::token::cose::recipient::KeyDistributionCryptoBackend; diff --git a/src/token/cose/encrypted/encrypt/tests.rs b/src/token/cose/encrypted/encrypt/tests.rs index f0f3266..4732e12 100644 --- a/src/token/cose/encrypted/encrypt/tests.rs +++ b/src/token/cose/encrypted/encrypt/tests.rs @@ -19,7 +19,7 @@ use rstest::rstest; use crate::token::cose::encrypted::encrypt::{CoseEncryptBuilderExt, CoseEncryptExt}; use crate::token::cose::encrypted::EncryptCryptoBackend; -use crate::token::cose::header_util::{determine_algorithm, HeaderBuilderExt}; +use crate::token::cose::header::{determine_algorithm, HeaderBuilderExt}; use crate::token::cose::key::CoseSymmetricKey; use crate::token::cose::recipient::{CoseRecipientBuilderExt, KeyDistributionCryptoBackend}; use crate::token::cose::test_helper::{ @@ -27,7 +27,7 @@ use crate::token::cose::test_helper::{ perform_cose_reference_output_test, perform_cose_self_signed_test, serialize_cose_with_failures, CoseStructTestHelper, TestCase, }; -use crate::token::cose::{determine_header_param, CryptoBackend}; +use crate::token::cose::{util::header::determine_header_param, CryptoBackend}; #[cfg(feature = "openssl")] use crate::token::cose::test_helper::openssl_ctx; diff --git a/src/token/cose/encrypted/encrypt0/tests.rs b/src/token/cose/encrypted/encrypt0/tests.rs index 3a39e53..f2e48b6 100644 --- a/src/token/cose/encrypted/encrypt0/tests.rs +++ b/src/token/cose/encrypted/encrypt0/tests.rs @@ -15,7 +15,7 @@ use rstest::rstest; use crate::token::cose::encrypted::encrypt0::{CoseEncrypt0BuilderExt, CoseEncrypt0Ext}; use crate::token::cose::encrypted::EncryptCryptoBackend; -use crate::token::cose::header_util::HeaderBuilderExt; +use crate::token::cose::header::HeaderBuilderExt; use crate::token::cose::test_helper::{ apply_attribute_failures, apply_header_failures, perform_cose_reference_output_test, perform_cose_self_signed_test, serialize_cose_with_failures, CoseStructTestHelper, TestCase, diff --git a/src/token/cose/encrypted/mod.rs b/src/token/cose/encrypted/mod.rs index 9e022e5..940e92b 100644 --- a/src/token/cose/encrypted/mod.rs +++ b/src/token/cose/encrypted/mod.rs @@ -17,9 +17,9 @@ use core::fmt::Display; use coset::{iana, Algorithm, Header, KeyOperation}; use crate::error::CoseCipherError; -use crate::token::cose::header_util::HeaderParam; +use crate::token::cose::header::HeaderParam; use crate::token::cose::key::{CoseParsedKey, CoseSymmetricKey, KeyProvider}; -use crate::token::cose::{header_util, key, CryptoBackend, KeyParam}; +use crate::token::cose::{header, key, CryptoBackend, KeyParam}; mod encrypt; mod encrypt0; @@ -347,11 +347,11 @@ fn determine_and_check_aes_params<'a, BE: Display>( ) -> Result<(CoseSymmetricKey<'a, BE>, Vec), CoseCipherError> { let symm_key = key::ensure_valid_aes_key::(alg, parsed_key)?; - let iv = header_util::determine_header_param(protected, unprotected, |v| { + let iv = header::determine_header_param(protected, unprotected, |v| { (!v.iv.is_empty()).then_some(&v.iv) }); - let partial_iv = header_util::determine_header_param(protected, unprotected, |v| { + let partial_iv = header::determine_header_param(protected, unprotected, |v| { (!v.partial_iv.is_empty()).then_some(&v.partial_iv) }); @@ -431,7 +431,7 @@ fn try_encrypt( // (RFC 9052, Section 5.3). enc_structure: &[u8], ) -> Result, CoseCipherError> { - header_util::try_cose_crypto_operation( + header::try_cose_crypto_operation( key_provider, protected, unprotected, @@ -487,7 +487,7 @@ pub(crate) fn try_decrypt( // (RFC 9052, Section 5.3). enc_structure: &[u8], ) -> Result, CoseCipherError> { - header_util::try_cose_crypto_operation( + header::try_cose_crypto_operation( key_provider, Some(protected), Some(unprotected), diff --git a/src/token/cose/maced/mac/tests.rs b/src/token/cose/maced/mac/tests.rs index c2fbc09..b93e5ff 100644 --- a/src/token/cose/maced/mac/tests.rs +++ b/src/token/cose/maced/mac/tests.rs @@ -18,7 +18,7 @@ use coset::{ }; use rstest::rstest; -use crate::token::cose::header_util::determine_algorithm; +use crate::token::cose::header::determine_algorithm; use crate::token::cose::key::CoseSymmetricKey; use crate::token::cose::maced::mac::{CoseMacBuilderExt, CoseMacExt}; use crate::token::cose::maced::MacCryptoBackend; diff --git a/src/token/cose/maced/mac0/tests.rs b/src/token/cose/maced/mac0/tests.rs index 6a349cb..dfcb1d0 100644 --- a/src/token/cose/maced/mac0/tests.rs +++ b/src/token/cose/maced/mac0/tests.rs @@ -15,7 +15,7 @@ use coset::iana::Algorithm; use coset::{CoseError, CoseKey, CoseKeyBuilder, CoseMac0, CoseMac0Builder, Header}; use rstest::rstest; -use crate::token::cose::header_util::determine_algorithm; +use crate::token::cose::header::determine_algorithm; use crate::token::cose::maced::mac0::{CoseMac0BuilderExt, CoseMac0Ext}; use crate::token::cose::maced::MacCryptoBackend; use crate::token::cose::test_helper::{ diff --git a/src/token/cose/maced/mod.rs b/src/token/cose/maced/mod.rs index 05efd78..4b59eaa 100644 --- a/src/token/cose/maced/mod.rs +++ b/src/token/cose/maced/mod.rs @@ -20,7 +20,7 @@ pub use mac0::{CoseMac0BuilderExt, CoseMac0Ext}; use crate::error::CoseCipherError; use crate::token::cose::key::{CoseParsedKey, CoseSymmetricKey, KeyProvider}; -use crate::token::cose::{header_util, key, CryptoBackend}; +use crate::token::cose::{header, key, CryptoBackend}; mod mac; mod mac0; @@ -157,7 +157,7 @@ fn try_compute( unprotected: Option<&Header>, payload: &[u8], ) -> Result, CoseCipherError> { - header_util::try_cose_crypto_operation( + header::try_cose_crypto_operation( key_provider, protected, unprotected, @@ -197,7 +197,7 @@ pub(crate) fn try_verify( tag: &[u8], payload: &[u8], ) -> Result<(), CoseCipherError> { - header_util::try_cose_crypto_operation( + header::try_cose_crypto_operation( key_provider, Some(protected), Some(unprotected), diff --git a/src/token/cose/mod.rs b/src/token/cose/mod.rs index 8fd7a79..4572af9 100644 --- a/src/token/cose/mod.rs +++ b/src/token/cose/mod.rs @@ -208,7 +208,6 @@ use core::fmt::{Debug, Display}; pub mod crypto_impl; mod encrypted; -mod header_util; mod key; mod signed; @@ -220,14 +219,15 @@ pub mod aad; pub use aad::AadProvider; pub use encrypted::*; -pub use header_util::*; pub use key::*; pub use maced::*; pub use recipient::*; pub use signed::*; +pub use util::*; #[cfg(all(test, feature = "std"))] pub(crate) mod test_helper; +pub mod util; /// Trait for implementations of cryptographic functions that can be used for COSE structures. pub trait CryptoBackend { diff --git a/src/token/cose/recipient/mod.rs b/src/token/cose/recipient/mod.rs index 14554d0..de7a252 100644 --- a/src/token/cose/recipient/mod.rs +++ b/src/token/cose/recipient/mod.rs @@ -22,12 +22,13 @@ use coset::{ use crate::error::CoseCipherError; use crate::token::cose::aad::{AadProvider, InvertedAadProvider}; -use crate::token::cose::header_util::{determine_algorithm, determine_key_candidates}; +use crate::token::cose::header::{determine_algorithm, determine_key_candidates}; use crate::token::cose::key::ensure_valid_aes_key; use crate::token::cose::key::{CoseParsedKey, KeyProvider}; -use crate::token::cose::{ - determine_header_param, try_cose_crypto_operation, CoseSymmetricKey, CryptoBackend, HeaderParam, +use crate::token::cose::util::header::{ + determine_header_param, try_cose_crypto_operation, HeaderParam, }; +use crate::token::cose::{CoseSymmetricKey, CryptoBackend}; /// Trait for cryptographic backends that can perform key distribution operations for algorithms /// used in COSE structures. diff --git a/src/token/cose/signed/mod.rs b/src/token/cose/signed/mod.rs index 9379798..73a84d7 100644 --- a/src/token/cose/signed/mod.rs +++ b/src/token/cose/signed/mod.rs @@ -18,7 +18,7 @@ pub use sign1::{CoseSign1BuilderExt, CoseSign1Ext}; use crate::error::CoseCipherError; use crate::token::cose::key::{CoseEc2Key, CoseParsedKey, KeyProvider}; -use crate::token::cose::{header_util, key, CryptoBackend}; +use crate::token::cose::{header, key, CryptoBackend}; mod sign; mod sign1; @@ -183,7 +183,7 @@ fn try_sign( unprotected: Option<&Header>, payload: &[u8], ) -> Result, CoseCipherError> { - header_util::try_cose_crypto_operation( + header::try_cose_crypto_operation( key_provider, protected, unprotected, @@ -227,7 +227,7 @@ fn try_verify( signature: &[u8], toverify: &[u8], ) -> Result<(), CoseCipherError> { - header_util::try_cose_crypto_operation( + header::try_cose_crypto_operation( key_provider, Some(protected), Some(unprotected), diff --git a/src/token/cose/header_util.rs b/src/token/cose/util/header.rs similarity index 100% rename from src/token/cose/header_util.rs rename to src/token/cose/util/header.rs diff --git a/src/token/cose/util/mod.rs b/src/token/cose/util/mod.rs new file mode 100644 index 0000000..9b56287 --- /dev/null +++ b/src/token/cose/util/mod.rs @@ -0,0 +1,3 @@ +pub(crate) mod header; +pub(crate) mod ops; +pub(crate) mod symm; diff --git a/src/token/cose/util/ops.rs b/src/token/cose/util/ops.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/token/cose/util/symm.rs b/src/token/cose/util/symm.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/token/mod.rs b/src/token/mod.rs index d0acd63..1d5ae26 100644 --- a/src/token/mod.rs +++ b/src/token/mod.rs @@ -103,8 +103,8 @@ pub use crate::token::cose::SignCryptoBackend; use ciborium::value::Value; use cose::AadProvider; use cose::CoseRecipientBuilderExt; -use cose::{determine_algorithm, KeyDistributionCryptoBackend}; use cose::{generate_cek_for_alg, KeyProvider}; +use cose::{util::header::determine_algorithm, KeyDistributionCryptoBackend}; use cose::{ CoseEncrypt0BuilderExt, CoseEncrypt0Ext, CoseEncryptBuilderExt, CoseEncryptExt, EncryptCryptoBackend, From 4cf9da1d2010d4a6c2ee07104467978fbfbf982e Mon Sep 17 00:00:00 2001 From: Hugo Hakim Damer Date: Tue, 27 Aug 2024 22:23:04 +0200 Subject: [PATCH 2/4] refactor: move commonly used COSE functions to utility module --- src/error/mod.rs | 2 +- src/token/cose/aad.rs | 2 +- src/token/cose/crypto_impl/openssl.rs | 8 +- .../cose/crypto_impl/rustcrypto/mac/mod.rs | 11 +- .../cose/crypto_impl/rustcrypto/sign/mod.rs | 4 +- src/token/cose/encrypted/encrypt/mod.rs | 2 +- src/token/cose/encrypted/encrypt/tests.rs | 5 +- src/token/cose/encrypted/mod.rs | 144 +---------- src/token/cose/header.rs | 54 +++++ src/token/cose/key.rs | 186 +-------------- src/token/cose/maced/mac/tests.rs | 2 +- src/token/cose/maced/mac0/tests.rs | 2 +- src/token/cose/maced/mod.rs | 11 +- src/token/cose/mod.rs | 5 +- src/token/cose/recipient/mod.rs | 10 +- src/token/cose/signed/mod.rs | 11 +- src/token/cose/util/header.rs | 100 +------- src/token/cose/util/mac.rs | 65 +++++ src/token/cose/util/mod.rs | 24 +- src/token/cose/util/ops.rs | 63 +++++ src/token/cose/util/sign.rs | 70 ++++++ src/token/cose/util/symm.rs | 225 ++++++++++++++++++ src/token/mod.rs | 5 +- src/token/tests.rs | 2 +- 24 files changed, 553 insertions(+), 460 deletions(-) create mode 100644 src/token/cose/header.rs create mode 100644 src/token/cose/util/mac.rs create mode 100644 src/token/cose/util/sign.rs diff --git a/src/error/mod.rs b/src/error/mod.rs index d2db256..8405c8b 100644 --- a/src/error/mod.rs +++ b/src/error/mod.rs @@ -24,7 +24,7 @@ use strum_macros::IntoStaticStr; use {alloc::format, alloc::string::String, alloc::string::ToString}; -use crate::token::cose::header::HeaderParam; +use crate::token::cose::HeaderParam; use crate::token::cose::{EllipticCurve, KeyParam}; use core::{marker::PhantomData, num::TryFromIntError}; diff --git a/src/token/cose/aad.rs b/src/token/cose/aad.rs index 7bbba4e..f184862 100644 --- a/src/token/cose/aad.rs +++ b/src/token/cose/aad.rs @@ -1,4 +1,4 @@ -use crate::token::cose::util::header::determine_header_param; +use crate::token::cose::util::determine_header_param; use alloc::collections::BTreeMap; use coset::{EncryptionContext, Header}; diff --git a/src/token/cose/crypto_impl/openssl.rs b/src/token/cose/crypto_impl/openssl.rs index e527314..e3bca26 100644 --- a/src/token/cose/crypto_impl/openssl.rs +++ b/src/token/cose/crypto_impl/openssl.rs @@ -26,13 +26,15 @@ use openssl::sign::{Signer, Verifier}; use strum_macros::Display; use crate::error::CoseCipherError; -use crate::token::cose::encrypted::{EncryptCryptoBackend, AES_GCM_TAG_LEN}; -use crate::token::cose::header::HeaderParam; +use crate::token::cose::encrypted::EncryptCryptoBackend; use crate::token::cose::key::{CoseEc2Key, CoseSymmetricKey, EllipticCurve}; use crate::token::cose::maced::MacCryptoBackend; use crate::token::cose::recipient::KeyDistributionCryptoBackend; use crate::token::cose::signed::SignCryptoBackend; -use crate::token::cose::{aes_ccm_algorithm_tag_len, CryptoBackend}; +use crate::token::cose::util::aes_ccm_algorithm_tag_len; +use crate::token::cose::util::AES_GCM_TAG_LEN; +use crate::token::cose::CryptoBackend; +use crate::token::cose::HeaderParam; /// Represents an error caused by the OpenSSL cryptographic backend. #[derive(Debug, Display)] diff --git a/src/token/cose/crypto_impl/rustcrypto/mac/mod.rs b/src/token/cose/crypto_impl/rustcrypto/mac/mod.rs index d0e3805..03a89ca 100644 --- a/src/token/cose/crypto_impl/rustcrypto/mac/mod.rs +++ b/src/token/cose/crypto_impl/rustcrypto/mac/mod.rs @@ -8,11 +8,12 @@ * * SPDX-License-Identifier: MIT OR Apache-2.0 */ -use coset::iana::Algorithm; -use crate::error::CoseCipherError; +use crate::token::cose::crypto_impl::rustcrypto::CoseCipherError; use crate::token::cose::crypto_impl::rustcrypto::RustCryptoContext; -use crate::token::cose::{CoseSymmetricKey, MacCryptoBackend}; +use crate::token::cose::CoseSymmetricKey; +use crate::token::cose::MacCryptoBackend; +use coset::iana; use rand::{CryptoRng, RngCore}; #[cfg(feature = "rustcrypto-hmac")] @@ -22,7 +23,7 @@ impl MacCryptoBackend for RustCryptoContext { #[cfg(feature = "rustcrypto-hmac")] fn compute_hmac( &mut self, - algorithm: Algorithm, + algorithm: iana::Algorithm, key: CoseSymmetricKey<'_, Self::Error>, payload: &[u8], ) -> Result, CoseCipherError> { @@ -32,7 +33,7 @@ impl MacCryptoBackend for RustCryptoContext { #[cfg(feature = "rustcrypto-hmac")] fn verify_hmac( &mut self, - algorithm: Algorithm, + algorithm: iana::Algorithm, key: CoseSymmetricKey<'_, Self::Error>, tag: &[u8], payload: &[u8], diff --git a/src/token/cose/crypto_impl/rustcrypto/sign/mod.rs b/src/token/cose/crypto_impl/rustcrypto/sign/mod.rs index 46b5aec..311a9c3 100644 --- a/src/token/cose/crypto_impl/rustcrypto/sign/mod.rs +++ b/src/token/cose/crypto_impl/rustcrypto/sign/mod.rs @@ -8,12 +8,12 @@ * * SPDX-License-Identifier: MIT OR Apache-2.0 */ +use crate::token::cose::crypto_impl::rustcrypto::CoseCipherError; +use crate::token::cose::CoseEc2Key; use coset::iana; use rand::{CryptoRng, RngCore}; -use crate::error::CoseCipherError; use crate::token::cose::crypto_impl::rustcrypto::RustCryptoContext; -use crate::token::cose::CoseEc2Key; use crate::token::SignCryptoBackend; #[cfg(feature = "rustcrypto-ecdsa")] diff --git a/src/token/cose/encrypted/encrypt/mod.rs b/src/token/cose/encrypted/encrypt/mod.rs index d68734b..edee572 100644 --- a/src/token/cose/encrypted/encrypt/mod.rs +++ b/src/token/cose/encrypted/encrypt/mod.rs @@ -46,7 +46,7 @@ pub trait CoseEncryptBuilderExt: Sized { /// override headers previously set using /// [`CoseEncryptBuilder::unprotected`](CoseEncryptBuilder). /// - `payload` - payload which should be added to the resulting - /// [`CoseEncrypt`](coset::CoseEncrypt) instance in encrypted form. + /// [`CoseEncrypt`](CoseEncrypt) instance in encrypted form. /// Will override a payload previously set using /// [`CoseEncryptBuilder::payload`](CoseEncryptBuilder). /// - `external_aad` - provider of additional authenticated data that should be included in the diff --git a/src/token/cose/encrypted/encrypt/tests.rs b/src/token/cose/encrypted/encrypt/tests.rs index 4732e12..13d90d1 100644 --- a/src/token/cose/encrypted/encrypt/tests.rs +++ b/src/token/cose/encrypted/encrypt/tests.rs @@ -19,7 +19,7 @@ use rstest::rstest; use crate::token::cose::encrypted::encrypt::{CoseEncryptBuilderExt, CoseEncryptExt}; use crate::token::cose::encrypted::EncryptCryptoBackend; -use crate::token::cose::header::{determine_algorithm, HeaderBuilderExt}; +use crate::token::cose::header::HeaderBuilderExt; use crate::token::cose::key::CoseSymmetricKey; use crate::token::cose::recipient::{CoseRecipientBuilderExt, KeyDistributionCryptoBackend}; use crate::token::cose::test_helper::{ @@ -27,7 +27,7 @@ use crate::token::cose::test_helper::{ perform_cose_reference_output_test, perform_cose_self_signed_test, serialize_cose_with_failures, CoseStructTestHelper, TestCase, }; -use crate::token::cose::{util::header::determine_header_param, CryptoBackend}; +use crate::token::cose::{util::determine_header_param, CryptoBackend}; #[cfg(feature = "openssl")] use crate::token::cose::test_helper::openssl_ctx; @@ -36,6 +36,7 @@ use crate::token::cose::test_helper::openssl_ctx; feature = "rustcrypto-aes-kw" ))] use crate::token::cose::test_helper::rustcrypto_ctx; +use crate::token::cose::util::determine_algorithm; impl CoseStructTestHelper for CoseEncrypt diff --git a/src/token/cose/encrypted/mod.rs b/src/token/cose/encrypted/mod.rs index 940e92b..e348fc2 100644 --- a/src/token/cose/encrypted/mod.rs +++ b/src/token/cose/encrypted/mod.rs @@ -11,26 +11,23 @@ use alloc::collections::BTreeSet; use alloc::rc::Rc; use alloc::vec::Vec; -use ciborium::Value; use core::cell::RefCell; -use core::fmt::Display; use coset::{iana, Algorithm, Header, KeyOperation}; use crate::error::CoseCipherError; -use crate::token::cose::header::HeaderParam; use crate::token::cose::key::{CoseParsedKey, CoseSymmetricKey, KeyProvider}; -use crate::token::cose::{header, key, CryptoBackend, KeyParam}; +use crate::token::cose::CryptoBackend; mod encrypt; mod encrypt0; +use crate::token::cose::util::{ + aes_ccm_algorithm_tag_len, determine_and_check_aes_params, try_cose_crypto_operation, + AES_GCM_TAG_LEN, +}; pub use encrypt::{CoseEncryptBuilderExt, CoseEncryptExt}; pub use encrypt0::{CoseEncrypt0BuilderExt, CoseEncrypt0Ext}; -/// Authentication tag length to use for AES-GCM (fixed to 128 bits according to -/// [RFC 9053, section 4.1](https://datatracker.ietf.org/doc/html/rfc9053#section-4.1)). -pub const AES_GCM_TAG_LEN: usize = 16; - /// Trait for cryptographic backends that can perform encryption and decryption operations for /// algorithms used for COSE. pub trait EncryptCryptoBackend: CryptoBackend { @@ -285,133 +282,6 @@ pub trait EncryptCryptoBackend: CryptoBackend { } } -/// Returns the IV length expected for the AES variant given as `alg`. -/// -/// # Errors -/// -/// Returns [CoseCipherError::UnsupportedAlgorithm] if the provided algorithm is not a supported -/// AES algorithm. -pub fn aes_algorithm_iv_len( - alg: iana::Algorithm, -) -> Result> { - match alg { - // AES-GCM: Nonce is fixed at 96 bits (RFC 9053, Section 4.1). - iana::Algorithm::A128GCM | iana::Algorithm::A192GCM | iana::Algorithm::A256GCM => Ok(12), - // AES-CCM: Nonce length is parameterized. - iana::Algorithm::AES_CCM_16_64_128 - | iana::Algorithm::AES_CCM_16_128_128 - | iana::Algorithm::AES_CCM_16_64_256 - | iana::Algorithm::AES_CCM_16_128_256 => Ok(13), - iana::Algorithm::AES_CCM_64_64_128 - | iana::Algorithm::AES_CCM_64_128_128 - | iana::Algorithm::AES_CCM_64_64_256 - | iana::Algorithm::AES_CCM_64_128_256 => Ok(7), - v => Err(CoseCipherError::UnsupportedAlgorithm(Algorithm::Assigned( - v, - ))), - } -} - -/// Returns the authentication tag length expected for the AES-CCM variant given as `alg`. -/// -/// # Errors -/// -/// Returns [CoseCipherError::UnsupportedAlgorithm] if the provided algorithm is not a supported -/// variant of AES-CCM. -pub fn aes_ccm_algorithm_tag_len( - algorithm: iana::Algorithm, -) -> Result> { - match algorithm { - iana::Algorithm::AES_CCM_16_64_128 - | iana::Algorithm::AES_CCM_64_64_128 - | iana::Algorithm::AES_CCM_16_64_256 - | iana::Algorithm::AES_CCM_64_64_256 => Ok(8), - iana::Algorithm::AES_CCM_16_128_256 - | iana::Algorithm::AES_CCM_64_128_256 - | iana::Algorithm::AES_CCM_16_128_128 - | iana::Algorithm::AES_CCM_64_128_128 => Ok(16), - v => Err(CoseCipherError::UnsupportedAlgorithm(Algorithm::Assigned( - v, - ))), - } -} - -/// Determines the key and IV for an AES AEAD operation using the provided `protected` and -/// `unprotected` headers, ensuring that the provided `parsed_key` is a valid AES key in the -/// process. -fn determine_and_check_aes_params<'a, BE: Display>( - alg: iana::Algorithm, - parsed_key: CoseParsedKey<'a, BE>, - protected: Option<&Header>, - unprotected: Option<&Header>, -) -> Result<(CoseSymmetricKey<'a, BE>, Vec), CoseCipherError> { - let symm_key = key::ensure_valid_aes_key::(alg, parsed_key)?; - - let iv = header::determine_header_param(protected, unprotected, |v| { - (!v.iv.is_empty()).then_some(&v.iv) - }); - - let partial_iv = header::determine_header_param(protected, unprotected, |v| { - (!v.partial_iv.is_empty()).then_some(&v.partial_iv) - }); - - let expected_iv_len = aes_algorithm_iv_len(alg)?; - - let iv = match (iv, partial_iv) { - // IV and partial IV must not be set at the same time. - (Some(_iv), Some(partial_iv)) => Err(CoseCipherError::InvalidHeaderParam( - HeaderParam::Generic(iana::HeaderParameter::PartialIv), - Value::Bytes(partial_iv.clone()), - )), - (Some(iv), None) => Ok(iv.clone()), - // See https://datatracker.ietf.org/doc/html/rfc9052#section-3.1 - (None, Some(partial_iv)) => { - let context_iv = (!symm_key.as_ref().base_iv.is_empty()) - .then(|| &symm_key.as_ref().base_iv) - .ok_or(CoseCipherError::MissingKeyParam(vec![KeyParam::Common( - iana::KeyParameter::BaseIv, - )]))?; - - if partial_iv.len() > expected_iv_len { - return Err(CoseCipherError::InvalidHeaderParam( - HeaderParam::Generic(iana::HeaderParameter::PartialIv), - Value::Bytes(partial_iv.clone()), - )); - } - - if context_iv.len() > expected_iv_len { - return Err(CoseCipherError::InvalidKeyParam( - KeyParam::Common(iana::KeyParameter::BaseIv), - Value::Bytes(context_iv.clone()), - )); - } - - let mut message_iv = vec![0u8; expected_iv_len]; - - // Left-pad the Partial IV with zeros to the length of IV - message_iv[(expected_iv_len - partial_iv.len())..].copy_from_slice(partial_iv); - // XOR the padded Partial IV with the Context IV. - message_iv - .iter_mut() - .zip(context_iv.iter().chain(core::iter::repeat(&0u8))) - .for_each(|(b1, b2)| *b1 ^= *b2); - Ok(message_iv) - } - (None, None) => Err(CoseCipherError::MissingHeaderParam(HeaderParam::Generic( - iana::HeaderParameter::Iv, - ))), - }?; - - if iv.len() != expected_iv_len { - return Err(CoseCipherError::InvalidHeaderParam( - HeaderParam::Generic(iana::HeaderParameter::Iv), - Value::Bytes(iv.clone()), - )); - } - - Ok((symm_key, iv)) -} - /// Attempts to perform a COSE encryption operation for a [`CoseEncrypt`](coset::CoseEncrypt) or /// [`CoseEncrypt0`](coset::CoseEncrypt0) structure with the given `protected` and `unprotected` /// headers, `plaintext` and `enc_structure` using the given `backend` and `key_provider`. @@ -431,7 +301,7 @@ fn try_encrypt( // (RFC 9052, Section 5.3). enc_structure: &[u8], ) -> Result, CoseCipherError> { - header::try_cose_crypto_operation( + try_cose_crypto_operation( key_provider, protected, unprotected, @@ -487,7 +357,7 @@ pub(crate) fn try_decrypt( // (RFC 9052, Section 5.3). enc_structure: &[u8], ) -> Result, CoseCipherError> { - header::try_cose_crypto_operation( + try_cose_crypto_operation( key_provider, Some(protected), Some(unprotected), diff --git a/src/token/cose/header.rs b/src/token/cose/header.rs new file mode 100644 index 0000000..d25e9ae --- /dev/null +++ b/src/token/cose/header.rs @@ -0,0 +1,54 @@ +use crate::error::CoseCipherError; +use crate::token::cose::util::aes_algorithm_iv_len; +use crate::token::cose::{CryptoBackend, EncryptCryptoBackend}; +use coset::{iana, HeaderBuilder}; + +/// Extensions to the [`HeaderBuilder`] type that enable usage of cryptographic backends. +pub trait HeaderBuilderExt: Sized { + /// Generate an initialization vector for the given `algorithm` using the given + /// cryptographic `backend`. + /// + /// # Errors + /// + /// Returns an error if the `algorithm` is unsupported/unknown or the cryptographic backend + /// returns an error. + fn gen_iv( + self, + backend: &mut B, + algorithm: iana::Algorithm, + ) -> Result>; +} + +impl HeaderBuilderExt for HeaderBuilder { + fn gen_iv( + self, + backend: &mut B, + alg: iana::Algorithm, + ) -> Result> { + let iv_size = aes_algorithm_iv_len(alg)?; + let mut iv = vec![0; iv_size]; + backend.generate_rand(&mut iv)?; + Ok(self.iv(iv)) + } +} + +/// A header parameter that can be used in a COSE header. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum HeaderParam { + /// Generic header parameter applicable to all algorithms. + Generic(iana::HeaderParameter), + /// Header parameter that is specific for a set of algorithms. + Algorithm(iana::HeaderAlgorithmParameter), +} + +impl From for HeaderParam { + fn from(value: iana::HeaderParameter) -> Self { + HeaderParam::Generic(value) + } +} + +impl From for HeaderParam { + fn from(value: iana::HeaderAlgorithmParameter) -> Self { + HeaderParam::Algorithm(value) + } +} diff --git a/src/token/cose/key.rs b/src/token/cose/key.rs index df4fbbb..9209b06 100644 --- a/src/token/cose/key.rs +++ b/src/token/cose/key.rs @@ -14,10 +14,9 @@ use core::borrow::Borrow; use core::fmt::Display; use core::marker::PhantomData; use coset::iana::EnumI64; -use coset::{iana, Algorithm, AsCborValue, CoseKey, KeyType, Label, RegisteredLabelWithPrivate}; +use coset::{iana, AsCborValue, CoseKey, KeyType, Label, RegisteredLabelWithPrivate}; use crate::error::CoseCipherError; -use crate::token::cose::CryptoBackend; /// Finds a key parameter by its label. fn find_param_by_label<'a>(label: &Label, param_vec: &'a [(Label, Value)]) -> Option<&'a Value> { @@ -475,186 +474,3 @@ impl KeyProvider for &T { (*self).lookup_key(key_id) } } - -/// Determines the key size that a key for the given `algorithm` should have. -fn symmetric_key_size( - algorithm: iana::Algorithm, -) -> Result> { - match algorithm { - iana::Algorithm::A128GCM - | iana::Algorithm::AES_CCM_16_64_128 - | iana::Algorithm::AES_CCM_64_64_128 - | iana::Algorithm::AES_CCM_16_128_128 - | iana::Algorithm::AES_CCM_64_128_128 - | iana::Algorithm::A128KW => Ok(16), - iana::Algorithm::A192GCM | iana::Algorithm::A192KW => Ok(24), - iana::Algorithm::A256GCM - | iana::Algorithm::AES_CCM_16_64_256 - | iana::Algorithm::AES_CCM_64_64_256 - | iana::Algorithm::AES_CCM_16_128_256 - | iana::Algorithm::AES_CCM_64_128_256 - | iana::Algorithm::A256KW => Ok(32), - _ => Err(CoseCipherError::UnsupportedAlgorithm(Algorithm::Assigned( - algorithm, - ))), - } -} - -/// Attempts to parse the given `parsed_key` as an AES symmetric key. -/// -/// Performs the checks required for symmetric keys suitable for AES according to -/// [RFC 9053, Section 4](https://datatracker.ietf.org/doc/html/rfc9053#section-4). -pub(crate) fn ensure_valid_aes_key( - algorithm: iana::Algorithm, - parsed_key: CoseParsedKey, -) -> Result, CoseCipherError> { - // Checks according to RFC 9053, Section 4.1 and 4.2. - - // Key type must be symmetric. - let symm_key = if let CoseParsedKey::Symmetric(symm_key) = parsed_key { - symm_key - } else { - return Err(CoseCipherError::KeyTypeAlgorithmMismatch( - parsed_key.as_ref().kty.clone(), - Algorithm::Assigned(algorithm), - )); - }; - - // Algorithm in key must match algorithm to use. - if let Some(key_alg) = &symm_key.as_ref().alg { - if key_alg != &Algorithm::Assigned(algorithm) { - return Err(CoseCipherError::KeyAlgorithmMismatch( - key_alg.clone(), - Algorithm::Assigned(algorithm), - )); - } - } - - // For algorithms that we know, check the key length (would lead to a cipher error later on). - let key_len = symmetric_key_size(algorithm)?; - if symm_key.k.len() != key_len { - return Err(CoseCipherError::InvalidKeyParam( - KeyParam::Symmetric(iana::SymmetricKeyParameter::K), - Value::Bytes(symm_key.k.to_vec()), - )); - } - - Ok(symm_key) -} - -/// Generates a random content encryption key for the given `algorithm` using the given `backend`. -pub(crate) fn generate_cek_for_alg( - backend: &mut B, - algorithm: iana::Algorithm, -) -> Result, CoseCipherError> { - let key_len = symmetric_key_size(algorithm)?; - let mut key = vec![0u8; key_len]; - backend.generate_rand(key.as_mut_slice())?; - Ok(key) -} - -/// Attempts to parse the given `parsed_key` as an ECDSA key. -/// -/// Performs the checks required for ECDSA keys according to -/// [RFC 9053, Section 2.1](https://datatracker.ietf.org/doc/html/rfc9053#section-2.1) and/or -/// [RFC 8812, Section 3.2](https://datatracker.ietf.org/doc/html/rfc8812#section-3.2). -pub(crate) fn ensure_valid_ecdsa_key( - algorithm: iana::Algorithm, - parsed_key: CoseParsedKey, - key_should_be_private: bool, -) -> Result, CoseCipherError> { - // Checks according to RFC 9053, Section 2.1 or RFC 8812, Section 3.2. - - // Key type must be EC2 - let ec2_key = if let CoseParsedKey::Ec2(ec2_key) = parsed_key { - ec2_key - } else { - return Err(CoseCipherError::KeyTypeAlgorithmMismatch( - parsed_key.as_ref().kty.clone(), - Algorithm::Assigned(algorithm), - )); - }; - - // If algorithm in key is set, it must match our algorithm - if let Some(key_alg) = &ec2_key.as_ref().alg { - if key_alg != &Algorithm::Assigned(algorithm) { - return Err(CoseCipherError::KeyAlgorithmMismatch( - key_alg.clone(), - Algorithm::Assigned(algorithm), - )); - } - } - - // Key must contain private key information to perform signature, and either D or X and Y to - // verify a signature. - if key_should_be_private && ec2_key.d.is_none() { - return Err(CoseCipherError::MissingKeyParam(vec![ - iana::Ec2KeyParameter::D.into(), - ])); - } else if !key_should_be_private && ec2_key.d.is_none() { - if ec2_key.x.is_none() { - return Err(CoseCipherError::MissingKeyParam(vec![ - iana::Ec2KeyParameter::X.into(), - iana::Ec2KeyParameter::D.into(), - ])); - } - if ec2_key.y.is_none() { - return Err(CoseCipherError::MissingKeyParam(vec![ - iana::Ec2KeyParameter::Y.into(), - iana::Ec2KeyParameter::D.into(), - ])); - } - } - - Ok(ec2_key) -} - -/// Attempts to parse the given `parsed_key` as an HMAC key. -/// -/// Performs the checks required for symmetric keys suitable for HMAC according to -/// [RFC 9053, Section 3.1](https://datatracker.ietf.org/doc/html/rfc9053#section-3.1). -pub(crate) fn ensure_valid_hmac_key( - algorithm: iana::Algorithm, - parsed_key: CoseParsedKey, -) -> Result, CoseCipherError> { - // Checks according to RFC 9053, Section 3.1. - - // Key type must be symmetric. - let symm_key = if let CoseParsedKey::Symmetric(symm_key) = parsed_key { - symm_key - } else { - return Err(CoseCipherError::KeyTypeAlgorithmMismatch( - parsed_key.as_ref().kty.clone(), - Algorithm::Assigned(algorithm), - )); - }; - - // Algorithm in key must match algorithm to use. - if let Some(key_alg) = &symm_key.as_ref().alg { - if key_alg != &Algorithm::Assigned(algorithm) { - return Err(CoseCipherError::KeyAlgorithmMismatch( - key_alg.clone(), - Algorithm::Assigned(algorithm), - )); - } - } - - // For algorithms that we know, check the key length (would lead to a cipher error later on). - let key_len = match algorithm { - iana::Algorithm::HMAC_256_256 | iana::Algorithm::HMAC_256_64 => Some(32), - iana::Algorithm::HMAC_384_384 => Some(48), - iana::Algorithm::HMAC_512_512 => Some(64), - _ => None, - }; - - if let Some(key_len) = key_len { - if symm_key.k.len() != key_len { - return Err(CoseCipherError::InvalidKeyParam( - KeyParam::Symmetric(iana::SymmetricKeyParameter::K), - Value::Bytes(symm_key.k.to_vec()), - )); - } - } - - Ok(symm_key) -} diff --git a/src/token/cose/maced/mac/tests.rs b/src/token/cose/maced/mac/tests.rs index b93e5ff..f574403 100644 --- a/src/token/cose/maced/mac/tests.rs +++ b/src/token/cose/maced/mac/tests.rs @@ -18,7 +18,6 @@ use coset::{ }; use rstest::rstest; -use crate::token::cose::header::determine_algorithm; use crate::token::cose::key::CoseSymmetricKey; use crate::token::cose::maced::mac::{CoseMacBuilderExt, CoseMacExt}; use crate::token::cose::maced::MacCryptoBackend; @@ -28,6 +27,7 @@ use crate::token::cose::test_helper::{ apply_attribute_failures, apply_header_failures, serialize_cose_with_failures, CoseStructTestHelper, TestCase, }; +use crate::token::cose::util::determine_algorithm; use crate::token::cose::{test_helper, CryptoBackend}; #[cfg(feature = "openssl")] diff --git a/src/token/cose/maced/mac0/tests.rs b/src/token/cose/maced/mac0/tests.rs index dfcb1d0..3162522 100644 --- a/src/token/cose/maced/mac0/tests.rs +++ b/src/token/cose/maced/mac0/tests.rs @@ -15,13 +15,13 @@ use coset::iana::Algorithm; use coset::{CoseError, CoseKey, CoseKeyBuilder, CoseMac0, CoseMac0Builder, Header}; use rstest::rstest; -use crate::token::cose::header::determine_algorithm; use crate::token::cose::maced::mac0::{CoseMac0BuilderExt, CoseMac0Ext}; use crate::token::cose::maced::MacCryptoBackend; use crate::token::cose::test_helper::{ apply_attribute_failures, apply_header_failures, serialize_cose_with_failures, CoseStructTestHelper, TestCase, }; +use crate::token::cose::util::determine_algorithm; use crate::token::cose::{test_helper, CryptoBackend}; #[cfg(feature = "openssl")] diff --git a/src/token/cose/maced/mod.rs b/src/token/cose/maced/mod.rs index 4b59eaa..ac137b8 100644 --- a/src/token/cose/maced/mod.rs +++ b/src/token/cose/maced/mod.rs @@ -20,7 +20,8 @@ pub use mac0::{CoseMac0BuilderExt, CoseMac0Ext}; use crate::error::CoseCipherError; use crate::token::cose::key::{CoseParsedKey, CoseSymmetricKey, KeyProvider}; -use crate::token::cose::{header, key, CryptoBackend}; +use crate::token::cose::util::{ensure_valid_hmac_key, try_cose_crypto_operation}; +use crate::token::cose::CryptoBackend; mod mac; mod mac0; @@ -157,7 +158,7 @@ fn try_compute( unprotected: Option<&Header>, payload: &[u8], ) -> Result, CoseCipherError> { - header::try_cose_crypto_operation( + try_cose_crypto_operation( key_provider, protected, unprotected, @@ -169,7 +170,7 @@ fn try_compute( iana::Algorithm::HMAC_256_256 | iana::Algorithm::HMAC_384_384 | iana::Algorithm::HMAC_512_512 => { - let symm_key = key::ensure_valid_hmac_key(alg, parsed_key)?; + let symm_key = ensure_valid_hmac_key(alg, parsed_key)?; backend.compute_hmac(alg, symm_key, payload) } alg => Err(CoseCipherError::UnsupportedAlgorithm(Algorithm::Assigned( @@ -197,7 +198,7 @@ pub(crate) fn try_verify( tag: &[u8], payload: &[u8], ) -> Result<(), CoseCipherError> { - header::try_cose_crypto_operation( + try_cose_crypto_operation( key_provider, Some(protected), Some(unprotected), @@ -209,7 +210,7 @@ pub(crate) fn try_verify( iana::Algorithm::HMAC_256_256 | iana::Algorithm::HMAC_384_384 | iana::Algorithm::HMAC_512_512 => { - let symm_key = key::ensure_valid_hmac_key(alg, parsed_key)?; + let symm_key = ensure_valid_hmac_key(alg, parsed_key)?; (*backend.borrow_mut()).verify_hmac(alg, symm_key, tag, payload) } alg => Err(CoseCipherError::UnsupportedAlgorithm(Algorithm::Assigned( diff --git a/src/token/cose/mod.rs b/src/token/cose/mod.rs index 4572af9..0325a1b 100644 --- a/src/token/cose/mod.rs +++ b/src/token/cose/mod.rs @@ -214,19 +214,22 @@ mod signed; mod maced; mod recipient; +mod header; + /// AAD providers and operations for those. pub mod aad; pub use aad::AadProvider; pub use encrypted::*; +pub use header::*; pub use key::*; pub use maced::*; pub use recipient::*; pub use signed::*; -pub use util::*; #[cfg(all(test, feature = "std"))] pub(crate) mod test_helper; +/// Utility functions for the cose module itself and for cryptographic backend implementors. pub mod util; /// Trait for implementations of cryptographic functions that can be used for COSE structures. diff --git a/src/token/cose/recipient/mod.rs b/src/token/cose/recipient/mod.rs index de7a252..a19e00f 100644 --- a/src/token/cose/recipient/mod.rs +++ b/src/token/cose/recipient/mod.rs @@ -22,12 +22,12 @@ use coset::{ use crate::error::CoseCipherError; use crate::token::cose::aad::{AadProvider, InvertedAadProvider}; -use crate::token::cose::header::{determine_algorithm, determine_key_candidates}; -use crate::token::cose::key::ensure_valid_aes_key; +use crate::token::cose::header::HeaderParam; use crate::token::cose::key::{CoseParsedKey, KeyProvider}; -use crate::token::cose::util::header::{ - determine_header_param, try_cose_crypto_operation, HeaderParam, -}; +use crate::token::cose::util::determine_header_param; +use crate::token::cose::util::ensure_valid_aes_key; +use crate::token::cose::util::try_cose_crypto_operation; +use crate::token::cose::util::{determine_algorithm, determine_key_candidates}; use crate::token::cose::{CoseSymmetricKey, CryptoBackend}; /// Trait for cryptographic backends that can perform key distribution operations for algorithms diff --git a/src/token/cose/signed/mod.rs b/src/token/cose/signed/mod.rs index 73a84d7..7883de4 100644 --- a/src/token/cose/signed/mod.rs +++ b/src/token/cose/signed/mod.rs @@ -18,7 +18,8 @@ pub use sign1::{CoseSign1BuilderExt, CoseSign1Ext}; use crate::error::CoseCipherError; use crate::token::cose::key::{CoseEc2Key, CoseParsedKey, KeyProvider}; -use crate::token::cose::{header, key, CryptoBackend}; +use crate::token::cose::util::{ensure_valid_ecdsa_key, try_cose_crypto_operation}; +use crate::token::cose::CryptoBackend; mod sign; mod sign1; @@ -183,7 +184,7 @@ fn try_sign( unprotected: Option<&Header>, payload: &[u8], ) -> Result, CoseCipherError> { - header::try_cose_crypto_operation( + try_cose_crypto_operation( key_provider, protected, unprotected, @@ -196,7 +197,7 @@ fn try_sign( | iana::Algorithm::ES512 | iana::Algorithm::ES256K => { // Check if this is a valid ECDSA key. - let ec2_key = key::ensure_valid_ecdsa_key::(alg, parsed_key, true)?; + let ec2_key = ensure_valid_ecdsa_key::(alg, parsed_key, true)?; // Perform signing operation using backend. backend.sign_ecdsa(alg, &ec2_key, payload) @@ -227,7 +228,7 @@ fn try_verify( signature: &[u8], toverify: &[u8], ) -> Result<(), CoseCipherError> { - header::try_cose_crypto_operation( + try_cose_crypto_operation( key_provider, Some(protected), Some(unprotected), @@ -240,7 +241,7 @@ fn try_verify( | iana::Algorithm::ES512 | iana::Algorithm::ES256K => { // Check if this is a valid ECDSA key. - let ec2_key = key::ensure_valid_ecdsa_key::(alg, parsed_key, false)?; + let ec2_key = ensure_valid_ecdsa_key::(alg, parsed_key, false)?; backend.verify_ecdsa(alg, &ec2_key, signature, toverify) } diff --git a/src/token/cose/util/header.rs b/src/token/cose/util/header.rs index 937a682..e80f495 100644 --- a/src/token/cose/util/header.rs +++ b/src/token/cose/util/header.rs @@ -15,33 +15,10 @@ use core::fmt::Display; use alloc::borrow::Borrow; use coset::iana::EnumI64; -use coset::{iana, Algorithm, CoseKey, Header, HeaderBuilder, KeyOperation, Label}; +use coset::{iana, Algorithm, CoseKey, Header, KeyOperation, Label}; use crate::error::CoseCipherError; use crate::token::cose::key::KeyProvider; -use crate::token::cose::{aes_algorithm_iv_len, CryptoBackend, EncryptCryptoBackend}; - -/// A header parameter that can be used in a COSE header. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum HeaderParam { - /// Generic header parameter applicable to all algorithms. - Generic(iana::HeaderParameter), - /// Header parameter that is specific for a set of algorithms. - Algorithm(iana::HeaderAlgorithmParameter), -} - -impl From for HeaderParam { - fn from(value: iana::HeaderParameter) -> Self { - HeaderParam::Generic(value) - } -} - -impl From for HeaderParam { - fn from(value: iana::HeaderAlgorithmParameter) -> Self { - HeaderParam::Algorithm(value) - } -} - /// Returns the set of header parameters that are set in the given `header_bucket`. fn create_header_parameter_set(header_bucket: &Header) -> BTreeSet