migrate hacker challenge on ratls
This commit is contained in:
parent
e361eba2ca
commit
9f7a8fb602
1049
rewrite/Cargo.lock
generated
1049
rewrite/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -4,23 +4,44 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
actix-web = "4.9.0"
|
||||
async-stream = "0.3.5"
|
||||
chrono = "0.4.38"
|
||||
dashmap = "6.1.0"
|
||||
prost = "0.13.2"
|
||||
prost-types = "0.13.2"
|
||||
rand = "0.8.5"
|
||||
serde = { version = "1.0.210", features = ["derive"] }
|
||||
serde_json = "1.0.128"
|
||||
solana-client = "2.0.11"
|
||||
solana-program = "2.0.11"
|
||||
solana-sdk = "2.0.10"
|
||||
spl-associated-token-account = "5.0.1"
|
||||
spl-token = "6.0.0"
|
||||
tokio = { version = "1.40.0", features = ["macros", "rt-multi-thread", "fs"] }
|
||||
tokio-stream = { version = "0.1.16", features = ["sync"] }
|
||||
tonic = "0.12.1"
|
||||
actix-web = "4.9"
|
||||
async-stream = "0.3"
|
||||
chrono = "0.4"
|
||||
dashmap = "6.1"
|
||||
prost = "0.13"
|
||||
prost-types = "0.13"
|
||||
rand = "0.8"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
solana-client = "2.0"
|
||||
solana-program = "2.0"
|
||||
solana-sdk = "2.0"
|
||||
spl-associated-token-account = "5.0"
|
||||
spl-token = "6.0"
|
||||
tokio = { version = "1.40", features = ["macros", "rt-multi-thread", "fs"] } # this can be "full"
|
||||
tokio-stream = { version = "0.1", features = ["sync"] }
|
||||
tonic = "0.12"
|
||||
# sgx poc dependencies
|
||||
rustls = "0.23"
|
||||
x509-parser = "0.16"
|
||||
ring = "0.17" # hash256
|
||||
rcgen = "0.13"
|
||||
log = "0.4"
|
||||
hex = "0.4"
|
||||
tokio-rustls = "0.26"
|
||||
tower = { version = "0.5", features = ["full"] }
|
||||
tower-http = { version = "0.5", features = ["full"] }
|
||||
hyper = "1.4.1"
|
||||
hyper-util = "0.1.7"
|
||||
hyper-rustls = { version = "0.27", features = ["http2"] }
|
||||
base64 = "0.22"
|
||||
lazy_static = "1.5"
|
||||
# TODO: create a feature for testing, make occlum feature optional and added only if not compiling for testing
|
||||
occlum-ratls = { git = "ssh://git@gitea.detee.cloud/vfaychuk/occlum-ratls", features = ["tonic", "occlum"] }
|
||||
|
||||
[build-dependencies]
|
||||
tonic-build = "0.12.1"
|
||||
tonic-build = "0.12"
|
||||
|
||||
[patch.crates-io.curve25519-dalek]
|
||||
git = "https://github.com/anza-xyz/curve25519-dalek.git"
|
||||
rev = "b500cdc2a920cd5bff9e2dd974d7b97349d61464"
|
@ -1,9 +1,6 @@
|
||||
fn main() {
|
||||
tonic_build::configure()
|
||||
.build_server(true)
|
||||
.compile(
|
||||
&["proto/challenge.proto"],
|
||||
&["proto"],
|
||||
)
|
||||
.compile_protos(&["proto/challenge.proto"], &["proto"])
|
||||
.unwrap_or_else(|e| panic!("Failed to compile protos {:?}", e));
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
reorder_impl_items = true
|
||||
use_small_heuristics = "Max"
|
||||
merge_imports = true
|
||||
imports_granularity = "Crate"
|
||||
|
@ -48,8 +48,48 @@ impl ConnManager {
|
||||
}
|
||||
|
||||
async fn connect(&self, node_ip: String) -> Result<(), Box<dyn std::error::Error>> {
|
||||
use hyper::Uri;
|
||||
use hyper_util::{client::legacy::connect::HttpConnector, rt::TokioExecutor};
|
||||
use occlum_ratls::{prelude::*, RaTlsConfigBuilder};
|
||||
use tokio_rustls::rustls::ClientConfig;
|
||||
|
||||
println!("Connecting to {node_ip}...");
|
||||
let mut client = UpdateClient::connect(format!("http://{node_ip}:31373")).await?;
|
||||
|
||||
let mrsigner_hex = "83E8A0C3ED045D9747ADE06C3BFC70FCA661A4A65FF79A800223621162A88B76";
|
||||
let mrsigner =
|
||||
crate::sgx::mrsigner_from_hex(mrsigner_hex).expect("mrsigner decoding failed");
|
||||
let config = RaTlsConfig::new()
|
||||
.allow_instance_measurement(InstanceMeasurement::new().with_mrsigners(vec![mrsigner]));
|
||||
|
||||
let tls = ClientConfig::from_ratls_config(config)
|
||||
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, format!("{}", e)))?;
|
||||
|
||||
let mut http = HttpConnector::new();
|
||||
http.enforce_http(false);
|
||||
|
||||
let cloned_node_ip = node_ip.clone();
|
||||
|
||||
let connector = tower::ServiceBuilder::new()
|
||||
.layer_fn(move |s| {
|
||||
let tls = tls.clone();
|
||||
|
||||
hyper_rustls::HttpsConnectorBuilder::new()
|
||||
.with_tls_config(tls)
|
||||
.https_or_http()
|
||||
.enable_http2()
|
||||
.wrap_connector(s)
|
||||
})
|
||||
.map_request(move |_| {
|
||||
Uri::from_str(&format!("https://{cloned_node_ip}:31373"))
|
||||
.expect("Could not parse URI")
|
||||
})
|
||||
.service(http);
|
||||
|
||||
let client =
|
||||
hyper_util::client::legacy::Client::builder(TokioExecutor::new()).build(connector);
|
||||
|
||||
let uri = Uri::from_static("https://example.com");
|
||||
let mut client = UpdateClient::with_origin(client, uri);
|
||||
|
||||
let rx = self.tx.subscribe();
|
||||
let rx_stream = BroadcastStream::new(rx).filter_map(|n| n.ok());
|
||||
|
@ -1,17 +1,14 @@
|
||||
pub mod client;
|
||||
pub mod server;
|
||||
use crate::datastore;
|
||||
use crate::datastore::NodeInfo;
|
||||
use crate::NodeUpdate;
|
||||
use std::time::SystemTime;
|
||||
use std::time::{Duration, UNIX_EPOCH};
|
||||
use crate::{datastore::NodeInfo, NodeUpdate};
|
||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||
|
||||
pub mod challenge {
|
||||
tonic::include_proto!("challenge");
|
||||
}
|
||||
|
||||
impl From<(String, datastore::NodeInfo)> for NodeUpdate {
|
||||
fn from((ip, info): (String, datastore::NodeInfo)) -> Self {
|
||||
impl From<(String, NodeInfo)> for NodeUpdate {
|
||||
fn from((ip, info): (String, NodeInfo)) -> Self {
|
||||
NodeUpdate {
|
||||
ip: ip.to_string(),
|
||||
started_at: Some(prost_types::Timestamp::from(info.started_at)),
|
||||
@ -25,24 +22,20 @@ impl From<(String, datastore::NodeInfo)> for NodeUpdate {
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<(String, datastore::NodeInfo)> for NodeUpdate {
|
||||
fn into(self) -> (String, datastore::NodeInfo) {
|
||||
impl Into<(String, NodeInfo)> for NodeUpdate {
|
||||
fn into(self) -> (String, NodeInfo) {
|
||||
let ip = self.ip;
|
||||
let started_at: SystemTime = match self.started_at {
|
||||
Some(ts) => {
|
||||
let duration = Duration::new(ts.seconds as u64, ts.nanos as u32);
|
||||
UNIX_EPOCH
|
||||
.checked_add(duration)
|
||||
.unwrap_or(SystemTime::now())
|
||||
UNIX_EPOCH.checked_add(duration).unwrap_or(SystemTime::now())
|
||||
}
|
||||
None => SystemTime::now(),
|
||||
};
|
||||
let keepalive: SystemTime = match self.keepalive {
|
||||
Some(ts) => {
|
||||
let duration = Duration::new(ts.seconds as u64, ts.nanos as u32);
|
||||
UNIX_EPOCH
|
||||
.checked_add(duration)
|
||||
.unwrap_or(SystemTime::now())
|
||||
UNIX_EPOCH.checked_add(duration).unwrap_or(SystemTime::now())
|
||||
}
|
||||
None => SystemTime::now(),
|
||||
};
|
||||
|
@ -5,7 +5,7 @@ use crate::{datastore::Store, grpc::challenge::update_server::Update};
|
||||
use std::{pin::Pin, sync::Arc};
|
||||
use tokio::sync::broadcast::Sender;
|
||||
use tokio_stream::{Stream, StreamExt};
|
||||
use tonic::{transport::Server, Request, Response, Status, Streaming};
|
||||
use tonic::{Request, Response, Status, Streaming};
|
||||
|
||||
pub struct MyServer {
|
||||
ds: Arc<Store>,
|
||||
@ -18,10 +18,90 @@ impl MyServer {
|
||||
}
|
||||
|
||||
pub async fn start(self) {
|
||||
let addr = "0.0.0.0:31373".parse().unwrap();
|
||||
if let Err(e) = Server::builder().add_service(UpdateServer::new(self)).serve(addr).await {
|
||||
println!("gRPC server failed: {e:?}");
|
||||
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::ServerConfig, TlsAcceptor};
|
||||
use tonic::{body::boxed, service::Routes};
|
||||
use tower::{ServiceBuilder, ServiceExt};
|
||||
|
||||
use occlum_ratls::{prelude::*, RaTlsConfigBuilder};
|
||||
|
||||
// TODO: ratls config should be global
|
||||
// TODO: error handling, shouldn't have expects
|
||||
|
||||
let mrsigner_hex = "83E8A0C3ED045D9747ADE06C3BFC70FCA661A4A65FF79A800223621162A88B76";
|
||||
let mrsigner =
|
||||
crate::sgx::mrsigner_from_hex(mrsigner_hex).expect("mrsigner decoding failed");
|
||||
let config = RaTlsConfig::new()
|
||||
.allow_instance_measurement(InstanceMeasurement::new().with_mrsigners(vec![mrsigner]));
|
||||
|
||||
let mut tls = ServerConfig::from_ratls_config(config)
|
||||
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, format!("{}", e)))
|
||||
.expect("failed to create server config");
|
||||
tls.alpn_protocols = vec![b"h2".to_vec()];
|
||||
|
||||
let svc = Routes::new(UpdateServer::new(self)).prepare();
|
||||
|
||||
let http = Builder::new(TokioExecutor::new());
|
||||
|
||||
let listener = TcpListener::bind("0.0.0.0:31373").await.expect("failed to bind listener");
|
||||
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();
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ConnInfo {
|
||||
pub addr: std::net::SocketAddr,
|
||||
pub certificates: Vec<rustls::pki_types::CertificateDer<'static>>,
|
||||
}
|
||||
|
||||
let extension_layer =
|
||||
tower_http::add_extension::AddExtensionLayer::new(Arc::new(ConnInfo {
|
||||
addr,
|
||||
certificates,
|
||||
}));
|
||||
let svc = ServiceBuilder::new().layer(extension_layer).service(svc);
|
||||
|
||||
http.serve_connection(
|
||||
TokioIo::new(conn),
|
||||
TowerToHyperService::new(
|
||||
svc.map_request(|req: hyper::Request<_>| req.map(boxed)),
|
||||
),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,9 @@ mod datastore;
|
||||
mod grpc;
|
||||
mod http_server;
|
||||
mod persistence;
|
||||
mod sgx;
|
||||
mod solana;
|
||||
|
||||
use crate::{datastore::LOCALHOST, grpc::challenge::NodeUpdate, solana::Client as SolClient};
|
||||
use datastore::Store;
|
||||
use solana_sdk::signer::Signer;
|
||||
|
6
rewrite/src/sgx.rs
Normal file
6
rewrite/src/sgx.rs
Normal file
@ -0,0 +1,6 @@
|
||||
// TODO: Use error types (define error types in error.rs, see occlum-ratls as an example)
|
||||
pub fn mrsigner_from_hex(mrsigner_hex: &str) -> Result<[u8; 32], Box<dyn std::error::Error>> {
|
||||
let mut mrsigner = [0u8; 32];
|
||||
hex::decode_to_slice(mrsigner_hex, &mut mrsigner)?;
|
||||
Ok(mrsigner)
|
||||
}
|
@ -1,16 +1,17 @@
|
||||
#![allow(dead_code)]
|
||||
use solana_client::rpc_client::RpcClient;
|
||||
use solana_program::program_pack::Pack;
|
||||
use solana_sdk::pubkey::Pubkey;
|
||||
use solana_sdk::signature::keypair::Keypair;
|
||||
use solana_sdk::signer::Signer;
|
||||
use solana_sdk::system_instruction;
|
||||
use solana_sdk::transaction::Transaction;
|
||||
use solana_sdk::{
|
||||
pubkey::Pubkey, signature::keypair::Keypair, signer::Signer, system_instruction,
|
||||
transaction::Transaction,
|
||||
};
|
||||
use spl_associated_token_account::{
|
||||
get_associated_token_address, instruction::create_associated_token_account,
|
||||
};
|
||||
use spl_token::instruction::{initialize_mint, mint_to};
|
||||
use spl_token::state::Mint;
|
||||
use spl_token::{
|
||||
instruction::{initialize_mint, mint_to},
|
||||
state::Mint,
|
||||
};
|
||||
use std::error::Error;
|
||||
use tokio::time::{sleep, Duration};
|
||||
|
||||
@ -27,19 +28,11 @@ impl Client {
|
||||
let client = RpcClient::new(RPC_URL);
|
||||
let keypair = Keypair::new();
|
||||
let token = create_token(&client, &keypair).await;
|
||||
Self {
|
||||
client,
|
||||
keypair,
|
||||
token,
|
||||
}
|
||||
Self { client, keypair, token }
|
||||
}
|
||||
|
||||
pub fn from(keypair: Keypair, token: Pubkey) -> Self {
|
||||
Self {
|
||||
client: RpcClient::new(RPC_URL),
|
||||
keypair,
|
||||
token,
|
||||
}
|
||||
Self { client: RpcClient::new(RPC_URL), keypair, token }
|
||||
}
|
||||
|
||||
pub fn mint(&self, recipient: &Pubkey) -> Result<String, Box<dyn std::error::Error>> {
|
||||
@ -118,9 +111,7 @@ async fn create_token(client: &RpcClient, keypair: &Keypair) -> Pubkey {
|
||||
|
||||
let mint_keypair = Keypair::new();
|
||||
let payer = Keypair::from_base58_string(&keypair.to_base58_string());
|
||||
let mint_rent = client
|
||||
.get_minimum_balance_for_rent_exemption(Mint::LEN)
|
||||
.unwrap();
|
||||
let mint_rent = client.get_minimum_balance_for_rent_exemption(Mint::LEN).unwrap();
|
||||
|
||||
let create_mint_account_ix = system_instruction::create_account(
|
||||
&payer.pubkey(),
|
||||
@ -130,14 +121,9 @@ async fn create_token(client: &RpcClient, keypair: &Keypair) -> Pubkey {
|
||||
&spl_token::id(),
|
||||
);
|
||||
|
||||
let init_mint_ix = initialize_mint(
|
||||
&spl_token::id(),
|
||||
&mint_keypair.pubkey(),
|
||||
&payer.pubkey(),
|
||||
None,
|
||||
9,
|
||||
)
|
||||
.unwrap();
|
||||
let init_mint_ix =
|
||||
initialize_mint(&spl_token::id(), &mint_keypair.pubkey(), &payer.pubkey(), None, 9)
|
||||
.unwrap();
|
||||
|
||||
let recent_blockhash = client.get_latest_blockhash().unwrap();
|
||||
let tx = Transaction::new_signed_with_payer(
|
||||
|
Loading…
Reference in New Issue
Block a user