Skip to content
Merged
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
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions revoke-test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ insta-cmd.workspace = true
rustls-pki-types.workspace = true
rustls-upki.workspace = true
upki = { path = "../upki" }
upki-ffi = { path = "../upki-ffi" }

[features]
__bench_codspeed = ["dep:codspeed-criterion-compat"]
Expand Down
17 changes: 17 additions & 0 deletions revoke-test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,23 @@ impl CertificateDetail {
scts,
})
}

pub fn end_entity_cert_der(&self) -> Result<CertificateDer<'static>> {
Ok(CertificateDer::from(
BASE64_STANDARD
.decode(&self.end_entity_cert)
.map_err(|e| eyre::eyre!("cannot base64-decode certificate {e:?}"))?,
))
}

pub fn intermediates_der(&self) -> impl Iterator<Item = Result<CertificateDer<'static>>> {
self.intermediates.iter().map(|pem| {
BASE64_STANDARD
.decode(pem)
.map_err(|e| eyre::eyre!("cannot base64-decode certificate {e:?}"))
.map(CertificateDer::from)
})
}
}

fn parse_octet_string(data: &[u8]) -> Result<&[u8]> {
Expand Down
64 changes: 64 additions & 0 deletions revoke-test/tests/api/ffi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use core::ptr;
use std::ffi::CString;

use revoke_test::CertificateDetail;
use rustls_pki_types::CertificateDer;
use upki_ffi::{
upki_certificate_der, upki_check_revocation, upki_config, upki_config_free, upki_config_new,
upki_result,
};

use super::{TEST_CONFIG_PATH, TestResult};

pub(super) fn ffi(detail: &CertificateDetail) -> TestResult {
let certs = [detail.end_entity_cert_der().unwrap()]
.into_iter()
.chain(
detail
.intermediates_der()
.collect::<eyre::Result<Vec<CertificateDer<'static>>>>()
.unwrap(),
)
.collect::<Vec<_>>();

let mut cert_pointers = Vec::new();
for c in &certs {
cert_pointers.push(upki_certificate_der {
data: c.as_ptr(),
len: c.len(),
});
}

let mut config = OwnedConfig(ptr::null_mut());
assert!(matches!(
unsafe {
upki_config_new(
CString::new(TEST_CONFIG_PATH)
.unwrap()
.as_ptr(),
&mut config.0,
)
},
upki_result::UPKI_OK
));
let rc =
unsafe { upki_check_revocation(config.0, cert_pointers.as_ptr(), cert_pointers.len()) };

drop(certs); // extend lifetime for benefit of cert_pointers

match rc {
upki_result::UPKI_REVOCATION_REVOKED => TestResult::CorrectlyRevoked,
upki_result::UPKI_REVOCATION_NOT_COVERED | upki_result::UPKI_REVOCATION_NOT_REVOKED => {
TestResult::IncorrectlyNotRevoked
}
e => panic!("upki_check_revocation() failed with {:?}", e as usize),
}
}

struct OwnedConfig(*mut upki_config);

impl Drop for OwnedConfig {
fn drop(&mut self) {
unsafe { upki_config_free(self.0) };
}
}
36 changes: 18 additions & 18 deletions revoke-test/tests/system_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@ use std::process::{Command, Stdio};
use std::sync::Arc;
use std::time::SystemTime;

use base64::prelude::*;
use insta_cmd::get_cargo_bin;
use revoke_test::{CertificateDetail, RevocationTestSite, RevocationTestSites};
use rustls::client::danger::ServerCertVerifier;
use rustls::pki_types::{CertificateDer, ServerName, UnixTime};
use rustls::pki_types::{ServerName, UnixTime};
use rustls::{CertificateError, Error, RootCertStore};
use rustls_pki_types::CertificateDer;
use rustls_upki::{Policy, ServerVerifier};

#[path = "api/ffi.rs"]
mod ffi;

#[ignore]
#[test]
fn real_world_system_tests() {
Expand Down Expand Up @@ -46,6 +49,7 @@ fn real_world_system_tests() {
);

let high_level_cli = test_each_site(tests.sites.iter(), high_level_cli, "cli");
let ffi = test_each_site(tests.sites.iter(), ffi::ffi, "ffi");

let verifier = ServerVerifier::new(
Policy::default(),
Expand All @@ -59,38 +63,34 @@ fn real_world_system_tests() {

let rustls_results = test_each_site(tests.sites.iter(), verifier, "rustls");

for ((site, high), rustls) in tests
for (((site, high), rustls), ffi) in tests
.sites
.iter()
.zip(high_level_cli.iter())
.zip(rustls_results.iter())
.zip(ffi.iter())
{
assert!(
high == rustls || *high == rustls.expired_as_revoked(),
"site {site:?} revocation result disagrees between high-level API ({high:?}) and rustls verifier ({rustls:?})"
);
assert!(
high == ffi,
"site {site:?} revocation result disagrees between high-level API ({high:?}) and FFI API ({ffi:?})"
);
}
}

impl TestCase for ServerVerifier {
fn run(&self, detail: &CertificateDetail, test: &RevocationTestSite) -> TestResult {
// Decode certificates from base64
let end_entity = CertificateDer::from(
BASE64_STANDARD
.decode(&detail.end_entity_cert)
.expect("cannot decode end_entity_cert"),
);
let end_entity = detail
.end_entity_cert_der()
.expect("cannot decode end_entity_cert");
let intermediates = detail
.intermediates
.iter()
.map(|c| {
CertificateDer::from(
BASE64_STANDARD
.decode(c)
.expect("cannot decode issuer_cert"),
)
})
.collect::<Vec<_>>();
.intermediates_der()
.collect::<eyre::Result<Vec<CertificateDer<'static>>>>()
.expect("cannot decode issuer_cert");

let url = &test.test_website_revoked;
let host = url
Expand Down
4 changes: 1 addition & 3 deletions upki-ffi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ license.workspace = true
description = "C FFI bindings for upki"

[lib]
name = "upki"
crate-type = ["cdylib"]
doc = false # Can't document this and `upki` because they have the same name
crate-type = ["cdylib", "lib"]

[dependencies]
rustls-pki-types.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion upki-ffi/example/Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
LIBDIR = ../../target/release

upki-demo: upki-demo.c demo-certs.h
$(CC) -o $@ $< -I.. -L$(LIBDIR) -lupki -Wl,-rpath,$(LIBDIR)
$(CC) -o $@ $< -I.. -L$(LIBDIR) -lupki_ffi -Wl,-rpath,$(LIBDIR)

clean:
rm -f upki-demo
Loading