Skip to content

Commit

Permalink
Use serde_plain instead of variant_name to stringify enums
Browse files Browse the repository at this point in the history
The variant_name() function from the `oauth2` crate is fragile and
doesn't support arbitrary `Serialize` implementations. Using `serde_plain`
will support all types as long as their `Serialize` implementations
emit a string.
  • Loading branch information
ramosbugs committed Jan 11, 2023
1 parent 47e0c41 commit 424b44f
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 15 deletions.
23 changes: 20 additions & 3 deletions Cargo-1.45.lock
Original file line number Diff line number Diff line change
Expand Up @@ -737,9 +737,9 @@ dependencies = [

[[package]]
name = "oauth2"
version = "4.2.0"
version = "4.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3bd7d544f02ae0fa9e06137962703d043870d7ad6e6d44786d6a5f20679b2c9"
checksum = "eeaf26a72311c087f8c5ba617c96fac67a5c04f430e716ac8d8ab2de62e23368"
dependencies = [
"base64",
"chrono",
Expand Down Expand Up @@ -774,7 +774,7 @@ checksum = "ac8b1a9b2518dc799a2271eff1688707eb315f0d4697aa6b0871369ca4c4da55"

[[package]]
name = "openidconnect"
version = "2.3.2"
version = "2.4.1"
dependencies = [
"anyhow",
"base64",
Expand All @@ -796,6 +796,8 @@ dependencies = [
"serde_derive",
"serde_json",
"serde_path_to_error",
"serde_plain",
"subtle",
"thiserror",
"url",
]
Expand Down Expand Up @@ -1176,6 +1178,15 @@ dependencies = [
"serde",
]

[[package]]
name = "serde_plain"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6018081315db179d0ce57b1fe4b62a12a0028c9cf9bbef868c9cf477b3c34ae"
dependencies = [
"serde",
]

[[package]]
name = "serde_urlencoded"
version = "0.7.1"
Expand Down Expand Up @@ -1222,6 +1233,12 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"

[[package]]
name = "subtle"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"

[[package]]
name = "syn"
version = "1.0.98"
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"
serde_path_to_error = "0.1"
serde_plain = "1.0"
serde-value = "0.7"
url = { version = "2.1", features = ["serde"] }
num-bigint = "0.4.3"
Expand Down
22 changes: 18 additions & 4 deletions src/core/jwk.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use oauth2::helpers::variant_name;
use ring::hmac;
use ring::rand;
use ring::signature as ring_signature;
Expand Down Expand Up @@ -250,7 +249,12 @@ impl JsonWebKey<CoreJwsSigningAlgorithm, CoreJsonWebKeyType, CoreJsonWebKeyUse>
}
}
ref other => Err(SignatureVerificationError::UnsupportedAlg(
variant_name(other).to_string(),
serde_plain::to_string(other).unwrap_or_else(|err| {
panic!(format!(
"signature alg {:?} failed to serialize to a string: {}",
other, err
))
}),
)),
}
}
Expand Down Expand Up @@ -298,7 +302,12 @@ impl
CoreJwsSigningAlgorithm::HmacSha512 => hmac::HMAC_SHA512,
ref other => {
return Err(SigningError::UnsupportedAlg(
variant_name(other).to_string(),
serde_plain::to_string(other).unwrap_or_else(|err| {
panic!(format!(
"signature alg {:?} failed to serialize to a string: {}",
other, err
))
}),
))
}
};
Expand Down Expand Up @@ -396,7 +405,12 @@ impl
CoreJwsSigningAlgorithm::RsaSsaPssSha512 => &ring_signature::RSA_PSS_SHA512,
ref other => {
return Err(SigningError::UnsupportedAlg(
variant_name(other).to_string(),
serde_plain::to_string(other).unwrap_or_else(|err| {
panic!(format!(
"signature alg {:?} failed to serialize to a string: {}",
other, err
))
}),
))
}
};
Expand Down
14 changes: 14 additions & 0 deletions src/core/tests.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::core::CoreJwsSigningAlgorithm;

use super::CoreGrantType;

#[test]
Expand All @@ -9,3 +11,15 @@ fn test_grant_type_serialize() {
serde_json::from_str::<CoreGrantType>(&serialized_implicit).unwrap()
);
}

#[test]
fn test_signature_alg_serde_plain() {
assert_eq!(
serde_plain::to_string(&CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha256).unwrap(),
"RS256"
);
assert_eq!(
serde_plain::from_str::<CoreJwsSigningAlgorithm>("RS256").unwrap(),
CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha256
);
}
11 changes: 8 additions & 3 deletions src/id_token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use std::marker::PhantomData;
use std::str::FromStr;

use chrono::{DateTime, Utc};
use oauth2::helpers::variant_name;
use oauth2::ClientId;
use serde::Serialize;
use serde_json::Value;
Expand Down Expand Up @@ -145,13 +144,19 @@ where
///
/// Returns the [`JwsSigningAlgorithm`] used to sign this ID token.
///
/// This function returns an error if the signing algorithm is unsupported.
/// This function returns an error if the token is unsigned or utilizes JSON Web Encryption
/// (JWE).
///
pub fn signing_alg(&self) -> Result<JS, SigningError> {
match self.0.unverified_header().alg {
JsonWebTokenAlgorithm::Signature(ref signing_alg, _) => Ok(signing_alg.clone()),
JsonWebTokenAlgorithm::Encryption(ref other) => Err(SigningError::UnsupportedAlg(
variant_name(other).to_string(),
serde_plain::to_string(other).unwrap_or_else(|err| {
panic!(format!(
"encryption alg {:?} failed to serialize to a string: {}",
other, err
))
}),
)),
JsonWebTokenAlgorithm::None => Err(SigningError::UnsupportedAlg("none".to_string())),
}
Expand Down
30 changes: 25 additions & 5 deletions src/verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use std::ops::Deref;
use std::sync::Arc;

use chrono::{DateTime, Utc};
use oauth2::helpers::variant_name;
use oauth2::{ClientId, ClientSecret};
use serde::de::DeserializeOwned;
use serde::Serialize;
Expand Down Expand Up @@ -266,7 +265,10 @@ where
if let JsonWebTokenAlgorithm::Encryption(ref encryption_alg) = jose_header.alg {
return Err(ClaimsVerificationError::Unsupported(format!(
"JWE encryption is not currently supported (found algorithm `{}`)",
variant_name(encryption_alg),
serde_plain::to_string(encryption_alg).unwrap_or_else(|err| panic!(format!(
"encryption alg {:?} failed to serialize to a string: {}",
encryption_alg, err
))),
)));
}
}
Expand Down Expand Up @@ -367,10 +369,22 @@ where
return Err(ClaimsVerificationError::SignatureVerification(
SignatureVerificationError::DisallowedAlg(format!(
"algorithm `{}` is not one of: {}",
variant_name(&signature_alg),
serde_plain::to_string(&signature_alg).unwrap_or_else(|err| panic!(
format!(
"signature alg {:?} failed to serialize to a string: {}",
signature_alg, err
)
)),
allowed_algs
.iter()
.map(variant_name)
.map(
|alg| serde_plain::to_string(alg).unwrap_or_else(|err| panic!(
format!(
"signature alg {:?} failed to serialize to a string: {}",
alg, err
)
))
)
.collect::<Vec<_>>()
.join(", "),
)),
Expand Down Expand Up @@ -446,7 +460,13 @@ where
key.key_id()
.map(|kid| format!("`{}`", **kid))
.unwrap_or_else(|| "null ID".to_string()),
variant_name(key.key_type())
serde_plain::to_string(key.key_type()).unwrap_or_else(|err| panic!(
format!(
"key type {:?} failed to serialize to a string: {}",
key.key_type(),
err
)
))
))
.collect::<Vec<_>>()
.join(", ")
Expand Down

0 comments on commit 424b44f

Please sign in to comment.