Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 2 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ aws-lc-rs = "1.15.2"
base64 = "0.22.1"
chrono = { version = "0.4.42", features = ["alloc"], default-features = false }
clap = { version = "4.5", features = ["derive"] }
clubcard-crlite = "0.3.2"
clubcard-crlite = "0.3.3"
criterion = "0.8"
directories = "6"
eyre = "0.6"
Expand Down Expand Up @@ -62,3 +62,6 @@ unreachable_pub = "warn"
unused_extern_crates = "warn"
unused_import_braces = "warn"
unused_qualifications = "warn"

[patch.crates-io]
clubcard-crlite = { git = "https://github.com/mozilla/clubcard-crlite", rev = "83d4afe61d511fe88e8bf22e8a71c3b582536e69" }
20 changes: 17 additions & 3 deletions revoke-test/benches/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use codspeed_criterion_compat::{Criterion, criterion_group, criterion_main};
use criterion::{Criterion, criterion_group, criterion_main};
use revoke_test::RevocationTestSites;
use rustls_pki_types::CertificateDer;
use upki::revocation::{Manifest, RevocationCheckInput, RevocationStatus};
use upki::revocation::{Index, Manifest, RevocationCheckInput, RevocationStatus};
use upki::{Config, ConfigPath};

fn revocation(c: &mut Criterion) {
Expand Down Expand Up @@ -44,13 +44,27 @@ fn revocation(c: &mut Criterion) {

c.bench_function("revocation-check", |b| {
let config = Config::from_file_or_default(&ConfigPath::new(None).unwrap()).unwrap();
let index = Index::from_cache(&config).unwrap();
let revoked_certs = certificates_for_test_site(BENCHMARK_CASE);

b.iter(|| {
let manifest = Manifest::from_config(&config).unwrap();
let input = RevocationCheckInput::from_certificates(&revoked_certs).unwrap();
assert_eq!(
manifest.check(&input, &config).unwrap(),
index.check(&input).unwrap(),
RevocationStatus::CertainlyRevoked
);
})
});

c.bench_function("e2e-revocation-check", |b| {
let config = Config::from_file_or_default(&ConfigPath::new(None).unwrap()).unwrap();
let revoked_certs = certificates_for_test_site(BENCHMARK_CASE);

b.iter(|| {
let index = Index::from_cache(&config).unwrap();
let input = RevocationCheckInput::from_certificates(&revoked_certs).unwrap();
assert_eq!(
index.check(&input).unwrap(),
RevocationStatus::CertainlyRevoked
);
})
Expand Down
7 changes: 3 additions & 4 deletions rustls-upki/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ use rustls::{
ExtendedKeyPurpose, RootCertStore, SignatureScheme, SupportedCipherSuite,
};
use upki::revocation::{
CertSerial, CtTimestamp, IssuerSpkiHash, Manifest, RevocationCheckInput, RevocationStatus,
CertSerial, CtTimestamp, Index, IssuerSpkiHash, Manifest, RevocationCheckInput,
RevocationStatus,
};
use upki::{self, Config, ConfigPath};
use webpki::{EndEntityCert, ExtendedKeyUsage, InvalidNameContext, VerifiedPath};
Expand Down Expand Up @@ -128,9 +129,7 @@ impl ServerVerifier {
sct_timestamps,
};

match Manifest::from_config(&self.config)
.and_then(|manifest| manifest.check(&input, &self.config))
{
match Index::from_cache(&self.config).and_then(|index| index.check(&input)) {
Ok(rs) => Ok(rs),
Err(e) => Err(rustls::Error::General(e.to_string())),
}
Expand Down
8 changes: 4 additions & 4 deletions upki-ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::path::Path;
use std::slice;

use rustls_pki_types::CertificateDer;
use upki::revocation::{self, Manifest, RevocationCheckInput, RevocationStatus};
use upki::revocation::{self, Index, RevocationCheckInput, RevocationStatus};
use upki::{Config, Error};

/// Check the revocation status of a certificate.
Expand Down Expand Up @@ -47,12 +47,12 @@ pub unsafe extern "C" fn upki_check_revocation(
Err(err) => return Error::Revocation(err).into(),
};

let manifest = match Manifest::from_config(config) {
Ok(manifest) => manifest,
let index = match Index::from_cache(config) {
Ok(index) => index,
Err(err) => return Error::Revocation(err).into(),
};

match manifest.check(&input, config) {
match index.check(&input) {
Ok(status) => match status {
RevocationStatus::NotCoveredByRevocationData => {
upki_result::UPKI_REVOCATION_NOT_COVERED
Expand Down
6 changes: 3 additions & 3 deletions upki/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use clap::{Parser, Subcommand};
use eyre::{Context, Report};
use rustls_pki_types::CertificateDer;
use rustls_pki_types::pem::PemObject;
use upki::revocation::{Manifest, RevocationCheckInput, fetch};
use upki::revocation::{Index, Manifest, RevocationCheckInput, fetch};
use upki::{Config, ConfigPath};

#[tokio::main(flavor = "current_thread")]
Expand Down Expand Up @@ -51,8 +51,8 @@ async fn main() -> Result<ExitCode, Report> {
}

let input = RevocationCheckInput::from_certificates(&certs)?;
Manifest::from_config(&config)?
.check(&input, &config)?
Index::from_cache(&config)?
.check(&input)?
.to_cli()
}
})
Expand Down
59 changes: 57 additions & 2 deletions upki/src/revocation/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use core::time::Duration;
use std::collections::HashSet;
use std::env;
use std::fs::{self, File, Permissions};
use std::io::{self, Read};
use std::io::{self, Read, Write};
#[cfg(target_family = "unix")]
use std::os::unix::fs::PermissionsExt;
use std::path::{Path, PathBuf};
Expand All @@ -20,7 +20,8 @@ use std::process::ExitCode;
use aws_lc_rs::digest;
use tracing::{debug, info};

use super::{Error, Filter, Manifest};
use super::index::INDEX_BIN;
use super::{Error, Filter, Index, Manifest};
use crate::Config;

/// Update the local revocation cache by fetching updates over the network.
Expand Down Expand Up @@ -157,6 +158,11 @@ impl Plan {
steps.push(PlanStep::download(filter, remote_url, local));
}

steps.push(PlanStep::SaveIndex {
manifest: manifest.clone(),
local_dir: local.to_owned(),
});

steps.push(PlanStep::SaveManifest {
manifest: manifest.clone(),
local_dir: local.to_owned(),
Expand Down Expand Up @@ -197,6 +203,12 @@ enum PlanStep {
/// Delete the given single local file.
Delete(PathBuf),

/// Build and save the index from filter universe metadata.
SaveIndex {
manifest: Manifest,
local_dir: PathBuf,
},

/// Save the manifest structure
SaveManifest {
manifest: Manifest,
Expand Down Expand Up @@ -266,6 +278,46 @@ impl PlanStep {
path: target,
})?;
}
Self::SaveIndex {
manifest,
local_dir,
} => {
debug!("building index");
let Some(buf) = Index::write(&manifest, &local_dir) else {
return Ok(());
};

#[cfg(target_family = "unix")]
let temp = tempfile::Builder::new()
.permissions(Permissions::from_mode(0o644))
.suffix(".new")
.tempfile_in(&local_dir);
#[cfg(not(target_family = "unix"))]
let temp = tempfile::Builder::new()
.suffix(".new")
.tempfile_in(&local_dir);

let mut local_temp = temp.map_err(|error| Error::FileWrite {
error,
path: local_dir.clone(),
})?;

local_temp
.as_file_mut()
.write_all(&buf)
.map_err(|error| Error::FileWrite {
error,
path: local_temp.path().to_owned(),
})?;

let path = local_dir.join(INDEX_BIN);
local_temp
.persist(&path)
.map_err(|error| Error::FileWrite {
error: error.error,
path,
})?;
}
Self::SaveManifest {
manifest,
local_dir,
Expand Down Expand Up @@ -329,6 +381,9 @@ impl fmt::Display for PlanStep {
filter.size
),
Self::Delete(path) => write!(f, "delete stale file {path:?}"),
Self::SaveIndex { local_dir, .. } => {
write!(f, "build index from filters into {local_dir:?}")
}
Self::SaveManifest { local_dir, .. } => {
write!(f, "save new manifest into {local_dir:?}")
}
Expand Down
Loading
Loading