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,13 +121,8 @@ 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, | ||||
|     ) | ||||
|     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(); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user