Skip to content

Commit

Permalink
Merge pull request #796 from ReFirmLabs/gpg_decompress
Browse files Browse the repository at this point in the history
Fixed signed GPG decompression bug
  • Loading branch information
devttys0 authored Dec 6, 2024
2 parents 671457f + fc55626 commit 9e7887b
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 5 deletions.
1 change: 1 addition & 0 deletions src/extractors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ pub mod dtb;
pub mod dumpifs;
pub mod dxbc;
pub mod gif;
pub mod gpg;
pub mod gzip;
pub mod inflate;
pub mod jboot;
Expand Down
57 changes: 57 additions & 0 deletions src/extractors/gpg.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use crate::extractors::common::{ExtractionResult, Extractor, ExtractorType};
use crate::extractors::inflate;

/// Defines the internal extractor function for decompressing signed GPG data
///
/// ```
/// use std::io::ErrorKind;
/// use std::process::Command;
/// use binwalk::extractors::common::ExtractorType;
/// use binwalk::extractors::gpg::gpg_extractor;
///
/// match gpg_extractor().utility {
/// ExtractorType::None => panic!("Invalid extractor type of None"),
/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func),
/// ExtractorType::External(cmd) => {
/// if let Err(e) = Command::new(&cmd).output() {
/// if e.kind() == ErrorKind::NotFound {
/// panic!("External extractor '{}' not found", cmd);
/// } else {
/// panic!("Failed to execute external extractor '{}': {}", cmd, e);
/// }
/// }
/// }
/// }
/// ```
pub fn gpg_extractor() -> Extractor {
Extractor {
utility: ExtractorType::Internal(gpg_decompress),
..Default::default()
}
}

/// Internal extractor for decompressing signed GPG data
pub fn gpg_decompress(
file_data: &[u8],
offset: usize,
output_directory: Option<&String>,
) -> ExtractionResult {
// Size of the GPG header
const HEADER_SIZE: usize = 2;

let mut exresult = ExtractionResult {
..Default::default()
};

// Do the decompression, ignoring the GPG header
let inflate_result =
inflate::inflate_decompressor(file_data, offset + HEADER_SIZE, output_directory);

// Check that the data decompressed OK
if inflate_result.success {
exresult.success = true;
exresult.size = Some(HEADER_SIZE + inflate_result.size);
}

exresult
}
2 changes: 1 addition & 1 deletion src/magic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ pub fn patterns() -> Vec<signatures::common::Signature> {
magic: signatures::gpg::gpg_signed_magic(),
parser: signatures::gpg::gpg_signed_parser,
description: signatures::gpg::GPG_SIGNED_DESCRIPTION.to_string(),
extractor: Some(extractors::zlib::zlib_extractor()),
extractor: Some(extractors::gpg::gpg_extractor()),
},
// pem certificates
signatures::common::Signature {
Expand Down
7 changes: 3 additions & 4 deletions src/signatures/gpg.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::extractors::zlib::{zlib_decompress, CHECKSUM_SIZE};
use crate::extractors::gpg::gpg_decompress;
use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_HIGH};

/// Human readable description
Expand Down Expand Up @@ -26,13 +26,12 @@ pub fn gpg_signed_parser(
* GPG signed files are just zlib compressed files with the zlib magic bytes replaced with the GPG magic bytes.
* Decompress the signed file; no output directory specified, dry run only.
*/
let decompression_dry_run = zlib_decompress(file_data, offset, None);
let decompression_dry_run = gpg_decompress(file_data, offset, None);

// If the decompression dry run was a success, this signature is almost certianly valid
if decompression_dry_run.success {
if let Some(total_size) = decompression_dry_run.size {
// GPG doesn't include the trailing checksum
result.size = total_size - CHECKSUM_SIZE;
result.size = total_size;
result.description =
format!("{}, total size: {} bytes", result.description, result.size);
return Ok(result);
Expand Down

0 comments on commit 9e7887b

Please sign in to comment.