Move base64 encoding/decoding out of RSA signing functions

This commit is contained in:
silverpill 2022-11-18 23:22:24 +00:00
parent bd4a9a0de9
commit 5974ac8618
5 changed files with 29 additions and 22 deletions

View file

@ -2,7 +2,10 @@ use actix_web::http::Method;
use chrono::Utc; use chrono::Utc;
use rsa::RsaPrivateKey; use rsa::RsaPrivateKey;
use crate::utils::crypto_rsa::{get_message_digest, sign_message}; use crate::utils::crypto_rsa::{
create_rsa_signature,
get_message_digest,
};
const HTTP_SIGNATURE_ALGORITHM: &str = "rsa-sha256"; const HTTP_SIGNATURE_ALGORITHM: &str = "rsa-sha256";
const HTTP_SIGNATURE_DATE_FORMAT: &str = "%a, %d %b %Y %T GMT"; const HTTP_SIGNATURE_DATE_FORMAT: &str = "%a, %d %b %Y %T GMT";
@ -69,7 +72,8 @@ pub fn create_http_signature(
.map(|(name, _)| name.to_string()) .map(|(name, _)| name.to_string())
.collect::<Vec<String>>() .collect::<Vec<String>>()
.join(" "); .join(" ");
let signature_parameter = sign_message(signer_key, &message)?; let signature = create_rsa_signature(signer_key, &message)?;
let signature_parameter = base64::encode(signature);
let signature_header = format!( let signature_header = format!(
r#"keyId="{}",algorithm="{}",headers="{}",signature="{}""#, r#"keyId="{}",algorithm="{}",headers="{}",signature="{}""#,
signer_key_id, signer_key_id,

View file

@ -120,11 +120,12 @@ pub fn verify_http_signature(
if expires_at < Utc::now() { if expires_at < Utc::now() {
log::warn!("signature has expired"); log::warn!("signature has expired");
}; };
let signature = base64::decode(&signature_data.signature)?;
let is_valid_signature = verify_rsa_signature( let is_valid_signature = verify_rsa_signature(
signer_key, signer_key,
&signature_data.message, &signature_data.message,
&signature_data.signature, &signature,
)?; );
if !is_valid_signature { if !is_valid_signature {
return Err(VerificationError::InvalidSignature); return Err(VerificationError::InvalidSignature);
}; };

View file

@ -16,7 +16,7 @@ use crate::utils::canonicalization::{
canonicalize_object, canonicalize_object,
CanonicalizationError, CanonicalizationError,
}; };
use crate::utils::crypto_rsa::sign_message; use crate::utils::crypto_rsa::create_rsa_signature;
pub(super) const PROOF_KEY: &str = "proof"; pub(super) const PROOF_KEY: &str = "proof";
pub(super) const PROOF_PURPOSE: &str = "assertionMethod"; pub(super) const PROOF_PURPOSE: &str = "assertionMethod";
@ -37,14 +37,14 @@ pub struct IntegrityProof {
impl IntegrityProof { impl IntegrityProof {
fn jcs_rsa( fn jcs_rsa(
signer_key_id: &str, signer_key_id: &str,
signature: &str, signature: &[u8],
) -> Self { ) -> Self {
Self { Self {
proof_type: PROOF_TYPE_JCS_RSA.to_string(), proof_type: PROOF_TYPE_JCS_RSA.to_string(),
proof_purpose: PROOF_PURPOSE.to_string(), proof_purpose: PROOF_PURPOSE.to_string(),
verification_method: signer_key_id.to_string(), verification_method: signer_key_id.to_string(),
created: Utc::now(), created: Utc::now(),
proof_value: signature.to_string(), proof_value: base64::encode(signature),
} }
} }
@ -115,9 +115,9 @@ pub fn sign_object(
// Canonicalize // Canonicalize
let message = canonicalize_object(object)?; let message = canonicalize_object(object)?;
// Sign // Sign
let signature_b64 = sign_message(signer_key, &message)?; let signature = create_rsa_signature(signer_key, &message)?;
// Insert proof // Insert proof
let proof = IntegrityProof::jcs_rsa(signer_key_id, &signature_b64); let proof = IntegrityProof::jcs_rsa(signer_key_id, &signature);
let mut object_value = serde_json::to_value(object)?; let mut object_value = serde_json::to_value(object)?;
add_integrity_proof(&mut object_value, proof)?; add_integrity_proof(&mut object_value, proof)?;
Ok(object_value) Ok(object_value)

View file

@ -103,11 +103,12 @@ pub fn verify_rsa_json_signature(
signature_data: &SignatureData, signature_data: &SignatureData,
signer_key: &RsaPublicKey, signer_key: &RsaPublicKey,
) -> Result<(), VerificationError> { ) -> Result<(), VerificationError> {
let signature = base64::decode(&signature_data.signature)?;
let is_valid_signature = verify_rsa_signature( let is_valid_signature = verify_rsa_signature(
signer_key, signer_key,
&signature_data.message, &signature_data.message,
&signature_data.signature, &signature,
)?; );
if !is_valid_signature { if !is_valid_signature {
return Err(VerificationError::InvalidSignature); return Err(VerificationError::InvalidSignature);
}; };

View file

@ -47,15 +47,14 @@ pub fn deserialize_public_key(
} }
/// RSASSA-PKCS1-v1_5 signature /// RSASSA-PKCS1-v1_5 signature
pub fn sign_message( pub fn create_rsa_signature(
private_key: &RsaPrivateKey, private_key: &RsaPrivateKey,
message: &str, message: &str,
) -> Result<String, rsa::errors::Error> { ) -> Result<Vec<u8>, rsa::errors::Error> {
let digest = Sha256::digest(message.as_bytes()); let digest = Sha256::digest(message.as_bytes());
let padding = PaddingScheme::new_pkcs1v15_sign(Some(Hash::SHA2_256)); let padding = PaddingScheme::new_pkcs1v15_sign(Some(Hash::SHA2_256));
let signature = private_key.sign(padding, &digest)?; let signature = private_key.sign(padding, &digest)?;
let signature_b64 = base64::encode(&signature); Ok(signature)
Ok(signature_b64)
} }
pub fn get_message_digest(message: &str) -> String { pub fn get_message_digest(message: &str) -> String {
@ -67,17 +66,16 @@ pub fn get_message_digest(message: &str) -> String {
pub fn verify_rsa_signature( pub fn verify_rsa_signature(
public_key: &RsaPublicKey, public_key: &RsaPublicKey,
message: &str, message: &str,
signature_b64: &str, signature: &[u8],
) -> Result<bool, base64::DecodeError> { ) -> bool {
let digest = Sha256::digest(message.as_bytes()); let digest = Sha256::digest(message.as_bytes());
let padding = PaddingScheme::new_pkcs1v15_sign(Some(Hash::SHA2_256)); let padding = PaddingScheme::new_pkcs1v15_sign(Some(Hash::SHA2_256));
let signature = base64::decode(signature_b64)?;
let is_valid = public_key.verify( let is_valid = public_key.verify(
padding, padding,
&digest, &digest,
&signature, signature,
).is_ok(); ).is_ok();
Ok(is_valid) is_valid
} }
#[cfg(test)] #[cfg(test)]
@ -104,14 +102,17 @@ YsFtrgWDQ/s8k86sNBU+Ce2GOL7seh46kyAWgJeohh4Rcrr23rftHbvxOcRM8VzYuCeb1DgVhPGtA0xU
fn test_verify_rsa_signature() { fn test_verify_rsa_signature() {
let private_key = generate_weak_rsa_key().unwrap(); let private_key = generate_weak_rsa_key().unwrap();
let message = "test".to_string(); let message = "test".to_string();
let signature = sign_message(&private_key, &message).unwrap(); let signature = create_rsa_signature(
&private_key,
&message,
).unwrap();
let public_key = RsaPublicKey::from(&private_key); let public_key = RsaPublicKey::from(&private_key);
let is_valid = verify_rsa_signature( let is_valid = verify_rsa_signature(
&public_key, &public_key,
&message, &message,
&signature, &signature,
).unwrap(); );
assert_eq!(is_valid, true); assert_eq!(is_valid, true);
} }
} }