nardl: fix hashing
This commit is contained in:
parent
25a01aad83
commit
afe1f86e1c
15
rust/nardl/Cargo.lock
generated
15
rust/nardl/Cargo.lock
generated
|
@ -367,6 +367,12 @@ dependencies = [
|
||||||
"syn 1.0.109",
|
"syn 1.0.109",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "data-encoding"
|
||||||
|
version = "2.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "der"
|
name = "der"
|
||||||
version = "0.7.9"
|
version = "0.7.9"
|
||||||
|
@ -879,12 +885,13 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-compression",
|
"async-compression",
|
||||||
"async-tempfile",
|
"async-tempfile",
|
||||||
"base64",
|
|
||||||
"color-eyre",
|
"color-eyre",
|
||||||
|
"data-encoding",
|
||||||
"ed25519-dalek",
|
"ed25519-dalek",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"log",
|
"log",
|
||||||
"narinfo",
|
"narinfo",
|
||||||
|
"nix-base32",
|
||||||
"nix-nar",
|
"nix-nar",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"sha2",
|
"sha2",
|
||||||
|
@ -902,6 +909,12 @@ dependencies = [
|
||||||
"derive_builder",
|
"derive_builder",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nix-base32"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8548db8274cf1b2b4c093557783f99e9ad64ffdaaa29a6c1af0abc9895c15612"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nix-nar"
|
name = "nix-nar"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
|
|
|
@ -6,12 +6,13 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-compression = { version = "0.4.11", features = [ "tokio", "xz", "bzip2", "zstd", "brotli" ] }
|
async-compression = { version = "0.4.11", features = [ "tokio", "xz", "bzip2", "zstd", "brotli" ] }
|
||||||
async-tempfile = "0.6.0"
|
async-tempfile = "0.6.0"
|
||||||
base64 = "0.22.1"
|
|
||||||
color-eyre = "0.6"
|
color-eyre = "0.6"
|
||||||
|
data-encoding = "2.6.0"
|
||||||
ed25519-dalek = "2.1.1"
|
ed25519-dalek = "2.1.1"
|
||||||
env_logger = "0.11"
|
env_logger = "0.11"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
narinfo = "1.0.1"
|
narinfo = "1.0.1"
|
||||||
|
nix-base32 = "0.1.1"
|
||||||
nix-nar = "0.3.0"
|
nix-nar = "0.3.0"
|
||||||
reqwest = { version = "0.12.5", features = ["http2", "stream", "rustls-tls", "zstd"], default-features = false }
|
reqwest = { version = "0.12.5", features = ["http2", "stream", "rustls-tls", "zstd"], default-features = false }
|
||||||
sha2 = "0.10.8"
|
sha2 = "0.10.8"
|
||||||
|
|
|
@ -1,15 +1,10 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
use base64::{
|
|
||||||
engine::general_purpose::{
|
|
||||||
STANDARD as BASE64_STANDARD, STANDARD_NO_PAD as BASE64_STANDARD_NO_PAD,
|
|
||||||
},
|
|
||||||
Engine,
|
|
||||||
};
|
|
||||||
use color_eyre::eyre::{self, Context, OptionExt};
|
use color_eyre::eyre::{self, Context, OptionExt};
|
||||||
use ed25519_dalek::{Signature, VerifyingKey};
|
use ed25519_dalek::{Signature, VerifyingKey};
|
||||||
use sha2::Digest;
|
use sha2::Digest;
|
||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
|
os::unix::fs::MetadataExt,
|
||||||
path::Path,
|
path::Path,
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
};
|
};
|
||||||
|
@ -58,8 +53,8 @@ async fn main() -> eyre::Result<()> {
|
||||||
.iter()
|
.iter()
|
||||||
.map(|key| -> eyre::Result<_> {
|
.map(|key| -> eyre::Result<_> {
|
||||||
let (name, public_str) = key.split_once(":").ok_or_eyre("Key has no name")?;
|
let (name, public_str) = key.split_once(":").ok_or_eyre("Key has no name")?;
|
||||||
let public_bytes = BASE64_STANDARD_NO_PAD
|
let public_bytes = data_encoding::BASE64_NOPAD
|
||||||
.decode(public_str.trim_end_matches("="))
|
.decode(public_str.trim_end_matches("=").as_bytes())
|
||||||
.wrap_err("Invalid base64 in key")?;
|
.wrap_err("Invalid base64 in key")?;
|
||||||
Ok((
|
Ok((
|
||||||
name,
|
name,
|
||||||
|
@ -166,12 +161,30 @@ async fn main() -> eyre::Result<()> {
|
||||||
.write(true)
|
.write(true)
|
||||||
.truncate(true)
|
.truncate(true)
|
||||||
.create(true)
|
.create(true)
|
||||||
.open(temp_dir.as_ref().join("temp.nar"))
|
.open(temp_dir.join("temp.nar"))
|
||||||
.await?;
|
.await?;
|
||||||
tokio::io::copy(&mut decompressed_stream, &mut out_file).await?;
|
tokio::io::copy(&mut decompressed_stream, &mut out_file).await?;
|
||||||
|
|
||||||
out_file.seek(std::io::SeekFrom::Start(0)).await?;
|
out_file.seek(std::io::SeekFrom::Start(0)).await?;
|
||||||
|
|
||||||
|
// Verify nar
|
||||||
|
let found_size = out_file.metadata().await?.size();
|
||||||
|
if found_size != narinfo_parsed.nar_size as u64 {
|
||||||
|
eyre::bail!("Wrong nar size for {}", output);
|
||||||
|
}
|
||||||
|
|
||||||
|
let (hash_algorithm, hash_expected) = narinfo_parsed
|
||||||
|
.nar_hash
|
||||||
|
.as_ref()
|
||||||
|
.split_once(":")
|
||||||
|
.ok_or_eyre("Invalid hash in nar")?;
|
||||||
|
|
||||||
|
if hash_algorithm != "sha256" {
|
||||||
|
eyre::bail!("who is using hashes other than sha256????");
|
||||||
|
}
|
||||||
|
|
||||||
|
log::trace!("expected hash: {}", hash_expected);
|
||||||
|
|
||||||
let mut buf = [0u8; 1024];
|
let mut buf = [0u8; 1024];
|
||||||
let mut hasher = sha2::Sha256::new();
|
let mut hasher = sha2::Sha256::new();
|
||||||
loop {
|
loop {
|
||||||
|
@ -182,8 +195,11 @@ async fn main() -> eyre::Result<()> {
|
||||||
hasher.update(&buf[0..num_read]);
|
hasher.update(&buf[0..num_read]);
|
||||||
}
|
}
|
||||||
|
|
||||||
let found_hash = hasher.finalize();
|
let hash_found = hasher.finalize();
|
||||||
log::trace!("Got hash {:?}", found_hash);
|
|
||||||
|
if &nix_base32::to_nix_base32(hash_found.as_ref()) != hash_expected {
|
||||||
|
eyre::bail!("Incorrect hash when downloading {}", output)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -226,7 +242,7 @@ fn verify_signature(
|
||||||
let Some(key) = trusted_keys.get(sig_info.key_name.as_ref()) else {
|
let Some(key) = trusted_keys.get(sig_info.key_name.as_ref()) else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
let signature_bytes = BASE64_STANDARD.decode(sig_info.sig.as_ref())?;
|
let signature_bytes = data_encoding::BASE64.decode(sig_info.sig.as_ref().as_bytes())?;
|
||||||
|
|
||||||
let signature = Signature::from_bytes(
|
let signature = Signature::from_bytes(
|
||||||
signature_bytes
|
signature_bytes
|
||||||
|
|
Loading…
Reference in a new issue