Skip to content

Commit 5a5f923

Browse files
committed
test: ✅ add client cert verification tests
1 parent 9ce0c68 commit 5a5f923

File tree

4 files changed

+65
-6
lines changed

4 files changed

+65
-6
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
# test-certs
44
A simple tool to generate a root certificate authority (CA), intermediate, client, and server certificates for testing purposes.
5+
This tool relies on [`rcgen`](https://docs.rs/rcgen/latest/rcgen/index.html) to generate x509 certificates.
56

67
> This tool is not intended for production use. Please use a dedicated certificate infrastructure!
78

test-certs/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ clap-stdin = "0.5"
2222

2323
[dev-dependencies]
2424
testdir = "0.9"
25+
rustls = "0.23"
2526

2627
[lints]
2728
workspace = true
28-

test-certs/src/configuration/certificates.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,25 @@ pub mod fixtures {
152152

153153
use super::*;
154154

155+
/// Provides a [`CertificateRoot`] with a root ca, an intermediate ca, and a client cert.
156+
pub fn ca_with_intermediate_and_client_certificate() -> CertificateRoot {
157+
let certs = CertificateRoot {
158+
certificates: HashMap::from([(
159+
"root-ca".to_string(),
160+
CertificateType::CertificateAuthority(CertificateAuthorityConfiguration {
161+
export_key: false,
162+
certificates: HashMap::from_iter([(
163+
"intermediate-ca".to_string(),
164+
ca_with_client_certificate_type(),
165+
)]),
166+
}),
167+
)]),
168+
};
169+
certs
170+
}
171+
155172
/// Provides a [`CertificateRoot`] with only one ca certificate.
156-
pub fn single_ca_certificate() -> CertificateRoot {
173+
pub fn ca_certificate() -> CertificateRoot {
157174
let certs = CertificateRoot {
158175
certificates: HashMap::from([(
159176
"ca".to_string(),
@@ -172,7 +189,7 @@ pub mod fixtures {
172189
}
173190

174191
/// Provides a [`CertificateRoot`] with only a client certificate.
175-
pub fn single_client_certificate() -> CertificateRoot {
192+
pub fn client_certificate() -> CertificateRoot {
176193
let certs = CertificateRoot {
177194
certificates: HashMap::from([("client".to_string(), client_certificate_type())]),
178195
};

test-certs/src/generation.rs

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,15 @@ fn certificate_params(
163163
mod tests {
164164
use std::net::{IpAddr, Ipv4Addr};
165165

166-
use crate::configuration::certificates::fixtures::{
167-
ca_certificate_type, client_certificate_type, server_certificate_type,
166+
use rustls::{RootCertStore, pki_types::UnixTime, server::WebPkiClientVerifier};
167+
168+
use crate::{
169+
configuration::certificates::fixtures::{
170+
ca_certificate_type, ca_with_client_certificates,
171+
ca_with_intermediate_and_client_certificate, client_certificate_type,
172+
server_certificate_type,
173+
},
174+
generate,
168175
};
169176

170177
use super::*;
@@ -220,5 +227,39 @@ mod tests {
220227
assert!(client_cert.issuer.is_none());
221228
}
222229

223-
// TODO: write test to check wether client/server certs are really issued by a ca
230+
#[test]
231+
fn should_verify_client_with_ca() {
232+
let root = ca_with_client_certificates();
233+
let mut certs = generate(&root).unwrap();
234+
let ca = certs.pop().unwrap();
235+
let client = certs.pop().unwrap();
236+
let mut roots = RootCertStore::empty();
237+
roots.add(ca.certificate.der().clone()).unwrap();
238+
239+
let client_verifier = WebPkiClientVerifier::builder(roots.into()).build().unwrap();
240+
let result =
241+
client_verifier.verify_client_cert(client.certificate.der(), &[], UnixTime::now());
242+
243+
assert!(result.is_ok());
244+
}
245+
246+
#[test]
247+
fn should_verify_client_with_intermediate_ca() {
248+
let root = ca_with_intermediate_and_client_certificate();
249+
let mut certs = generate(&root).unwrap();
250+
let root_ca = certs.pop().unwrap();
251+
let intermediate_ca = certs.pop().unwrap();
252+
let client = certs.pop().unwrap();
253+
let mut roots = RootCertStore::empty();
254+
roots.add(root_ca.certificate.der().clone()).unwrap();
255+
256+
let client_verifier = WebPkiClientVerifier::builder(roots.into()).build().unwrap();
257+
let result = client_verifier.verify_client_cert(
258+
client.certificate.der(),
259+
&[intermediate_ca.certificate.der().clone()],
260+
UnixTime::now(),
261+
);
262+
263+
assert!(result.is_ok());
264+
}
224265
}

0 commit comments

Comments
 (0)