diff --git a/kbs/src/api/src/http/config.rs b/kbs/src/api/src/http/config.rs index dcf46a1360..70e2d6324c 100644 --- a/kbs/src/api/src/http/config.rs +++ b/kbs/src/api/src/http/config.rs @@ -10,10 +10,10 @@ pub(crate) async fn attestation_policy( request: HttpRequest, input: web::Bytes, user_pub_key: web::Data>, - insecure: web::Data, + insecure_api: web::Data, attestation_service: web::Data>, ) -> Result { - if !insecure.get_ref() { + if !insecure_api.get_ref() { let user_pub_key = user_pub_key .as_ref() .as_ref() @@ -38,10 +38,10 @@ pub(crate) async fn resource_policy( request: HttpRequest, input: web::Json, user_pub_key: web::Data>, - insecure: web::Data, + insecure_api: web::Data, policy_engine: web::Data, ) -> Result { - if !insecure.get_ref() { + if !insecure_api.get_ref() { let user_pub_key = user_pub_key .as_ref() .as_ref() @@ -85,10 +85,10 @@ pub(crate) async fn set_resource( request: HttpRequest, data: web::Bytes, user_pub_key: web::Data>, - insecure: web::Data, + insecure_api: web::Data, repository: web::Data>>, ) -> Result { - if !insecure.get_ref() { + if !insecure_api.get_ref() { let user_pub_key = user_pub_key .as_ref() .as_ref() diff --git a/kbs/src/api/src/http/error.rs b/kbs/src/api/src/http/error.rs index 961ad68094..35598c603c 100644 --- a/kbs/src/api/src/http/error.rs +++ b/kbs/src/api/src/http/error.rs @@ -42,6 +42,9 @@ pub enum Error { #[error("The request is invalid: {0}")] InvalidRequest(String), + #[error("Cannot return plain resource data without HTTPS")] + InsecureResponse, + #[error("Json Web Encryption failed: {0}")] JWEFailed(String), diff --git a/kbs/src/api/src/http/resource.rs b/kbs/src/api/src/http/resource.rs index 8bdbae3b27..11981acaa1 100644 --- a/kbs/src/api/src/http/resource.rs +++ b/kbs/src/api/src/http/resource.rs @@ -28,6 +28,7 @@ pub(crate) async fn get_resource( #[cfg(feature = "as")] map: web::Data, token_verifier: web::Data>>, #[cfg(feature = "policy")] policy_engine: web::Data, + https_enabled: web::Data, ) -> Result { #[allow(unused_mut)] let mut claims_option = None; @@ -46,31 +47,6 @@ pub(crate) async fn get_resource( Error::AttestationClaimsParseFailed(format!("illegal attestation claims: {e}")) })?; - let pkey_value = claims - .get("customized_claims") - .ok_or(Error::AttestationClaimsParseFailed(String::from( - "No `customized_claims` in the attestation claims thus no `tee-pubkey`", - )))? - .as_object() - .ok_or(Error::AttestationClaimsParseFailed(String::from( - "`customized_claims` should be a JSON map", - )))? - .get("runtime_data") - .ok_or(Error::AttestationClaimsParseFailed(String::from( - "No `runtime_data` in the attestation claims thus no `tee-pubkey`", - )))? - .as_object() - .ok_or(Error::AttestationClaimsParseFailed(String::from( - "`runtime_data` should be a JSON map", - )))? - .get("tee-pubkey") - .ok_or(Error::AttestationClaimsParseFailed(String::from( - "No `tee-pubkey` in the attestation claims", - )))?; - let pubkey = TeePubKey::deserialize(pkey_value).map_err(|e| { - Error::AttestationClaimsParseFailed(format!("illegal attestation claims: {e}")) - })?; - let resource_description = ResourceDesc { repository_name: request .match_info() @@ -123,13 +99,24 @@ pub(crate) async fn get_resource( .await .map_err(|e| Error::ReadSecretFailed(e.to_string()))?; - let jwe = jwe(pubkey, resource_byte)?; - - let res = serde_json::to_string(&jwe).map_err(|e| Error::JWEFailed(e.to_string()))?; - - Ok(HttpResponse::Ok() - .content_type("application/json") - .body(res)) + // If public key is included in claims, use JWE to wrap resource byte, + // else check if HTTPS is enabled. + match get_pkey(claims) { + Ok(pubkey) => { + let jwe = jwe(pubkey, resource_byte)?; + let res = serde_json::to_string(&jwe).map_err(|e| Error::JWEFailed(e.to_string()))?; + Ok(HttpResponse::Ok() + .content_type("application/json") + .body(res)) + } + Err(_) => { + if !https_enabled.enabled { + return Err(Error::InsecureResponse); + } + let res = URL_SAFE_NO_PAD.encode(resource_byte); + Ok(HttpResponse::Ok().body(res)) + } + } } #[cfg(feature = "as")] @@ -243,3 +230,32 @@ pub(crate) fn jwe(tee_pub_key: TeePubKey, payload_data: Vec) -> Result Result { + let pkey_value = claims + .get("customized_claims") + .ok_or(Error::AttestationClaimsParseFailed(String::from( + "No `customized_claims` in the attestation claims thus no `tee-pubkey`", + )))? + .as_object() + .ok_or(Error::AttestationClaimsParseFailed(String::from( + "`customized_claims` should be a JSON map", + )))? + .get("runtime_data") + .ok_or(Error::AttestationClaimsParseFailed(String::from( + "No `runtime_data` in the attestation claims thus no `tee-pubkey`", + )))? + .as_object() + .ok_or(Error::AttestationClaimsParseFailed(String::from( + "`runtime_data` should be a JSON map", + )))? + .get("tee-pubkey") + .ok_or(Error::AttestationClaimsParseFailed(String::from( + "No `tee-pubkey` in the attestation claims", + )))?; + let pubkey = TeePubKey::deserialize(pkey_value).map_err(|e| { + Error::AttestationClaimsParseFailed(format!("illegal attestation claims: {e}")) + })?; + + Ok(pubkey) +} diff --git a/kbs/src/api/src/lib.rs b/kbs/src/api/src/lib.rs index 1e8866c7fd..7eeffb9828 100644 --- a/kbs/src/api/src/lib.rs +++ b/kbs/src/api/src/lib.rs @@ -278,6 +278,9 @@ impl ApiServer { }; let insecure_api = self.insecure_api; + let https_enabled = HttpsFlag { + enabled: !self.insecure, + }; let http_server = HttpServer::new(move || { #[allow(unused_mut)] @@ -285,7 +288,8 @@ impl ApiServer { .wrap(middleware::Logger::default()) .app_data(web::Data::new(http_timeout)) .app_data(web::Data::new(user_public_key.clone())) - .app_data(web::Data::new(insecure_api)); + .app_data(web::Data::new(insecure_api)) + .app_data(web::Data::new(https_enabled)); cfg_if::cfg_if! { if #[cfg(feature = "as")] { @@ -343,3 +347,8 @@ impl ApiServer { } } } + +#[derive(Clone, Copy, Debug)] +pub(crate) struct HttpsFlag { + enabled: bool, +}