1use crate::error::ConversionError;
2use crate::openssl::ParsedPfx;
3use openssl::pkcs12::Pkcs12;
4use std::fs;
5use std::path::Path;
6
7pub struct PfxParser;
9
10impl PfxParser {
11 pub fn parse_file<P: AsRef<Path>>(
13 path: P,
14 password: &str,
15 ) -> Result<ParsedPfx, ConversionError> {
16 let path = path.as_ref();
17
18 if !path.exists() {
20 return Err(ConversionError::FileNotFound(path.display().to_string()));
21 }
22
23 let pfx_data =
25 fs::read(path).map_err(|e| ConversionError::FileRead(path.display().to_string(), e))?;
26
27 Self::parse_bytes(&pfx_data, password)
28 }
29
30 pub fn parse_bytes(data: &[u8], password: &str) -> Result<ParsedPfx, ConversionError> {
32 let pkcs12 = Pkcs12::from_der(data).map_err(|e| {
34 ConversionError::InvalidFormat(format!("Failed to parse PFX structure: {}", e))
35 })?;
36
37 let parsed = pkcs12.parse2(password).map_err(|e| {
39 if password.is_empty() {
40 ConversionError::Authentication(format!(
41 "Failed to parse PFX file: {}. This file may require a password. Use --password option.",
42 e
43 ))
44 } else {
45 ConversionError::Authentication(format!(
46 "Failed to parse PFX file with provided password: {}",
47 e
48 ))
49 }
50 })?;
51
52 Ok(ParsedPfx::from(parsed))
53 }
54}