From 365bcca6baeac522db0eb263d7de22dd0d6c4e31 Mon Sep 17 00:00:00 2001 From: nganhkhoa Date: Fri, 27 Aug 2021 08:36:52 +0000 Subject: [PATCH] parse subject key ids from signature --- src/main.rs | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index a91a19f..9cfc246 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,9 +5,86 @@ use std::env; use memmap2::MmapOptions; use byteorder::{BigEndian, ReadBytesExt}; +use der_parser::ber::{parse_ber_sequence, BerObjectContent}; use osx::{Macho}; +fn parse_pkcs7_signed_data(data: &[u8]) -> Result, Box> { + let (_, root) = parse_ber_sequence(data)?; + let root = root.content.as_sequence()?; + let oid = root[0].content.as_oid()?; + + // assert oid SignedData + + let signed_data = { + if let BerObjectContent::Unknown(_, rest) = root[1].content { + Some(rest) + } else { + None + } + } + .and_then(|x| parse_ber_sequence(x).ok()) + .map(|(_, x)| x) + .ok_or("cannot parse nested signed data")?; + let signed_data = signed_data.content.as_sequence()?; + // println!("signed data {:?}", signed_data); + + let certificates = { + if let BerObjectContent::Unknown(_, rest) = signed_data[3].content { + Some(rest) + } else { + None + } + }.ok_or("cannot get certificate list")?; + let (rest, cert1) = parse_ber_sequence(certificates)?; + let (rest, cert2) = parse_ber_sequence(rest)?; + let (_, cert3) = parse_ber_sequence(rest)?; + + let mut certificates = vec![]; + certificates.push(&cert1); + certificates.push(&cert2); + certificates.push(&cert3); + let certificates = certificates + .iter() + .filter_map(|x| x.content.as_sequence().ok()); + + let subject_key_ids = certificates + .filter_map(|cert| { + let ext = &cert[0].as_sequence().ok()?; + if let BerObjectContent::Unknown(_, rest) = ext[ext.len() - 1].content { + Some(rest) + } else { + None + } + .and_then(|x| parse_ber_sequence(x).ok()) + .map(|(_, x)| x) + .and_then(|extention_list| { + extention_list + .content + .as_sequence() + .ok()? + .iter() + .find_map(|extension| { + let content = extension.content.as_sequence().ok()?; + let oid = content[0].as_oid().ok()?.to_id_string(); + if oid != "2.5.29.14" { + return None + } + content[1] + .as_slice() + .ok() + .map(|arr| arr[2..] + .iter() + .map(|x| format!("{:02x}", x)) + .collect::>() + .concat()) + }) + }) + }) + .collect::>(); + Ok(subject_key_ids) +} + fn main() -> Result<(), Box> { let args = env::args().collect::>(); let ref filename = args.get(1).ok_or("No argument specified")?; @@ -30,7 +107,7 @@ fn main() -> Result<(), Box> { codedata }; - let sig = { + let mut sig = { let mut file = Cursor::new(codedata); let magic = file.read_u32::()?; @@ -66,5 +143,8 @@ fn main() -> Result<(), Box> { // let mut sigfile = File::create("signature.p7b")?; // sigfile.write_all(&sig)?; + let subject_key_ids = parse_pkcs7_signed_data(&sig)?; + println!("{:?}", subject_key_ids); + Ok(()) }