use std::sync::Arc;
use lexe_common::{constants, env::DeployEnv};
use lexe_enclave::enclave::Measurement;
use rustls::{
DigitallySignedStruct,
client::{
WebPkiServerVerifier,
danger::{
HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier,
},
},
pki_types::{CertificateDer, ServerName, UnixTime},
};
use crate::{attest_client::verifier::EnclavePolicy, lexe_ca};
pub mod cert;
pub mod quote;
pub mod verifier;
pub fn user_node_provision_client_config(
use_sgx: bool,
deploy_env: DeployEnv,
measurement: Measurement,
) -> rustls::ClientConfig {
let enclave_policy = EnclavePolicy::trust_measurements_with_signer(
use_sgx,
deploy_env,
vec![measurement],
);
let attestation_verifier = verifier::AttestationCertVerifier {
expect_dummy_quote: !use_sgx,
enclave_policy,
};
let lexe_server_verifier = lexe_ca::lexe_server_verifier(deploy_env);
let server_cert_verifier = UserNodeProvisionVerifier {
lexe_server_verifier,
attestation_verifier,
};
let mut config = lexe_tls_core::client_config_builder()
.dangerous()
.with_custom_certificate_verifier(Arc::new(server_cert_verifier))
.with_no_client_auth();
config
.alpn_protocols
.clone_from(&lexe_tls_core::LEXE_ALPN_PROTOCOLS);
config
}
#[derive(Debug)]
struct UserNodeProvisionVerifier {
attestation_verifier: verifier::AttestationCertVerifier,
lexe_server_verifier: Arc<WebPkiServerVerifier>,
}
impl ServerCertVerifier for UserNodeProvisionVerifier {
fn verify_server_cert(
&self,
end_entity: &CertificateDer,
intermediates: &[CertificateDer],
server_name: &ServerName,
ocsp_response: &[u8],
now: UnixTime,
) -> Result<ServerCertVerified, rustls::Error> {
let maybe_dns_name = match server_name {
ServerName::DnsName(dns) => Some(dns.as_ref()),
_ => None,
};
match maybe_dns_name {
Some(dns_name)
if dns_name.ends_with(constants::NODE_PROVISION_DNS_SUFFIX) =>
self.attestation_verifier.verify_server_cert(
end_entity,
intermediates,
server_name,
ocsp_response,
now,
),
_ => self.lexe_server_verifier.verify_server_cert(
end_entity,
intermediates,
server_name,
ocsp_response,
now,
),
}
}
fn verify_tls12_signature(
&self,
_message: &[u8],
_cert: &CertificateDer<'_>,
_dss: &DigitallySignedStruct,
) -> Result<HandshakeSignatureValid, rustls::Error> {
let error = rustls::PeerIncompatible::ServerDoesNotSupportTls12Or13;
Err(rustls::Error::PeerIncompatible(error))
}
fn verify_tls13_signature(
&self,
message: &[u8],
cert: &CertificateDer<'_>,
dss: &DigitallySignedStruct,
) -> Result<HandshakeSignatureValid, rustls::Error> {
rustls::crypto::verify_tls13_signature(
message,
cert,
dss,
&lexe_tls_core::LEXE_SIGNATURE_ALGORITHMS,
)
}
fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
lexe_tls_core::LEXE_SUPPORTED_VERIFY_SCHEMES.clone()
}
}