Skip to content

Commit

Permalink
fix: verify key length in compatible_with method
Browse files Browse the repository at this point in the history
  • Loading branch information
Stupremee committed Nov 4, 2023
1 parent ab0d001 commit 79f7bb1
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 8 deletions.
2 changes: 1 addition & 1 deletion src/jwa/pbes2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
/// [section 4.8 of RFC 7518]: <https://datatracker.ietf.org/doc/html/rfc7518#section-4.8>
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Pbes2 {
/// PBES2 with HMAC SHA56 and "A128KW" wrapping
/// PBES2 with HMAC SHA-256 and "A128KW" wrapping
Hs256Aes128,
/// PBES2 with HMAC SHA-384 and "A192KW" wrapping
Hs384Aes192,
Expand Down
42 changes: 36 additions & 6 deletions src/jwk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@ use hashbrown::HashSet;
use serde::{de::DeserializeOwned, Deserialize, Serialize};

use crate::{
jwa::{EcDSA, JsonWebAlgorithm, JsonWebEncryptionAlgorithm, JsonWebSigningAlgorithm},
jwa::{
AesGcm, AesKw, EcDSA, Hmac, JsonWebAlgorithm, JsonWebEncryptionAlgorithm,
JsonWebSigningAlgorithm, Pbes2,
},
jwk::{
ec::{EcPrivate, EcPublic},
okp::{
curve25519::{Curve25519Private, Curve25519Public},
OkpPrivate, OkpPublic,
},
symmetric::hmac::{HmacVariant, Hs256, Hs384, Hs512},
},
policy::{Checkable, Checked, CryptographicOperation, Policy},
sealed::Sealed,
Expand Down Expand Up @@ -727,13 +731,39 @@ impl JsonWebKeyType {
// it is unreadable with the matches! macro and there's no benefit
#[allow(clippy::match_like_matches_macro)]
match (self, alg) {
(
Symmetric(SymmetricJsonWebKey::OctetSequence(key)),
Signing(JsonWebSigningAlgorithm::Hmac(hmac)),
) => match (hmac, key.len()) {
(Hmac::Hs256, Hs256::OUTPUT_SIZE..)
| (Hmac::Hs384, Hs384::OUTPUT_SIZE..)
| (Hmac::Hs512, Hs512::OUTPUT_SIZE..) => true,
_ => false,

Check warning on line 741 in src/jwk.rs

View check run for this annotation

Codecov / codecov/patch

src/jwk.rs#L735-L741

Added lines #L735 - L741 were not covered by tests
},
(
Symmetric(SymmetricJsonWebKey::OctetSequence(key)),
Encryption(JsonWebEncryptionAlgorithm::AesKw(aes)),
) => matches!(
(aes, key.len()),

Check warning on line 747 in src/jwk.rs

View check run for this annotation

Codecov / codecov/patch

src/jwk.rs#L744-L747

Added lines #L744 - L747 were not covered by tests
(AesKw::Aes128, 16) | (AesKw::Aes192, 24) | (AesKw::Aes256, 32)
),
(
Symmetric(SymmetricJsonWebKey::OctetSequence(key)),
Encryption(JsonWebEncryptionAlgorithm::AesGcmKw(aes)),
) => matches!(
(aes, key.len()),

Check warning on line 754 in src/jwk.rs

View check run for this annotation

Codecov / codecov/patch

src/jwk.rs#L751-L754

Added lines #L751 - L754 were not covered by tests
(AesGcm::Aes128, 16) | (AesGcm::Aes192, 24) | (AesGcm::Aes256, 32)
),
(
Symmetric(SymmetricJsonWebKey::OctetSequence(key)),
Encryption(JsonWebEncryptionAlgorithm::Pbes2(pbes2)),
) => matches!(
(pbes2, key.len()),

Check warning on line 761 in src/jwk.rs

View check run for this annotation

Codecov / codecov/patch

src/jwk.rs#L758-L761

Added lines #L758 - L761 were not covered by tests
(Pbes2::Hs256Aes128, 16) | (Pbes2::Hs384Aes192, 24) | (Pbes2::Hs512Aes256, 32)
),
(
Symmetric(SymmetricJsonWebKey::OctetSequence(..)),
Signing(JsonWebSigningAlgorithm::Hmac(..))
| Encryption(JsonWebEncryptionAlgorithm::Direct)
| Encryption(JsonWebEncryptionAlgorithm::AesKw(..))
| Encryption(JsonWebEncryptionAlgorithm::AesGcmKw(..))
| Encryption(JsonWebEncryptionAlgorithm::Pbes2(..)),
Encryption(JsonWebEncryptionAlgorithm::Direct),
) => true,
(Asymmetric(key), alg) => match (&**key, alg) {
(
Expand Down
12 changes: 12 additions & 0 deletions src/jwk/symmetric.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,18 @@ impl OctetSequence {
pub(crate) fn new(x: impl Into<Vec<u8>>) -> Self {
Self(Base64UrlBytes(x.into()))
}

/// Returns the number of bytes that are in this octet sequence.
#[inline]
pub fn len(&self) -> usize {
self.0 .0.len()
}

Check warning on line 44 in src/jwk/symmetric.rs

View check run for this annotation

Codecov / codecov/patch

src/jwk/symmetric.rs#L42-L44

Added lines #L42 - L44 were not covered by tests

/// Returns `true` if this octet sequence has a length of zero.
#[inline]
pub fn is_empty(&self) -> bool {
self.len() == 0
}

Check warning on line 50 in src/jwk/symmetric.rs

View check run for this annotation

Codecov / codecov/patch

src/jwk/symmetric.rs#L48-L50

Added lines #L48 - L50 were not covered by tests
}

impl crate::sealed::Sealed for OctetSequence {}
Expand Down
5 changes: 4 additions & 1 deletion src/jwk/symmetric/hmac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ pub trait HmacVariant: Sealed {
/// The JWA algorithm for this variant.
const ALGORITHM: JsonWebSigningAlgorithm;

/// The output size of this HMAC variant in bytes.
const OUTPUT_SIZE: usize = <<Self::HmacType as OutputSizeUser>::OutputSize as Unsigned>::USIZE;

/// The [`hmac::Hmac`] type for this variant.
type HmacType: Clone + KeyInit + FixedOutput + FixedOutputReset + Update + fmt::Debug;
}
Expand Down Expand Up @@ -186,7 +189,7 @@ impl<H: HmacVariant> FromKey<&OctetSequence> for HmacKey<H> {
// This check is not required for normal Hmac implementations based on RFC 2104
// but RFC 7518 section 3.2 requires this check and forbids keys with a length <
// output
if key.len() < <<H::HmacType as OutputSizeUser>::OutputSize as Unsigned>::USIZE {
if key.len() < <H as HmacVariant>::OUTPUT_SIZE {
return Err(digest::InvalidLength.into());
}

Expand Down

0 comments on commit 79f7bb1

Please sign in to comment.