diff --git a/src/cosign/client_builder.rs b/src/cosign/client_builder.rs index f076e83528..4bfae89e2d 100644 --- a/src/cosign/client_builder.rs +++ b/src/cosign/client_builder.rs @@ -28,7 +28,7 @@ use crate::tuf::Repository; /// ## Rekor integration /// /// Rekor integration can be enabled by specifying Rekor's public key. -/// This can be provided via the [`ClientBuilder::with_rekor_pub_key`] method. +/// This can be provided via a [`crate::tuf::FakeRepository`]. /// /// > Note well: the [`tuf`](crate::tuf) module provides helper structs and methods /// > to obtain this data from the official TUF repository of the Sigstore project. @@ -36,7 +36,7 @@ use crate::tuf::Repository; /// ## Fulcio integration /// /// Fulcio integration can be enabled by specifying Fulcio's certificate. -/// This can be provided via the [`ClientBuilder::with_fulcio_certs`] method. +/// This can be provided via a [`crate::tuf::FakeRepository`]. /// /// > Note well: the [`tuf`](crate::tuf) module provides helper structs and methods /// > to obtain this data from the official TUF repository of the Sigstore project. diff --git a/src/cosign/mod.rs b/src/cosign/mod.rs index 4e6be029f2..9ddcdcc813 100644 --- a/src/cosign/mod.rs +++ b/src/cosign/mod.rs @@ -102,13 +102,14 @@ pub trait CosignCapabilities { /// must be satisfied: /// /// * The [`sigstore::cosign::Client`](crate::cosign::client::Client) must - /// have been created with Rekor integration enabled (see - /// [`sigstore::cosign::ClientBuilder::with_rekor_pub_key`](crate::cosign::ClientBuilder::with_rekor_pub_key)) + /// have been created with Rekor integration enabled (see [`crate::tuf::FakeRepository`]) /// * The [`sigstore::cosign::Client`](crate::cosign::client::Client) must - /// have been created with Fulcio integration enabled (see - /// [`sigstore::cosign::ClientBuilder::with_fulcio_certs`](crate::cosign::ClientBuilder::with_fulcio_certs)) + /// have been created with Fulcio integration enabled (see [`crate::tuf::FakeRepository]) /// * The layer must include a bundle produced by Rekor /// + /// > Note well: the [`tuf`](crate::tuf) module provides helper structs and methods + /// > to obtain this data from the official TUF repository of the Sigstore project. + /// /// When the embedded certificate cannot be verified, [`SignatureLayer::certificate_signature`] /// is going to be `None`. /// @@ -199,7 +200,7 @@ pub trait CosignCapabilities { /// verification. /// /// Returns a `Result` with either `Ok()` for passed verification or -/// [`SigstoreVerifyConstraintsError`](crate::errors::SigstoreVerifyConstraintsError), +/// [`SigstoreVerifyConstraintsError`] /// which contains a vector of references to unsatisfied constraints. /// /// See the documentation of the [`cosign::verification_constraint`](crate::cosign::verification_constraint) module for more @@ -249,7 +250,7 @@ where /// passes applying constraints process. /// /// Returns a `Result` with either `Ok()` for success or -/// [`SigstoreApplicationConstraintsError`](crate::errors::SigstoreApplicationConstraintsError), +/// [`SigstoreApplicationConstraintsError`] /// which contains a vector of references to unapplied constraints. /// /// See the documentation of the [`cosign::sign_constraint`](crate::cosign::sign_constraint) module for more diff --git a/src/crypto/verification_key.rs b/src/crypto/verification_key.rs index 9ba0feaaab..1cf40d7eed 100644 --- a/src/crypto/verification_key.rs +++ b/src/crypto/verification_key.rs @@ -59,7 +59,7 @@ pub enum CosignVerificationKey { ED25519(ed25519_dalek::VerifyingKey), } -/// Attempts to convert a [x509 Subject Public Key Info](SubjectPublicKeyInfo) object into +/// Attempts to convert a [x509 Subject Public Key Info](x509_cert::spki::SubjectPublicKeyInfo) object into /// a `CosignVerificationKey` one. /// /// Currently can convert only the following types of keys: diff --git a/src/lib.rs b/src/lib.rs index f439bfc663..30475140a1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,7 +27,7 @@ //! //! # Verification //! -//! Sigstore verification is done using the [`cosign::Client`](crate::cosign::Client) +//! Sigstore verification is done using the [`cosign::Client`] //! struct. //! //! ## Triangulation of Sigstore signature @@ -92,9 +92,11 @@ //! data: fulcio_cert_data //! }; //! -//! let mut repo = sigstore::tuf::FakeRepository::default(); -//! repo.fulcio_certs.get_or_insert(Vec::new()).push(fulcio_cert.try_into().unwrap()); -//! repo.rekor_key = Some(rekor_pub_key); +//! let mut repo = sigstore::tuf::FakeRepository { +//! fulcio_certs: Some(vec![fulcio_cert.try_into().unwrap()]), +//! rekor_key: Some(rekor_pub_key), +//! ..Default::default() +//! }; //! //! let mut client = sigstore::cosign::ClientBuilder::default() //! .with_trust_repository(&repo) @@ -222,7 +224,7 @@ //! //! ## Fulcio and Rekor integration //! -//! [`cosign::Client`](crate::cosign::Client) integration with Fulcio and Rekor +//! [`cosign::Client`] integration with Fulcio and Rekor //! requires the following data to work: Fulcio's certificate and Rekor's public key. //! //! These files are safely distributed by the Sigstore project via a TUF repository. diff --git a/src/tuf/trustroot.rs b/src/tuf/trustroot.rs index 61586a8ffa..aeb321fd92 100644 --- a/src/tuf/trustroot.rs +++ b/src/tuf/trustroot.rs @@ -13,6 +13,13 @@ use serde_with::serde_as; #[derive(Serialize, Deserialize, Debug, PartialEq)] #[allow(non_camel_case_types)] +/// Only a subset of the secure hash standard algorithms are supported. +/// See for more +/// details. +/// UNSPECIFIED SHOULD not be used, primary reason for inclusion is to force +/// any proto JSON serialization to emit the used hash algorithm, as default +/// option is to *omit* the default value of an enum (which is the first +/// value, represented by '0'. pub(crate) enum HashAlgorithm { HASH_ALGORITHM_UNSPECIFIED = 0, SHA2_256 = 1, @@ -20,6 +27,12 @@ pub(crate) enum HashAlgorithm { #[derive(Serialize, Deserialize, Debug, PartialEq)] #[allow(non_camel_case_types)] +/// Details of a specific public key, capturing the the key encoding method, +/// and signature algorithm. +/// To avoid the possibility of contradicting formats such as PKCS1 with +/// ED25519 the valid permutations are listed as a linear set instead of a +/// cartesian set (i.e one combined variable instead of two, one for encoding +/// and one for the signature algorithm). pub(crate) enum PublicKeyDetails { PUBLIC_KEY_DETAILS_UNSPECIFIED = 0, // RSA @@ -37,6 +50,7 @@ pub(crate) enum PublicKeyDetails { #[serde_as] #[derive(Serialize, Deserialize, Debug, PartialEq)] #[serde(rename_all = "camelCase")] +/// LogId captures the identity of a transparency log. pub(crate) struct LogId { #[serde_as(as = "Base64")] pub key_id: Vec, @@ -44,6 +58,10 @@ pub(crate) struct LogId { #[derive(Serialize, Deserialize, Debug, PartialEq)] #[serde(rename_all = "camelCase")] +/// The time range is closed and includes both the start and end times, +/// (i.e., [start, end]). +/// End is optional to be able to capture a period that has started but +/// has no known end. pub(crate) struct TimeRange { pub start: DateTime, pub end: Option>, @@ -76,12 +94,19 @@ pub(crate) struct X509Certificate { #[derive(Serialize, Deserialize, Debug, PartialEq)] #[serde(rename_all = "camelCase")] +/// A chain of X.509 certificates. pub(crate) struct X509CertificateChain { pub certificates: Vec, } #[derive(Serialize, Deserialize, Debug, PartialEq)] #[serde(rename_all = "camelCase")] +/// TransparencyLogInstance describes the immutable parameters from a +/// transparency log. +/// See https://www.rfc-editor.org/rfc/rfc9162.html#name-log-parameters +/// for more details. +/// The included parameters are the minimal set required to identify a log, +/// and verify an inclusion proof/promise. pub(crate) struct TransparencyLogInstance { pub base_url: String, pub hash_algorithm: HashAlgorithm, @@ -91,6 +116,8 @@ pub(crate) struct TransparencyLogInstance { #[derive(Serialize, Deserialize, Debug, PartialEq)] #[serde(rename_all = "camelCase")] +/// CertificateAuthority enlists the information required to identify which +/// CA to use and perform signature verification. pub(crate) struct CertificateAuthority { pub subject: DistinguishedName, pub uri: Option, @@ -100,6 +127,25 @@ pub(crate) struct CertificateAuthority { #[derive(Serialize, Deserialize, Debug, PartialEq)] #[serde(rename_all = "camelCase")] +/// TrustedRoot describes the client's complete set of trusted entities. +/// How the TrustedRoot is populated is not specified, but can be a +/// combination of many sources such as TUF repositories, files on disk etc. +/// +/// The TrustedRoot is not meant to be used for any artifact verification, only +/// to capture the complete/global set of trusted verification materials. +/// When verifying an artifact, based on the artifact and policies, a selection +/// of keys/authorities are expected to be extracted and provided to the +/// verification function. This way the set of keys/authorities can be kept to +/// a minimal set by the policy to gain better control over what signatures +/// that are allowed. +/// +/// The embedded transparency logs, CT logs, CAs and TSAs MUST include any +/// previously used instance -- otherwise signatures made in the past cannot +/// be verified. +/// The currently used instances MUST NOT have their 'end' timestamp set in +/// their 'valid_for' attribute for easy identification. +/// All the listed instances SHOULD be sorted by the 'valid_for' in ascending +/// order, that is, the oldest instance first and the current instance last. pub(crate) struct TrustedRoot { pub media_type: String, pub tlogs: Vec,