diff options
author | Florian Klink <flokli@flokli.de> | 2023-11-27T16·20+0200 |
---|---|---|
committer | flokli <flokli@flokli.de> | 2023-11-28T16·08+0000 |
commit | 4297e33d949d6789a84c95632077897cbecd45de (patch) | |
tree | b79a887916ff8f6271155e2c63fe3f478a3829b3 /tvix/store/src | |
parent | 5fc737b02e5530131d4fbac620d38499be3fce80 (diff) |
feat(tvix/store/pathinfosvc): add signature verification r/7085
Introduce an Option<Vec<narinfo::PubKey>>, configurable with a `set_public_keys` method. If set, this configures NixHTTPPathInfoService to validate signatures. Change-Id: I157c5e13c41fc9bfd40b0655381fb4cf33900868 Reviewed-on: https://cl.tvl.fyi/c/depot/+/10152 Autosubmit: flokli <flokli@flokli.de> Tested-by: BuildkiteCI Reviewed-by: tazjin <tazjin@tvl.su>
Diffstat (limited to 'tvix/store/src')
-rw-r--r-- | tvix/store/src/pathinfoservice/nix_http.rs | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/tvix/store/src/pathinfoservice/nix_http.rs b/tvix/store/src/pathinfoservice/nix_http.rs index 26e516a90d4f..08e01d2540f0 100644 --- a/tvix/store/src/pathinfoservice/nix_http.rs +++ b/tvix/store/src/pathinfoservice/nix_http.rs @@ -6,7 +6,10 @@ use std::{ use data_encoding::BASE64; use futures::{Stream, TryStreamExt}; -use nix_compat::{narinfo::NarInfo, nixbase32}; +use nix_compat::{ + narinfo::{self, NarInfo}, + nixbase32, +}; use reqwest::StatusCode; use sha2::{digest::FixedOutput, Digest, Sha256}; use tonic::async_trait; @@ -41,6 +44,10 @@ pub struct NixHTTPPathInfoService { blob_service: Arc<dyn BlobService>, directory_service: Arc<dyn DirectoryService>, + + /// An optional list of [narinfo::PubKey]. + /// If set, the .narinfo files received need to have correct signature by at least one of these. + public_keys: Option<Vec<narinfo::PubKey>>, } impl NixHTTPPathInfoService { @@ -54,8 +61,15 @@ impl NixHTTPPathInfoService { http_client: reqwest::Client::new(), blob_service, directory_service, + + public_keys: None, } } + + /// Configures [Self] to validate NARInfo fingerprints with the public keys passed. + pub fn set_public_keys(&mut self, public_keys: Vec<narinfo::PubKey>) { + self.public_keys = Some(public_keys); + } } #[async_trait] @@ -109,6 +123,24 @@ impl PathInfoService for NixHTTPPathInfoService { ) })?; + // if [self.public_keys] is set, ensure there's at least one valid signature. + if let Some(public_keys) = &self.public_keys { + let fingerprint = narinfo.fingerprint(); + + if !public_keys.iter().any(|pubkey| { + narinfo + .signatures + .iter() + .any(|sig| pubkey.verify(&fingerprint, sig)) + }) { + warn!("no valid signature found"); + Err(io::Error::new( + io::ErrorKind::InvalidData, + "no valid signature found", + ))?; + } + } + // Convert to a (sparse) PathInfo. We still need to populate the node field, // and for this we need to download the NAR file. // FUTUREWORK: Keep some database around mapping from narsha256 to |