Add new command sq download.

- Add a new command, `sq download`, which downloads a file and a
    signature file, and then authenticates the file.

  - Fixes #84.
This commit is contained in:
Neal H. Walfield 2024-11-09 13:28:17 +01:00
parent 6697846b78
commit 7ecc843dee
No known key found for this signature in database
GPG Key ID: 6863C9AD5B4D22D3
11 changed files with 1154 additions and 1 deletions

16
Cargo.lock generated
View File

@ -3088,10 +3088,12 @@ dependencies = [
"system-configuration",
"tokio",
"tokio-native-tls",
"tokio-util",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"wasm-streams",
"web-sys",
"winreg",
]
@ -3615,6 +3617,7 @@ dependencies = [
"dirs",
"fehler",
"fs_extra",
"futures-util",
"humantime",
"indicatif",
"libc",
@ -4660,6 +4663,19 @@ version = "0.2.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d"
[[package]]
name = "wasm-streams"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65"
dependencies = [
"futures-util",
"js-sys",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
]
[[package]]
name = "web-sys"
version = "0.3.72"

View File

@ -40,10 +40,11 @@ sequoia-policy-config = ">= 0.6, <0.8"
anyhow = "1.0.18"
chrono = "0.4.10"
clap = { version = "4", features = ["derive", "env", "string", "wrap_help"] }
futures-util = "0.3"
humantime = "2"
indicatif = "0.17"
once_cell = "1.17"
reqwest = { version = ">=0.11.27, <0.13", features = ["hickory-dns"] }
reqwest = { version = ">=0.11.27, <0.13", features = ["hickory-dns", "stream"] }
sequoia-cert-store = "0.6.0"
sequoia-keystore = { version = ">=0.5, <0.7" }
sequoia-wot = { version = "0.13", default-features = false }

3
NEWS
View File

@ -3,6 +3,9 @@
#+STARTUP: content hidestars
* Changes in 0.40.0
** New functionality
- New subcommand `sq download`, which downloads a file and a
signature file, and then authenticates the file.
** Notable changes
- `sq toolbox keyring merge` now supports merging bare revocation
certificates.

96
src/cli/download.rs Normal file
View File

@ -0,0 +1,96 @@
//! Command-line parser for `sq download`.
use clap::Parser;
use crate::cli::examples;
use examples::Action;
use examples::Actions;
use examples::Example;
use examples::Setup;
use super::types::ClapData;
use super::types::cert_designator::*;
use crate::cli::types::FileOrStdout;
const EXAMPLES: Actions = Actions {
actions: &[
Action::Setup(Setup {
command: &[
"sq", "cert", "import", "debian/debian-cd-signing-key.pgp",
],
}),
Action::Example(Example {
comment: "\
Verify the Debian 12 checksum file.",
command: &[
"sq", "download",
"--url=file://debian/SHA512SUMS",
"--signature=file://debian/SHA512SUMS.sign",
"--signer=DF9B9C49EAA9298432589D76DA87E80D6294BE9B",
],
}),
]
};
test_examples!(sq_download, EXAMPLES);
#[derive(Parser, Debug)]
#[clap(
name = "download",
about = "Download and authenticate the data",
long_about =
"Download and authenticates the data.
This command downloads the data from the specified URL, checks the
signature, and then authenticates the signer. If the signer cannot be
authenticated, the data is deleted, if possible.
",
after_help = EXAMPLES,
)]
pub struct Command {
#[clap(
long = "url",
value_name = "URL",
help = "The data to download",
)]
pub url: String,
#[clap(
long = "signature",
value_name = "URL",
help = "URL of the signature",
long_help = "\
URL of the signature.
Use this when the signature is detached from the data.
If no signature is specified, then the signature is assumed to be \
inline.
",
)]
pub signature: Option<String>,
#[command(flatten)]
pub signers: CertDesignators<CertFileArgs,
SignerPrefix,
OptionalValue,
ToVerifyDoc>,
#[clap(
long = "signatures",
value_name = "N",
default_value_t = 1,
help = "Set the threshold of valid signatures to N",
long_help = "Set the threshold of valid signatures to N. \
If this threshold is not reached, the message \
will not be considered verified."
)]
pub signatures: usize,
#[clap(
help = FileOrStdout::HELP_OPTIONAL,
long,
value_name = FileOrStdout::VALUE_NAME,
default_value = "-",
)]
pub output: FileOrStdout,
}

View File

@ -94,6 +94,7 @@ pub mod examples;
pub mod cert;
pub mod decrypt;
pub mod download;
pub mod encrypt;
pub mod inspect;
pub mod key;
@ -556,6 +557,7 @@ pub enum SqSubcommands {
Sign(sign::Command),
Verify(verify::Command),
Download(download::Command),
Inspect(inspect::Command),

View File

@ -27,6 +27,7 @@ use crate::cli::{SqCommand, SqSubcommands};
pub mod autocrypt;
pub mod cert;
pub mod decrypt;
pub mod download;
pub mod encrypt;
pub mod sign;
pub mod inspect;
@ -49,6 +50,8 @@ pub fn dispatch(sq: Sq, command: SqCommand) -> Result<()>
sign::dispatch(sq, command),
SqSubcommands::Verify(command) =>
verify::dispatch(sq, command),
SqSubcommands::Download(command) =>
download::dispatch(sq, command),
SqSubcommands::Inspect(command) =>
inspect::dispatch(sq, command),

523
src/commands/download.rs Normal file
View File

@ -0,0 +1,523 @@
use std::collections::HashSet;
use std::fs::File;
use std::io::IsTerminal;
use std::io::Seek;
use std::io::Write;
use std::path::Path;
use std::path::PathBuf;
use anyhow::Context;
use futures_util::StreamExt;
use tokio::sync::oneshot;
use tokio::task::JoinSet;
use tokio::task::LocalSet;
use indicatif::ProgressBar;
use indicatif::ProgressStyle;
use indicatif::WeakProgressBar;
use sequoia_net as net;
use net::reqwest;
use tempfile::NamedTempFile;
use openpgp::Packet;
use openpgp::parse::PacketParser;
use openpgp::parse::PacketParserResult;
use openpgp::parse::Parse;
use openpgp::types::KeyFlags;
use sequoia_openpgp as openpgp;
use crate::Result;
use crate::Sq;
use crate::cli::download;
use crate::cli::types::TrustAmount;
use crate::commands::network::CONNECT_TIMEOUT;
use crate::commands::network::USER_AGENT;
use crate::commands::pki::authenticate;
use crate::commands::verify::verify;
// So we can deal with either named temp files or files.
enum SomeFile {
Temp(NamedTempFile),
File((File, PathBuf)),
}
impl SomeFile {
fn as_ref(&self) -> &File {
match self {
SomeFile::Temp(t) => t.as_file(),
SomeFile::File((f, _)) => &f,
}
}
fn as_mut(&mut self) -> &mut File {
match self {
SomeFile::Temp(t) => t.as_file_mut(),
SomeFile::File((ref mut f, _)) => f,
}
}
fn path(&self) -> &Path {
match self {
SomeFile::Temp(t) => t.path(),
SomeFile::File((_, p)) => p.as_path(),
}
}
}
// Spawn a task to download the `$url` to `$output` using `$http_client`.
//
// This is a macro rather than a function due to lifetimes.
//
// `$rt` is uninterpreted, and is returned as is.
//
// `$limit` causes the download to abort after that many bytes.
//
// `$file_name` is `$output`'s file name. Its purely used for
// decorative purposes.
//
// `$pb` is a weak reference to a progress bar.
macro_rules! get {
($http_client:expr, $rt:expr, $url:expr, $limit:expr, $file_name:expr,
$output: expr, $pb:expr) => {{
let url: String = $url.into();
let http_client: reqwest::Client = $http_client.clone();
let limit: Option<usize> = $limit;
let file_name: String = $file_name.into();
let mut output = $output;
let pb: WeakProgressBar = $pb;
async move {
if let Some(local_file_name) = url.strip_prefix("file://") {
let local_file_name = PathBuf::from(local_file_name);
match File::open(&local_file_name) {
Ok(file) => {
Ok(($rt, SomeFile::File((file, local_file_name))))
}
Err(err) => Err(err.into()),
}
} else {
let mut bytes = 0;
let response = http_client.get(&url).send()
.await
.and_then(|r| r.error_for_status())
.with_context(|| format!("Fetching {}", url))?;
let len = response.content_length();
if let Some(pb) = pb.upgrade() {
if let Some(len) = len {
pb.inc_length(len);
} else {
// We don't know how much we need to download. Switch
// to a spinner.
if ! pb.is_hidden() {
pb.set_style(ProgressStyle::default_spinner());
}
}
}
let mut stream = response.bytes_stream();
while let Some(item) = stream.next().await {
let item = item.with_context(|| {
format!("Fetching {}", url)
})?;
output.write_all(item.as_ref()).with_context(|| {
format!("Writing to {}", file_name)
})?;
bytes += item.len();
pb.upgrade().map(|pb| pb.inc(item.len() as u64));
if let Some(limit) = limit {
if bytes > limit {
return Err(anyhow::anyhow!(
"{} exceeded download limit size ({} bytes)",
url, limit));
}
}
}
output.flush()?;
Ok::<_, anyhow::Error>(($rt, SomeFile::Temp(output)))
}
}
}}
}
pub fn dispatch(sq: Sq, c: download::Command)
-> Result<()>
{
let url = c.url;
let signature = c.signature;
let signatures = c.signatures;
let signers =
sq.resolve_certs_or_fail(&c.signers, sequoia_wot::FULLY_TRUSTED)?;
let output = c.output;
if ! sq.quiet && ! sq.batch {
let output_is_terminal
= output.path().is_none() && std::io::stdout().is_terminal();
if output_is_terminal {
wprintln!("Warning: will write the data to stdout, \
which appears to be a terminal. Use --output \
to write to a file instead.");
}
}
// Create the progress bar.
let progress_bar = if sq.verbose || sq.batch {
ProgressBar::hidden()
} else {
ProgressBar::new(0)
.with_style(ProgressStyle::with_template(
"{wide_bar} {decimal_bytes}/{decimal_total_bytes} ({eta} left)")
.expect("valid format"))
};
// A temporary file for the main data. If output is not stdout,
// we try and put it in the same directory as where it should end
// up.
let data_file = {
let mut data_file = tempfile::Builder::new();
data_file.prefix("sq-download");
let partial;
if let Some(path) = output.path() {
if let Some(file_name) = path.file_name() {
partial = format!(
"{}-partial",
String::from_utf8_lossy(file_name.as_encoded_bytes()));
data_file.prefix(&partial);
}
if let Some(directory) = path.parent() {
data_file.tempfile_in(directory)
} else {
let cwd = std::env::current_dir()?;
data_file.tempfile_in(cwd)
}
} else {
data_file.tempfile()
}.context("Creating temporary file")?
};
let http_client = reqwest::Client::builder()
.user_agent(USER_AGENT)
.connect_timeout(CONNECT_TIMEOUT)
.build()?;
let requests = LocalSet::new();
let mut task_set = JoinSet::new();
// Since JoinSet::join_next has to return the same type, we use
// the following to discriminate the tasks.
enum Task {
Url,
Signature,
}
// Schedule the download of the file.
task_set.spawn_local_on(
get!(http_client.clone(), Task::Url, url, None,
data_file.path().display().to_string(), data_file,
progress_bar.downgrade()),
&requests);
// We need to do some acrobatics!!! After we download the
// signature file, we want to make sure that we can authenticate a
// signer. This means we need to use sq. But, we can't move sq
// to an async task, because sq has a lifetime that is shorter
// than 'static. Instead, we set up a scoped thread, which can
// use variables with lifetimes less than static, and then do the
// processing there.
let (mut data_file, signature_file) = std::thread::scope(|scope| {
// Schedule the download of the signature.
if let Some(ref url) = signature {
let sig_file = tempfile::NamedTempFile::new()?;
let getter = get!(
http_client.clone(), Task::Signature, url, None,
sig_file.path().display().to_string(), sig_file,
progress_bar.downgrade());
let (request_tx, request_rx) = oneshot::channel();
let (response_tx, response_rx) = oneshot::channel();
task_set.spawn_local_on(
async move {
let (task, sig_file) = getter.await?;
// The processing is handled by the thread below.
if request_tx.send(sig_file).is_err() {
return Err(anyhow::anyhow!(
"internal error: protocol violation"));
}
let sig_file = response_rx.await??;
Ok((task, sig_file))
},
&requests);
let progress_bar_ = progress_bar.downgrade();
let sq_ = &sq;
let signers_ = &signers;
scope.spawn(move || {
let result = (|| {
let progress_bar = progress_bar_;
let sq = sq_;
let signers = signers_;
let mut sig_file = if let Ok(sig_file)
= request_rx.blocking_recv()
{
sig_file
} else {
return Err(anyhow::anyhow!(
"internal error: protocol violation"));
};
// Read the signature data and make sure we can
// authenticate at least one issuer's certificate.
sig_file.as_mut().rewind()?;
let mut ppr = PacketParser::from_reader(sig_file.as_ref())
.context("Parsing detached signature: either the signature \
file does not actually contain an OpenPGP \
signature, or it is corrupted.")?;
let mut signatures = Vec::new();
while let PacketParserResult::Some(pp) = ppr {
let (packet, next_ppr) = pp.next()?;
ppr = next_ppr;
match packet {
Packet::Signature(sig) => {
signatures.push(sig);
}
Packet::Marker(_) => (),
_ => {
return Err(anyhow::anyhow!(
"Signature file does not contain a detached \
signature. It includes a {}.",
packet.tag()));
}
}
}
if signatures.is_empty() {
return Err(anyhow::anyhow!(
"Signature file does not contain any signatures."));
}
let mut seen = HashSet::new();
let mut authenticated = false;
for sig in signatures.iter() {
for issuer in sig.get_issuers() {
if let Some(cert)
= signers.iter().find(|c| c.key_handle().aliases(&issuer))
{
if ! seen.insert(cert.fingerprint()) {
// Already saw that certificate.
continue;
}
authenticated = true;
if let Some(pb) = progress_bar.upgrade() {
pb.suspend(|| {
eprintln!("Alleged signer {} is good listed.",
cert.fingerprint());
})
}
} else if let Ok(cert)
= sq.lookup_one(issuer,
Some(KeyFlags::signing()),
false)
{
if ! seen.insert(cert.fingerprint()) {
// Already saw that certificate.
continue;
}
let mut auth = || {
eprintln!("Alleged signer: {}, {}",
cert.fingerprint(),
sq.best_userid(&cert, true));
let good = authenticate(
&sq,
false, // precompute
None, // list pattern
false, // email
false, // gossip
false, // certification network
Some(TrustAmount::Full), // trust amount
None, // user ID
Some(&cert.key_handle()),
true, // show paths
).is_ok();
if good {
wprintln!("Authenticated possible \
signer: {}, {}",
cert.fingerprint(),
sq.best_userid(&cert, true));
} else {
wprintln!("Couldn't authenticate the \
alleged signer: {}, {}",
cert.fingerprint(),
sq.best_userid(&cert, true));
}
if good {
authenticated = true;
}
};
if let Some(pb) = progress_bar.upgrade() {
pb.suspend(auth);
} else {
auth();
}
}
}
}
if ! authenticated {
if let Some(pb) = progress_bar.upgrade() {
pb.finish_and_clear();
}
if seen.is_empty() {
eprintln!("Don't have certificates for any of the \
alleged signers:");
} else {
eprintln!("Couldn't authenticated any of the alleged \
signers:");
}
eprintln!();
for sig in signatures.iter() {
for issuer in sig.get_issuers() {
eprintln!(" - {}", issuer);
}
}
return Err(anyhow::anyhow!("\
Couldn't authenticate any of the alleged signers"));
}
drop(ppr);
Ok(sig_file)
})();
if let Err(result) = response_tx.send(result) {
// (send returns result on failure.) We failed to
// return the result. Don't make things worse by
// swallowing any error.
if let Err(err) = result.as_ref() {
crate::print_error_chain(&err);
}
Err(anyhow::anyhow!("Internal error: failed to return \
result to caller"))
} else {
Ok(())
}
});
}
// And GO!!!
let rt = tokio::runtime::Runtime::new()?;
let (data_file, signature_file) = requests.block_on(&rt, async move {
let mut data_file = None;
let mut signature_file = None;
while let Some(result) = task_set.join_next().await {
match result {
Ok(Ok((Task::Signature, file))) => signature_file = Some(file),
Ok(Ok((Task::Url, file))) => data_file = Some(file),
Ok(Err(err)) => {
if data_file.is_none() {
eprintln!();
eprintln!("Aborting download.");
}
return Err(err);
}
Err(err) => {
return Err(err).context("While downloading data");
}
}
}
let data_file = if let Some(data_file) = data_file {
data_file
} else {
return Err(anyhow::anyhow!(
"Internal error while downloading data file"));
};
if signature.is_some() && signature_file.is_none() {
return Err(anyhow::anyhow!(
"Internal error while downloading signature file"));
}
Ok::<_, anyhow::Error>((data_file, signature_file))
})?;
Ok::<_, anyhow::Error>((data_file, signature_file))
})?;
drop(progress_bar);
wprintln!();
wprintln!("Finished downloading data. Authenticating data.");
wprintln!();
data_file.as_mut().rewind()?;
let mut output_file_;
let mut stdout_;
let mut output_file: &mut dyn Write = if let Some(file) = output.path() {
output_file_ = if sq.overwrite {
File::create(file)
} else {
File::options().write(true).create_new(true).open(file)
}.with_context(|| format!("Opening {}", file.display()))?;
&mut output_file_
} else {
stdout_ = std::io::stdout();
&mut stdout_
};
let result = verify(
sq,
data_file.as_mut(),
signature_file.as_ref().map(|f| f.path().to_path_buf()),
&mut output_file,
signatures,
signers);
if let Err(err) = result {
if let Some(path) = output.path() {
if let Err(err) = std::fs::remove_file(path) {
wprintln!("Verification failed, failed to remove \
unverified output saved to {}: {}",
path.display(), err);
}
}
return Err(err);
}
if signature_file.is_some() {
// Verify doesn't copy the data when checking detached
// signatures. Do it now.
data_file.as_mut().rewind()?;
std::io::copy(&mut data_file.as_ref(), output_file)?;
}
result
}

View File

@ -84,3 +84,9 @@ By using static data, we can use known fingerprints in the examples.
- ciphertext.pgp: A document encrypted for Juliet, and signed by Romeo.
- `echo 'Ti amo!' | sq encrypt --for-file juliet.pgp --signer-file romeo-secret.pgp > ciphertext.pgp`
- debian/: The checksum file, the signature file, and the signing key
for the debian 12.7.0 release.
- https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/SHA512SUMS
- https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/SHA512SUMS.sign

View File

@ -0,0 +1,3 @@
e0bd9ba03084a6fd42413b425a2d20e3731678a31fe5fb2cc84f79332129afca2ad4ec897b4224d6a833afaf28a5d938b0fe5d680983182944162c6825b135ce debian-12.7.0-amd64-netinst.iso
915ab697472fd9a25a6b7b5d4988ee659fed61cd6dc6cd990435971af5894fca82426f213913fd95cce04de8d10e0ee709023b677d02d5c48062208ff5ab3112 debian-edu-12.7.0-amd64-netinst.iso
d9480c2d765f3b1ebe8e7d06b1cf6ecf30b95146d5c2036f20904957db6139a440f9f8e7f4f901da6a02f810f2b3ab660aea56d99778c647c62386a2082c9407 debian-mac-12.7.0-amd64-netinst.iso

View File

@ -0,0 +1,16 @@
-----BEGIN PGP SIGNATURE-----
iQIzBAABCAAdFiEE35ucSeqpKYQyWJ122ofoDWKUvpsFAmbTkqcACgkQ2ofoDWKU
vpsr5hAA1HwsGfbiuSxCqBs3PbpRUlozIWH7Z9Xdk0LNVWGI+op9kvKdOjRQmFpp
UwJNav5TS7boCo971ygiK/iWWUWWOUXKe4sRJPj/HpBI1x6uO2klXor9CvjsQs41
n4ldaa8mEEHmGTRxIRlgvR0M8BPKGjBkbA+4obKgVwoKxMTN9bxgvTnisCfsJKuO
+Rej27jRuUcinrnoEuNHwKIVLpitZtBT9Zxk2MNp6Y3FFWZrr2dO8kX1QzOCVLcN
XedDAUxVvYrZgVX6knV6BKV39TMcZslvATr9z//3mEYobIzblTsMhPMwkvCl2ns6
CiBD6HCSXGuwgFbsSBrXDTCPp9+irZ6PFA5qy4WcZRTyp6+Oqw2aMzK+jmh2uTvv
7Fh91wzvIg8FZ7b3vf9Iqb8K2qT+avwD5TrLX2c6jByAK8gA6uR52qM09EtJlrZV
RUoOs3QRze3Cn6OJi0ODuT311uva3U9GaD9cSBGf8TNu9nevil6qodVu23yzc9sT
UfJ0O6ONvLdldE3MTMoS9YzcgVbt8mgvTQfCD3bw+rK8M6+KDvbg6WrtuEqHdPuV
4y33Pw6AS7C20wISsFAmUWSFdCk7KrE+y3rD992bZ/Lyiip8vkjESFRdHXjT+SKc
SxpKwrlnnDrhF2b2VHkyIOsPGKNhwg6OLkwsnts6Wm1rc4Y6ULg=
=B0gn
-----END PGP SIGNATURE-----

View File

@ -0,0 +1,484 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
drYwF6VVRcfb9YJuKZkLVrTiV8ee22eEF7OO0A==
=bsKe
-----END PGP PUBLIC KEY BLOCK-----