diff --git a/Cargo.lock b/Cargo.lock index 74d8b1f..52ffc65 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1284,7 +1284,7 @@ dependencies = [ "hex", "kbs-types", "lazy_static", - "p256", + "p521", "rand", "sec1", "serde_json", @@ -1520,14 +1520,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] -name = "p256" -version = "0.13.2" +name = "p521" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +checksum = "0fc9e2161f1f215afdfce23677034ae137bbd45016a880c2eb3ba8eb95f085b2" dependencies = [ + "base16ct", "ecdsa", "elliptic-curve", "primeorder", + "rand_core", "sha2", ] diff --git a/Cargo.toml b/Cargo.toml index 0e93020..e0705ea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ concat-kdf = "0.1.0" hex = "0.4.3" kbs-types = "0.14.0" lazy_static = "1.5.0" -p256 = { version = "0.13.2", features = ["ecdh"] } +p521 = { version = "0.13.3", features = ["ecdh"] } rand = "0.8.5" sec1 = "0.7.3" serde_json = "1.0.133" diff --git a/src/main.rs b/src/main.rs index e8b312b..531ae65 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,7 +16,7 @@ use base64::{engine::general_purpose::URL_SAFE_NO_PAD, prelude::BASE64_STANDARD, use clap::Parser; use kbs_types::{Challenge, ProtectedHeader, Request, Response, TeePubKey}; use lazy_static::lazy_static; -use p256::{ +use p521::{ ecdh::EphemeralSecret, elliptic_curve::sec1::FromEncodedPoint, EncodedPoint, PublicKey, }; use rand::Rng; @@ -27,12 +27,13 @@ use uuid::Uuid; const AES_GCM_256_ALGORITHM: &str = "A256GCM"; const AES_GCM_256_KEY_BITS: u32 = 256; const ECDH_ES_A256KW: &str = "ECDH-ES+A256KW"; -const P256_CURVE: &str = "P-256"; +const P521_CURVE: &str = "P-521"; const EC_KTY: &str = "EC"; lazy_static! { pub static ref KEY: RwLock> = RwLock::new(Vec::new()); pub static ref MEASUREMENT: RwLock> = RwLock::new(Vec::new()); + pub static ref SECRET: RwLock> = RwLock::new(Vec::new()); pub static ref ATTESTED: Mutex = Mutex::new(false); } @@ -40,12 +41,18 @@ lazy_static! { struct Args { #[arg(long, short)] pub measurement: Option, + #[arg(long, short)] + pub secret: Option, } fn launch_measurement() -> Vec { MEASUREMENT.read().unwrap().clone() } +fn secret() -> Vec { + SECRET.read().unwrap().clone() +} + #[actix_web::main] async fn main() -> io::Result<()> { let args = Args::parse(); @@ -58,6 +65,14 @@ async fn main() -> io::Result<()> { m.append(&mut bytes); } + if args.secret.is_some() { + let secret = args.secret.clone().unwrap(); + + let mut bytes = hex::decode(secret).unwrap(); + let mut s = SECRET.write().unwrap(); + s.append(&mut bytes); + } + HttpServer::new(|| { App::new().service( web::scope("/kbs/v0") @@ -95,11 +110,19 @@ pub async fn attest(req: HttpRequest, attest: web::Json) let attest = attest.into_inner(); - let serde_json::Value::String(tee_evidence) = attest.tee_evidence.primary_evidence else { + let serde_json::Value::Object(tee_evidence) = attest.tee_evidence.primary_evidence else { panic!("evidence not a base64 string"); }; - let evidence = BASE64_STANDARD.decode(&tee_evidence).unwrap(); + let evidence = { + let report = tee_evidence.get("snp-report").unwrap(); + + let Value::String(s) = report else { + panic!("SNP attestation report is not represented as a base64-encoded JSON string"); + }; + + BASE64_STANDARD.decode(s).unwrap() + }; let report: AttestationReport = unsafe { std::ptr::read(evidence.as_ptr() as *const _) }; @@ -131,7 +154,11 @@ pub async fn attest(req: HttpRequest, attest: web::Json) key.push((x, y)); - HttpResponse::Ok().into() + let json = json!({ + "token": "test-token".to_string(), + }); + + HttpResponse::Ok().json(json) } #[get("/resource/default/sample/test")] @@ -142,7 +169,7 @@ pub async fn resource(_req: HttpRequest) -> HttpResponse { return HttpResponse::ExpectationFailed().into(); } - let mut payload = "attestation successful".as_bytes().to_vec(); + let mut payload = secret(); let mut rng = rand::thread_rng(); @@ -153,11 +180,11 @@ pub async fn resource(_req: HttpRequest) -> HttpResponse { let (x, y) = key.pop().unwrap(); - let x: [u8; 32] = URL_SAFE_NO_PAD.decode(x).unwrap().try_into().unwrap(); - let y: [u8; 32] = URL_SAFE_NO_PAD.decode(y).unwrap().try_into().unwrap(); + let x: [u8; 66] = URL_SAFE_NO_PAD.decode(x).unwrap().try_into().unwrap(); + let y: [u8; 66] = URL_SAFE_NO_PAD.decode(y).unwrap().try_into().unwrap(); let client_point = EncodedPoint::from_affine_coordinates( - &GenericArray::from(x), - &GenericArray::from(y), + GenericArray::from_slice(&x), + GenericArray::from_slice(&y), false, ); let public_key = PublicKey::from_encoded_point(&client_point) @@ -194,7 +221,7 @@ pub async fn resource(_req: HttpRequest) -> HttpResponse { enc: AES_GCM_256_ALGORITHM.to_string(), other_fields: json!({ "epk": { - "crv": P256_CURVE, + "crv": P521_CURVE, "kty": EC_KTY, "x": epk_x, "y": epk_y