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]

Reply via email to