@@ -16,9 +16,9 @@ use http::{HeaderMap, Response, StatusCode, header};
1616use pingora:: apps:: http_app:: { HttpServer , ServeHttp } ;
1717use pingora:: protocols:: http:: ServerSession ;
1818use pingora:: services:: listening:: Service ;
19+ use sanitization:: ct:: ConstantTimeEq ;
1920use serde:: Serialize ;
2021use serde_json:: { Value , json} ;
21- use subtle:: ConstantTimeEq ;
2222use zeroize:: { Zeroize , ZeroizeOnDrop , Zeroizing } ;
2323
2424use crate :: config:: { AdminAuthThrottleConfig , AdminConfig , AdminHealthResponseMode , Config } ;
@@ -3197,7 +3197,8 @@ fn constant_time_eq(candidate: &[u8], token: &AdminToken) -> bool {
31973197 let candidate_digest = digest_admin_token ( candidate, token. mac_provider ) ;
31983198 let candidate_len = ( candidate. len ( ) as u64 ) . to_le_bytes ( ) ;
31993199 let token_len = ( token. len as u64 ) . to_le_bytes ( ) ;
3200- bool:: from ( candidate_digest. ct_eq ( & token. digest ) & candidate_len. ct_eq ( & token_len) )
3200+ ( candidate_digest. ct_eq ( & token. digest ) & candidate_len. ct_eq ( & token_len) )
3201+ . declassify ( "admin bearer-token comparison result is public" )
32013202}
32023203
32033204fn digest_admin_token (
@@ -4240,8 +4241,9 @@ mod tests {
42404241
42414242 use super :: {
42424243 AdminApp , AdminAuthThrottle , AdminToken , MAX_ADMIN_TOKEN_FILE_BYTES ,
4243- admin_services_from_config, authorized, constant_time_eq, error_response, json_response,
4244- native_admin_target_parts, read_bounded_secret_file, read_secret_file,
4244+ admin_fingerprint_list_contains, admin_services_from_config, authorized, constant_time_eq,
4245+ error_response, json_response, native_admin_target_parts, read_bounded_secret_file,
4246+ read_secret_file,
42454247 } ;
42464248 #[ cfg( feature = "cache" ) ]
42474249 use crate :: config:: ByteSize ;
@@ -7842,6 +7844,7 @@ mod tests {
78427844 let token = AdminToken :: new ( "secret-token" , false ) ;
78437845 assert ! ( authorized( Some ( "Bearer secret-token" ) , & token) ) ;
78447846 assert ! ( !authorized( Some ( "Bearer secret" ) , & token) ) ;
7847+ assert ! ( !authorized( Some ( "Bearer secret-token-extra" ) , & token) ) ;
78457848 assert ! ( !constant_time_eq( b"secret" , & token) ) ;
78467849 assert ! ( !authorized(
78477850 Some ( & format!(
@@ -7852,6 +7855,22 @@ mod tests {
78527855 ) ) ;
78537856 }
78547857
7858+ #[ test]
7859+ fn certificate_fingerprint_comparison_uses_exact_length_match ( ) {
7860+ let fingerprint = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ;
7861+ let values = vec ! [ fingerprint. to_owned( ) ] ;
7862+
7863+ assert ! ( admin_fingerprint_list_contains( & values, fingerprint) ) ;
7864+ assert ! ( !admin_fingerprint_list_contains(
7865+ & values,
7866+ & fingerprint[ ..63 ]
7867+ ) ) ;
7868+ assert ! ( !admin_fingerprint_list_contains(
7869+ & values,
7870+ & format!( "{fingerprint}a" )
7871+ ) ) ;
7872+ }
7873+
78557874 #[ test]
78567875 fn admin_client_certificate_policy_requires_trusted_fingerprint_header ( ) {
78577876 let app = app_with_config ( Config {
0 commit comments