Skip to content

Commit

Permalink
fix: address changes done to Sigstore TUF repository
Browse files Browse the repository at this point in the history
The Sigstore project changed the internals of its TUF repository, which
broke sigstore-rs.

This commit updates to the latest version of sigstore-rs. The code
changes have been caused by the massive changes done by sigstore-rs.

Required to fix kubewarden/kwctl#753

Signed-off-by: Flavio Castelli <fcastelli@suse.com>
  • Loading branch information
flavio committed Apr 12, 2024
1 parent 36bbcc8 commit e2dbd8b
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 60 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ picky = { version = "7.0.0-rc.8", default-features = false, features = [
"chrono_conversion",
"x509",
] }
policy-fetcher = { git = "https://github.com/kubewarden/policy-fetcher", tag = "v0.8.3" }
policy-fetcher = { git = "https://github.com/kubewarden/policy-fetcher", tag = "v0.8.4" }
semver = { version = "1.0.22", features = ["serde"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
Expand Down
30 changes: 13 additions & 17 deletions src/callback_handler/builder.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use std::sync::Arc;

use anyhow::Result;
use policy_fetcher::sigstore::trust::ManualTrustRoot;
use policy_fetcher::sources::Sources;
use policy_fetcher::verify::FulcioAndRekorData;
use std::sync::Arc;
use tokio::sync::{mpsc, oneshot};

use super::CallbackHandler;
Expand All @@ -12,21 +11,21 @@ use crate::callback_requests::CallbackRequest;
const DEFAULT_CHANNEL_BUFF_SIZE: usize = 100;

/// Helper struct that creates CallbackHandler objects
pub struct CallbackHandlerBuilder<'a> {
pub struct CallbackHandlerBuilder {
oci_sources: Option<Sources>,
channel_buffer_size: usize,
shutdown_channel: oneshot::Receiver<()>,
fulcio_and_rekor_data: Option<&'a FulcioAndRekorData>,
trust_root: Option<Arc<ManualTrustRoot<'static>>>,
kube_client: Option<kube::Client>,
}

impl<'a> CallbackHandlerBuilder<'a> {
impl CallbackHandlerBuilder {
pub fn new(shutdown_channel: oneshot::Receiver<()>) -> Self {
CallbackHandlerBuilder {
oci_sources: None,
shutdown_channel,
channel_buffer_size: DEFAULT_CHANNEL_BUFF_SIZE,
fulcio_and_rekor_data: None,
trust_root: None,
kube_client: None,
}
}
Expand All @@ -37,11 +36,8 @@ impl<'a> CallbackHandlerBuilder<'a> {
self
}

pub fn fulcio_and_rekor_data(
mut self,
fulcio_and_rekor_data: Option<&'a FulcioAndRekorData>,
) -> Self {
self.fulcio_and_rekor_data = fulcio_and_rekor_data;
pub fn trust_root(mut self, trust_root: Option<Arc<ManualTrustRoot<'static>>>) -> Self {
self.trust_root = trust_root;
self
}

Expand All @@ -61,13 +57,13 @@ impl<'a> CallbackHandlerBuilder<'a> {
}

/// Create a CallbackHandler object
pub fn build(self) -> Result<CallbackHandler> {
pub async fn build(self) -> Result<CallbackHandler> {
let (tx, rx) = mpsc::channel::<CallbackRequest>(self.channel_buffer_size);
let oci_client = Arc::new(oci::Client::new(self.oci_sources.clone()));
let sigstore_client = sigstore_verification::Client::new(
self.oci_sources.clone(),
self.fulcio_and_rekor_data,
)?;
let sigstore_client =
sigstore_verification::Client::new(self.oci_sources.clone(), self.trust_root.clone())
.await?
.to_owned();

let kubernetes_client = self.kube_client.map(super::kubernetes::Client::new);

Expand Down
70 changes: 28 additions & 42 deletions src/callback_handler/sigstore_verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ use kubewarden_policy_sdk::host_capabilities::verification::{
KeylessInfo, KeylessPrefixInfo, VerificationResponse,
};
use policy_fetcher::sigstore;
use policy_fetcher::sigstore::trust::ManualTrustRoot;
use policy_fetcher::sources::Sources;
use policy_fetcher::verify::config::{LatestVerificationConfig, Signature, Subject};
use policy_fetcher::verify::{fetch_sigstore_remote_data, FulcioAndRekorData, Verifier};
use policy_fetcher::verify::{fetch_sigstore_remote_data, Verifier};
use sha2::{Digest, Sha256};
use sigstore::cosign::verification_constraint::{
AnnotationVerifier, CertificateVerifier, VerificationConstraintVec,
Expand All @@ -20,19 +21,20 @@ use tracing::warn;

#[derive(Clone)]
pub(crate) struct Client {
cosign_client: Arc<Mutex<sigstore::cosign::Client>>,
verifier: Verifier,
cosign_client: Arc<Mutex<sigstore::cosign::Client<'static>>>,
verifier: Verifier<'static>,
}

impl Client {
pub fn new(
pub async fn new(
sources: Option<Sources>,
fulcio_and_rekor_data: Option<&FulcioAndRekorData>,
trust_root: Option<Arc<ManualTrustRoot<'static>>>,
) -> Result<Self> {
let cosign_client = Arc::new(Mutex::new(Self::build_cosign_client(
sources.clone(),
fulcio_and_rekor_data,
)?));
let cosign_client = Arc::new(Mutex::new(
Self::build_cosign_client(sources.clone(), trust_root)
.await?
.to_owned(),
));
let verifier = Verifier::new_from_cosign_client(cosign_client.clone(), sources);

Ok(Client {
Expand All @@ -41,48 +43,32 @@ impl Client {
})
}

fn build_cosign_client(
async fn build_cosign_client(
sources: Option<Sources>,
fulcio_and_rekor_data: Option<&FulcioAndRekorData>,
trust_root: Option<Arc<ManualTrustRoot<'static>>>,
) -> Result<sigstore::cosign::Client> {
let client_config: sigstore::registry::ClientConfig = sources.unwrap_or_default().into();
let mut cosign_client_builder =
sigstore::cosign::ClientBuilder::default().with_oci_client_config(client_config);
match fulcio_and_rekor_data {
Some(FulcioAndRekorData::FromTufRepository { repo }) => {
cosign_client_builder = cosign_client_builder
.with_rekor_pub_key(repo.rekor_pub_key())
.with_fulcio_certs(repo.fulcio_certs());
}
Some(FulcioAndRekorData::FromCustomData {
rekor_public_key,
fulcio_certs,
}) => {
if let Some(pk) = rekor_public_key {
cosign_client_builder = cosign_client_builder.with_rekor_pub_key(pk);
}
if !fulcio_certs.is_empty() {
let certs: Vec<sigstore::registry::Certificate> = fulcio_certs
.iter()
.map(|c| {
let sc: sigstore::registry::Certificate = c.into();
sc
})
.collect();
cosign_client_builder = cosign_client_builder.with_fulcio_certs(&certs);
}

let mut cosign_client_builder = sigstore::cosign::ClientBuilder::default()
.with_oci_client_config(client_config)
.enable_registry_caching();
let cosign_client = match trust_root {
Some(trust_root) => {
cosign_client_builder =
cosign_client_builder.with_trust_repository(trust_root.as_ref())?;
let cosign_client = cosign_client_builder.build()?;
cosign_client.to_owned()
}
None => {
warn!("Sigstore Verifier created without Fulcio data: keyless signatures are going to be discarded because they cannot be verified");
warn!("Sigstore Verifier created without Rekor data: transparency log data won't be used");
warn!("Sigstore capabilities are going to be limited");
}
}

cosign_client_builder = cosign_client_builder.enable_registry_caching();
cosign_client_builder
.build()
.map_err(|e| anyhow!("could not build a cosign client: {}", e))
let cosign_client = cosign_client_builder.build()?;
cosign_client.to_owned()
}
};
Ok(cosign_client)
}

pub async fn verify_public_key(
Expand Down
2 changes: 2 additions & 0 deletions tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ async fn test_runtime_context_aware<F, Fut>(
let mut callback_handler = callback_builder
.kube_client(client)
.build()
.await
.expect("cannot build callback handler");
let callback_handler_channel = callback_handler.sender_channel();

Expand Down Expand Up @@ -326,6 +327,7 @@ async fn test_oci_manifest_capability(
let callback_builder = CallbackHandlerBuilder::new(callback_handler_shutdown_channel_rx);
let mut callback_handler = callback_builder
.build()
.await
.expect("cannot build callback handler");
let callback_handler_channel = callback_handler.sender_channel();

Expand Down

0 comments on commit e2dbd8b

Please sign in to comment.