prettified scripts, docs and code
This commit is contained in:
parent
f2f2d545b3
commit
ada83ece3a
30
README.md
30
README.md
@ -1,14 +1,32 @@
|
||||
# Occlum SGX Remote Attestation integrated in TLS connection
|
||||
|
||||
Steps to test the project:
|
||||
The MRSIGNER of the `example/signing_key.pem` is hardcoded in the enclave code:
|
||||
|
||||
```
|
||||
occlum-cargo build --example server --features="occlum,actix-web"
|
||||
strip -s target/x86_64-unknown-linux-musl/debug/examples/server
|
||||
./build_server.sh
|
||||
6871A831CED408CD99F0ED31587CC2B5C728C99D4A0A1ADF2F0C5574EBBB00DC
|
||||
```
|
||||
|
||||
occlum-cargo build --example client --features="occlum,reqwest"
|
||||
strip -s target/x86_64-unknown-linux-musl/debug/examples/client
|
||||
You can generate your own signing key. Just use the following command:
|
||||
|
||||
```
|
||||
openssl genrsa -3 -out signing_key.pem 3072
|
||||
```
|
||||
|
||||
To get the MRSIGNER of the key, compile [this project](https://github.com/intel/sgx-ra-sample)
|
||||
and use the following command:
|
||||
|
||||
```
|
||||
./mrsigner signing_key.pem
|
||||
```
|
||||
|
||||
## Running Examples
|
||||
|
||||
Before running make sure you have installed the Occlum and the SGX driver.
|
||||
You should also have the Occlum Rust toolchain installed to get `occlum-cargo`.
|
||||
To test the project just run client and server scripts in different terminals:
|
||||
|
||||
```
|
||||
./build_server.sh
|
||||
./build_client.sh
|
||||
```
|
||||
|
||||
|
@ -1,12 +1,33 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# initialize occlum workspace
|
||||
rm -rf client_instance && mkdir client_instance && cd client_instance
|
||||
SCRIPT=$0
|
||||
EXAMPLE=$1
|
||||
|
||||
if [ $# -eq 0 ] || [ "$EXAMPLE" != "https" ] && [ "$EXAMPLE" != "grpcs" ]; then
|
||||
echo "usage: $SCRIPT https|grpcs"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
FEATURES=$(if [ "$EXAMPLE" == "https" ]; then echo "reqwest,occlum"; else echo "tonic,occlum"; fi)
|
||||
|
||||
occlum-cargo build --example mratls_"${EXAMPLE}"_client --features="$FEATURES"
|
||||
strip target/x86_64-unknown-linux-musl/debug/examples/mratls_"${EXAMPLE}"_client
|
||||
|
||||
cat > client.yaml <<EOF
|
||||
includes:
|
||||
- base.yaml
|
||||
targets:
|
||||
- target: /bin
|
||||
copy:
|
||||
- files:
|
||||
- ../target/x86_64-unknown-linux-musl/debug/examples/mratls_${EXAMPLE}_client
|
||||
EOF
|
||||
|
||||
rm -rf client_instance && mkdir client_instance && cd client_instance
|
||||
occlum init && rm -rf image
|
||||
copy_bom -f ../client.yaml --root image --include-dir /opt/occlum/etc/template
|
||||
|
||||
occlum build
|
||||
occlum build --sign-key ../examples/signing_key.pem --enable-edmm Y
|
||||
occlum package --debug client.tar.gz
|
||||
|
||||
occlum run /bin/client
|
||||
|
@ -1,12 +1,33 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# initialize occlum workspace
|
||||
rm -rf server_instance && mkdir server_instance && cd server_instance
|
||||
SCRIPT=$0
|
||||
EXAMPLE=$1
|
||||
|
||||
if [ $# -eq 0 ] || [ "$EXAMPLE" != "https" ] && [ "$EXAMPLE" != "grpcs" ]; then
|
||||
echo "usage: $SCRIPT https|grpcs"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
FEATURES=$(if [ "$EXAMPLE" == "https" ]; then echo "actix-web,occlum"; else echo "tonic,occlum"; fi)
|
||||
|
||||
occlum-cargo build --example mratls_"${EXAMPLE}"_server --features="$FEATURES"
|
||||
strip target/x86_64-unknown-linux-musl/debug/examples/mratls_"${EXAMPLE}"_server
|
||||
|
||||
cat > server.yaml <<EOF
|
||||
includes:
|
||||
- base.yaml
|
||||
targets:
|
||||
- target: /bin
|
||||
copy:
|
||||
- files:
|
||||
- ../target/x86_64-unknown-linux-musl/debug/examples/mratls_${EXAMPLE}_server
|
||||
EOF
|
||||
|
||||
rm -rf server_instance && mkdir server_instance && cd server_instance
|
||||
occlum init && rm -rf image
|
||||
copy_bom -f ../server.yaml --root image --include-dir /opt/occlum/etc/template
|
||||
|
||||
occlum build
|
||||
occlum build --sign-key ../examples/signing_key.pem --enable-edmm Y
|
||||
occlum package --debug server.tar.gz
|
||||
|
||||
occlum run /bin/server
|
||||
|
@ -4,4 +4,4 @@ targets:
|
||||
- target: /bin
|
||||
copy:
|
||||
- files:
|
||||
- ../target/x86_64-unknown-linux-musl/debug/examples/client
|
||||
- ../target/x86_64-unknown-linux-musl/debug/examples/mratls_https_client
|
||||
|
@ -12,7 +12,9 @@ use tokio_rustls::rustls::ClientConfig;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mrsigner_hex = "83D719E77DEACA1470F6BAF62A4D774303C899DB69020F9C70EE1DFC08C7CE9E";
|
||||
env_logger::init_from_env(env_logger::Env::default().default_filter_or("trace"));
|
||||
|
||||
let mrsigner_hex = "6871A831CED408CD99F0ED31587CC2B5C728C99D4A0A1ADF2F0C5574EBBB00DC";
|
||||
let mut mrsigner = [0u8; 32];
|
||||
hex::decode_to_slice(mrsigner_hex, &mut mrsigner).expect("mrsigner decoding failed");
|
||||
|
||||
@ -39,16 +41,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.enable_http2()
|
||||
.wrap_connector(s)
|
||||
})
|
||||
// Since our cert is signed with `example.com` but we actually want to connect
|
||||
// to a local server we will override the Uri passed from the `HttpsConnector`
|
||||
// and map it to the correct `Uri` that will connect us directly to the local server.
|
||||
.map_request(|_| Uri::from_static("https://[::1]:50051"))
|
||||
.service(http);
|
||||
|
||||
let client = hyper_util::client::legacy::Client::builder(TokioExecutor::new()).build(connector);
|
||||
|
||||
// Using `with_origin` will let the codegenerated client set the `scheme` and
|
||||
// `authority` from the provided `Uri`.
|
||||
let uri = Uri::from_static("https://example.com");
|
||||
let mut client = EchoClient::with_origin(client, uri);
|
||||
|
||||
|
@ -23,7 +23,9 @@ use occlum_ratls::RaTlsConfigBuilder;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mrsigner_hex = "83D719E77DEACA1470F6BAF62A4D774303C899DB69020F9C70EE1DFC08C7CE9E";
|
||||
env_logger::init_from_env(env_logger::Env::default().default_filter_or("trace"));
|
||||
|
||||
let mrsigner_hex = "6871A831CED408CD99F0ED31587CC2B5C728C99D4A0A1ADF2F0C5574EBBB00DC";
|
||||
let mut mrsigner = [0u8; 32];
|
||||
hex::decode_to_slice(mrsigner_hex, &mut mrsigner).expect("mrsigner decoding failed");
|
||||
|
||||
|
@ -5,18 +5,14 @@ use reqwest::ClientBuilder;
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
env_logger::init_from_env(env_logger::Env::default().default_filter_or("trace"));
|
||||
|
||||
let mrsigner_hex = "83D719E77DEACA1470F6BAF62A4D774303C899DB69020F9C70EE1DFC08C7CE9E";
|
||||
let mrsigner_hex = "6871A831CED408CD99F0ED31587CC2B5C728C99D4A0A1ADF2F0C5574EBBB00DC";
|
||||
let mut mrsigner = [0u8; 32];
|
||||
hex::decode_to_slice(mrsigner_hex, &mut mrsigner)?;
|
||||
|
||||
let client = ClientBuilder::new()
|
||||
.use_ratls(
|
||||
RaTlsConfig::new().allow_instance_measurement(
|
||||
InstanceMeasurement::new()
|
||||
.with_mrsigners(vec![SGXMeasurement::new(mrsigner)])
|
||||
.with_product_ids(vec![0]),
|
||||
),
|
||||
)
|
||||
.use_ratls(RaTlsConfig::new().allow_instance_measurement(
|
||||
InstanceMeasurement::new().with_mrsigners(vec![SGXMeasurement::new(mrsigner)]),
|
||||
))
|
||||
.build()?;
|
||||
let res = client.get("https://127.0.0.1:8000").send().await?;
|
||||
let data = res.text().await?;
|
||||
|
@ -8,30 +8,23 @@ async fn index() -> String {
|
||||
}
|
||||
|
||||
#[actix_web::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
env_logger::init_from_env(env_logger::Env::default().default_filter_or("trace"));
|
||||
|
||||
let mrsigner_hex = "83D719E77DEACA1470F6BAF62A4D774303C899DB69020F9C70EE1DFC08C7CE9E";
|
||||
let mrsigner_hex = "6871A831CED408CD99F0ED31587CC2B5C728C99D4A0A1ADF2F0C5574EBBB00DC";
|
||||
let mut mrsigner = [0u8; 32];
|
||||
hex::decode_to_slice(mrsigner_hex, &mut mrsigner).expect("mrsigner decoding failed");
|
||||
hex::decode_to_slice(mrsigner_hex, &mut mrsigner)?;
|
||||
|
||||
HttpServer::new(|| App::new().service(index))
|
||||
.bind_ratls(
|
||||
SocketAddr::from(([127, 0, 0, 1], 8000)),
|
||||
RaTlsConfig::new()
|
||||
.allow_instance_measurement(
|
||||
InstanceMeasurement::new().with_mrsigners(vec![SGXMeasurement::new(mrsigner)]),
|
||||
)
|
||||
.allow_instance_measurement(
|
||||
InstanceMeasurement::new()
|
||||
.with_mrenclaves(vec![
|
||||
SGXMeasurement::new([0u8; 32]),
|
||||
SGXMeasurement::new([1u8; 32]),
|
||||
])
|
||||
.with_product_ids(vec![0, 2]),
|
||||
),
|
||||
RaTlsConfig::new().allow_instance_measurement(
|
||||
InstanceMeasurement::new().with_mrsigners(vec![SGXMeasurement::new(mrsigner)]),
|
||||
),
|
||||
)
|
||||
.unwrap()
|
||||
.run()
|
||||
.await
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
40
examples/signing_key.pem
Normal file
40
examples/signing_key.pem
Normal file
@ -0,0 +1,40 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
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
|
||||
9DTouKJTmbNzsk375oViTww=
|
||||
-----END PRIVATE KEY-----
|
@ -2,4 +2,5 @@
|
||||
pub mod actix_web;
|
||||
#[cfg(feature = "reqwest")]
|
||||
pub mod reqwest;
|
||||
//mod tonic_server;
|
||||
#[cfg(feature = "tonic")]
|
||||
pub mod tonic;
|
||||
|
1
src/http/tonic.rs
Normal file
1
src/http/tonic.rs
Normal file
@ -0,0 +1 @@
|
||||
|
@ -1,97 +0,0 @@
|
||||
use hyper::server::conn::http2::Builder;
|
||||
use hyper_util::{
|
||||
rt::{TokioExecutor, TokioIo},
|
||||
service::TowerToHyperService,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
use tokio::net::TcpListener;
|
||||
use tokio_rustls::{
|
||||
rustls::{pki_types::CertificateDer, ServerConfig},
|
||||
TlsAcceptor,
|
||||
};
|
||||
use tonic::transport::server::TcpIncoming;
|
||||
use tonic::{body::boxed, service::Routes, Request, Response, Status};
|
||||
use tower::ServiceExt;
|
||||
use tower_http::ServiceBuilderExt;
|
||||
|
||||
use crate::{config::RaTlsConfig, RaTlsConfigBuilder};
|
||||
|
||||
fn bind_ratls(config: RaTlsConfig) -> Result<(), std::io::Error> {
|
||||
let config = ServerConfig::from_ratls_config(config)
|
||||
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, format!("{}", e)))?;
|
||||
let tls_acceptor = TlsAcceptor::from(Arc::new(config));
|
||||
|
||||
// add tls_acceptor to the server
|
||||
let incoming = TcpIncoming::new("[::1]:50051".parse().unwrap(), true, None)?;
|
||||
|
||||
let svc = tower::ServiceBuilder::new()
|
||||
.add_extension(Arc::new(ConnInfo { addr, certificates }))
|
||||
.service(svc);
|
||||
|
||||
self.bind_rustls_0_23(addr, config)
|
||||
}
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let listener = TcpListener::bind("[::1]:50051").await?;
|
||||
let tls_acceptor = TlsAcceptor::from(Arc::new(tls));
|
||||
|
||||
loop {
|
||||
let (conn, addr) = match listener.accept().await {
|
||||
Ok(incoming) => incoming,
|
||||
Err(e) => {
|
||||
eprintln!("Error accepting connection: {}", e);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
let http = http.clone();
|
||||
let tls_acceptor = tls_acceptor.clone();
|
||||
let svc = svc.clone();
|
||||
|
||||
tokio::spawn(async move {
|
||||
let mut certificates = Vec::new();
|
||||
|
||||
let conn = tls_acceptor
|
||||
.accept_with(conn, |info| {
|
||||
if let Some(certs) = info.peer_certificates() {
|
||||
for cert in certs {
|
||||
certificates.push(cert.clone());
|
||||
}
|
||||
}
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
http.serve_connection(
|
||||
TokioIo::new(conn),
|
||||
TowerToHyperService::new(svc.map_request(|req: http::Request<_>| req.map(boxed))),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ConnInfo {
|
||||
addr: std::net::SocketAddr,
|
||||
certificates: Vec<CertificateDer<'static>>,
|
||||
}
|
||||
|
||||
type EchoResult<T> = Result<Response<T>, Status>;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct EchoServer {}
|
||||
|
||||
#[tonic::async_trait]
|
||||
impl pb::echo_server::Echo for EchoServer {
|
||||
async fn unary_echo(&self, request: Request<EchoRequest>) -> EchoResult<EchoResponse> {
|
||||
let conn_info = request.extensions().get::<Arc<ConnInfo>>().unwrap();
|
||||
println!(
|
||||
"Got a request from: {:?} with certs: {:?}",
|
||||
conn_info.addr, conn_info.certificates
|
||||
);
|
||||
|
||||
let message = request.into_inner().message;
|
||||
Ok(Response::new(EchoResponse { message }))
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user