Skip to content

Commit

Permalink
Merge pull request #311 from trail-of-forks/jl/verify
Browse files Browse the repository at this point in the history
verify: init
  • Loading branch information
flavio authored Apr 17, 2024
2 parents 3194eb5 + c018346 commit d5279eb
Show file tree
Hide file tree
Showing 42 changed files with 1,841 additions and 1,810 deletions.
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"] }
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

0 comments on commit d5279eb

Please sign in to comment.