Skip to content

Commit 8ff7f21

Browse files
committed
Add initial new_with_extra_roots testing
1 parent f357528 commit 8ff7f21

File tree

3 files changed

+66
-9
lines changed

3 files changed

+66
-9
lines changed

rustls-platform-verifier/src/tests/verification_mock/ca.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ func doIt() error {
6969

7070
var err error = nil
7171

72-
root1_key, err := generateRoot("root1", now)
72+
root1_key, err := generateRoot("root1", now, "")
7373
if err != nil {
7474
return err
7575
}
@@ -96,6 +96,11 @@ func doIt() error {
9696
}
9797
}
9898

99+
_, err = generateRoot("root2", now, "example.com")
100+
if err != nil {
101+
return err
102+
}
103+
99104
return nil
100105
}
101106

@@ -210,11 +215,12 @@ func generateInt(intName string, serial int64, now time.Time, caKey crypto.Signe
210215
return intKey, nil
211216
}
212217

213-
func generateRoot(name string, now time.Time) (crypto.Signer, error) {
218+
func generateRoot(name string, now time.Time, commonName string) (crypto.Signer, error) {
214219
caKey, err := generateKey()
215220
if err != nil {
216221
return nil, err
217222
}
223+
218224
template := x509.Certificate{
219225
SerialNumber: big.NewInt(1),
220226
Subject: pkix.Name{
@@ -227,6 +233,14 @@ func generateRoot(name string, now time.Time) (crypto.Signer, error) {
227233
BasicConstraintsValid: true,
228234
}
229235

236+
if len(commonName) != 0 {
237+
template.Subject.CommonName = commonName
238+
template.KeyUsage = 0
239+
// See `generateEndEntity` for list of macOS requirements.
240+
template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}
241+
template.DNSNames = []string{commonName}
242+
}
243+
230244
cert, err := x509.CreateCertificate(rand.Reader, &template, &template, caKey.Public(), caKey)
231245
if err != nil {
232246
return nil, err

rustls-platform-verifier/src/tests/verification_mock/mod.rs

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use std::net::{Ipv4Addr, Ipv6Addr};
2828
use std::sync::Arc;
2929

3030
use rustls::client::danger::ServerCertVerifier;
31-
use rustls::pki_types;
31+
use rustls::pki_types::{self, CertificateDer};
3232
#[cfg(not(any(target_vendor = "apple", windows)))]
3333
use rustls::pki_types::{DnsName, ServerName};
3434
use rustls::{CertificateError, Error as TlsError, OtherError};
@@ -80,13 +80,17 @@ macro_rules! no_error {
8080
};
8181
}
8282

83-
const ROOT1: pki_types::CertificateDer<'static> =
84-
pki_types::CertificateDer::from_slice(include_bytes!("root1.crt"));
83+
const ROOT1: CertificateDer = CertificateDer::from_slice(include_bytes!("root1.crt"));
8584
const ROOT1_INT1: &[u8] = include_bytes!("root1-int1.crt");
8685
const ROOT1_INT1_EXAMPLE_COM_GOOD: &[u8] = include_bytes!("root1-int1-ee_example.com-good.crt");
8786
const ROOT1_INT1_LOCALHOST_IPV4_GOOD: &[u8] = include_bytes!("root1-int1-ee_127.0.0.1-good.crt");
8887
const ROOT1_INT1_LOCALHOST_IPV6_GOOD: &[u8] = include_bytes!("root1-int1-ee_1-good.crt");
8988

89+
// `ffi-testing` is currently only used for Android, which doesn't support extra roots yet.
90+
#[cfg_attr(feature = "ffi-testing", allow(unused))]
91+
#[cfg(not(any(target_os = "android", target_os = "windows")))]
92+
const ROOT2: CertificateDer = CertificateDer::from_slice(include_bytes!("root2.crt"));
93+
9094
const EXAMPLE_COM: &str = "example.com";
9195
const LOCALHOST_IPV4: &str = "127.0.0.1";
9296
const LOCALHOST_IPV6: &str = "::1";
@@ -111,8 +115,8 @@ pub(super) fn verification_without_mock_root() {
111115
let verifier = Verifier::new(crypto_provider).unwrap();
112116

113117
let server_name = pki_types::ServerName::try_from(EXAMPLE_COM).unwrap();
114-
let end_entity = pki_types::CertificateDer::from(ROOT1_INT1_EXAMPLE_COM_GOOD);
115-
let intermediates = [pki_types::CertificateDer::from(ROOT1_INT1)];
118+
let end_entity = CertificateDer::from(ROOT1_INT1_EXAMPLE_COM_GOOD);
119+
let intermediates = [CertificateDer::from(ROOT1_INT1)];
116120

117121
// Fails because the server cert has no trust root in Windows, and can't since it uses a self-signed CA.
118122
// Similarly on UNIX platforms using the Webpki verifier, it can't fetch extra certificates through
@@ -139,6 +143,45 @@ fn test_verification_without_mock_root() {
139143
verification_without_mock_root()
140144
}
141145

146+
#[cfg(not(any(target_os = "android", target_os = "windows")))]
147+
#[test]
148+
fn test_selfsigned_cert_with_extra_roots() {
149+
let crypto_provider = test_provider();
150+
151+
let selfsigned = ROOT2;
152+
let roots = vec![selfsigned.clone()];
153+
let server_name = pki_types::ServerName::try_from(EXAMPLE_COM).unwrap();
154+
155+
let verifier = Verifier::new_with_extra_roots(roots, crypto_provider).unwrap();
156+
157+
verifier
158+
.verify_server_cert(&selfsigned, &[], &server_name, &[], verification_time())
159+
.expect("failed to validate singular extra root certificate chain");
160+
}
161+
162+
#[cfg(not(target_os = "android"))]
163+
#[test]
164+
fn test_chain_signed_with_extra_roots() {
165+
let crypto_provider = test_provider();
166+
167+
let server_name = pki_types::ServerName::try_from(EXAMPLE_COM).unwrap();
168+
let end_entity = CertificateDer::from(ROOT1_INT1_EXAMPLE_COM_GOOD);
169+
let intermediates = [CertificateDer::from(ROOT1_INT1)];
170+
let roots = vec![ROOT1];
171+
172+
let verifier = Verifier::new_with_extra_roots(roots, crypto_provider).unwrap();
173+
174+
verifier
175+
.verify_server_cert(
176+
&end_entity,
177+
&intermediates,
178+
&server_name,
179+
&[],
180+
verification_time(),
181+
)
182+
.expect("failed to validate extra root-only certificate chain");
183+
}
184+
142185
// Note: Android does not currently support IP address hosts, so these tests are disabled for
143186
// Android.
144187
// Verifies that our test trust anchor(s) are not trusted when `Verifier::new()`
@@ -349,10 +392,10 @@ fn test_with_mock_root<E: std::error::Error + PartialEq + 'static>(
349392
let mut chain = test_case
350393
.chain
351394
.iter()
352-
.map(|bytes| pki_types::CertificateDer::from(*bytes));
395+
.map(|bytes| CertificateDer::from(*bytes));
353396

354397
let end_entity = chain.next().unwrap();
355-
let intermediates: Vec<pki_types::CertificateDer<'_>> = chain.collect();
398+
let intermediates: Vec<CertificateDer<'_>> = chain.collect();
356399

357400
let server_name = pki_types::ServerName::try_from(test_case.reference_id).unwrap();
358401

475 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)