webpki/tests/better_tls.rs

96 lines
2.8 KiB
Rust

use serde::Deserialize;
use std::{collections::HashMap, convert::TryFrom};
use webpki::TrustAnchor;
#[test]
pub fn path_building() {
let raw_json = include_bytes!("../third-party/bettertls/pathbuilding.tests.json");
let better_tls: BetterTls = serde_json::from_slice(raw_json).expect("invalid test JSON");
println!("Testing BetterTLS revision {:?}", better_tls.revision);
let root_der = &better_tls.root_der();
let roots = &[TrustAnchor::try_from_cert_der(root_der).expect("invalid trust anchor")];
let trust_anchors = &webpki::TlsServerTrustAnchors(roots);
let path_building_suite = better_tls
.suites
.get("pathbuilding")
.expect("missing pathbuilding suite");
for testcase in &path_building_suite.test_cases {
println!("Testing path building test case {:?}", testcase.id);
let certs_der = testcase.certs_der();
let ee_der = &certs_der[0];
let intermediates = &certs_der[1..]
.iter()
.map(|cert| cert.as_slice())
.collect::<Vec<_>>();
let ee_cert =
webpki::EndEntityCert::try_from(ee_der.as_slice()).expect("invalid end entity cert");
// Set the time to the time of test case generation. This ensures that the test case
// certificates won't expire.
let now = webpki::Time::from_seconds_since_unix_epoch(1_688_651_734);
let result = ee_cert.verify_is_valid_tls_server_cert(
&[&webpki::ECDSA_P256_SHA256], // All of the BetterTLS testcases use P256 keys.
trust_anchors,
intermediates,
now,
);
match testcase.expected {
ExpectedResult::Accept => assert!(result.is_ok(), "expected success, got {:?}", result),
ExpectedResult::Reject => {
assert!(result.is_err(), "expected failure, got {:?}", result)
}
}
}
}
#[derive(Deserialize, Debug)]
struct BetterTls {
#[serde(rename(deserialize = "betterTlsRevision"))]
revision: String,
#[serde(rename(deserialize = "trustRoot"))]
root: String,
suites: HashMap<String, BetterTlsSuite>,
}
impl BetterTls {
fn root_der(&self) -> Vec<u8> {
base64::decode(&self.root).expect("invalid trust anchor base64")
}
}
#[derive(Deserialize, Debug)]
struct BetterTlsSuite {
#[serde(rename(deserialize = "testCases"))]
test_cases: Vec<BetterTlsTest>,
}
#[derive(Deserialize, Debug)]
struct BetterTlsTest {
id: u32,
certificates: Vec<String>,
expected: ExpectedResult,
}
impl BetterTlsTest {
fn certs_der(&self) -> Vec<Vec<u8>> {
self.certificates
.iter()
.map(|cert| base64::decode(cert).expect("invalid cert base64"))
.collect()
}
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "UPPERCASE")]
enum ExpectedResult {
Accept,
Reject,
}