From 690edddbc17e1183cc15ccee643acf67ae5d10b7 Mon Sep 17 00:00:00 2001 From: silverpill Date: Mon, 27 Dec 2021 15:28:05 +0000 Subject: [PATCH] Add "algorithm" parameter to HTTP signature --- src/http_signatures/create.rs | 4 +++- src/http_signatures/verify.rs | 34 ++++++++++++++++++---------------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/http_signatures/create.rs b/src/http_signatures/create.rs index 30ec62a..9675fd6 100644 --- a/src/http_signatures/create.rs +++ b/src/http_signatures/create.rs @@ -63,7 +63,7 @@ pub fn create_http_signature( .collect::>().join(" "); let signature_parameter = sign_message(actor_key, &message)?; let signature_header = format!( - r#"keyId="{}",headers="{}",signature="{}""#, + r#"keyId="{}",algorithm="rsa-sha256",headers="{}",signature="{}""#, actor_key_id, headers_parameter, signature_parameter, @@ -100,6 +100,7 @@ mod tests { assert_eq!(headers.digest, None); let expected_signature_header = concat!( r#"keyId="https://myserver.org/actor#main-key","#, + r#"algorithm="rsa-sha256","#, r#"headers="(request-target) host date","#, r#"signature=""#, ); @@ -133,6 +134,7 @@ mod tests { ); let expected_signature_header = concat!( r#"keyId="https://myserver.org/actor#main-key","#, + r#"algorithm="rsa-sha256","#, r#"headers="(request-target) host date digest","#, r#"signature=""#, ); diff --git a/src/http_signatures/verify.rs b/src/http_signatures/verify.rs index e90bcd6..250bcaa 100644 --- a/src/http_signatures/verify.rs +++ b/src/http_signatures/verify.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + use actix_web::{ HttpRequest, http::{HeaderMap, Method, Uri}, @@ -44,6 +46,8 @@ pub struct SignatureData { pub signature: String, // base64-encoded signature } +const SIGNATURE_PARAMETER_RE: &str = r#"^(?P[a-zA-Z]+)="(?P.+)"$"#; + fn parse_http_signature( request_method: &Method, request_uri: &Uri, @@ -53,27 +57,25 @@ fn parse_http_signature( .ok_or(VerificationError::HeaderError("missing signature header"))? .to_str() .map_err(|_| VerificationError::HeaderError("invalid signature header"))?; - // TODO: support arbitrary parameter order - let signature_header_regexp_raw = concat!( - r#"keyId="(?P.+)","#, - r#"headers="(?P.+)","#, - r#"signature="(?P.+)""#, - ); - let signature_header_regexp = Regex::new(signature_header_regexp_raw).unwrap(); - let signature_header_caps = signature_header_regexp - .captures(signature_header) - .ok_or(VerificationError::HeaderError("invalid signature header"))?; - let key_id = signature_header_caps.name("key_id") + + let signature_parameter_re = Regex::new(SIGNATURE_PARAMETER_RE).unwrap(); + let mut signature_parameters = HashMap::new(); + for item in signature_header.split(",") { + let caps = signature_parameter_re.captures(item) + .ok_or(VerificationError::HeaderError("invalid signature header"))?; + let key = caps["key"].to_string(); + let value = caps["value"].to_string(); + signature_parameters.insert(key, value); + }; + + let key_id = signature_parameters.get("keyId") .ok_or(VerificationError::ParseError("keyId parameter is missing"))? - .as_str() .to_owned(); - let headers_parameter = signature_header_caps.name("headers") + let headers_parameter = signature_parameters.get("headers") .ok_or(VerificationError::ParseError("headers parameter is missing"))? - .as_str() .to_owned(); - let signature = signature_header_caps.name("signature") + let signature = signature_parameters.get("signature") .ok_or(VerificationError::ParseError("signature is missing"))? - .as_str() .to_owned(); let mut message = format!(