From 5ce0ece69114cb9a2b133e433215dbee4575c56f Mon Sep 17 00:00:00 2001 From: kieran Date: Thu, 20 Feb 2025 09:44:57 +0000 Subject: [PATCH] wip --- apk-parser/src/manifest.rs | 28 +++++++++++++++++++++++++++- apk-parser/src/signing_block.rs | 18 +++++++++++++++++- src/repo/mod.rs | 10 ++++++++++ 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/apk-parser/src/manifest.rs b/apk-parser/src/manifest.rs index ff54156..59a201c 100644 --- a/apk-parser/src/manifest.rs +++ b/apk-parser/src/manifest.rs @@ -1,10 +1,36 @@ use anyhow::{bail, Result}; use apk::res::Chunk; use apk::AndroidManifest; -use log::debug; +use log::{debug, trace}; use std::collections::HashMap; +use std::fmt::Write; use std::io::Cursor; +/// Converts [Chunk::Xml] to actual XML string +pub fn xml_chunk_to_xml(chunk: &Chunk) -> Result { + let nodes = if let Chunk::Xml(nodes) = chunk { + nodes + } else { + bail!("Not an XML chunk") + }; + + let mut buf = String::with_capacity(4096); + for node in nodes { + match node { + Chunk::Xml(x) => buf.write_str(&xml_chunk_to_xml(&Chunk::Xml(x.clone()))?)?, + Chunk::XmlStartNamespace(_, _) => {} + Chunk::XmlEndNamespace(_, _) => {} + Chunk::XmlStartElement(_, _, _) => {} + Chunk::XmlEndElement(_, _) => {} + Chunk::XmlResourceMap(_) => {} + Chunk::TablePackage(_, _) => {} + Chunk::TableType(_, _, _) => {} + Chunk::TableTypeSpec(_, _) => {} + _ => trace!("Skipping chunk: {:?}", node), + } + } + Ok(buf) +} /// Parse android manifest from AndroidManifest.xml file data pub fn parse_android_manifest(data: &[u8]) -> Result { let chunks = if let Chunk::Xml(chunks) = Chunk::parse(&mut Cursor::new(data))? { diff --git a/apk-parser/src/signing_block.rs b/apk-parser/src/signing_block.rs index 88b54ca..fb2184d 100644 --- a/apk-parser/src/signing_block.rs +++ b/apk-parser/src/signing_block.rs @@ -30,6 +30,7 @@ impl ApkSigningBlock { pub fn get_signatures(&self) -> Result> { const V2_SIG_BLOCK_ID: u32 = 0x7109871a; const V3_SIG_BLOCK_ID: u32 = 0xf05368c0; + const NOSTR_SIG_BLOCK_ID: u32 = 0x4e535452; // "NSTR" let mut sigs = vec![]; for (k, v) in &self.data { @@ -158,6 +159,12 @@ pub enum ApkSignatureBlock { min_sdk: u32, max_sdk: u32, }, + + /// Nostr Schnorr sig + Nostr { + signature: Vec, + public_key: Vec, + }, } impl Display for ApkSignatureBlock { @@ -190,6 +197,15 @@ impl Display for ApkSignatureBlock { } Ok(()) } + ApkSignatureBlock::Nostr { + public_key, + signature, + } => write!( + f, + "Nostr: pubkey={}, sig={}", + hex::encode(&public_key), + hex::encode(&signature) + ), } } } @@ -323,7 +339,7 @@ fn get_lv_u32(slice: &[u8]) -> Result<&[u8]> { } #[inline] -fn take_lv_u32<'a>(slice: &mut &'a[u8]) -> Result<&'a [u8]> { +fn take_lv_u32<'a>(slice: &mut &'a [u8]) -> Result<&'a [u8]> { let len = u32::from_le_bytes(slice[..4].try_into()?); ensure!( len <= (slice.len() - 4) as u32, diff --git a/src/repo/mod.rs b/src/repo/mod.rs index 0c647b3..acd3e42 100644 --- a/src/repo/mod.rs +++ b/src/repo/mod.rs @@ -94,6 +94,16 @@ impl TryInto for RepoArtifact { ])?); } } + ApkSignatureBlock::Nostr { + signature, + public_key, + } => { + b = b.tag(Tag::parse([ + "apk_nostr_signature", + &hex::encode(public_key), + &hex::encode(signature), + ])?); + } } } if let Some(vn) = manifest.version_name {