1
0
Fork 0
mirror of https://github.com/zhaofengli/attic.git synced 2024-12-14 11:57:30 +00:00

Merge pull request #181 from zhaofengli/hs256-allow-arbitrary-byte-string

token: Don't require valid UTF-8 for HS256 secrets
This commit is contained in:
Zhaofeng Li 2024-10-06 12:29:24 -06:00 committed by GitHub
commit 880ca6d477
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 35 additions and 18 deletions

View file

@ -369,28 +369,46 @@ fn load_jwt_signing_config_from_env() -> JWTSigningConfig {
config
}
fn load_token_hs256_secret_from_env() -> Option<JWTSigningConfig> {
let s = env::var(ENV_TOKEN_HS256_SECRET_BASE64).ok()?;
fn read_non_empty_var(key: &str) -> Result<Option<String>> {
let value = match env::var(key) {
Err(env::VarError::NotPresent) => {
return Ok(None);
}
r => r?,
};
decode_token_hs256_secret_base64(&s)
.ok()
.map(JWTSigningConfig::HS256SignAndVerify)
if value.is_empty() {
Ok(None)
} else {
Ok(Some(value))
}
}
fn load_token_hs256_secret_from_env() -> Option<JWTSigningConfig> {
let s = read_non_empty_var(ENV_TOKEN_HS256_SECRET_BASE64)
.expect("HS256 environment cannot be read")?;
let secret = decode_token_hs256_secret_base64(&s).expect("HS256 secret cannot be decoded");
Some(JWTSigningConfig::HS256SignAndVerify(secret))
}
fn load_token_rs256_secret_from_env() -> Option<JWTSigningConfig> {
let s = env::var(ENV_TOKEN_RS256_SECRET_BASE64).ok()?;
let s = read_non_empty_var(ENV_TOKEN_RS256_SECRET_BASE64)
.expect("RS256 environment cannot be read")?;
decode_token_rs256_secret_base64(&s)
.ok()
.map(JWTSigningConfig::RS256SignAndVerify)
let secret = decode_token_rs256_secret_base64(&s).expect("RS256 cannot be decoded");
Some(JWTSigningConfig::RS256SignAndVerify(secret))
}
fn load_token_rs256_pubkey_from_env() -> Option<JWTSigningConfig> {
let s = env::var(ENV_TOKEN_RS256_PUBKEY_BASE64).ok()?;
let s = read_non_empty_var(ENV_TOKEN_RS256_PUBKEY_BASE64)
.expect("RS256 pubkey environment cannot be read")?;
decode_token_rs256_pubkey_base64(&s)
.ok()
.map(JWTSigningConfig::RS256VerifyOnly)
let pubkey = decode_token_rs256_pubkey_base64(&s).expect("RS256 pubkey cannot be decoded");
Some(JWTSigningConfig::RS256VerifyOnly(pubkey))
}
fn load_database_url_from_env() -> String {

View file

@ -444,8 +444,7 @@ impl StdError for Error {}
pub fn decode_token_hs256_secret_base64(s: &str) -> Result<HS256Key> {
let decoded = BASE64_STANDARD.decode(s).map_err(Error::Base64Error)?;
let secret = std::str::from_utf8(&decoded).map_err(Error::Utf8Error)?;
Ok(HS256Key::from_bytes(&secret.as_bytes()))
Ok(HS256Key::from_bytes(&decoded))
}
pub fn decode_token_rs256_secret_base64(s: &str) -> Result<RS256KeyPair> {

View file

@ -32,11 +32,11 @@ fn test_basic() {
(
"hs256",
Box::new(|| {
// "very secure secret"
let base64_secret = "dmVyeSBzZWN1cmUgc2VjcmV0";
// printf '\xc3\x28 <- invalid utf8' | base64
let base64_secret = "wyggPC0gaW52YWxpZCB1dGY4";
let dec_key = decode_token_hs256_secret_base64(base64_secret).unwrap();
let token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjQxMDIzMjQ5ODYsImh0dHBzOi8vand0LmF0dGljLnJzL3YxIjp7ImNhY2hlcyI6eyJhbGwtKiI6eyJyIjoxfSwiYWxsLWNpLSoiOnsidyI6MX0sImNhY2hlLXJvIjp7InIiOjF9LCJjYWNoZS1ydyI6eyJyIjoxLCJ3IjoxfSwidGVhbS0qIjp7ImNjIjoxLCJyIjoxLCJ3IjoxfX19LCJpYXQiOjE3MTY2NjA1ODksInN1YiI6Im1lb3cifQ.8vtxp_1OEYdcnkGPM4c9ORXooJZV7DOTS4NRkMKN8mw";
let token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjQxMDIzMjQ5ODYsImh0dHBzOi8vand0LmF0dGljLnJzL3YxIjp7ImNhY2hlcyI6eyJhbGwtKiI6eyJyIjoxfSwiYWxsLWNpLSoiOnsidyI6MX0sImNhY2hlLXJvIjp7InIiOjF9LCJjYWNoZS1ydyI6eyJyIjoxLCJ3IjoxfSwidGVhbS0qIjp7ImNjIjoxLCJyIjoxLCJ3IjoxfX19LCJpYXQiOjE3MjgyMzI5OTYsIm5iZiI6MCwic3ViIjoibWVvdyJ9.wESluTI5K5v2W1WISGwAjazKMMUZBD-zSUYN-_XFN9I";
Token::from_jwt(token, &SignatureType::HS256(dec_key), &None, &None).unwrap()
}),