Skip to content

Commit

Permalink
fix(pkcs12): Added API to query and set MAC algorithm for PFX (#317)
Browse files Browse the repository at this point in the history
  • Loading branch information
pacmancoder authored Oct 30, 2024
1 parent 7980381 commit ca9d764
Show file tree
Hide file tree
Showing 9 changed files with 289 additions and 1 deletion.
20 changes: 20 additions & 0 deletions ffi/dotnet/Devolutions.Picky/Generated/Pfx.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 26 additions & 0 deletions ffi/dotnet/Devolutions.Picky/Generated/PfxBuilder.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

124 changes: 124 additions & 0 deletions ffi/dotnet/Devolutions.Picky/Generated/Pkcs12MacAlgorithmHmac.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions ffi/dotnet/Devolutions.Picky/Generated/RawPfx.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions ffi/dotnet/Devolutions.Picky/Generated/RawPfxBuilder.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

68 changes: 67 additions & 1 deletion ffi/src/pkcs12.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,32 @@ pub mod ffi {
}
}

#[diplomat::opaque]
pub struct Pkcs12MacAlgorithmHmac(pub(crate) pkcs12::Pkcs12MacAlgorithmHmac);

impl Pkcs12MacAlgorithmHmac {
pub fn new_hmac(hash_algorithm: Pkcs12HashAlgorithm) -> Box<Pkcs12MacAlgorithmHmac> {
Box::new(Self(pkcs12::Pkcs12MacAlgorithmHmac::new(hash_algorithm.into())))
}

pub fn new_hmac_with_iterations(
hash_algorithm: Pkcs12HashAlgorithm,
iterations: u32,
) -> Box<Pkcs12MacAlgorithmHmac> {
Box::new(Self(
pkcs12::Pkcs12MacAlgorithmHmac::new(hash_algorithm.into()).with_iterations(iterations),
))
}

pub fn hash_algorithm(&self) -> Pkcs12HashAlgorithm {
self.0.hash_algorithm().into()
}

pub fn iterations(&self) -> Option<Box<u32>> {
self.0.iterations().map(Box::new)
}
}

#[diplomat::opaque]
pub struct Pkcs12ParsingParams(pub(crate) pkcs12::Pkcs12ParsingParams);

Expand Down Expand Up @@ -286,6 +312,8 @@ pub mod ffi {
safe_bags_acc: Vec<pkcs12::SafeBag>,
safe_contents: Vec<pkcs12::SafeContents>,
crypto_context: Arc<Mutex<pkcs12::Pkcs12CryptoContext>>,
hmac_algorithm: Option<pkcs12::Pkcs12MacAlgorithmHmac>,
detected_old_encryption: bool,
}

impl PfxBuilder {
Expand All @@ -294,6 +322,8 @@ pub mod ffi {
safe_bags_acc: Vec::new(),
safe_contents: Vec::new(),
crypto_context: crypto_context.0.clone(),
hmac_algorithm: None,
detected_old_encryption: false,
})
}

Expand All @@ -317,13 +347,21 @@ pub mod ffi {

let encryption = encryption.0.to_picky_encryption(&mut crypto_context);

if let pkcs12::Pkcs12EncryptionKind::Pbes1(_) = encryption.kind() {
self.detected_old_encryption = true
}

let safe_contents = pkcs12::SafeContents::new_encrypted(safe_bags, encryption, &crypto_context)?;

self.safe_contents.push(safe_contents);

Ok(())
}

pub fn set_hmac_algorithm(&mut self, mac_algorithm: &Pkcs12MacAlgorithmHmac) {
self.hmac_algorithm = Some(mac_algorithm.0.clone());
}

pub fn build(&mut self) -> Result<Box<Pfx>, Box<PickyError>> {
let mut crypto_context = self.crypto_context.lock().unwrap();

Expand All @@ -334,7 +372,14 @@ pub mod ffi {
safe_contents.push(pkcs12::SafeContents::new(safe_bags));
}

let mac = pkcs12::Pkcs12MacAlgorithmHmac::new(pkcs12::Pkcs12HashAlgorithm::Sha256);
let mac = if let Some(mac_algorithm) = &self.hmac_algorithm {
mac_algorithm.clone()
} else if self.detected_old_encryption {
// Automaically use SHA1 for HMAC if old encryption was detected
pkcs12::Pkcs12MacAlgorithmHmac::new(pkcs12::Pkcs12HashAlgorithm::Sha1)
} else {
pkcs12::Pkcs12MacAlgorithmHmac::new(pkcs12::Pkcs12HashAlgorithm::Sha256)
};

let pfx = pkcs12::Pfx::new_with_hmac(safe_contents, mac, &mut crypto_context)?;

Expand Down Expand Up @@ -362,6 +407,15 @@ pub mod ffi {
Ok(Box::new(Self(pfx)))
}

pub fn hmac_algorithm(&self) -> Option<Box<Pkcs12MacAlgorithmHmac>> {
let mac_data = self.0.mac_data()?;

match mac_data.algorithm() {
pkcs12::Pkcs12MacAlgorithm::Hmac(mac) => Some(Box::new(Pkcs12MacAlgorithmHmac(mac.clone()))),
_ => None,
}
}

/// Saves this PKCS12 archive to the filesystem.
pub fn save_to_file(&self, path: &str) -> Result<(), Box<PickyError>> {
use std::io::Write as _;
Expand Down Expand Up @@ -514,6 +568,18 @@ impl From<ffi::Pkcs12HashAlgorithm> for picky::pkcs12::Pkcs12HashAlgorithm {
}
}

impl From<picky::pkcs12::Pkcs12HashAlgorithm> for ffi::Pkcs12HashAlgorithm {
fn from(value: picky::pkcs12::Pkcs12HashAlgorithm) -> Self {
match value {
picky::pkcs12::Pkcs12HashAlgorithm::Sha1 => Self::Sha1,
picky::pkcs12::Pkcs12HashAlgorithm::Sha224 => Self::Sha224,
picky::pkcs12::Pkcs12HashAlgorithm::Sha256 => Self::Sha256,
picky::pkcs12::Pkcs12HashAlgorithm::Sha384 => Self::Sha384,
picky::pkcs12::Pkcs12HashAlgorithm::Sha512 => Self::Sha512,
}
}
}

impl From<ffi::Pbes2Cipher> for picky::pkcs12::Pbes2Cipher {
fn from(value: ffi::Pbes2Cipher) -> Self {
match value {
Expand Down
1 change: 1 addition & 0 deletions picky-asn1-x509/src/pkcs7/content_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use crate::{oids, DigestInfo};
///
/// ContentType ::= OBJECT IDENTIFIER
/// ```
#[allow(clippy::large_enum_variant)]
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum ContentValue {
SpcIndirectDataContent(SpcIndirectDataContent),
Expand Down
8 changes: 8 additions & 0 deletions picky/src/pkcs12/mac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ impl Pkcs12MacAlgorithmHmac {
self.iterations = Some(iterations);
self
}

pub fn hash_algorithm(&self) -> Pkcs12HashAlgorithm {
self.hash_algorithm
}

pub fn iterations(&self) -> Option<u32> {
self.iterations
}
}

/// Parsed MAC algorithm parameters
Expand Down

0 comments on commit ca9d764

Please sign in to comment.