Skip to content

Commit 4e0db54

Browse files
committed
Add initial new_with_extra_roots testing
1 parent 2a1affd commit 4e0db54

File tree

4 files changed

+108
-10
lines changed

4 files changed

+108
-10
lines changed

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

Lines changed: 22 additions & 3 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, "", true)
7373
if err != nil {
7474
return err
7575
}
@@ -96,6 +96,16 @@ func doIt() error {
9696
}
9797
}
9898

99+
_, err = generateRoot("root2", now, "example.com", true)
100+
if err != nil {
101+
return err
102+
}
103+
104+
_, err = generateRoot("root3", now, "example.com", false)
105+
if err != nil {
106+
return err
107+
}
108+
99109
return nil
100110
}
101111

@@ -210,23 +220,32 @@ func generateInt(intName string, serial int64, now time.Time, caKey crypto.Signe
210220
return intKey, nil
211221
}
212222

213-
func generateRoot(name string, now time.Time) (crypto.Signer, error) {
223+
func generateRoot(name string, now time.Time, commonName string, IsCA bool) (crypto.Signer, error) {
214224
caKey, err := generateKey()
215225
if err != nil {
216226
return nil, err
217227
}
228+
218229
template := x509.Certificate{
219230
SerialNumber: big.NewInt(1),
220231
Subject: pkix.Name{
221232
Organization: []string{name},
222233
},
223234
NotBefore: now.Add(-OneDay),
224235
NotAfter: now.Add(OneYear),
225-
IsCA: true,
236+
IsCA: IsCA,
226237
KeyUsage: x509.KeyUsageCertSign,
227238
BasicConstraintsValid: true,
228239
}
229240

241+
if len(commonName) != 0 {
242+
template.Subject.CommonName = commonName
243+
template.KeyUsage = 0
244+
// See `generateEndEntity` for list of macOS requirements.
245+
template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}
246+
template.DNSNames = []string{commonName}
247+
}
248+
230249
cert, err := x509.CreateCertificate(rand.Reader, &template, &template, caKey.Public(), caKey)
231250
if err != nil {
232251
return nil, err

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

Lines changed: 86 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,21 @@ 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(target_os = "android"))]
92+
const ROOT2: CertificateDer = CertificateDer::from_slice(include_bytes!("root2.crt"));
93+
94+
#[cfg_attr(feature = "ffi-testing", allow(unused))]
95+
#[cfg(not(target_os = "android"))]
96+
const ROOT3: CertificateDer = CertificateDer::from_slice(include_bytes!("root3.crt"));
97+
9098
const EXAMPLE_COM: &str = "example.com";
9199
const LOCALHOST_IPV4: &str = "127.0.0.1";
92100
const LOCALHOST_IPV6: &str = "::1";
@@ -111,8 +119,8 @@ pub(super) fn verification_without_mock_root() {
111119
let verifier = Verifier::new(crypto_provider).unwrap();
112120

113121
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)];
122+
let end_entity = CertificateDer::from(ROOT1_INT1_EXAMPLE_COM_GOOD);
123+
let intermediates = [CertificateDer::from(ROOT1_INT1)];
116124

117125
// Fails because the server cert has no trust root in Windows, and can't since it uses a self-signed CA.
118126
// Similarly on UNIX platforms using the Webpki verifier, it can't fetch extra certificates through
@@ -139,6 +147,77 @@ fn test_verification_without_mock_root() {
139147
verification_without_mock_root()
140148
}
141149

150+
#[cfg(not(target_os = "android"))]
151+
#[test]
152+
fn test_selfsigned_cert_with_extra_roots() {
153+
let crypto_provider = test_provider();
154+
155+
let selfsigned = ROOT2;
156+
let selfsigned_as_leaf = ROOT3;
157+
let roots = vec![selfsigned.clone(), selfsigned_as_leaf.clone()];
158+
let server_name = pki_types::ServerName::try_from(EXAMPLE_COM).unwrap();
159+
160+
let verifier = Verifier::new_with_extra_roots(roots, crypto_provider).unwrap();
161+
162+
let result =
163+
verifier.verify_server_cert(&selfsigned, &[], &server_name, &[], verification_time());
164+
165+
#[cfg(target_vendor = "apple")]
166+
assert!(
167+
result.is_ok(),
168+
"failed to validate self-signed ca certificate"
169+
);
170+
171+
#[cfg(not(target_vendor = "apple"))]
172+
assert!(
173+
result.is_err(),
174+
"self-signed ca certificate is accepted unexpectly"
175+
);
176+
177+
let result = verifier.verify_server_cert(
178+
&selfsigned_as_leaf,
179+
&[],
180+
&server_name,
181+
&[],
182+
verification_time(),
183+
);
184+
185+
#[cfg(not(target_os = "windows"))]
186+
assert!(
187+
result.is_ok(),
188+
"failed to validate self-signed leaf certificate"
189+
);
190+
191+
#[cfg(target_os = "windows")]
192+
assert!(
193+
result.is_err(),
194+
"self-signed leaf certificate is accepted unexpectly"
195+
);
196+
}
197+
198+
#[cfg(not(target_os = "android"))]
199+
#[test]
200+
fn test_chain_signed_with_extra_roots() {
201+
let crypto_provider = test_provider();
202+
203+
let server_name = pki_types::ServerName::try_from(EXAMPLE_COM).unwrap();
204+
let end_entity = CertificateDer::from(ROOT1_INT1_EXAMPLE_COM_GOOD);
205+
let intermediates = [CertificateDer::from(ROOT1_INT1)];
206+
let roots = vec![ROOT1];
207+
208+
let verifier = Verifier::new_with_extra_roots(roots, crypto_provider).unwrap();
209+
210+
verifier
211+
.verify_server_cert(
212+
&end_entity,
213+
&intermediates,
214+
&server_name,
215+
&[],
216+
verification_time(),
217+
)
218+
.expect("failed to validate extra root-only certificate chain");
219+
}
220+
142221
// Note: Android does not currently support IP address hosts, so these tests are disabled for
143222
// Android.
144223
// Verifies that our test trust anchor(s) are not trusted when `Verifier::new()`
@@ -349,10 +428,10 @@ fn test_with_mock_root<E: std::error::Error + PartialEq + 'static>(
349428
let mut chain = test_case
350429
.chain
351430
.iter()
352-
.map(|bytes| pki_types::CertificateDer::from(*bytes));
431+
.map(|bytes| CertificateDer::from(*bytes));
353432

354433
let end_entity = chain.next().unwrap();
355-
let intermediates: Vec<pki_types::CertificateDer<'_>> = chain.collect();
434+
let intermediates: Vec<CertificateDer<'_>> = chain.collect();
356435

357436
let server_name = pki_types::ServerName::try_from(test_case.reference_id).unwrap();
358437

474 Bytes
Binary file not shown.
442 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)