Skip to content

Commit

Permalink
make sure to attempt signature verification with subkeys as well as t…
Browse files Browse the repository at this point in the history
…he primary pubkey
  • Loading branch information
cyr committed Oct 22, 2024
1 parent d3a7121 commit 403eca3
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 29 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "aptmirs"
description = "A simple tool for mirroring apt/deb repositories"
version = "0.11.1"
version = "0.11.2"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
3 changes: 3 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,7 @@ pub enum MirsError {

#[error("this repository does not provide a PGP signature, yet a public key has been provided - no verification can be made")]
PgpNotSupported,

#[error("could not verify PGP signature with provided public key")]
PgpNotVerified,
}
4 changes: 1 addition & 3 deletions src/mirror.rs
Original file line number Diff line number Diff line change
Expand Up @@ -388,9 +388,7 @@ pub async fn download_release(repository: &Repository, downloader: &mut Download

progress_bar.finish_using_style();

if repository.verify_pgp_requirement() {
repository.verify_release_signature(&files)?;
}
repository.verify_release_signature(&files)?;

let Some(release_file) = get_release_file(&files) else {
return Err(MirsError::NoReleaseFile)
Expand Down
58 changes: 34 additions & 24 deletions src/mirror/repository.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,27 +201,21 @@ impl Repository {
}))
}

pub fn verify_pgp_requirement(&self) -> bool {
self.pgp_pub_key.is_some()
}

pub fn verify_release_signature(&self, files: &[FilePath]) -> Result<()> {
let Some(pgp_pub_key) = &self.pgp_pub_key else {
panic!("implementation error: trying to verify signature without a pgp_pub_key set")
};

if let Some(inrelease_file) = files.iter().find(|v| v.file_name() == "InRelease") {
self.verify_signed_message(pgp_pub_key, inrelease_file)?;
} else {
let Some(release_file) = files.iter().find(|v| v.file_name() == "Release") else {
return Err(MirsError::PgpNotSupported)
};

let Some(release_file_signature) = files.iter().find(|v| v.file_name() == "Release.pgp") else {
return Err(MirsError::PgpNotSupported)
};

self.verify_message_with_standlone_signature(pgp_pub_key, release_file, release_file_signature)?;
if let Some(pgp_pub_key) = &self.pgp_pub_key {
if let Some(inrelease_file) = files.iter().find(|v| v.file_name() == "InRelease") {
self.verify_signed_message(pgp_pub_key, inrelease_file)?;
} else {
let Some(release_file) = files.iter().find(|v| v.file_name() == "Release") else {
return Err(MirsError::PgpNotSupported)
};

let Some(release_file_signature) = files.iter().find(|v| v.file_name() == "Release.pgp") else {
return Err(MirsError::PgpNotSupported)
};

self.verify_message_with_standlone_signature(pgp_pub_key, release_file, release_file_signature)?;
}
}

Ok(())
Expand All @@ -232,9 +226,17 @@ impl Repository {

let (msg, _) = CleartextSignedMessage::from_string(&content)?;

_ = msg.verify(pgp_pub_key)?;
if msg.verify(&pgp_pub_key).is_ok() {
return Ok(())
}

Ok(())
for subkey in &pgp_pub_key.public_subkeys {
if msg.verify(subkey).is_ok() {
return Ok(())
}
}

Err(MirsError::PgpNotVerified)
}

fn verify_message_with_standlone_signature(&self, pgp_pub_key: &SignedPublicKey, release_file: &FilePath, release_file_signature: &FilePath) -> Result<()> {
Expand All @@ -243,9 +245,17 @@ impl Repository {

let (signature, _) = StandaloneSignature::from_reader_single(&sign_handle)?;

signature.verify(pgp_pub_key, content.as_bytes())?;
if signature.verify(&pgp_pub_key, content.as_bytes()).is_ok() {
return Ok(())
}

for subkey in &pgp_pub_key.public_subkeys {
if signature.verify(&subkey, content.as_bytes()).is_ok() {
return Ok(())
}
}

Ok(())
Err(MirsError::PgpNotVerified)
}
}

Expand Down

0 comments on commit 403eca3

Please sign in to comment.