Skip to content

Commit

Permalink
Merge pull request #22 from mdsol/feature/normalize_pem_key_format
Browse files Browse the repository at this point in the history
Normalize provided private key string to the correct PEM format
  • Loading branch information
ykitamura-mdsol authored Dec 24, 2024
2 parents a2a0fb9 + 2506152 commit 54d05f3
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 3 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# 0.6.0
- Normalize provided private key string to the correct PEM format.
- Update thiserror to version 2.

# 0.5.0
- Convert from anyhow to thiserror.

# 0.4.1
- Add the Debug and Clone traits to `Signer` and `Verifier`.

Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mauth-core"
version = "0.5.0"
version = "0.6.0"
edition = "2021"
authors = ["Medidata Solutions <support@mdsol.com>"]
description = "Generate and verify Medidata MAuth protocol signatures"
Expand All @@ -13,7 +13,7 @@ keywords = ["security", "authentication"]
categories = ["authentication"]

[dependencies]
thiserror = "1"
thiserror = "2"
base64 = "0.22"
hex = "0.4"
lazy-regex = "3"
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ pub(crate) mod signable;
pub mod signer;
/// Signature verification for incoming requests
pub mod verifier;

mod pem_format;
54 changes: 54 additions & 0 deletions src/pem_format.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
const RSA_PRIVATE_KEY_HEADER: &str = "-----BEGIN RSA PRIVATE KEY-----";
const RSA_PRIVATE_KEY_FOOTER: &str = "-----END RSA PRIVATE KEY-----";

pub fn normalize_rsa_private_key(key: impl Into<String>) -> String {
let key = key.into();

match key.contains('\n') {
true => key,
false => {
let body = key
.trim()
.trim_start_matches(RSA_PRIVATE_KEY_HEADER)
.trim_end_matches(RSA_PRIVATE_KEY_FOOTER)
.trim();

let body = match body.contains(' ') {
true => body.replace(' ', "\n"),
false => body
.chars()
.collect::<Vec<char>>()
.chunks(64)
.map(|chunk| chunk.iter().collect::<String>())
.collect::<Vec<String>>()
.join("\n"),
};
format!(
"{}\n{}\n{}",
RSA_PRIVATE_KEY_HEADER, body, RSA_PRIVATE_KEY_FOOTER
)
}
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn normalize_rsa_private_key_test() {
let rsa_private_key = "-----BEGIN RSA PRIVATE KEY-----\nMIIBOgIBAAJBAKj34GkxFhD90vcNLYLInFEX6Ppy1tPf9Cnzj4p4WGeKLs1Pt8Qu\n/5OiPgoTdSy7bcF9IGpSE8ZgGKzgYQVZeN97YE00\n-----END RSA PRIVATE KEY-----";
let rsa_private_key_with_space = rsa_private_key.replace('\n', " ");
let rsa_private_key_without_newline = rsa_private_key.replace('\n', "");

assert_eq!(normalize_rsa_private_key(rsa_private_key), rsa_private_key);
assert_eq!(
normalize_rsa_private_key(rsa_private_key_with_space),
rsa_private_key
);
assert_eq!(
normalize_rsa_private_key(rsa_private_key_without_newline),
rsa_private_key
);
}
}
5 changes: 4 additions & 1 deletion src/signer.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::pem_format;
use crate::{error::Error, signable::Signable};
use base64::{engine::general_purpose, Engine as _};
use rsa::pkcs1::DecodeRsaPrivateKey;
Expand Down Expand Up @@ -27,7 +28,9 @@ impl Signer {
/// assert!(signer.is_ok());
/// ```
pub fn new(app_uuid: impl Into<String>, private_key_data: String) -> Result<Self, Error> {
let private_key = RsaPrivateKey::from_pkcs1_pem(&private_key_data)?;
let private_key = RsaPrivateKey::from_pkcs1_pem(&pem_format::normalize_rsa_private_key(
private_key_data,
))?;
let signing_key = rsa::pkcs1v15::SigningKey::<Sha512>::new(private_key.to_owned());

Ok(Self {
Expand Down

0 comments on commit 54d05f3

Please sign in to comment.