Skip to content

Commit 7de97ff

Browse files
committed
Add initial new_with_extra_roots testing
1 parent 1de6bb8 commit 7de97ff

File tree

4 files changed

+105
-10
lines changed

4 files changed

+105
-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: 83 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,74 @@ 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!(result.is_ok(), "failed to validate self-signed certificate");
167+
168+
#[cfg(not(target_vendor = "apple"))]
169+
assert!(
170+
result.is_err(),
171+
"self-signed certificate is accepted unexpectly"
172+
);
173+
174+
let result = verifier.verify_server_cert(
175+
&selfsigned_as_leaf,
176+
&[],
177+
&server_name,
178+
&[],
179+
verification_time(),
180+
);
181+
182+
#[cfg(not(target_os = "windows"))]
183+
assert!(
184+
result.is_ok(),
185+
"failed to validate self-signed leaf certificate"
186+
);
187+
188+
#[cfg(target_os = "windows")]
189+
assert!(
190+
result.is_err(),
191+
"self-signed leaf certificate is accepted unexpectly"
192+
);
193+
}
194+
195+
#[cfg(not(target_os = "android"))]
196+
#[test]
197+
fn test_chain_signed_with_extra_roots() {
198+
let crypto_provider = test_provider();
199+
200+
let server_name = pki_types::ServerName::try_from(EXAMPLE_COM).unwrap();
201+
let end_entity = CertificateDer::from(ROOT1_INT1_EXAMPLE_COM_GOOD);
202+
let intermediates = [CertificateDer::from(ROOT1_INT1)];
203+
let roots = vec![ROOT1];
204+
205+
let verifier = Verifier::new_with_extra_roots(roots, crypto_provider).unwrap();
206+
207+
verifier
208+
.verify_server_cert(
209+
&end_entity,
210+
&intermediates,
211+
&server_name,
212+
&[],
213+
verification_time(),
214+
)
215+
.expect("failed to validate extra root-only certificate chain");
216+
}
217+
142218
// Note: Android does not currently support IP address hosts, so these tests are disabled for
143219
// Android.
144220
// Verifies that our test trust anchor(s) are not trusted when `Verifier::new()`
@@ -349,10 +425,10 @@ fn test_with_mock_root<E: std::error::Error + PartialEq + 'static>(
349425
let mut chain = test_case
350426
.chain
351427
.iter()
352-
.map(|bytes| pki_types::CertificateDer::from(*bytes));
428+
.map(|bytes| CertificateDer::from(*bytes));
353429

354430
let end_entity = chain.next().unwrap();
355-
let intermediates: Vec<pki_types::CertificateDer<'_>> = chain.collect();
431+
let intermediates: Vec<CertificateDer<'_>> = chain.collect();
356432

357433
let server_name = pki_types::ServerName::try_from(test_case.reference_id).unwrap();
358434

476 Bytes
Binary file not shown.
441 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)