-
Notifications
You must be signed in to change notification settings - Fork 714
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: add rust well-known-endpoint tests (#4884)
- Loading branch information
Showing
10 changed files
with
326 additions
and
152 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#[cfg(all(feature = "network-tests", test))] | ||
mod network; | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use s2n_tls::{ | ||
security::Policy, | ||
testing::{self, TestPair}, | ||
}; | ||
|
||
/// This test provides a helpful debug message if the PQ feature is incorrectly | ||
/// configured. | ||
#[cfg(feature = "pq")] | ||
#[test] | ||
fn pq_sanity_check() -> Result<(), Box<dyn std::error::Error>> { | ||
let config = testing::build_config(&Policy::from_version("KMS-PQ-TLS-1-0-2020-07")?)?; | ||
let mut pair = TestPair::from_config(&config); | ||
pair.handshake()?; | ||
|
||
if pair.client.kem_name().is_none() { | ||
panic!( | ||
"PQ tests are enabled, but PQ functionality is unavailable. \ | ||
Are you sure that the libcrypto supports PQ?" | ||
); | ||
} | ||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
use bytes::Bytes; | ||
use http::{Response, StatusCode, Uri}; | ||
use http_body_util::{BodyExt, Empty}; | ||
use hyper::body::Incoming; | ||
use hyper_util::{client::legacy::Client, rt::TokioExecutor}; | ||
use s2n_tls::{ | ||
config::Config, | ||
security::{self, Policy}, | ||
}; | ||
use s2n_tls_hyper::connector::HttpsConnector; | ||
use std::str::FromStr; | ||
|
||
#[derive(Debug)] | ||
struct TestCase { | ||
pub query_target: &'static str, | ||
pub expected_status_code: u16, | ||
} | ||
|
||
impl TestCase { | ||
const fn new(domain: &'static str, expected_status_code: u16) -> Self { | ||
TestCase { | ||
query_target: domain, | ||
expected_status_code, | ||
} | ||
} | ||
} | ||
|
||
const TEST_CASES: &[TestCase] = &[ | ||
// this is a link to the s2n-tls unit test coverage report, hosted on cloudfront | ||
TestCase::new("https://dx1inn44oyl7n.cloudfront.net/main/index.html", 200), | ||
// this is a link to a non-existent S3 item | ||
TestCase::new("https://notmybucket.s3.amazonaws.com/folder/afile.jpg", 403), | ||
TestCase::new("https://www.amazon.com", 200), | ||
TestCase::new("https://www.apple.com", 200), | ||
TestCase::new("https://www.att.com", 200), | ||
TestCase::new("https://www.cloudflare.com", 200), | ||
TestCase::new("https://www.ebay.com", 200), | ||
TestCase::new("https://www.google.com", 200), | ||
TestCase::new("https://www.mozilla.org", 200), | ||
TestCase::new("https://www.netflix.com", 200), | ||
TestCase::new("https://www.openssl.org", 200), | ||
TestCase::new("https://www.t-mobile.com", 200), | ||
TestCase::new("https://www.verizon.com", 200), | ||
TestCase::new("https://www.wikipedia.org", 200), | ||
TestCase::new("https://www.yahoo.com", 200), | ||
TestCase::new("https://www.youtube.com", 200), | ||
TestCase::new("https://www.github.com", 301), | ||
TestCase::new("https://www.samsung.com", 301), | ||
TestCase::new("https://www.twitter.com", 301), | ||
TestCase::new("https://www.facebook.com", 302), | ||
TestCase::new("https://www.microsoft.com", 302), | ||
TestCase::new("https://www.ibm.com", 303), | ||
TestCase::new("https://www.f5.com", 403), | ||
]; | ||
|
||
/// perform an HTTP GET request against `uri` using an s2n-tls config with | ||
/// `security_policy`. | ||
async fn https_get( | ||
uri: &str, | ||
security_policy: &Policy, | ||
) -> Result<Response<Incoming>, hyper_util::client::legacy::Error> { | ||
let mut config = Config::builder(); | ||
config.set_security_policy(security_policy).unwrap(); | ||
|
||
let connector = HttpsConnector::new(config.build().unwrap()); | ||
let client: Client<_, Empty<Bytes>> = Client::builder(TokioExecutor::new()).build(connector); | ||
|
||
let uri = Uri::from_str(uri).unwrap(); | ||
client.get(uri).await | ||
} | ||
|
||
/// Ensure that s2n-tls is compatible with other http/TLS implementations. | ||
/// | ||
/// This test uses s2n-tls-hyper to make http requests over a TLS connection to | ||
/// a number of well known http sites. | ||
#[test_log::test(tokio::test)] | ||
async fn http_get_test() -> Result<(), Box<dyn std::error::Error>> { | ||
for test_case in TEST_CASES { | ||
for policy in [security::DEFAULT, security::DEFAULT_TLS13] { | ||
tracing::info!("executing test case {:#?} with {:?}", test_case, policy); | ||
|
||
let response = https_get(test_case.query_target, &policy).await?; | ||
let expected_status = StatusCode::from_u16(test_case.expected_status_code).unwrap(); | ||
assert_eq!(response.status(), expected_status); | ||
|
||
if expected_status == StatusCode::OK { | ||
let body = response.into_body().collect().await?.to_bytes(); | ||
assert!(!body.is_empty()); | ||
} | ||
} | ||
} | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
mod https_client; | ||
mod tls_client; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
use s2n_tls::{config::Config, enums::Version, security::Policy}; | ||
use s2n_tls_tokio::{TlsConnector, TlsStream}; | ||
use tokio::net::TcpStream; | ||
|
||
/// Perform a TLS handshake with port 443 of `domain`. | ||
/// | ||
/// * `domain`: The domain to perform the handshake with | ||
/// * `security_policy`: The security policy to set on the handshaking client. | ||
/// | ||
/// Returns an open `TlsStream` if the handshake was successful, otherwise an | ||
/// `Err``. | ||
async fn handshake_with_domain( | ||
domain: &str, | ||
security_policy: &str, | ||
) -> Result<TlsStream<TcpStream>, Box<dyn std::error::Error>> { | ||
tracing::info!("querying {domain} with {security_policy}"); | ||
const PORT: u16 = 443; | ||
|
||
let mut config = Config::builder(); | ||
config.set_security_policy(&Policy::from_version(security_policy)?)?; | ||
|
||
let client = TlsConnector::new(config.build()?); | ||
// open the TCP stream | ||
let stream = TcpStream::connect((domain, PORT)).await?; | ||
// complete the TLS handshake | ||
Ok(client.connect(domain, stream).await?) | ||
} | ||
|
||
#[cfg(feature = "pq")] | ||
mod kms_pq { | ||
use super::*; | ||
|
||
const DOMAIN: &str = "kms.us-east-1.amazonaws.com"; | ||
|
||
// confirm that we successfully negotiate a supported PQ key exchange. | ||
// | ||
// Note: In the future KMS will deprecate kyber_r3 in favor of ML-KEM. | ||
// At that point this test should be updated with a security policy that | ||
// supports ML-KEM. | ||
#[test_log::test(tokio::test)] | ||
async fn pq_handshake() -> Result<(), Box<dyn std::error::Error>> { | ||
let tls = handshake_with_domain(DOMAIN, "KMS-PQ-TLS-1-0-2020-07").await?; | ||
|
||
assert_eq!( | ||
tls.as_ref().cipher_suite()?, | ||
"ECDHE-KYBER-RSA-AES256-GCM-SHA384" | ||
); | ||
assert_eq!(tls.as_ref().kem_name(), Some("kyber512r3")); | ||
|
||
Ok(()) | ||
} | ||
|
||
// We want to confirm that non-supported kyber drafts successfully fall | ||
// back to a full handshake. | ||
#[test_log::test(tokio::test)] | ||
async fn early_draft_falls_back_to_classical() -> Result<(), Box<dyn std::error::Error>> { | ||
const EARLY_DRAFT_PQ_POLICIES: &[&str] = &[ | ||
"KMS-PQ-TLS-1-0-2019-06", | ||
"PQ-SIKE-TEST-TLS-1-0-2019-11", | ||
"KMS-PQ-TLS-1-0-2020-02", | ||
"PQ-SIKE-TEST-TLS-1-0-2020-02", | ||
]; | ||
|
||
for security_policy in EARLY_DRAFT_PQ_POLICIES { | ||
let tls = handshake_with_domain(DOMAIN, security_policy).await?; | ||
|
||
assert_eq!(tls.as_ref().cipher_suite()?, "ECDHE-RSA-AES256-GCM-SHA384"); | ||
assert_eq!(tls.as_ref().kem_name(), None); | ||
} | ||
Ok(()) | ||
} | ||
} | ||
|
||
#[test_log::test(tokio::test)] | ||
async fn tls_client() -> Result<(), Box<dyn std::error::Error>> { | ||
// The akamai request should be in internet_https_client.rs but Akamai | ||
// http requests hang indefinitely. This behavior is also observed with | ||
// curl and chrome. https://github.com/aws/s2n-tls/issues/4883 | ||
const DOMAINS: &[&str] = &["www.akamai.com"]; | ||
|
||
for domain in DOMAINS { | ||
tracing::info!("querying {domain}"); | ||
|
||
let tls12 = handshake_with_domain(domain, "default").await?; | ||
assert_eq!(tls12.as_ref().actual_protocol_version()?, Version::TLS12); | ||
|
||
let tls13 = handshake_with_domain(domain, "default_tls13").await?; | ||
assert_eq!(tls13.as_ref().actual_protocol_version()?, Version::TLS13); | ||
} | ||
|
||
Ok(()) | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.