Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bettertls: test both pathbuilding and nameconstraints. #151

Merged
merged 1 commit into from
Aug 14, 2023
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.toml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ untrusted = "0.7.1"
[dev-dependencies]
base64 = "0.21"
bencher = "0.1.5"
bzip2 = "0.4.4"
once_cell = "1.17.2"
rcgen = { version = "0.11.1", default-features = false }
serde = { version = "1.0", features = ["derive"] }
Expand Down
88 changes: 66 additions & 22 deletions tests/better_tls.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,51 @@
#![cfg(feature = "ring")]

use std::collections::HashMap;
use std::fs::File;

use base64::{engine::general_purpose, Engine as _};
use bzip2::read::BzDecoder;
use serde::Deserialize;
use std::collections::HashMap;
use webpki::{KeyUsage, TrustAnchor};

use webpki::{KeyUsage, SubjectNameRef, 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);
fn better_tls() {
let better_tls = testdata();
let root_der = &better_tls.root_der();
let roots = &[TrustAnchor::try_from_cert_der(root_der).expect("invalid trust anchor")];

let suite = "pathbuilding";
run_testsuite(
suite,
better_tls
.suites
.get(suite)
.expect(&format!("missing {suite} suite")),
roots,
);
}

#[test]
fn name_constraints() {
let better_tls = testdata();
let root_der = &better_tls.root_der();
let roots = &[TrustAnchor::try_from_cert_der(root_der).expect("invalid trust anchor")];

let path_building_suite = better_tls
.suites
.get("pathbuilding")
.expect("missing pathbuilding suite");
let suite = "nameconstraints";
run_testsuite(
suite,
better_tls
.suites
.get(suite)
.expect(&format!("missing {suite} suite")),
roots,
);
}

for testcase in &path_building_suite.test_cases {
println!("Testing path building test case {:?}", testcase.id);
fn run_testsuite(suite_name: &str, suite: &BetterTlsSuite, roots: &[TrustAnchor]) {
for testcase in &suite.test_cases {
println!("Testing {suite_name} test case {}", testcase.id);

let certs_der = testcase.certs_der();
let ee_der = &certs_der[0];
Expand All @@ -34,16 +59,23 @@ pub fn path_building() {

// 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_for_usage(
&[webpki::ECDSA_P256_SHA256], // All of the BetterTLS testcases use P256 keys.
roots,
intermediates,
now,
KeyUsage::server_auth(),
None,
);
let now = webpki::Time::from_seconds_since_unix_epoch(1_691_788_832);

let result = ee_cert
.verify_for_usage(
&[webpki::ECDSA_P256_SHA256], // All of the BetterTLS testcases use P256 keys.
roots,
intermediates,
now,
KeyUsage::server_auth(),
None,
)
.and_then(|_| {
ee_cert.verify_is_valid_for_subject_name(
SubjectNameRef::try_from_ascii_str(&testcase.hostname)
.expect("invalid testcase hostname"),
)
});

match testcase.expected {
ExpectedResult::Accept => assert!(result.is_ok(), "expected success, got {:?}", result),
Expand All @@ -54,6 +86,17 @@ pub fn path_building() {
}
}

fn testdata() -> BetterTls {
let mut data_file = File::open("third-party/bettertls/bettertls.tests.json.bz2")
.expect("failed to open data file");
let decompressor = BzDecoder::new(&mut data_file);

let better_tls: BetterTls = serde_json::from_reader(decompressor).expect("invalid test JSON");
println!("Testing BetterTLS revision {:?}", better_tls.revision);

better_tls
}

#[derive(Deserialize, Debug)]
struct BetterTls {
#[serde(rename(deserialize = "betterTlsRevision"))]
Expand Down Expand Up @@ -81,6 +124,7 @@ struct BetterTlsSuite {
struct BetterTlsTest {
id: u32,
certificates: Vec<String>,
hostname: String,
expected: ExpectedResult,
}

Expand Down
14 changes: 10 additions & 4 deletions third-party/bettertls/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,20 @@ Generated using the Netflix [bettertls] project.

[bettertls]: https://github.com/Netflix/bettertls

## Pathbuilding
## Test Data

To regenerate pathbuilding test data:
To regenerate vendored test data:

1. Install Go
2. Generate the JSON testdata export for the path building suite:
2. Generate the JSON testdata export:

```bash
GOBIN=$PWD go install github.com/Netflix/bettertls/test-suites/cmd/bettertls@latest
./bettertls export-tests --suite pathbuilding --out ./pathbuilding.tests.json
./bettertls export-tests --out ./bettertls.tests.json
```

3. Bzip2 compress it:

```bash
bzip2 ./bettertls.tests.json
```
Binary file added third-party/bettertls/bettertls.tests.json.bz2
Binary file not shown.
1 change: 0 additions & 1 deletion third-party/bettertls/pathbuilding.tests.json

This file was deleted.