Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

verify: init #311

Merged
merged 29 commits into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
69f64fa
verify: init
jleightcap Jan 3, 2024
6af5c49
pr feedback 2024-01-31
jleightcap Jan 31, 2024
afdf3b0
tuf: fixup target fetching
tnytown Feb 15, 2024
4dc13fe
sign, verify: use `sigstore-protobuf-specs` 0.3.2
tnytown Feb 15, 2024
428aa41
Add `bundle` feature
tnytown Feb 15, 2024
7d0db8b
verify: rework certificate validation
tnytown Feb 15, 2024
ffc2232
crypto: fixup is_root_ca & usages
tnytown Feb 16, 2024
0e79204
conformance: fixup
tnytown Feb 16, 2024
68fea4a
`cargo fmt`
tnytown Feb 16, 2024
752f87f
sign, verify: add TODOs for SCT verification
tnytown Feb 16, 2024
5c6854a
verify, crypto: asyncify, revamp error handling
tnytown Feb 23, 2024
d9fff73
verify: relax `'static` bound on async `verify`
tnytown Feb 23, 2024
8a80a36
sign, crypto: review comments
tnytown Feb 23, 2024
526c2a2
verify: basic `Verifier` / `AsyncVerifier` docs
tnytown Feb 23, 2024
230ead7
crypto/certificate: move `ExtensionErrorKind` up
tnytown Feb 23, 2024
fe83993
feedback from review
tnytown Feb 26, 2024
ce0c6cb
certificate: undo is_ca feedback changes
tnytown Feb 26, 2024
126442e
chore(deps): Update json-syntax requirement from 0.11.1 to 0.12.2
dependabot[bot] Feb 26, 2024
18a17c0
Merge remote-tracking branch 'origin/main' into jl/verify
tnytown Feb 28, 2024
34985ad
Merge remote-tracking branch 'origin/main' into jl/verify
tnytown Apr 9, 2024
caec81c
2024-04-10 pr feedback
tnytown Apr 10, 2024
11970d5
verify: publicize `verify_digest`
tnytown Apr 10, 2024
39ea179
`cargo fmt`
tnytown Apr 10, 2024
ecf8995
adjust `bundle`, `sign`, `verify` feature flags
tnytown Apr 10, 2024
3f150a2
fixup `cargo build` on features `bundle, wasm`
tnytown Apr 10, 2024
81ae539
verifier: fixup time range check
tnytown Apr 11, 2024
71f5161
trust/sigstore: test caching behavior
tnytown Apr 11, 2024
1e73783
`sign`, `verify`: reparent to `bundle`, doc fixups
tnytown Apr 11, 2024
c018346
trust/sigstore: rework tests
tnytown Apr 12, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 23 additions & 19 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ readme = "README.md"
repository = "https://github.com/sigstore/sigstore-rs"

[features]
default = ["full-native-tls", "cached-client", "sigstore-trust-root", "sign"]
wasm = ["getrandom/js"]
default = ["full-native-tls", "cached-client", "sigstore-trust-root", "bundle"]
wasm = ["getrandom/js", "ring/wasm32_unknown_unknown_js", "chrono/wasmbind"]

full-native-tls = [
"fulcio-native-tls",
Expand All @@ -28,21 +28,23 @@ full-rustls-tls = [
# This features is used by tests that use docker to create a registry
test-registry = []

fulcio-native-tls = ["oauth-native-tls", "reqwest/native-tls", "fulcio"]
fulcio-rustls-tls = ["oauth-rustls-tls", "reqwest/rustls-tls", "fulcio"]
fulcio = []

oauth-native-tls = ["openidconnect/native-tls", "oauth"]
oauth-rustls-tls = ["openidconnect/rustls-tls", "oauth"]
oauth = []
oauth = ["openidconnect"]

fulcio-native-tls = ["oauth-native-tls", "reqwest/native-tls", "fulcio"]
fulcio-rustls-tls = ["oauth-rustls-tls", "reqwest/rustls-tls", "fulcio"]
fulcio = ["oauth", "serde_with"]

rekor-native-tls = ["reqwest/native-tls", "rekor"]
rekor-rustls-tls = ["reqwest/rustls-tls", "rekor"]
rekor = ["reqwest"]

sigstore-trust-root = ["futures-util", "tough", "regex", "tokio/sync"]
sign = ["sigstore_protobuf_specs", "fulcio", "rekor", "cert"]
verify = ["sigstore_protobuf_specs", "fulcio", "rekor", "cert"]
bundle = ["sign", "verify"]

sign = []
sigstore-trust-root = ["sigstore_protobuf_specs", "futures-util", "tough", "regex", "tokio/sync"]

cosign-native-tls = [
"oci-distribution/native-tls",
Expand All @@ -56,12 +58,12 @@ cosign-rustls-tls = [
"cosign",
"registry-rustls-tls",
]
cosign = []
cosign = ["olpc-cjson"]
cert = []

registry-native-tls = ["oci-distribution/native-tls", "registry"]
registry-rustls-tls = ["oci-distribution/rustls-tls", "registry"]
registry = []
registry = ["olpc-cjson"]

mock-client-native-tls = ["oci-distribution/native-tls", "mock-client"]
mock-client-rustls-tls = ["oci-distribution/rustls-tls", "mock-client"]
Expand All @@ -74,8 +76,8 @@ async-trait = "0.1.52"
base64 = "0.22.0"
cached = { version = "0.49.2", optional = true, features = ["async"] }
cfg-if = "1.0.0"
chrono = { version = "0.4.27", default-features = false, features = ["serde"] }
const-oid = "0.9.1"
chrono = { version = "0.4.27", default-features = false, features = ["now", "serde"] }
const-oid = { version = "0.9.6", features = ["db"] }
digest = { version = "0.10.3", default-features = false }
ecdsa = { version = "0.16.7", features = ["pkcs8", "digest", "der", "signing"] }
ed25519 = { version = "2.2.1", features = ["alloc"] }
Expand All @@ -85,13 +87,13 @@ futures = "0.3"
futures-util = { version = "0.3.30", optional = true }
lazy_static = "1.4.0"
oci-distribution = { version = "0.11", default-features = false, optional = true }
olpc-cjson = "0.1"
olpc-cjson = { version = "0.1", optional = true }
openidconnect = { version = "3.0", default-features = false, features = [
"reqwest",
], optional = true }
p256 = "0.13.2"
p256 = "0.13"
p384 = "0.13"
webbrowser = "0.8.4"
webbrowser = "0.8.12"
pem = { version = "3.0", features = ["serde"] }
pkcs1 = { version = "0.7.5", features = ["std"] }
pkcs8 = { version = "0.10.2", features = [
Expand All @@ -111,23 +113,25 @@ rsa = "0.9.2"
scrypt = "0.11.0"
serde = { version = "1.0.136", features = ["derive"] }
serde_json = "1.0.79"
serde_with = { version = "3.4.0", features = ["base64"] }
flavio marked this conversation as resolved.
Show resolved Hide resolved
serde_with = { version = "3.4.0", features = ["base64", "json"], optional = true }
sha2 = { version = "0.10.6", features = ["oid"] }
signature = { version = "2.0" }
sigstore_protobuf_specs = "0.1.0-rc.2"
sigstore_protobuf_specs = { version = "0.3.2", optional = true }
thiserror = "1.0.30"
tokio = { version = "1.17.0", features = ["rt"] }
tokio-util = { version = "0.7.10", features = ["io-util"] }
tough = { version = "0.17.1", features = ["http"], optional = true }
tracing = "0.1.31"
url = "2.2.2"
x509-cert = { version = "0.2.2", features = ["builder", "pem", "std"] }
x509-cert = { version = "0.2.5", features = ["builder", "pem", "std", "sct"] }
crypto_secretbox = "0.1.1"
zeroize = "1.5.7"
rustls-webpki = { version = "0.102.1", features = ["alloc"] }
serde_repr = "0.1.16"
hex = "0.4.3"
json-syntax = { version = "0.12.2", features = ["canonicalize", "serde"] }
tls_codec = { version = "0.4.1", features = ["derive"] }
ring = "0.17.6"

[dev-dependencies]
anyhow = { version = "1.0", features = ["backtrace"] }
Expand Down
7 changes: 3 additions & 4 deletions examples/cosign/verify/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ async fn run_app(

let mut client_builder =
sigstore::cosign::ClientBuilder::default().with_oci_client_config(oci_client_config);
client_builder = client_builder.with_trust_repository(frd).await?;
client_builder = client_builder.with_trust_repository(frd)?;

let cert_chain: Option<Vec<sigstore::registry::Certificate>> = match cli.cert_chain.as_ref() {
None => None,
Expand Down Expand Up @@ -184,7 +184,7 @@ async fn run_app(
}
if let Some(path_to_cert) = cli.cert.as_ref() {
let cert = fs::read(path_to_cert).map_err(|e| anyhow!("Cannot read cert: {:?}", e))?;
let require_rekor_bundle = if !frd.rekor_keys().await?.is_empty() {
let require_rekor_bundle = if !frd.rekor_keys()?.is_empty() {
true
} else {
warn!("certificate based verification is weaker when Rekor integration is disabled");
Expand Down Expand Up @@ -229,8 +229,7 @@ async fn fulcio_and_rekor_data(cli: &Cli) -> anyhow::Result<Box<dyn sigstore::tr
if cli.use_sigstore_tuf_data {
info!("Downloading data from Sigstore TUF repository");

let repo: sigstore::errors::Result<SigstoreTrustRoot> =
SigstoreTrustRoot::new(None).await?.prefetch().await;
let repo: sigstore::errors::Result<SigstoreTrustRoot> = SigstoreTrustRoot::new(None).await;

return Ok(Box::new(repo?));
};
Expand Down
24 changes: 7 additions & 17 deletions src/bundle/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.

//! Useful types for Sigstore bundles.
//! Sigstore bundle support.

use std::fmt::Display;
pub use sigstore_protobuf_specs::dev::sigstore::bundle::v1::Bundle;

pub use sigstore_protobuf_specs::Bundle;
mod models;

// Known Sigstore bundle media types.
#[derive(Clone, Copy, Debug)]
pub enum Version {
_Bundle0_1,
Bundle0_2,
}
#[cfg(feature = "sign")]
pub mod sign;

impl Display for Version {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match &self {
Version::_Bundle0_1 => "application/vnd.dev.sigstore.bundle+json;version=0.1",
Version::Bundle0_2 => "application/vnd.dev.sigstore.bundle+json;version=0.2",
})
}
}
#[cfg(feature = "verify")]
pub mod verify;
107 changes: 107 additions & 0 deletions src/bundle/models.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
use std::fmt::Display;
use std::str::FromStr;

use base64::{engine::general_purpose::STANDARD as base64, Engine as _};
use json_syntax::Print;

use sigstore_protobuf_specs::dev::sigstore::{
common::v1::LogId,
rekor::v1::{Checkpoint, InclusionPromise, InclusionProof, KindVersion, TransparencyLogEntry},
};

use crate::rekor::models::{
log_entry::InclusionProof as RekorInclusionProof, LogEntry as RekorLogEntry,
};

// Known Sigstore bundle media types.
#[derive(Clone, Copy, Debug)]
pub enum Version {
Bundle0_1,
Bundle0_2,
}

impl Display for Version {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match &self {
Version::Bundle0_1 => "application/vnd.dev.sigstore.bundle+json;version=0.1",
Version::Bundle0_2 => "application/vnd.dev.sigstore.bundle+json;version=0.2",
})
}
}

impl FromStr for Version {
type Err = ();

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"application/vnd.dev.sigstore.bundle+json;version=0.1" => Ok(Version::Bundle0_1),
"application/vnd.dev.sigstore.bundle+json;version=0.2" => Ok(Version::Bundle0_2),
_ => Err(()),
}
}
}

#[inline]
fn decode_hex<S: AsRef<str>>(hex: S) -> Result<Vec<u8>, ()> {
hex::decode(hex.as_ref()).or(Err(()))
}

impl TryFrom<RekorInclusionProof> for InclusionProof {
type Error = ();

fn try_from(value: RekorInclusionProof) -> Result<Self, Self::Error> {
let hashes = value
.hashes
.iter()
.map(decode_hex)
.collect::<Result<Vec<_>, _>>()?;

Ok(InclusionProof {
checkpoint: Some(Checkpoint {
envelope: value.checkpoint,
}),
hashes,
log_index: value.log_index,
root_hash: decode_hex(value.root_hash)?,
tree_size: value.tree_size,
})
}
}

/// Convert log entries returned from Rekor into Sigstore Bundle format entries.
impl TryFrom<RekorLogEntry> for TransparencyLogEntry {
type Error = ();

fn try_from(value: RekorLogEntry) -> Result<Self, Self::Error> {
let canonicalized_body = {
let mut body = json_syntax::to_value(value.body).or(Err(()))?;
body.canonicalize();
body.compact_print().to_string().into_bytes()
};
let inclusion_promise = Some(InclusionPromise {
signed_entry_timestamp: base64
.decode(value.verification.signed_entry_timestamp)
.or(Err(()))?,
});
let inclusion_proof = value
.verification
.inclusion_proof
.map(|p| p.try_into())
.transpose()?;

Ok(TransparencyLogEntry {
canonicalized_body,
inclusion_promise,
inclusion_proof,
integrated_time: value.integrated_time,
kind_version: Some(KindVersion {
kind: "hashedrekord".to_owned(),
version: "0.0.1".to_owned(),
}),
log_id: Some(LogId {
key_id: decode_hex(value.log_i_d)?,
}),
log_index: value.log_index,
})
}
}
Loading
Loading