Skip to content

Commit caec81c

Browse files
committed
2024-04-10 pr feedback
Signed-off-by: Andrew Pan <[email protected]>
1 parent 34985ad commit caec81c

File tree

7 files changed

+48
-35
lines changed

7 files changed

+48
-35
lines changed

Cargo.toml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ test-registry = []
3030

3131
fulcio-native-tls = ["oauth-native-tls", "reqwest/native-tls", "fulcio"]
3232
fulcio-rustls-tls = ["oauth-rustls-tls", "reqwest/rustls-tls", "fulcio"]
33-
fulcio = []
33+
fulcio = ["serde_with"]
3434

3535
oauth-native-tls = ["openidconnect/native-tls", "oauth"]
3636
oauth-rustls-tls = ["openidconnect/rustls-tls", "oauth"]
@@ -40,12 +40,12 @@ rekor-native-tls = ["reqwest/native-tls", "rekor"]
4040
rekor-rustls-tls = ["reqwest/rustls-tls", "rekor"]
4141
rekor = ["reqwest"]
4242

43-
sigstore-trust-root = ["futures-util", "tough", "regex", "tokio/sync"]
44-
45-
bundle = []
43+
bundle = ["sigstore_protobuf_specs"]
4644
sign = ["bundle"]
4745
verify = ["bundle"]
4846

47+
sigstore-trust-root = ["bundle", "futures-util", "tough", "regex", "tokio/sync"]
48+
4949
cosign-native-tls = [
5050
"oci-distribution/native-tls",
5151
"cert",
@@ -113,10 +113,10 @@ rsa = "0.9.2"
113113
scrypt = "0.11.0"
114114
serde = { version = "1.0.136", features = ["derive"] }
115115
serde_json = "1.0.79"
116-
serde_with = { version = "3.4.0", features = ["base64", "json"] }
116+
serde_with = { version = "3.4.0", features = ["base64", "json"], optional = true }
117117
sha2 = { version = "0.10.6", features = ["oid"] }
118118
signature = { version = "2.0" }
119-
sigstore_protobuf_specs = "0.3.2"
119+
sigstore_protobuf_specs = { version = "0.3.2", optional = true }
120120
thiserror = "1.0.30"
121121
tokio = { version = "1.17.0", features = ["rt"] }
122122
tokio-util = { version = "0.7.10", features = ["io-util"] }

src/crypto/verification_key.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ impl CosignVerificationKey {
331331

332332
/// Verify the signature provided has been actually generated by the given key
333333
/// when signing the provided prehashed message.
334-
pub fn verify_prehash(&self, signature: Signature, msg: &[u8]) -> Result<()> {
334+
pub(crate) fn verify_prehash(&self, signature: Signature, msg: &[u8]) -> Result<()> {
335335
let sig = match signature {
336336
Signature::Raw(data) => data.to_owned(),
337337
Signature::Base64Encoded(data) => BASE64_STD_ENGINE.decode(data)?,

src/errors.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,6 @@ pub enum SigstoreError {
109109
#[error("Certificate pool error: {0}")]
110110
CertificatePoolError(String),
111111

112-
#[error("Certificate invalid: {0}")]
113-
InvalidCertError(String),
114-
115112
#[error("Signing session expired")]
116113
ExpiredSigningSession(),
117114

src/trust/sigstore/constants.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub(crate) const SIGSTORE_TARGET_BASE: &str = "https://tuf-repo-cdn.sigstore.dev
1919
macro_rules! impl_static_resource {
2020
{$($name:literal,)+} => {
2121
#[inline]
22-
pub(crate) fn static_resource(name: impl AsRef<str>) -> Option<&'static [u8]> {
22+
pub(crate) fn static_resource<N>(name: N) -> Option<&'static [u8]> where N: AsRef<str> {
2323
match name.as_ref() {
2424
$(
2525
$name => Some(include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/trust_root/prod/", $name)))

src/trust/sigstore/mod.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
/// ```
3939
use futures_util::TryStreamExt;
4040
use sha2::{Digest, Sha256};
41-
use std::path::{Path, PathBuf};
41+
use std::path::PathBuf;
4242
use tokio_util::bytes::BytesMut;
4343

4444
use sigstore_protobuf_specs::dev::sigstore::{
@@ -62,7 +62,7 @@ pub struct SigstoreTrustRoot {
6262

6363
impl SigstoreTrustRoot {
6464
/// Constructs a new trust repository established by a [tough::Repository].
65-
pub async fn new(checkout_dir: Option<&Path>) -> Result<Self> {
65+
pub async fn new(checkout_dir: Option<PathBuf>) -> Result<Self> {
6666
// These are statically defined and should always parse correctly.
6767
let metadata_base = url::Url::parse(constants::SIGSTORE_METADATA_BASE)?;
6868
let target_base = url::Url::parse(constants::SIGSTORE_TARGET_BASE)?;
@@ -77,8 +77,6 @@ impl SigstoreTrustRoot {
7777
.await
7878
.map_err(Box::new)?;
7979

80-
let checkout_dir = checkout_dir.map(ToOwned::to_owned);
81-
8280
let trusted_root = {
8381
let data = Self::fetch_target(&repository, &checkout_dir, "trusted_root.json").await?;
8482
serde_json::from_slice(&data[..])?
@@ -105,12 +103,13 @@ impl SigstoreTrustRoot {
105103
}
106104
};
107105

108-
// Try reading the target from disk cache.
106+
// First, try reading the target from disk cache.
109107
let data = if let Some(Ok(local_data)) = local_path.as_ref().map(std::fs::read) {
108+
debug!("{}: reading from embedded resources", name.raw());
110109
local_data.to_vec()
111110
// Try reading the target embedded into the binary.
112111
} else if let Some(embedded_data) = constants::static_resource(name.raw()) {
113-
debug!("read embedded target {}", name.raw());
112+
debug!("{}: reading from remote", name.raw());
114113
embedded_data.to_vec()
115114
// If all else fails, read the data from the TUF repo.
116115
} else if let Ok(remote_data) = read_remote_target().await {
@@ -128,15 +127,15 @@ impl SigstoreTrustRoot {
128127
};
129128

130129
let data = if Sha256::digest(&data)[..] != target.hashes.sha256[..] {
130+
debug!("{}: out of date", name.raw());
131131
read_remote_target().await?.to_vec()
132132
} else {
133133
data
134134
};
135135

136-
// Write the up-to-date data back to the disk. This doesn't need to succeed, as we can
137-
// always fetch the target again later.
136+
// Write our updated data back to the disk.
138137
if let Some(local_path) = local_path {
139-
let _ = std::fs::write(local_path, &data);
138+
std::fs::write(local_path, &data)?;
140139
}
141140

142141
Ok(data)

src/verify/policy.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ impl<T: SingleX509ExtPolicy + const_oid::AssociatedOid> VerificationPolicy for T
109109

110110
// Parse raw string without DER encoding.
111111
let val = std::str::from_utf8(ext.extn_value.as_bytes())
112-
.expect("failed to parse constructed Extension!");
112+
.or(Err(PolicyError::ExtensionNotFound))?;
113113

114114
if val != self.value() {
115115
return Err(PolicyError::ExtensionCheckFailed {
@@ -172,7 +172,10 @@ pub struct AnyOf<'a> {
172172
}
173173

174174
impl<'a> AnyOf<'a> {
175-
pub fn new<I: IntoIterator<Item = &'a dyn VerificationPolicy>>(policies: I) -> Self {
175+
pub fn new<I>(policies: I) -> Self
176+
where
177+
I: IntoIterator<Item = &'a dyn VerificationPolicy>,
178+
{
176179
Self {
177180
children: policies.into_iter().collect(),
178181
}
@@ -200,7 +203,10 @@ pub struct AllOf<'a> {
200203
}
201204

202205
impl<'a> AllOf<'a> {
203-
pub fn new<I: IntoIterator<Item = &'a dyn VerificationPolicy>>(policies: I) -> Option<Self> {
206+
pub fn new<I>(policies: I) -> Option<Self>
207+
where
208+
I: IntoIterator<Item = &'a dyn VerificationPolicy>,
209+
{
204210
let children: Vec<_> = policies.into_iter().collect();
205211

206212
// Without this, we'd be able to construct an `AllOf` containing an empty list of child

src/verify/verifier.rs

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,16 @@ impl AsyncVerifier {
6262
})
6363
}
6464

65-
async fn verify_digest(
65+
async fn verify_digest<P>(
6666
&self,
6767
input_digest: Sha256,
6868
bundle: Bundle,
69-
policy: &impl VerificationPolicy,
69+
policy: &P,
7070
offline: bool,
71-
) -> VerificationResult {
71+
) -> VerificationResult
72+
where
73+
P: VerificationPolicy,
74+
{
7275
let input_digest = input_digest.finalize();
7376
let materials: CheckedBundle = bundle.try_into()?;
7477

@@ -129,9 +132,9 @@ impl AsyncVerifier {
129132

130133
// 4) Verify that the Rekor entry is consistent with the other signing
131134
// materials
132-
let Some(log_entry) = materials.tlog_entry(offline, &input_digest) else {
133-
return Err(SignatureErrorKind::Transparency)?;
134-
};
135+
let log_entry = materials
136+
.tlog_entry(offline, &input_digest)
137+
.ok_or(SignatureErrorKind::Transparency)?;
135138
debug!("log entry is consistent with other materials");
136139

137140
// 5) Verify the inclusion proof supplied by Rekor for this artifact,
@@ -166,13 +169,17 @@ impl AsyncVerifier {
166169

167170
/// Verifies an input against the given Sigstore Bundle, ensuring conformance to the provided
168171
/// [`VerificationPolicy`].
169-
pub async fn verify<R: AsyncRead + Unpin + Send>(
172+
pub async fn verify<R, P>(
170173
&self,
171174
mut input: R,
172175
bundle: Bundle,
173-
policy: &impl VerificationPolicy,
176+
policy: &P,
174177
offline: bool,
175-
) -> VerificationResult {
178+
) -> VerificationResult
179+
where
180+
R: AsyncRead + Unpin + Send,
181+
P: VerificationPolicy,
182+
{
176183
// arbitrary buffer size, chosen to be a multiple of the digest size.
177184
let mut buf = [0u8; 1024];
178185
let mut hasher = Sha256::new();
@@ -228,13 +235,17 @@ impl Verifier {
228235

229236
/// Verifies an input against the given Sigstore Bundle, ensuring conformance to the provided
230237
/// [`VerificationPolicy`].
231-
pub fn verify<R: Read>(
238+
pub fn verify<R, P>(
232239
&self,
233240
mut input: R,
234241
bundle: Bundle,
235-
policy: &impl VerificationPolicy,
242+
policy: &P,
236243
offline: bool,
237-
) -> VerificationResult {
244+
) -> VerificationResult
245+
where
246+
R: Read,
247+
P: VerificationPolicy,
248+
{
238249
let mut hasher = Sha256::new();
239250
io::copy(&mut input, &mut hasher).map_err(VerificationError::Input)?;
240251

0 commit comments

Comments
 (0)