Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

quote handling #6

Closed
wants to merge 10 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ teleport.env
exex.manifest.sgx
exex.manifest
exex.sig
*.csr
*.pem
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,7 @@ http = "1.1.0"
axum-server = {version = "0.6.0", features = ["tls-rustls"]}
bincode = "1.3.3"
getrandom = "0.2.15"

acme-lib = "0.9.1"
openssl = "0.10.63"
sha2 = "0.10.8"
Empty file added data/.ignore
Empty file.
2 changes: 0 additions & 2 deletions env.example
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ DB_PATH=
WS_RPC_URL=
RPC_URL=
NFT_MINTER_MNEMONIC=
TLS_CERT_PATH=
TLS_KEY_PATH=
APP_URL=
TEE_URL=
NFT_ADDRESS=
21 changes: 0 additions & 21 deletions self_signed_certs/cert.pem

This file was deleted.

28 changes: 0 additions & 28 deletions self_signed_certs/key.pem

This file was deleted.

41 changes: 41 additions & 0 deletions src/cert.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use openssl::{
hash::MessageDigest,
pkey::{self, PKey},
stack::Stack,
x509::{extension::SubjectAlternativeName, X509Req, X509ReqBuilder},
};

// from https://github.com/flashbots/gramine-andromeda-revm/blob/amiller-frame/src/main.rs
pub fn create_csr(domain: &str, pkey: &PKey<pkey::Private>) -> eyre::Result<X509Req> {
//
// the csr builder
let mut req_bld = X509ReqBuilder::new().expect("X509ReqBuilder");

let mut x509_name = openssl::x509::X509NameBuilder::new().unwrap();
x509_name.append_entry_by_text("C", "US").unwrap();
x509_name.append_entry_by_text("ST", "IL").unwrap();
x509_name.append_entry_by_text("O", "n/a").unwrap();
x509_name.append_entry_by_text("CN", domain).unwrap();
let x509_name = x509_name.build();

req_bld.set_subject_name(&x509_name).unwrap();

// set private/public key in builder
req_bld.set_pubkey(pkey).expect("set_pubkey");

// set all domains as alt names
let mut stack = Stack::new().expect("Stack::new");
let ctx = req_bld.x509v3_context(None);
let mut an = SubjectAlternativeName::new();
an.dns(domain);

let ext = an.build(&ctx).expect("SubjectAlternativeName::build");
stack.push(ext).expect("Stack::push");
req_bld.add_extensions(&stack).expect("add_extensions");

// sign it
req_bld.sign(pkey, MessageDigest::sha256()).expect("csr_sign");

// the csr
Ok(req_bld.build())
}
8 changes: 0 additions & 8 deletions src/endpoints.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use alloy::primitives::Address;
use std::{str::FromStr, sync::Arc};
use tokio::fs;

use axum::{
extract::{Query, State},
Expand Down Expand Up @@ -212,13 +211,6 @@ pub async fn get_tweet_id<A: TeleportDB>(
Json(TweetIdResponse { tweet_id })
}

pub async fn get_ratls_cert() -> Json<AttestationResponse> {
let cert = fs::read_to_string(std::env::var("TLS_CERT_PATH").expect("TLS_CERT_PATH not set"))
.await
.expect("gramine ratls rootCA.crt not found");
Json(AttestationResponse { cert })
}

pub async fn hello_world() -> &'static str {
log::info!("Hello, World!");
"Hello, World!"
Expand Down
79 changes: 51 additions & 28 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,35 @@
use std::{net::SocketAddr, sync::Arc};
use std::{net::SocketAddr, path::Path, sync::Arc};

use acme_lib::create_rsa_key;
use alloy::{
providers::ProviderBuilder,
signers::local::{coins_bip39::English, MnemonicBuilder},
};
use tokio::time::Duration;

use axum_server::tls_rustls::RustlsConfig;
use endpoints::{
callback, get_ratls_cert, get_tweet_id, hello_world, mint, new_user, redeem, SharedState,
};
use tokio::{fs, sync::Mutex};
use endpoints::{callback, get_tweet_id, hello_world, mint, new_user, redeem, SharedState};
use openssl::pkey::PKey;
use tokio::{fs, sync::Mutex, time::sleep};
use tower_http::cors::CorsLayer;

use crate::{actions::nft::subscribe_to_nft_events, db::TeleportDB, endpoints::check_redeem};
use crate::{
actions::nft::subscribe_to_nft_events, cert::create_csr, db::TeleportDB,
endpoints::check_redeem,
};

mod actions;
mod cert;
mod db;
mod endpoints;
mod oai;
mod sgx_attest;
mod twitter;

const PRIVATE_KEY_PATH: &str = "data/private_key.pem";
const CERTIFICATE_PATH: &str = "untrustedhost/certificate.pem";
const CSR_PATH: &str = "untrustedhost/request.csr";

#[tokio::main]
async fn main() {
env_logger::init();
Expand All @@ -29,12 +39,32 @@ async fn main() {
let ws_rpc_url = std::env::var("WS_RPC_URL").expect("WS_RPC_URL not set");
let rpc_url = std::env::var("RPC_URL").expect("RPC_URL not set");
let mnemonic = std::env::var("NFT_MINTER_MNEMONIC").expect("NFT_MINTER_MNEMONIC not set");
let tls_key_path = std::env::var("TLS_KEY_PATH").expect("TLS_KEY_PATH not set");
let tls_cert_path = std::env::var("TLS_CERT_PATH").expect("TLS_CERT_PATH not set");
let db_path = std::env::var("DB_PATH").expect("DB_PATH not set");
let app_url = std::env::var("APP_URL").expect("APP_URL not set");
let tee_url = std::env::var("TEE_URL").expect("TEE_URL not set");

let pkey = if std::path::Path::new(PRIVATE_KEY_PATH).exists() {
let pk_bytes = fs::read(PRIVATE_KEY_PATH).await.expect("Failed to read pk file");
PKey::private_key_from_pem(pk_bytes.as_slice()).unwrap()
} else {
let pk = create_rsa_key(2048);
let pk_bytes = pk.private_key_to_pem_pkcs8().unwrap();
fs::write(PRIVATE_KEY_PATH, pk_bytes).await.expect("Failed to write pk to file");
pk
};

let csr = create_csr(&tee_url, &pkey).unwrap();
let csr_pem_bytes = csr.to_pem().unwrap();
fs::write(CSR_PATH, csr_pem_bytes).await.expect("Failed to write csr to file");

let mut pk_bytes = pkey.public_key_to_pem().unwrap();
let mut csr_pem_bytes = csr.to_pem().unwrap();
pk_bytes.append(&mut csr_pem_bytes);
if let Ok(quote) = sgx_attest::sgx_attest(pk_bytes) {
// handle quote
log::info!("quote: {:?}", quote);
}
rpalakkal marked this conversation as resolved.
Show resolved Hide resolved

let signer =
MnemonicBuilder::<English>::default().phrase(mnemonic).index(0).unwrap().build().unwrap();

Expand All @@ -54,38 +84,31 @@ async fn main() {
let db = Arc::new(Mutex::new(db));
let shared_state = SharedState { db: db.clone(), provider, app_url, tee_url };

let eph = fs::read(tls_key_path).await.expect("gramine ratls rootCA.key not found");

let remove_str = "TRUSTED C";

let mut gram_crt_print =
fs::read_to_string(tls_cert_path).await.expect("gramine ratls rootCA.crt not found");
let mut remove_offset = 0;
while let Some(index) = gram_crt_print[remove_offset..].find(remove_str) {
let start = remove_offset + index;
let end = start + remove_str.len();
gram_crt_print.replace_range(start..end, "C");
remove_offset = end;
}

let app = axum::Router::new()
.route("/new", axum::routing::get(new_user))
.route("/callback", axum::routing::get(callback))
.route("/mint", axum::routing::get(mint))
.route("/redeem", axum::routing::post(redeem))
.route("/checkRedeem", axum::routing::post(check_redeem))
.route("/tweetId", axum::routing::get(get_tweet_id))
.route("/attestSgx", axum::routing::get(get_ratls_cert))
.route("/", axum::routing::get(hello_world))
.layer(CorsLayer::permissive())
.with_state(shared_state);
// let config = RustlsConfig::from_pem(gram_crt_print.as_bytes().to_vec(), eph).await.unwrap();
// let addr = SocketAddr::from(([0, 0, 0, 0], 3000));
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();

log::info!("Waiting for cert ...");
while !Path::new(CERTIFICATE_PATH).exists() {
sleep(Duration::from_secs(1)).await;
}
log::info!("Cert found");
let cert = fs::read(CERTIFICATE_PATH).await.expect("cert not found");
let config =
RustlsConfig::from_pem(cert, pkey.private_key_to_pem_pkcs8().unwrap()).await.unwrap();
let addr = SocketAddr::from(([0, 0, 0, 0], 8001));
// let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();

tokio::spawn(async move {
axum::serve(listener, app).await.unwrap();
// axum_server::bind_rustls(addr, config).serve(app.into_make_service()).await.unwrap();
// axum::serve(listener, app).await.unwrap();
axum_server::bind_rustls(addr, config).serve(app.into_make_service()).await.unwrap();
});
let db_clone = db.clone();
tokio::spawn(async move {
Expand Down
38 changes: 38 additions & 0 deletions src/sgx_attest.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use std::{
fs::{self, File},
io::Write,
path::Path,
};

use sha2::Digest;

pub fn sgx_attest(input: Vec<u8>) -> eyre::Result<Vec<u8>> {
if !Path::new("/dev/attestation/quote").exists() {
eyre::bail!("sgx quote not found");
}

let mut f = match File::create("/dev/attestation/user_report_data") {
Ok(f) => f,
Err(error) => {
panic!("sgx open failed {:?}", error);
}
};

let hash = sha2::Sha256::digest(input).to_vec();

match f.write_all(&hash) {
Ok(()) => (),
Err(error) => {
eyre::bail!("sgx write failed {:?}", error);
}
};

let quote = match fs::read("/dev/attestation/quote") {
Ok(quote) => quote,
Err(error) => {
eyre::bail!("sgx read failed {:?}", error);
}
};

Ok(quote)
}
Empty file added untrustedhost/.ignore
Empty file.
Loading