A fork of attic a self-hostable Nix Binary Cache server
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

token: Don't require valid UTF-8 for HS256 secrets

authored by

Zhaofeng Li and committed by
GitHub
880ca6d4 b4338a16

+34 -17
+30 -12
server/src/config.rs
··· 369 369 config 370 370 } 371 371 372 + fn read_non_empty_var(key: &str) -> Result<Option<String>> { 373 + let value = match env::var(key) { 374 + Err(env::VarError::NotPresent) => { 375 + return Ok(None); 376 + } 377 + r => r?, 378 + }; 379 + 380 + if value.is_empty() { 381 + Ok(None) 382 + } else { 383 + Ok(Some(value)) 384 + } 385 + } 386 + 372 387 fn load_token_hs256_secret_from_env() -> Option<JWTSigningConfig> { 373 - let s = env::var(ENV_TOKEN_HS256_SECRET_BASE64).ok()?; 388 + let s = read_non_empty_var(ENV_TOKEN_HS256_SECRET_BASE64) 389 + .expect("HS256 environment cannot be read")?; 374 390 375 - decode_token_hs256_secret_base64(&s) 376 - .ok() 377 - .map(JWTSigningConfig::HS256SignAndVerify) 391 + let secret = decode_token_hs256_secret_base64(&s).expect("HS256 secret cannot be decoded"); 392 + 393 + Some(JWTSigningConfig::HS256SignAndVerify(secret)) 378 394 } 379 395 380 396 fn load_token_rs256_secret_from_env() -> Option<JWTSigningConfig> { 381 - let s = env::var(ENV_TOKEN_RS256_SECRET_BASE64).ok()?; 397 + let s = read_non_empty_var(ENV_TOKEN_RS256_SECRET_BASE64) 398 + .expect("RS256 environment cannot be read")?; 399 + 400 + let secret = decode_token_rs256_secret_base64(&s).expect("RS256 cannot be decoded"); 382 401 383 - decode_token_rs256_secret_base64(&s) 384 - .ok() 385 - .map(JWTSigningConfig::RS256SignAndVerify) 402 + Some(JWTSigningConfig::RS256SignAndVerify(secret)) 386 403 } 387 404 388 405 fn load_token_rs256_pubkey_from_env() -> Option<JWTSigningConfig> { 389 - let s = env::var(ENV_TOKEN_RS256_PUBKEY_BASE64).ok()?; 406 + let s = read_non_empty_var(ENV_TOKEN_RS256_PUBKEY_BASE64) 407 + .expect("RS256 pubkey environment cannot be read")?; 390 408 391 - decode_token_rs256_pubkey_base64(&s) 392 - .ok() 393 - .map(JWTSigningConfig::RS256VerifyOnly) 409 + let pubkey = decode_token_rs256_pubkey_base64(&s).expect("RS256 pubkey cannot be decoded"); 410 + 411 + Some(JWTSigningConfig::RS256VerifyOnly(pubkey)) 394 412 } 395 413 396 414 fn load_database_url_from_env() -> String {
+1 -2
token/src/lib.rs
··· 444 444 445 445 pub fn decode_token_hs256_secret_base64(s: &str) -> Result<HS256Key> { 446 446 let decoded = BASE64_STANDARD.decode(s).map_err(Error::Base64Error)?; 447 - let secret = std::str::from_utf8(&decoded).map_err(Error::Utf8Error)?; 448 - Ok(HS256Key::from_bytes(&secret.as_bytes())) 447 + Ok(HS256Key::from_bytes(&decoded)) 449 448 } 450 449 451 450 pub fn decode_token_rs256_secret_base64(s: &str) -> Result<RS256KeyPair> {
+3 -3
token/src/tests.rs
··· 32 32 ( 33 33 "hs256", 34 34 Box::new(|| { 35 - // "very secure secret" 36 - let base64_secret = "dmVyeSBzZWN1cmUgc2VjcmV0"; 35 + // printf '\xc3\x28 <- invalid utf8' | base64 36 + let base64_secret = "wyggPC0gaW52YWxpZCB1dGY4"; 37 37 let dec_key = decode_token_hs256_secret_base64(base64_secret).unwrap(); 38 38 39 - let token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjQxMDIzMjQ5ODYsImh0dHBzOi8vand0LmF0dGljLnJzL3YxIjp7ImNhY2hlcyI6eyJhbGwtKiI6eyJyIjoxfSwiYWxsLWNpLSoiOnsidyI6MX0sImNhY2hlLXJvIjp7InIiOjF9LCJjYWNoZS1ydyI6eyJyIjoxLCJ3IjoxfSwidGVhbS0qIjp7ImNjIjoxLCJyIjoxLCJ3IjoxfX19LCJpYXQiOjE3MTY2NjA1ODksInN1YiI6Im1lb3cifQ.8vtxp_1OEYdcnkGPM4c9ORXooJZV7DOTS4NRkMKN8mw"; 39 + let token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjQxMDIzMjQ5ODYsImh0dHBzOi8vand0LmF0dGljLnJzL3YxIjp7ImNhY2hlcyI6eyJhbGwtKiI6eyJyIjoxfSwiYWxsLWNpLSoiOnsidyI6MX0sImNhY2hlLXJvIjp7InIiOjF9LCJjYWNoZS1ydyI6eyJyIjoxLCJ3IjoxfSwidGVhbS0qIjp7ImNjIjoxLCJyIjoxLCJ3IjoxfX19LCJpYXQiOjE3MjgyMzI5OTYsIm5iZiI6MCwic3ViIjoibWVvdyJ9.wESluTI5K5v2W1WISGwAjazKMMUZBD-zSUYN-_XFN9I"; 40 40 41 41 Token::from_jwt(token, &SignatureType::HS256(dec_key), &None, &None).unwrap() 42 42 }),