#![cfg(any(feature = "native-tls", feature = "rustls-tls"))]
extern crate os_type;
pub mod common;
use common::*;
use elasticsearch::cert::{Certificate, CertificateValidation};
use os_type::OSType;
static CA_CERT: &[u8] = include_bytes!("../../.ci/certs/ca.crt");
static CA_CHAIN_CERT: &[u8] = include_bytes!("../../.ci/certs/ca-chain.crt");
static TESTNODE_CERT: &[u8] = include_bytes!("../../.ci/certs/testnode.crt");
static TESTNODE_NO_SAN_CERT: &[u8] = include_bytes!("../../.ci/certs/testnode_no_san.crt");
fn expected_error_message() -> String {
if cfg!(windows) {
"terminated in a root certificate which is not trusted by the trust provider".to_string()
} else {
let os = os_type::current_platform();
match os.os_type {
OSType::OSX => "The certificate was not trusted".to_string(),
_ => "unable to get local issuer certificate".to_string(),
}
}
}
#[tokio::test]
#[cfg(feature = "native-tls")]
async fn default_certificate_validation() -> Result<(), failure::Error> {
let builder = client::create_default_builder().cert_validation(CertificateValidation::Default);
let client = client::create(builder);
let result = client.ping().send().await;
match result {
Ok(response) => Err(failure::err_msg(format!(
"Expected error but response was {}",
response.status_code()
))),
Err(e) => {
let expected = expected_error_message();
let actual = e.to_string();
assert!(
actual.contains(&expected),
"Expected error message to contain '{}' but was '{}'",
expected,
actual
);
Ok(())
}
}
}
#[tokio::test]
#[cfg(all(feature = "rustls-tls", not(feature = "native-tls")))]
async fn default_certificate_validation_rustls_tls() -> Result<(), failure::Error> {
let builder = client::create_default_builder().cert_validation(CertificateValidation::Default);
let client = client::create(builder);
let result = client.ping().send().await;
match result {
Ok(response) => Err(failure::err_msg(format!(
"Expected error but response was {}",
response.status_code()
))),
Err(e) => {
let expected = "invalid certificate: UnknownIssuer";
let actual = e.to_string();
assert!(
actual.contains(&expected),
"Expected error message to contain '{}' but was '{}'",
expected,
actual
);
Ok(())
}
}
}
#[tokio::test]
async fn none_certificate_validation() -> Result<(), failure::Error> {
let builder = client::create_default_builder().cert_validation(CertificateValidation::None);
let client = client::create(builder);
let _response = client.ping().send().await?;
Ok(())
}
#[tokio::test]
#[cfg(any(feature = "native-tls", feature = "rustls-tls"))]
async fn full_certificate_ca_validation() -> Result<(), failure::Error> {
let cert = Certificate::from_pem(CA_CERT)?;
let builder =
client::create_default_builder().cert_validation(CertificateValidation::Full(cert));
let client = client::create(builder);
let _response = client.ping().send().await?;
Ok(())
}
#[tokio::test]
#[cfg(any(feature = "native-tls", feature = "rustls-tls"))]
async fn full_certificate_ca_chain_validation() -> Result<(), failure::Error> {
let mut cert = Certificate::from_pem(CA_CHAIN_CERT)?;
cert.append(Certificate::from_pem(CA_CERT)?);
assert_eq!(cert.len(), 3, "expected three certificates in CA chain");
let builder =
client::create_default_builder().cert_validation(CertificateValidation::Full(cert));
let client = client::create(builder);
let _response = client.ping().send().await?;
Ok(())
}
#[tokio::test]
#[cfg(all(windows, feature = "native-tls"))]
async fn full_certificate_validation() -> Result<(), failure::Error> {
let cert = Certificate::from_pem(TESTNODE_CERT)?;
let builder =
client::create_default_builder().cert_validation(CertificateValidation::Full(cert));
let client = client::create(builder);
let _response = client.ping().send().await?;
Ok(())
}
#[tokio::test]
#[cfg(feature = "rustls-tls")]
async fn full_certificate_validation_rustls_tls() -> Result<(), failure::Error> {
let mut chain: Vec<u8> = Vec::with_capacity(TESTNODE_CERT.len() + CA_CERT.len());
chain.extend(CA_CERT);
chain.extend(TESTNODE_CERT);
let cert = Certificate::from_pem(chain.as_slice())?;
let builder =
client::create_default_builder().cert_validation(CertificateValidation::Full(cert));
let client = client::create(builder);
let _response = client.ping().send().await?;
Ok(())
}
#[tokio::test]
#[cfg(all(unix, any(feature = "native-tls", feature = "rustls-tls")))]
async fn full_certificate_validation() -> Result<(), failure::Error> {
let cert = Certificate::from_pem(TESTNODE_CERT)?;
let builder =
client::create_default_builder().cert_validation(CertificateValidation::Full(cert));
let client = client::create(builder);
let result = client.ping().send().await;
let os_type = os_type::current_platform();
match os_type.os_type {
OSType::OSX => match result {
Ok(_) => Ok(()),
Err(e) => Err(failure::err_msg(e.to_string())),
},
_ => match result {
Ok(response) => Err(failure::err_msg(format!(
"Expected error but response was {}",
response.status_code()
))),
Err(e) => {
let expected = expected_error_message();
let actual = e.to_string();
assert!(
actual.contains(&expected),
"Expected error message to contain '{}' but was '{}'",
expected,
actual
);
Ok(())
}
},
}
}
#[tokio::test]
#[cfg(all(windows, feature = "native-tls"))]
async fn certificate_certificate_validation() -> Result<(), failure::Error> {
let cert = Certificate::from_pem(TESTNODE_CERT)?;
let builder =
client::create_default_builder().cert_validation(CertificateValidation::Certificate(cert));
let client = client::create(builder);
let _response = client.ping().send().await?;
Ok(())
}
#[tokio::test]
#[cfg(all(unix, feature = "native-tls"))]
async fn certificate_certificate_validation() -> Result<(), failure::Error> {
let cert = Certificate::from_pem(TESTNODE_CERT)?;
let builder =
client::create_default_builder().cert_validation(CertificateValidation::Certificate(cert));
let client = client::create(builder);
let result = client.ping().send().await;
let os_type = os_type::current_platform();
match os_type.os_type {
OSType::OSX => match result {
Ok(_) => Ok(()),
Err(e) => Err(failure::err_msg(e.to_string())),
},
_ => match result {
Ok(response) => Err(failure::err_msg(format!(
"Expected error but response was {}",
response.status_code()
))),
Err(e) => {
let expected = expected_error_message();
let actual = e.to_string();
assert!(
actual.contains(&expected),
"Expected error message to contain '{}' but was '{}'",
expected,
actual
);
Ok(())
}
},
}
}
#[tokio::test]
#[cfg(feature = "native-tls")]
async fn certificate_certificate_ca_validation() -> Result<(), failure::Error> {
let cert = Certificate::from_pem(CA_CERT)?;
let builder =
client::create_default_builder().cert_validation(CertificateValidation::Certificate(cert));
let client = client::create(builder);
let _response = client.ping().send().await?;
Ok(())
}
#[tokio::test]
#[cfg(feature = "native-tls")]
async fn fail_certificate_certificate_validation() -> Result<(), failure::Error> {
let cert = Certificate::from_pem(TESTNODE_NO_SAN_CERT)?;
let builder =
client::create_default_builder().cert_validation(CertificateValidation::Certificate(cert));
let client = client::create(builder);
let result = client.ping().send().await;
match result {
Ok(response) => Err(failure::err_msg(format!(
"Expected error but response was {}",
response.status_code()
))),
Err(e) => {
let expected = expected_error_message();
let actual = e.to_string();
assert!(
actual.contains(&expected),
"Expected error message to contain '{}' but was '{}'",
expected,
actual
);
Ok(())
}
}
}