Skip to content

Platform verifier: intermediate CA as root validation differs #199

@BiagioFesta

Description

@BiagioFesta

rustls_platform_verifier::Verifier seems to behave differently (Linux and Windows) when validating a certificate using intermediate CA as additional root.

The following (complete) example:

use rustls::client::danger::ServerCertVerifier;
use rustls_pemfile::certs;
use rustls_platform_verifier::Verifier;
use std::convert::TryInto;
use std::sync::Arc;

fn main() {
    const SERVER_NAME: &str = "localhost";

    let _ca = certs(&mut &*certs::CA.as_bytes()).next().unwrap().unwrap();

    let intermediate_ca = certs(&mut &*certs::INTERMEDIATE_CA.as_bytes())
        .next()
        .unwrap()
        .unwrap();

    let end_entity = certs(&mut &*certs::END_ENTITY.as_bytes())
        .next()
        .unwrap()
        .unwrap();

    let crypto_provider = Arc::new(rustls::crypto::aws_lc_rs::default_provider());
    let verifier = Verifier::new_with_extra_roots([intermediate_ca], crypto_provider).unwrap();

    let result = verifier.verify_server_cert(
        &end_entity,
        &[],
        &SERVER_NAME.try_into().unwrap(),
        &[],
        rustls::pki_types::UnixTime::now(),
    );

    println!("{result:?}");
}

// Root CA
//  └── Intermediate CA
//        └── End Entity (leaf)
mod certs {
    /*
    Certificate:
        Data:
            Version: 3 (0x2)
            Serial Number:
                09:d1:77:d6:93:69:aa:2c:8d:71:26:9a:e1:f9:7a:c9:9b:13:d1:35
            Signature Algorithm: sha256WithRSAEncryption
            Issuer: O = Test CA
            Validity
                Not Before: Nov  5 22:00:52 2025 GMT
                Not After : Nov  3 22:00:52 2035 GMT
            Subject: O = Test CA
            Subject Public Key Info:
                Public Key Algorithm: rsaEncryption
                    Public-Key: (2048 bit)
                    Modulus:
                     ...
                    Exponent: 65537 (0x10001)
            X509v3 extensions:
                X509v3 Basic Constraints:
                    CA:TRUE
                X509v3 Key Usage:
                    Certificate Sign, CRL Sign
                X509v3 Subject Key Identifier:
                    DF:85:A6:D3:9E:0B:87:F9:20:DE:6F:BD:A5:31:14:75:B8:74:EE:9A
        Signature Algorithm: sha256WithRSAEncryption
        Signature Value:
            ...
        */
    pub const CA: &str = r#"
-----BEGIN CERTIFICATE-----
MIIC7jCCAdagAwIBAgIUCdF31pNpqiyNcSaa4fl6yZsT0TUwDQYJKoZIhvcNAQEL
BQAwEjEQMA4GA1UECgwHVGVzdCBDQTAeFw0yNTExMDUyMjAwNTJaFw0zNTExMDMy
MjAwNTJaMBIxEDAOBgNVBAoMB1Rlc3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQC5R21mfIoskBDDcD54bNfwQX0rjQKl2WLFApl9PUFqbhSaNZFt
5j6J/hBRjlcT4VL0m5pDGcdgaSki3R7NF14qGVKITeLi5zqfjnElA9WDr2LVhRgH
Ng2jbwKVcv7r+D/+4CY5a5fGVSdhxDoH0eR0CPuXL9xfKj4wJCadRz4cZ1OZQdxg
WZ3N05SoOELldIfLBYCYhqMBCKnLrHkpgoSon/mXmkHh8m+qwE7+DhfYIeZw7EL6
E0qST4ip4qte4cPTju7Ni+qHBXyWgqJoztMrnpd88vo20IqEnKZlqIUz771QkKRw
M+XCjZQPj2TO4UxDn2RHxfyEtFW+H4I+SkFLAgMBAAGjPDA6MAwGA1UdEwQFMAMB
Af8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBTfhabTnguH+SDeb72lMRR1uHTumjAN
BgkqhkiG9w0BAQsFAAOCAQEAlU/TIYxzQnuqiEeRvJvn9mvI5UoxmX3/mAfL4YZH
sMISqdJ0kcaqhInFfjBiHCLdnhpCgmdnsNF6hDhk4F9SmRSPGtquj4+kBMM6wT8P
6lzDrYtAbtFWn/F3jr2u0NyhXFULP5845w4PH6qN4O89IgyUy+VW5JEstMH2e/X6
OTWCT2oKpQzxV2wh9aJq3P2tQ4mY/WjCOEhmzDJEDPhp7weiWwVmmUoAs5PS952N
nX3scG2uieIMgIc4eXTt5c6LUUDwginxTPEAHNJX37dxAsyVlDJdEdyji4FOqTUf
wAtypu1s8IN4WqeZJgdA+191as7VepHn+zH/zWn5fbGJmQ==
-----END CERTIFICATE-----
"#;

    /*
    Certificate:
        Data:
            Version: 3 (0x2)
            Serial Number:
                30:d8:da:85:5f:f7:3f:45:1e:c2:77:05:ea:05:10:1c:55:e8:6f:27
            Signature Algorithm: sha256WithRSAEncryption
            Issuer: O = Test CA
            Validity
                Not Before: Nov  5 22:01:13 2025 GMT
                Not After : Nov  3 22:01:13 2035 GMT
            Subject: O = Test Intermediate CA
            Subject Public Key Info:
                Public Key Algorithm: rsaEncryption
                    Public-Key: (2048 bit)
                    Modulus:
                      ...
                    Exponent: 65537 (0x10001)
            X509v3 extensions:
                X509v3 Basic Constraints:
                    CA:TRUE, pathlen:0
                X509v3 Key Usage:
                    Certificate Sign, CRL Sign
                X509v3 Subject Key Identifier:
                    BD:13:36:DE:54:D9:6F:15:B6:63:84:74:96:43:1A:9A:42:2D:6A:55
                X509v3 Authority Key Identifier:
                    DF:85:A6:D3:9E:0B:87:F9:20:DE:6F:BD:A5:31:14:75:B8:74:EE:9A
        Signature Algorithm: sha256WithRSAEncryption
        Signature Value:
           ...
        */
    pub const INTERMEDIATE_CA: &str = r#"
-----BEGIN CERTIFICATE-----
MIIDHzCCAgegAwIBAgIUMNjahV/3P0UewncF6gUQHFXobycwDQYJKoZIhvcNAQEL
BQAwEjEQMA4GA1UECgwHVGVzdCBDQTAeFw0yNTExMDUyMjAxMTNaFw0zNTExMDMy
MjAxMTNaMB8xHTAbBgNVBAoMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIIBIjANBgkq
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqyAjU9btfM0tfMCFVTwLzU//j0JCesOu
ZUzC/UUBiTmRCQ8XcxfBlm+fTumLhd458OjAQFRpfYvp6DpBw6FD37/EXNS/2G6h
4NGWuN80VU2xpskM+I2rxIBsQDtR+8Mz1BBuZOVIwxbmn7My4cxXkJnSPjt+skeb
0EP1t849LHwwj7l3lTESjRXDJO1WrVhr8iifH796bDmdJt2KTOI3WNgK5gVML+4O
pwuTInNknCJpYk6KxZIetqi2OM6mE/cG9qlUvqXum6v5UbxUycofVpM4oYI1grbZ
fH0KrFqTgEWI7Ur23875pkCtyxHTNlaszAcI4py2L85X7D0oSFFZdwIDAQABo2Aw
XjAPBgNVHRMECDAGAQH/AgEAMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUvRM23lTZ
bxW2Y4R0lkMamkItalUwHwYDVR0jBBgwFoAU34Wm054Lh/kg3m+9pTEUdbh07pow
DQYJKoZIhvcNAQELBQADggEBAE+KKVg+ghESClloEmynehEorRnU0e340I5k6QWd
rj1Jrq8sd09zgImrbk2lxyup3pr+q0ii5h6mMQkAZhiVc9WrcA5i8/g9fQtnP+xa
vjWV0sIZK5wte4FAzLZo8jqBQ7CHuR88f3oDV2JXCpxX/gTgaGnZuZJZ/N2g+2Lh
GAZkO7iCDjXU2UZr6hVoUTtjp11qhR1k53zCeuK1KyEbOqh7OmiZJGVQnzVVje8X
6E2E9ewy0qbfJ1EIUlaoAd6t79GSVBGDTKfQqk5VhvRu6mPoRVyNlFvhymX7bHIz
OAEzJqwyKPcU65wRjkvVL5p66uy8sFIVh8zUtCyrjKSNRr0=
-----END CERTIFICATE-----
"#;

    /*
    Certificate:
        Data:
            Version: 3 (0x2)
            Serial Number:
                4d:28:d3:c0:20:72:35:aa:58:d0:01:67:69:67:aa:35:1e:32:9b:3c
            Signature Algorithm: sha256WithRSAEncryption
            Issuer: O = Test Intermediate CA
            Validity
                Not Before: Nov  5 22:01:30 2025 GMT
                Not After : Nov  3 22:01:30 2035 GMT
            Subject: O = Test End Entity
            Subject Public Key Info:
                Public Key Algorithm: rsaEncryption
                    Public-Key: (2048 bit)
                    Modulus:
                      ...
                    Exponent: 65537 (0x10001)
            X509v3 extensions:
                X509v3 Basic Constraints:
                    CA:FALSE
                X509v3 Key Usage:
                    Digital Signature, Key Encipherment
                X509v3 Subject Alternative Name:
                    DNS:localhost
                X509v3 Subject Key Identifier:
                    5D:04:B7:61:BF:68:F6:8B:EB:7D:23:C4:29:34:38:57:2E:85:EC:E4
                X509v3 Authority Key Identifier:
                    BD:13:36:DE:54:D9:6F:15:B6:63:84:74:96:43:1A:9A:42:2D:6A:55
        Signature Algorithm: sha256WithRSAEncryption
        Signature Value:
           ...
        */
    pub const END_ENTITY: &str = r#"
-----BEGIN CERTIFICATE-----
MIIDNzCCAh+gAwIBAgIUTSjTwCByNapY0AFnaWeqNR4ymzwwDQYJKoZIhvcNAQEL
BQAwHzEdMBsGA1UECgwUVGVzdCBJbnRlcm1lZGlhdGUgQ0EwHhcNMjUxMTA1MjIw
MTMwWhcNMzUxMTAzMjIwMTMwWjAaMRgwFgYDVQQKDA9UZXN0IEVuZCBFbnRpdHkw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCQX4W9OcE7xaR6ff21H8Ib
Cb2rLQcUckrMO/8Zihu0Xs9wLt9umkcwUrnJSl2By7X9u9RdRnwvkMfx17SbAlW6
KBCMIAi2SX2/xdlI/aGAaKV/q+36K3aSZPWn8fiMqAkVzaDjKtavXYs0+3jt7Sxo
oyZZnyfO0lbPOm7LBU3XiRXxBNvajclEaOINEp8wqa3fTwZXP33JZJp72Z3mdqQR
dPsiTH+BiEBavftzRscz6hjMKn5odnab05SfOqBOP502CD31wgtu6bK1vJFbfcra
U/gWE0Kph14Pbv8jPXWB3HnqkWuBx5Z8EwwefSJX+5BU8MbUIRDsuHoz726gFV/J
AgMBAAGjcDBuMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgWgMBQGA1UdEQQNMAuCCWxv
Y2FsaG9zdDAdBgNVHQ4EFgQUXQS3Yb9o9ovrfSPEKTQ4Vy6F7OQwHwYDVR0jBBgw
FoAUvRM23lTZbxW2Y4R0lkMamkItalUwDQYJKoZIhvcNAQELBQADggEBAIgZo25S
r2wvzMmNrcZtUT94mZW9cO9AyE41vtmNh52f1lfyvbxv6D+OxSTktGxXwj4ePsE/
IAqg7BJwei20um9tHxqOoZ+sgqW/Amy69lHs5oWPlwraqqrlNmNDa8c8raFlqLuV
M8aVa8PuSBHA44v7r3XnojREc3UXkflghHYui0RoIMKIXmRQ501snyP/vQsCnVMR
4kpGzt56KWzjiSHp0vpk3U2Go/i7OL2qq+5eVh1GxJI79wrUjJjU0h3Xy5zgQYnA
tvJsFJD9XLK4x3dOtWaJ2zk2YHU5KsNZU4aJIgpVaUHatR67QRjxwljIM398TqJ4
yILLPjcRUaQB1ZU=
-----END CERTIFICATE-----
"#;
}
$ cargo add rustls && cargo add rustls_platform_verifier && cargo add rustls_pemfile && cargo run

Linux Output

Ok(ServerCertVerified(()))

Windows Output

Err(InvalidCertificate(UnknownIssuer))

Question

  • Is this behavior expected?

Metadata

Metadata

Assignees

No one assigned

    Labels

    O-WindowsWork related to the Windows verifier implementationdiscussion

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions