File: better_tls.rs

package info (click to toggle)
rust-rustls-webpki-0.101 0.101.7-7
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,688 kB
  • sloc: python: 1,519; perl: 282; sh: 140; makefile: 17
file content (104 lines) | stat: -rw-r--r-- 3,108 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
use base64::{engine::general_purpose, Engine as _};
use serde::Deserialize;
use std::collections::HashMap;
use webpki::{KeyUsage, TrustAnchor};

#[test]
#[ignore]
pub fn path_building() {
    let raw_json = include_bytes!(concat!(env!("SOURCEPACKAGEDIR"),"/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 path_building_suite = better_tls
        .suites
        .get("pathbuilding")
        .unwrap_or_else(|| panic!("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_for_usage(
            &[&webpki::ECDSA_P256_SHA256], // All of the BetterTLS testcases use P256 keys.
            roots,
            intermediates,
            now,
            KeyUsage::server_auth(),
            &[],
        );

        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> {
        general_purpose::STANDARD
            .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| {
                general_purpose::STANDARD
                    .decode(cert)
                    .expect("invalid cert base64")
            })
            .collect()
    }
}

#[derive(Deserialize, Debug)]
#[serde(rename_all = "UPPERCASE")]
enum ExpectedResult {
    Accept,
    Reject,
}