certificate chain verification test

This commit is contained in:
Richard van der Hoff
2026-04-28 08:10:43 +01:00
parent 861e187d88
commit 8ad676f95e
7 changed files with 144 additions and 0 deletions

7
Cargo.lock generated
View File

@@ -7765,6 +7765,13 @@ dependencies = [
"zeroize",
]
[[package]]
name = "x509test"
version = "0.1.0"
dependencies = [
"rustls",
]
[[package]]
name = "xshell"
version = "0.2.2"

11
labs/x509test/Cargo.toml Normal file
View File

@@ -0,0 +1,11 @@
[package]
name = "x509test"
version = "0.1.0"
edition = "2024"
rust-version.workspace = true
[dependencies]
rustls = "^0.23.4"
[lints]
workspace = true

View File

Binary file not shown.

View File

@@ -0,0 +1,31 @@
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIUcP2Ij9JBq8IQfZT5dhNLsbPXYwowDQYJKoZIhvcNAQEL
BQAwRTELMAkGA1UEBhMCVUsxDzANBgNVBAgMBkxvbmRvbjETMBEGA1UECgwKZWxl
bWVudC5pbzEQMA4GA1UEAwwHdGVzdC1jYTAeFw0yNjA0MjcxMzIxMjdaFw0yNzA0
MjcxMzIxMjdaMEUxCzAJBgNVBAYTAlVLMQ8wDQYDVQQIDAZMb25kb24xEzARBgNV
BAoMCmVsZW1lbnQuaW8xEDAOBgNVBAMMB3Rlc3QtY2EwggIiMA0GCSqGSIb3DQEB
AQUAA4ICDwAwggIKAoICAQD3R1GuEpYIBXuZ47E4Cd6GNuaaUgF9ygRuy1dFgoqY
wRt564jkOYB6Ht5le4R/rb3u6fIeu9j4X2k7DNJPc4H5smHX3ih4BJ5Yli2pzG9S
iUj7dFY69bDA02c4DQP/gjVQddbBUEolPj5L5Ig3a++7zaPloegB/AQ+f9NTceI8
eehVQ2dWZlI45ltVlXPxUI5MFm3iSJ889ogX+OQMSouARm6/4d3VMTHpSkPPKpH0
vgFzn/96/C6yWKz7Fis8lM6MRqd8Ka5O5eZ0hAhVktPkUfgVZKpEsCYNVCBqJgOU
OU8FcMLinK9Zp0k8xZkTBXQbFXsKQNTa9/alX9wi2+c41O9d1MmhkYUwkdNh7OJO
//jbm7E5x//10bVgPB7eEqDUA/M/LzSZPmw/94lOcHRHBJyo0mcP74Bcg+tHydwD
xUe8gETLb7ctrlZ+HXMozoeZLeieR7knlHdFbUyufmpsrs/ONLzkPKqG4nqEjhCi
B+PZLFkRM08677FVDTmHWTN2ARAjhdOGWQBSkoD/0qlNJ3cmaqRl4uApPNRCnEKL
HDLwDNA1AH0Y5RmJX9vblfOdmGNEygpxLQmQ5IsQbJS47orupSNnDToP+IjGheOe
r5e8pWTzGO+ptO1a8GaSurrfWLk5D4wVNp+i0rCU1yBa/vCpaUjmSxEn2sG/SyKX
jQIDAQABo1MwUTAdBgNVHQ4EFgQU2F6Rmhfww1sT23VCfSE3mt8+lhEwHwYDVR0j
BBgwFoAU2F6Rmhfww1sT23VCfSE3mt8+lhEwDwYDVR0TAQH/BAUwAwEB/zANBgkq
hkiG9w0BAQsFAAOCAgEAJmUlRR7PrS5EXNy+fToAYkSt4xFlTfOeXN6JdQzCia+x
s5TFtqQe/giphQKLN/i9Mm3w0E0u8WA87TKlaWdrZrCivLEhwvieq0u3XwqY628z
8vlcqJuhM4Soe80AQiL51NeHp0WDhBTWnwCXF/e7GA4xryjg7zqhGZjY8+m61vSd
sLT/N05mSsW/m7ZAwxhe2XBVMXvHNTVuAbHX5+4mX9OXRAbnXg5Cexn1sKONsR1L
kN5VjSSvLmzX4AhV0oIRT23NfWBPJnq2s4S9DFDi2uYqE0BWUR1AZOagaVowFsJQ
q8ccwOQMdZZkAC3h2IIVNzYuFFeXkpZM6Bp7Js9IOJrDCL+A/UsndRkv9gX4SVgd
y9vQQBr5iaI5RTKkEiprnZhKOyBd3X/QpAoPRdhiGeImRpKt8vhF+JetGc2E1o+O
CSDpNjD6uI3SHSKt2mlOfeNoZms1pxY36gNYsytFGXf3qdb1I9cP4GRI6cz4JbmP
Y3eczjaqZMcOaPBBZlYz867C5sZi2tvqT75jlB+rVckKRIEl1bL4EZEpvRbK+nfJ
RFSPEY1fryCthLfa67ThB+IAonX4jU663sLoAQW1FEpJp3q08kKJOoCXlCMZ7g1P
eXmIj7ZEOIsufPdiYuKDp/aUdgUHmuCGyegfoCJze36SdFX5q6z8Aq5nKPtz+FM=
-----END CERTIFICATE-----

View File

@@ -0,0 +1,25 @@
-----BEGIN CERTIFICATE-----
MIIEKjCCAhKgAwIBAgIBADANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJVSzEP
MA0GA1UECAwGTG9uZG9uMRMwEQYDVQQKDAplbGVtZW50LmlvMRAwDgYDVQQDDAd0
ZXN0LWNhMB4XDTI2MDQyNzEzMzIzNVoXDTI3MDQyNzEzMzIzNVowKDEmMCQGCSqG
SIb3DQEJARYXdmRoLXg1MDl0ZXN0QG1hdHJpeC5vcmcwggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQCzMke0NO4fXtAnkvqqc9PHcf6tMAB7P7+xjWDTpKfJ
PHohC7IzTNR8u1+Oz76fCLq0bIWDbXS570YoA9hlj6UCH5a/+4NhsNYKTapbUVfq
LVk41oNKAFt7brKZ8tkvAG9GCSKztrc3xAG5+QmiEoVY1XSShz3WuD94LIp3me2R
doQcgSP3Gb6zIhpE8sI4MMRsyjU/k822SfiKOqrWKa+HuXTmNDC2UeCTj2++y0e4
s2IRrniOjM84Ci2mMhv/L6cpwwhyI1PsL28tGAX1NhEdVdrQxcOyhh3T9Q2er8J1
kJsfOEmLecNutiSi+mdYbY1pKc60St4KVBE89zAWIg/FAgMBAAGjQjBAMB0GA1Ud
DgQWBBQdCjaG9Xzjyxv9S7xlM1ryXhGyWTAfBgNVHSMEGDAWgBTYXpGaF/DDWxPb
dUJ9ITea3z6WETANBgkqhkiG9w0BAQsFAAOCAgEAhhIcWrFaAd4DuDlHHoqmL9rs
sLn3rx+v4Et+GRV0EjMIOX+tTPO3mUCUb8Ifvk8cC3fucoClKVG8snzIir4eUFOx
d6M7+GAoTLkh8V8XAre3Xo9O2vxB2V8m3IO8Sbnht9aWj9FeMB5Pb9yzTFr8GZPf
7jky+o9R9lrIrURprKBehStYTaNj5YIjYxDXwy+64yXyrckhA8vioFpUFz/CBQMz
B4DwEZRjtFNDxNKA/LcoSnTRfoTpclZIUtJ7YX/qC98QUleuNzpGHM3/59Tn7lzt
ykuWvCAFc3f1nELrEe2ffhCs5M9HNBtGJZ21iEK4LaIu4PBgRTuXDXfsZpC02VKi
s8S9G+er9IUyLpJ1dajY2jXhJuUvmcFLltlzUPYocWcQVVFFAkrrHnew5NzZUPOD
+LQYjNFszITmFc6V49Df23d/kDK+4QzpdtjEf+hjWdDtUDLsAvc48RylwoSIwxn+
3poImhlL5uqHuyQfQqnEVo/DrV44qi3Qv+cBzC+DQ0SQQJ89keWNTGGAVRggY6lX
iQOKT/LtaDO8mtCwY9GT5ZqjynCnLygdG+GgE7sBaRhoj5FFIaXHD83Gcwpv/JI6
giqgGwii4W8KvNkR/k1Z6C9+RvENbluqMRbQ3CXVNDbyU1MB6ZliRGTtbZvL0bd1
/F4LixSyyHVXMUn4/1Q=
-----END CERTIFICATE-----

28
labs/x509test/src/key.pem Normal file
View File

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCzMke0NO4fXtAn
kvqqc9PHcf6tMAB7P7+xjWDTpKfJPHohC7IzTNR8u1+Oz76fCLq0bIWDbXS570Yo
A9hlj6UCH5a/+4NhsNYKTapbUVfqLVk41oNKAFt7brKZ8tkvAG9GCSKztrc3xAG5
+QmiEoVY1XSShz3WuD94LIp3me2RdoQcgSP3Gb6zIhpE8sI4MMRsyjU/k822SfiK
OqrWKa+HuXTmNDC2UeCTj2++y0e4s2IRrniOjM84Ci2mMhv/L6cpwwhyI1PsL28t
GAX1NhEdVdrQxcOyhh3T9Q2er8J1kJsfOEmLecNutiSi+mdYbY1pKc60St4KVBE8
9zAWIg/FAgMBAAECggEADkeBFpIVMONsRjWxyygPBdib87mx1XW/VRWv/o14tVIg
D/Fk/NjazH8IiVJynSz5O8FeDkVdmidqpBZSWx123P7JaM5Q/4Azk39G259VbcVj
/mHRn8b8LeTPT0czw/QOlI/LzR2lPJ4I3oSYHkBy5yDzThiAIVPDSFSRoCA1oclO
oD/PiXADtfa3vkHTswmnT8JTZP7Dpe1zl5AZALQSFVZyQJ4oFxKqJMWc6LsYpHQ3
AqAAHk7VFyJQGsFZ+D1EgXv3Tzh8YB1nfhjvAucj8VPP9gbDzf4uHEp8FJEHCEAb
lJcEyWNNcpLhSl5T6oY9hjnIkDrxEITdUts+jMRHLQKBgQDrL9ivhSZMZbytU5sv
20JTBFYpgK4TFHeaWnsOwO53AsPTFsl2s6cQ18UNbWIdxn2E7AiTqPVO++E6etNc
HUo76gR9/0gNXILNysQAP0Wzkwtz4c0pXx6pa4zZTihvIcwO0Q6NRAB4sOk+XgDP
Pu79nUSaO8O+d8EUOb+9P2gAZwKBgQDDDfhq12ElgUmhDW92iuD2LwDGg22U4qNQ
0dMXju268TPwx1dYYi/f2yzp/Tn4xKlIo9NZNOzf6GW0+cnOjzyGKCzUglME6Pei
X2Hn8nSD4j60bRCIcf5VfFRAUm9j/y9F/hE5JX+XSM5DKrw09IqzMuu3+Z9TKxRg
dKNOTUQi8wKBgE+d8PLqVl7Cii77AKwgw8Eq1KhUIZnf8eVVABeshI3RZ82MB0Oh
6cqv4Mt83hxKV6+p3/Vs2y6T4llTvz2NxNWnkUG+K/wp9zYHkHas9MGn49ak+Dkr
NEwSVqox5UpJ3LSfXRfBj49MBInSdN+z5GAC33h/BvLxw3E/Y4ODdYe9AoGAaWju
XAbjOBqDiOay2vQ4mLJUD/PMz44fRjjuhCe4r7NUJ4YC3P/K8YYH4rf3kUnuVhQ6
zlW8wVBdTo1DEz7zLWkeuQVpChlAYl57kZbEgtVMn8LlEWfRU69p9IzYJ8kraf7g
nep25nHxDflVVqTlI+yb2IOtJ4v7ahj+e/1jmiMCgYBX57KyNSGew08r2ezjuV6f
wy/qfzJlieWhESZIckJcrDurfzR3xCj4n4xyC4GMTt3bGYs/rGTdkJGxJ6Bq4Ld2
foobh78qDEn1mFVwUuW2kzOJsIlN3FQFSKK3upVdRmzXTvaJN4MKRjwmu6KYIpxA
03GLFlPRHwxXrJAV+om1nQ==
-----END PRIVATE KEY-----

42
labs/x509test/src/main.rs Normal file
View File

@@ -0,0 +1,42 @@
use std::sync::Arc;
use rustls::{
RootCertStore,
pki_types::{CertificateDer, UnixTime, pem::PemObject},
server::WebPkiClientVerifier,
};
// TODO: how to load from a PKCS12 bundle? cms::encrypted_data, I think
const KEY_BUNDLE: &[u8] = include_bytes!("bundle.p12");
const CA_CERT: &[u8] = include_bytes!("cacert.pem");
const CERT_BUNDLE_PEM: &[u8] = include_bytes!("cert.pem");
const PRIVATE_KEY_PEM: &[u8] = include_bytes!("key.pem");
fn main() {
// Load the trusted root certificates into a verifier. These would come from
// local configuration.
let mut root_store = RootCertStore::empty();
for result in CertificateDer::pem_slice_iter(CA_CERT) {
root_store
.add(result.expect("Unable to parse certificate in root store"))
.expect("Unable to add certificate to root store");
}
let verifier = WebPkiClientVerifier::builder(Arc::new(root_store))
//.with_crls(...)
.build()
.unwrap();
// Verify the certificate chain presented by the device
let mut cert_iter = CertificateDer::pem_slice_iter(CERT_BUNDLE_PEM)
.map(|r| r.expect("Unable to parse cert in cert chain"));
let end_cert = cert_iter.next().expect("Empty certificate chain");
let intermediate_certs: Vec<_> = cert_iter.collect();
verifier
.verify_client_cert(&end_cert, intermediate_certs.as_ref(), UnixTime::now())
.expect("Unable to verify client certificate");
// TODO: verify that the end cert is valid for the user id in question
// TODO: verify a signature from the end cert
}