Skip to content

Commit

Permalink
Merge pull request #3 from kpcyrd/lfs
Browse files Browse the repository at this point in the history
Add tests and test data
  • Loading branch information
kpcyrd authored Apr 8, 2024
2 parents c2209b4 + b686959 commit e9bba64
Show file tree
Hide file tree
Showing 17 changed files with 150 additions and 39 deletions.
3 changes: 1 addition & 2 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
tests/data/**/*.xz filter=lfs diff=lfs merge=lfs -text
tests/data/**/*.gz filter=lfs diff=lfs merge=lfs -text
tests/data/** filter=lfs diff=lfs merge=lfs -text
2 changes: 2 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ jobs:
# features: -F vendored
steps:
- uses: actions/checkout@v4
with:
lfs: true

- name: Set up cargo cache
uses: actions/cache@v4
Expand Down
10 changes: 10 additions & 0 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,6 @@ sha2 = "0.10.8"
tar = { version = "0.4.40", default-features = false }
tokio = { version = "1.37.0", features = ["macros", "rt-multi-thread", "fs"] }
yash-syntax = "0.7.0"

[dev-dependencies]
lz4_flex = "0.11.3"
40 changes: 38 additions & 2 deletions src/apt.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::compression;
use crate::errors::*;
use apt_parser::release::ReleaseHash;
use std::str;

#[derive(Debug, Default)]
pub struct Source {
Expand All @@ -9,9 +10,9 @@ pub struct Source {
pub checksums_sha256: Vec<ReleaseHash>,
}

pub fn parse_sources(mut bytes: &[u8]) -> Result<Vec<Source>> {
pub fn parse_sources(bytes: &[u8]) -> Result<Vec<Source>> {
let buf = compression::decompress(bytes).context("Failed to decompress sources index")?;
let sources = String::from_utf8(buf)?;
let sources = str::from_utf8(&buf)?;

let mut out = Vec::new();

Expand Down Expand Up @@ -66,3 +67,38 @@ pub fn parse_sources(mut bytes: &[u8]) -> Result<Vec<Source>> {

Ok(out)
}

pub struct Release {
release: apt_parser::Release,
}

impl Release {
pub fn parse(bytes: &[u8]) -> Result<Self> {
let release = str::from_utf8(bytes)?;
let release = apt_parser::Release::from(release)?;
Ok(Release { release })
}

pub fn find_source_entry_by_sha256(&self, sha256: &str) -> Result<&ReleaseHash> {
let sha256sums = self
.release
.sha256sum
.as_ref()
.context("Release file has no sha256sum section")?;

let sources_entry = sha256sums
.iter()
.filter(|entry| entry.filename.contains("/source/Sources"))
.find(|entry| {
debug!("Found sha256sum entry for sources index: {entry:?}");
entry.hash == sha256
})
.with_context(|| {
anyhow!(
"Failed to find matching source entry in release file with sha256={sha256:?}"
)
})?;

Ok(sources_entry)
}
}
13 changes: 13 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//! WARNING: This API may not be stable
//!
//! If that's fine with you, you may still use this code according to `GPL-3.0-or-later`. 🖤
pub mod apt;
pub mod args;
pub mod buildinfo;
pub mod chksums;
pub mod compression;
pub mod errors;
pub mod pgp;
pub mod pkgbuild;
pub mod plumbing;
15 changes: 3 additions & 12 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,6 @@
mod apt;
mod args;
mod buildinfo;
mod chksums;
mod compression;
mod errors;
mod pgp;
mod pkgbuild;
mod plumbing;

use crate::args::{Args, SubCommand};
use crate::errors::*;
use backseat_signed::args::{Args, SubCommand};
use backseat_signed::errors::*;
use backseat_signed::plumbing;
use clap::Parser;
use env_logger::Env;
use std::io;
Expand Down
2 changes: 1 addition & 1 deletion src/pgp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use sequoia_openpgp::types::SignatureType;
use sequoia_openpgp::Packet;
use sequoia_openpgp::{Cert, Fingerprint};

pub fn pubkey(bytes: &[u8]) -> Result<Vec<SigningKey>> {
pub fn keyring(bytes: &[u8]) -> Result<Vec<SigningKey>> {
let mut keys = Vec::new();

let ppr = PacketParser::from_bytes(bytes)?;
Expand Down
27 changes: 5 additions & 22 deletions src/plumbing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use crate::compression;
use crate::errors::*;
use crate::pgp;
use crate::pkgbuild;
use apt_parser::Release;
use clap::{Parser, Subcommand};
use std::ops::Not;
use std::path::PathBuf;
Expand Down Expand Up @@ -51,7 +50,7 @@ impl ArchlinuxPkgFromSig {
async fn run(&self) -> Result<()> {
info!("Loading keyring from {:?}", self.keyring);
let keyring = fs::read(&self.keyring).await?;
let keyring = pgp::pubkey(&keyring)?;
let keyring = pgp::keyring(&keyring)?;
info!("Loaded {} public keys", keyring.len());

info!("Loading signature from {:?}", self.sig);
Expand Down Expand Up @@ -183,7 +182,7 @@ impl PgpVerify {
async fn run(&self) -> Result<()> {
info!("Loading keyring from {:?}", self.keyring);
let keyring = fs::read(&self.keyring).await?;
let keyring = pgp::pubkey(&keyring)?;
let keyring = pgp::keyring(&keyring)?;
info!("Loaded {} public keys", keyring.len());

info!("Loading signature from {:?}", self.sig);
Expand Down Expand Up @@ -218,7 +217,7 @@ impl DebianSourcesFromRelease {
let keyring = fs::read(&self.keyring)
.await
.with_context(|| anyhow!("Failed to load keyring from {:?}", self.keyring))?;
let keyring = pgp::pubkey(&keyring)?;
let keyring = pgp::keyring(&keyring)?;
info!("Loaded {} public keys", keyring.len());

info!("Loading signature from {:?}", self.sig);
Expand All @@ -241,27 +240,11 @@ impl DebianSourcesFromRelease {
pgp::verify(&keyring, &sig, &release)?;

// Parse release, match with sources
let release = String::from_utf8(release)?;
let release = Release::from(&release)?;
let release = apt::Release::parse(&release)?;

debug!("Checking hash...");
let sha256 = chksums::sha256(&sources);

let sha256sums = release
.sha256sum
.context("Release file has no sha256sum section")?;
let _sources_entry = sha256sums
.into_iter()
.filter(|entry| entry.filename.contains("/source/Sources"))
.find(|entry| {
debug!("Found sha256sum entry for sources index: {entry:?}");
entry.hash == sha256
})
.with_context(|| {
anyhow!(
"Failed to find matching source entry in release file with sha256={sha256:?}"
)
})?;
let _sources_entry = release.find_source_entry_by_sha256(&sha256)?;

info!("Sources index verified successfully");
Ok(())
Expand Down
3 changes: 3 additions & 0 deletions tests/data/debian-archive-bookworm-automatic.asc
Git LFS file not shown
3 changes: 3 additions & 0 deletions tests/data/vim/Release
Git LFS file not shown
3 changes: 3 additions & 0 deletions tests/data/vim/Release.gpg
Git LFS file not shown
3 changes: 3 additions & 0 deletions tests/data/vim/Sources.gz
Git LFS file not shown
3 changes: 3 additions & 0 deletions tests/data/vim/Sources.lz4
Git LFS file not shown
3 changes: 3 additions & 0 deletions tests/data/vim/Sources.xz
Git LFS file not shown
3 changes: 3 additions & 0 deletions tests/data/vim/vim_9.1.0199.orig.tar.xz
Git LFS file not shown
53 changes: 53 additions & 0 deletions tests/integration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use backseat_signed::apt;
use backseat_signed::chksums;
use backseat_signed::pgp;
use std::io::Read;

#[test]
fn parse_lookup_apt_release_xz() {
let release = include_bytes!("data/vim/Release");
let release = apt::Release::parse(release).unwrap();

let sources = include_bytes!("data/vim/Sources.xz");
let sha256 = chksums::sha256(sources);

let _sources_entry = release.find_source_entry_by_sha256(&sha256).unwrap();
}

#[test]
fn parse_lookup_apt_release_gz() {
let release = include_bytes!("data/vim/Release");
let release = apt::Release::parse(release).unwrap();

let sources = include_bytes!("data/vim/Sources.gz");
let sha256 = chksums::sha256(sources);

let _sources_entry = release.find_source_entry_by_sha256(&sha256).unwrap();
}

#[test]
fn parse_lookup_apt_release_plain() {
let release = include_bytes!("data/vim/Release");
let release = apt::Release::parse(release).unwrap();

let sources = include_bytes!("data/vim/Sources.lz4");
let mut lz4 = lz4_flex::frame::FrameDecoder::new(&sources[..]);

let mut sources = Vec::new();
lz4.read_to_end(&mut sources).unwrap();
let sha256 = chksums::sha256(&sources);

let _sources_entry = release.find_source_entry_by_sha256(&sha256).unwrap();
}

#[test]
fn test_pgp_verify_vim() {
let keyring = include_bytes!("data/debian-archive-bookworm-automatic.asc");
let keyring = pgp::keyring(keyring).unwrap();

let sig = include_bytes!("data/vim/Release.gpg");
let sig = pgp::signature(sig).unwrap();

let release = include_bytes!("data/vim/Release");
pgp::verify(&keyring, &sig, release).unwrap();
}

0 comments on commit e9bba64

Please sign in to comment.