This is an automated email from the ASF dual-hosted git repository. mssun pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/incubator-teaclave.git
commit 876a933ef3645f6df6c71040721abc3bbcd7df0f Author: Mingshen Sun <[email protected]> AuthorDate: Mon Feb 3 13:02:29 2020 -0800 Implement mutual attestation --- config/runtime.config.toml | 2 +- rpc/src/channel.rs | 3 +- rpc/src/config.rs | 63 ++++++++++++++++------ rpc/src/endpoint.rs | 2 +- rpc/src/server.rs | 3 +- services/authentication/enclave/src/lib.rs | 51 ++++++++++++++++-- services/frontend/enclave/src/lib.rs | 31 ++++++++--- services/frontend/enclave/src/service.rs | 13 +++-- .../enclave/src/teaclave_authentication_service.rs | 4 +- types/src/lib.rs | 6 +-- 10 files changed, 135 insertions(+), 43 deletions(-) diff --git a/config/runtime.config.toml b/config/runtime.config.toml index b0c46fb..b0f1216 100644 --- a/config/runtime.config.toml +++ b/config/runtime.config.toml @@ -9,7 +9,7 @@ authentication = { listen_address = "0.0.0.0:7776" } frontend = { listen_address = "0.0.0.0:7777" } [internal_endpoints] -authentication = { listen_address = "0.0.0.0:17776", advertised_address = "localhost:17776" } +authentication = { listen_address = "0.0.0.0:17776", advertised_address = "localhost:17776", inbound_services = ["frontend"] } dbs = { listen_address = "0.0.0.0:7778", advertised_address = "127.0.0.1:7778", inbound_services = ["frontend"] } execution = { listen_address = "0.0.0.0:7989", advertised_address = "127.0.0.1:7989" } diff --git a/rpc/src/channel.rs b/rpc/src/channel.rs index cb87a14..aa15139 100644 --- a/rpc/src/channel.rs +++ b/rpc/src/channel.rs @@ -5,6 +5,7 @@ use anyhow::anyhow; use anyhow::Result; use http::Uri; use serde::{Deserialize, Serialize}; +use std::sync::Arc; pub struct SgxTrustedTlsChannel<U, V> where @@ -28,7 +29,7 @@ where let hostname = uri.host().ok_or_else(|| anyhow!("Invalid hostname."))?; let stream = std::net::TcpStream::connect(address)?; let hostname = webpki::DNSNameRef::try_from_ascii_str(hostname)?; - let session = rustls::ClientSession::new(&client_config.config, hostname); + let session = rustls::ClientSession::new(&Arc::new(client_config.config.clone()), hostname); let tls_stream = rustls::StreamOwned::new(session, stream); let transport = SgxTrustedTlsTransport::new(tls_stream); diff --git a/rpc/src/config.rs b/rpc/src/config.rs index 1832acd..3545e3b 100644 --- a/rpc/src/config.rs +++ b/rpc/src/config.rs @@ -7,7 +7,7 @@ use teaclave_attestation::verifier::AttestationReportVerifier; use teaclave_types::EnclaveAttr; pub struct SgxTrustedTlsServerConfig { - pub config: Arc<rustls::ServerConfig>, + pub config: rustls::ServerConfig, } impl SgxTrustedTlsServerConfig { @@ -18,14 +18,34 @@ impl SgxTrustedTlsServerConfig { let mut config = rustls::ServerConfig::new(client_cert_verifier); config.set_single_cert(cert_chain, key_der)?; - Ok(Self { - config: Arc::new(config), - }) + Ok(Self { config }) + } + + pub fn new_with_attestation_report_verifier( + accepted_enclave_attrs: Vec<EnclaveAttr>, + cert: &[u8], + key_der: &[u8], + root_ca: &[u8], + verifier: fn(&AttestationReport) -> bool, + ) -> Result<Self> { + let cert_chain = vec![rustls::Certificate(cert.to_vec())]; + let key_der = rustls::PrivateKey(key_der.to_vec()); + + let verifier = Arc::new(AttestationReportVerifier::new( + accepted_enclave_attrs, + root_ca, + verifier, + )); + + let mut config = rustls::ServerConfig::new(verifier); + config.set_single_cert(cert_chain, key_der)?; + + Ok(Self { config }) } } pub struct SgxTrustedTlsClientConfig { - pub config: Arc<rustls::ClientConfig>, + pub config: rustls::ClientConfig, } struct NoServerAuth; @@ -51,8 +71,8 @@ impl rustls::ServerCertVerifier for NoServerAuth { } } -impl SgxTrustedTlsClientConfig { - pub fn new_without_verifier() -> Self { +impl Default for SgxTrustedTlsClientConfig { + fn default() -> Self { let mut config = rustls::ClientConfig::new(); config @@ -61,29 +81,40 @@ impl SgxTrustedTlsClientConfig { config.versions.clear(); config.versions.push(rustls::ProtocolVersion::TLSv1_2); - Self { - config: Arc::new(config), - } + Self { config } } +} - pub fn new_with_attestation_report_verifier( +impl SgxTrustedTlsClientConfig { + pub fn new() -> Self { + Self::default() + } + + pub fn attestation_report_verifier( + mut self, accepted_enclave_attrs: Vec<EnclaveAttr>, root_ca: &[u8], verifier: fn(&AttestationReport) -> bool, ) -> Self { - let mut config = rustls::ClientConfig::new(); let verifier = Arc::new(AttestationReportVerifier::new( accepted_enclave_attrs, root_ca, verifier, )); + self.config.dangerous().set_certificate_verifier(verifier); - config.dangerous().set_certificate_verifier(verifier); - config.versions.clear(); - config.versions.push(rustls::ProtocolVersion::TLSv1_2); + Self { + config: self.config, + } + } + + pub fn client_cert(mut self, cert: &[u8], key_der: &[u8]) -> Self { + let cert_chain = vec![rustls::Certificate(cert.to_vec())]; + let key_der = rustls::PrivateKey(key_der.to_vec()); + self.config.set_single_client_cert(cert_chain, key_der); Self { - config: Arc::new(config), + config: self.config, } } } diff --git a/rpc/src/endpoint.rs b/rpc/src/endpoint.rs index 5788e28..a24d40c 100644 --- a/rpc/src/endpoint.rs +++ b/rpc/src/endpoint.rs @@ -11,7 +11,7 @@ pub struct Endpoint { impl Endpoint { pub fn new(url: &str) -> Self { - let config = SgxTrustedTlsClientConfig::new_without_verifier(); + let config = SgxTrustedTlsClientConfig::new(); Self { url: url.to_string(), config, diff --git a/rpc/src/server.rs b/rpc/src/server.rs index 8c91cd3..29edaa2 100644 --- a/rpc/src/server.rs +++ b/rpc/src/server.rs @@ -5,6 +5,7 @@ use crate::TeaclaveService; use anyhow::Result; use log::debug; use serde::{Deserialize, Serialize}; +use std::sync::Arc; pub struct SgxTrustedTlsServer<U, V> where @@ -27,7 +28,7 @@ where ) -> SgxTrustedTlsServer<U, V> { Self { addr, - tls_config: server_config.config.clone(), + tls_config: Arc::new(server_config.config.clone()), maker: std::marker::PhantomData::<(U, V)>, } } diff --git a/services/authentication/enclave/src/lib.rs b/services/authentication/enclave/src/lib.rs index 0e11bb7..66682b7 100644 --- a/services/authentication/enclave/src/lib.rs +++ b/services/authentication/enclave/src/lib.rs @@ -28,7 +28,9 @@ use rand::RngCore; use std::prelude::v1::*; use std::sync::Arc; use std::thread; +use teaclave_attestation::verifier; use teaclave_attestation::{AttestationConfig, RemoteAttestation}; +use teaclave_config::BUILD_CONFIG; use teaclave_ipc::proto::{ ECallCommand, FinalizeEnclaveInput, FinalizeEnclaveOutput, InitEnclaveInput, InitEnclaveOutput, StartServiceInput, StartServiceOutput, @@ -41,6 +43,7 @@ use teaclave_proto::teaclave_authentication_service::{ use teaclave_rpc::config::SgxTrustedTlsServerConfig; use teaclave_rpc::server::SgxTrustedTlsServer; use teaclave_service_enclave_utils::ServiceEnclave; +use teaclave_types::EnclaveInfo; mod api_service; mod internal_service; @@ -52,12 +55,21 @@ fn start_internal_endpoint( db_client: user_db::DbClient, jwt_secret: Vec<u8>, attestation: Arc<RemoteAttestation>, + accepted_enclave_attrs: Vec<teaclave_types::EnclaveAttr>, ) { - let config = SgxTrustedTlsServerConfig::new_without_verifier( - &attestation.cert, - &attestation.private_key, - ) - .unwrap(); + let config = if cfg!(test_mode) { + SgxTrustedTlsServerConfig::new_without_verifier(&attestation.cert, &attestation.private_key) + .unwrap() + } else { + SgxTrustedTlsServerConfig::new_with_attestation_report_verifier( + accepted_enclave_attrs, + &attestation.cert, + &attestation.private_key, + BUILD_CONFIG.ias_root_ca_cert, + verifier::universal_quote_verifier, + ) + .unwrap() + }; let mut server = SgxTrustedTlsServer::< TeaclaveAuthenticationInternalResponse, @@ -105,6 +117,34 @@ fn start_api_endpoint( #[handle_ecall] fn handle_start_service(args: &StartServiceInput) -> Result<StartServiceOutput> { debug!("handle_start_service"); + let enclave_info = EnclaveInfo::verify_and_new( + args.config + .audit + .enclave_info_bytes + .as_ref() + .expect("enclave_info"), + BUILD_CONFIG.auditor_public_keys, + args.config + .audit + .auditor_signatures_bytes + .as_ref() + .expect("auditor signatures"), + )?; + let inbound_services = args + .config + .internal_endpoints + .authentication + .inbound_services + .as_ref() + .expect("inbound_service"); + let accepted_enclave_attrs: Vec<teaclave_types::EnclaveAttr> = inbound_services + .iter() + .map(|service| { + enclave_info + .get_enclave_attr(&format!("teaclave_{}_service", service)) + .expect("enclave_info") + }) + .collect(); let api_listen_address = args.config.api_endpoints.authentication.listen_address; let internal_listen_address = args.config.internal_endpoints.authentication.listen_address; let ias_config = args.config.ias.as_ref().unwrap(); @@ -134,6 +174,7 @@ fn handle_start_service(args: &StartServiceInput) -> Result<StartServiceOutput> client, internal_jwt_secret, attestation, + accepted_enclave_attrs, ); }); diff --git a/services/frontend/enclave/src/lib.rs b/services/frontend/enclave/src/lib.rs index febdee7..4c1cc07 100644 --- a/services/frontend/enclave/src/lib.rs +++ b/services/frontend/enclave/src/lib.rs @@ -25,7 +25,9 @@ extern crate log; use anyhow::Result; use std::prelude::v1::*; +use teaclave_attestation::verifier; use teaclave_attestation::{AttestationConfig, RemoteAttestation}; +use teaclave_config::BUILD_CONFIG; use teaclave_ipc::proto::{ ECallCommand, FinalizeEnclaveInput, FinalizeEnclaveOutput, InitEnclaveInput, InitEnclaveOutput, StartServiceInput, StartServiceOutput, @@ -34,7 +36,9 @@ use teaclave_ipc::{handle_ecall, register_ecall_handler}; use teaclave_proto::teaclave_frontend_service::{ TeaclaveFrontendRequest, TeaclaveFrontendResponse, }; +use teaclave_rpc::config::SgxTrustedTlsClientConfig; use teaclave_rpc::config::SgxTrustedTlsServerConfig; +use teaclave_rpc::endpoint::Endpoint; use teaclave_rpc::server::SgxTrustedTlsServer; use teaclave_service_enclave_utils::ServiceEnclave; @@ -61,13 +65,28 @@ fn handle_start_service(args: &StartServiceInput) -> Result<StartServiceOutput> &config, ); - let service = service::TeaclaveFrontendService::new( - &args - .config - .internal_endpoints - .authentication - .advertised_address, + let enclave_info = teaclave_types::EnclaveInfo::from_bytes( + &args.config.audit.enclave_info_bytes.as_ref().unwrap(), ); + let enclave_attr = enclave_info + .get_enclave_attr("teaclave_authentication_service") + .expect("authentication"); + let config = SgxTrustedTlsClientConfig::new() + .client_cert(&attestation.cert, &attestation.private_key) + .attestation_report_verifier( + vec![enclave_attr], + BUILD_CONFIG.ias_root_ca_cert, + verifier::universal_quote_verifier, + ); + let authentication_service_address = &args + .config + .internal_endpoints + .authentication + .advertised_address; + let authentication_service_endpoint = + Endpoint::new(authentication_service_address).config(config); + + let service = service::TeaclaveFrontendService::new(authentication_service_endpoint)?; match server.start(service) { Ok(_) => (), Err(e) => { diff --git a/services/frontend/enclave/src/service.rs b/services/frontend/enclave/src/service.rs index a2bca0a..a241894 100644 --- a/services/frontend/enclave/src/service.rs +++ b/services/frontend/enclave/src/service.rs @@ -1,3 +1,4 @@ +use anyhow::Result; use std::prelude::v1::*; use std::sync::{Arc, SgxMutex as Mutex}; use teaclave_proto::teaclave_authentication_service::TeaclaveAuthenticationInternalClient; @@ -32,14 +33,12 @@ pub(crate) struct TeaclaveFrontendService { } impl TeaclaveFrontendService { - pub(crate) fn new(authentication_service_address: &str) -> Self { - let channel = Endpoint::new(authentication_service_address) - .connect() - .unwrap(); - let client = TeaclaveAuthenticationInternalClient::new(channel).unwrap(); - Self { + pub(crate) fn new(authentication_service_endpoint: Endpoint) -> Result<Self> { + let channel = authentication_service_endpoint.connect()?; + let client = TeaclaveAuthenticationInternalClient::new(channel)?; + Ok(Self { authentication_client: Arc::new(Mutex::new(client)), - } + }) } } diff --git a/tests/functional_tests/enclave/src/teaclave_authentication_service.rs b/tests/functional_tests/enclave/src/teaclave_authentication_service.rs index 443f6b2..06bf5bd 100644 --- a/tests/functional_tests/enclave/src/teaclave_authentication_service.rs +++ b/tests/functional_tests/enclave/src/teaclave_authentication_service.rs @@ -28,7 +28,7 @@ fn get_api_client() -> TeaclaveAuthenticationApiClient { let enclave_attr = enclave_info .get_enclave_attr("teaclave_authentication_service") .expect("authentication"); - let config = SgxTrustedTlsClientConfig::new_with_attestation_report_verifier( + let config = SgxTrustedTlsClientConfig::new().attestation_report_verifier( vec![enclave_attr], BUILD_CONFIG.ias_root_ca_cert, verifier::universal_quote_verifier, @@ -48,7 +48,7 @@ fn get_internal_client() -> TeaclaveAuthenticationInternalClient { let enclave_attr = enclave_info .get_enclave_attr("teaclave_authentication_service") .expect("authentication"); - let config = SgxTrustedTlsClientConfig::new_with_attestation_report_verifier( + let config = SgxTrustedTlsClientConfig::new().attestation_report_verifier( vec![enclave_attr], BUILD_CONFIG.ias_root_ca_cert, verifier::universal_quote_verifier, diff --git a/types/src/lib.rs b/types/src/lib.rs index c032396..c3f2a92 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -93,7 +93,7 @@ pub struct EnclaveInfo { struct EnclaveInfoToml(HashMap<String, EnclaveMeasurement>); impl EnclaveInfo { - pub fn load_and_verify<T, U>( + pub fn verify_and_new<T, U>( enclave_info: &[u8], public_keys: &[T], signatures: &[U], @@ -133,9 +133,9 @@ impl EnclaveInfo { { use ring::signature; - for k in public_keys { + for s in signatures { let mut verified = false; - for s in signatures { + for k in public_keys { if signature::UnparsedPublicKey::new(&signature::RSA_PKCS1_2048_8192_SHA256, k) .verify(enclave_info, s.as_ref()) .is_ok() --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
