diff --git a/0100-challenge-may-generate-by-requester-so-aa-and-as-may.patch b/0100-challenge-may-generate-by-requester-so-aa-and-as-may.patch new file mode 100644 index 0000000000000000000000000000000000000000..e750c0b25534066ceeb2f28c17c0846fcaf19cdf --- /dev/null +++ b/0100-challenge-may-generate-by-requester-so-aa-and-as-may.patch @@ -0,0 +1,155 @@ +From 54e0d971449ac9b8f30bad4f15adb82d42395dc6 Mon Sep 17 00:00:00 2001 +From: xuraoqing +Date: Tue, 11 Mar 2025 08:22:18 +0800 +Subject: [PATCH 1/3] challenge may generate by requester,so aa and as may can + not get previous session by challenge + +Signed-off-by: xuraoqing +--- + .../attestation-agent/agent/src/lib.rs | 37 ++++++------ + .../service/src/restapi/mod.rs | 57 +++++++++++-------- + 2 files changed, 51 insertions(+), 43 deletions(-) + +diff --git a/service/attestation/attestation-agent/agent/src/lib.rs b/service/attestation/attestation-agent/agent/src/lib.rs +index d1234d1..dae5559 100644 +--- a/service/attestation/attestation-agent/agent/src/lib.rs ++++ b/service/attestation/attestation-agent/agent/src/lib.rs +@@ -320,23 +320,11 @@ impl AttestationAgent { + policy_id: Option>, + ) -> Result { + let challenge = String::from_utf8_lossy(challenge).to_string(); +- let mut session = match self ++ let ss = self + .as_client_sessions + .session_map + .get_async(&challenge) +- .await +- { +- Some(entry) => entry, +- None => { +- // Challenge should be posted to service previously. +- bail!("challenge '{}' does not exist in sessions", challenge); +- } +- }; +- +- // If the session is already attested, directly use the token. +- if let Some(t) = session.get().token.as_ref() { +- return Ok(t.clone()); +- } ++ .await; + + let request_body = json!({ + "challenge": challenge, +@@ -344,9 +332,20 @@ impl AttestationAgent { + "policy_id": policy_id, + }); + let mut map = HeaderMap::new(); +- map.insert("Content-Type", HeaderValue::from_static("application/json")); +- map.insert("as-challenge", HeaderValue::from_static("as")); +- let client = session.get().as_client.clone(); ++ let client; ++ if ss.is_none() { ++ client = self.create_client(self.config.protocal.clone(), true)?; ++ map.insert("Content-Type", HeaderValue::from_static("application/json")); ++ } else { ++ // If the session is already attested, directly use the token. ++ if let Some(t) = ss.as_ref().unwrap().get().token.as_ref() { ++ return Ok(t.clone()); ++ } ++ map.insert("Content-Type", HeaderValue::from_static("application/json")); ++ map.insert("as-challenge", HeaderValue::from_static("as")); ++ client = ss.as_ref().unwrap().get().as_client.clone(); ++ } ++ + let attest_endpoint = format!("{}/attestation", self.config.svr_url); + let res = client + .post(attest_endpoint) +@@ -358,7 +357,9 @@ impl AttestationAgent { + match res.status() { + reqwest::StatusCode::OK => { + let token = res.text().await?; +- session.get_mut().token = Some(token.clone()); ++ if ss.as_ref().is_some() { ++ ss.unwrap().get_mut().token = Some(token.clone()); ++ } + log::debug!("Remote Attestation success, AS Response: {:?}", token); + Ok(token) + } +diff --git a/service/attestation/attestation-service/service/src/restapi/mod.rs b/service/attestation/attestation-service/service/src/restapi/mod.rs +index c3d6309..26a0f84 100644 +--- a/service/attestation/attestation-service/service/src/restapi/mod.rs ++++ b/service/attestation/attestation-service/service/src/restapi/mod.rs +@@ -77,30 +77,32 @@ pub async fn attestation( + let map = service.read().await.get_sessions(); + let request = request.0; + let challenge = request.challenge; +- +- if http_req.headers().contains_key("as-challenge") { +- log::warn!("attestation request lacks 'as-challenge' header field."); +- } +- +- log::info!("sessions map len:{}", map.session_map.len()); +- let cookie = http_req +- .cookie("oeas-session-id") +- .ok_or(AsError::CookieMissing)?; +- let session = map +- .session_map +- .get_async(cookie.value()) +- .await +- .ok_or(AsError::SessionNotFound)?; +- if session.is_expired() { +- return Err(AsError::SessionExpired); +- } +- if challenge != session.challenge { +- log::error!( +- "request challenge:{} does not match session challenge:{}", +- challenge, +- session.challenge +- ); +- return Err(AsError::ChallengeInvalid); ++ let mut cookie_exist = false; ++ let mut cookie = actix_web::cookie::Cookie::new("init", "init"); ++ if !http_req.headers().contains_key("as-challenge") { ++ log::info!("attestation request lacks 'as-challenge' header field."); ++ } else { ++ log::info!("sessions map len:{}", map.session_map.len()); ++ cookie = http_req ++ .cookie("oeas-session-id") ++ .ok_or(AsError::CookieMissing)?; ++ cookie_exist = true; ++ let session = map ++ .session_map ++ .get_async(cookie.value()) ++ .await ++ .ok_or(AsError::SessionNotFound)?; ++ if session.is_expired() { ++ return Err(AsError::SessionExpired); ++ } ++ if challenge != session.challenge { ++ log::error!( ++ "request challenge:{} does not match session challenge:{}", ++ challenge, ++ session.challenge ++ ); ++ return Err(AsError::ChallengeInvalid); ++ } + } + + // The challenge in evidence is base64 encoded. +@@ -113,7 +115,12 @@ pub async fn attestation( + .evaluate(&nonce, &evidence, &ids) + .await?; + +- Ok(HttpResponse::Ok().cookie(cookie).body(token)) ++ if cookie_exist { ++ Ok(HttpResponse::Ok().cookie(cookie).body(token)) ++ } else { ++ Ok(HttpResponse::Ok().body(token)) ++ } ++ + } + + #[derive(Deserialize, Serialize, Debug)] +-- +2.33.0 + diff --git a/0101-generate-random-by-ra_tls-itself.patch b/0101-generate-random-by-ra_tls-itself.patch new file mode 100644 index 0000000000000000000000000000000000000000..8dccb6f243b89bd195ccdd299453ddcebb12290c --- /dev/null +++ b/0101-generate-random-by-ra_tls-itself.patch @@ -0,0 +1,176 @@ +From 7ca3d2ff7269501d4810c10e209e18a70fdfda95 Mon Sep 17 00:00:00 2001 +From: xuraoqing +Date: Tue, 11 Mar 2025 12:41:24 +0800 +Subject: [PATCH 2/3] generate random by ra_tls itself + +Signed-off-by: xuraoqing +--- + component/ra_tls/openssl_imp.c | 14 ++++++ + component/ra_tls/ra_tls.c | 87 +++++++++------------------------- + component/ra_tls/ra_tls_imp.h | 1 + + 3 files changed, 37 insertions(+), 65 deletions(-) + +diff --git a/component/ra_tls/openssl_imp.c b/component/ra_tls/openssl_imp.c +index 82e0fd0..19bb280 100644 +--- a/component/ra_tls/openssl_imp.c ++++ b/component/ra_tls/openssl_imp.c +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include + #include "ra_tls_imp.h" + + #define OID_LEN_MAX 64 +@@ -539,6 +540,19 @@ int get_hash(ra_tls_buf *hash, ra_tls_buf *input, hash_type type) + return 0; + } + ++int get_random(uint8_t *random, size_t len) ++{ ++ if (random == NULL) { ++ printf("buf for random is empty\n"); ++ return -1; ++ } ++ if (RAND_bytes(random, len) != 1) { ++ printf("generate random failed\n"); ++ return -1; ++ } ++ return 0; ++} ++ + int generate_certificate_with_extension(ra_tls_buf *cert, ra_tls_buf *extension, ra_tls_buf *public_key, + ra_tls_buf *private_key, const char *oid) + { +diff --git a/component/ra_tls/ra_tls.c b/component/ra_tls/ra_tls.c +index eba084f..b0ba9a0 100644 +--- a/component/ra_tls/ra_tls.c ++++ b/component/ra_tls/ra_tls.c +@@ -220,64 +220,15 @@ static int get_token(ra_tls_buf *token, const char *endpoint_prefix, const char + return ret; + } + +-static char *fill_endpoint(char **endpoint, const char *prefix, const char *source) +-{ +- size_t endpoint_len = 0; +- endpoint_len = strlen(prefix) + strlen(source) + 1; +- *endpoint = malloc(endpoint_len); +- if (*endpoint == NULL) { +- return NULL; +- } +- strcpy(*endpoint, prefix); +- strcat(*endpoint, source); +- return *endpoint; +-} +- +-static char *fill_http_data(char **data, ra_tls_buf *key_hash) +-{ +- const char *http_data_format = "{\"user_data\":[]}"; +- size_t data_len = 0; +- int res; +- char *ptr; +- data_len = strlen(http_data_format) + PUBLIC_KEY_HASH_PRINT_LEN + strlen("]}") + 1; +- *data = malloc(data_len); +- if (*data == NULL) { +- return NULL; +- } +- ptr = *data; +- res = sprintf(ptr, "{\"user_data\":["); +- ptr += res; +- for (size_t i = 0; i < key_hash->filled; i++) { +- res = sprintf(ptr, "%hhu,", key_hash->buf[i]); +- ptr += res; +- if (ptr >= *data + data_len) { +- goto err; +- } +- } +- // point to last character +- --ptr; +- if (data_len - (ptr - *data) < 3) { // 3 means min buffer left to filled +- goto err; +- } +- (void)sprintf(ptr, "]}"); +- goto end; +-err: +- if (*data) { +- free(*data); +- *data = NULL; +- } +-end: +- return *data; +-} +- + static int get_challenge(ra_tls_buf *challenge, const char *endpoint_prefix, ra_tls_buf *user_data) + { + int res; + int ret = -1; +- const char *source_name = "challenge"; +- char *endpoint = NULL; +- char *http_data = NULL; ++ const size_t challenge_len = 32; // 32 means the length of challenge by default ++ size_t base64_len = 0; ++ uint8_t *base64 = NULL; + ra_tls_buf key_hash = RA_TLS_BUF_INIT; ++ ra_tls_buf challenge_raw = RA_TLS_BUF_INIT; + ra_tls_buf *pub_key = user_data; + if (endpoint_prefix == NULL || challenge == NULL || pub_key == NULL) { + return -1; +@@ -291,25 +242,31 @@ static int get_challenge(ra_tls_buf *challenge, const char *endpoint_prefix, ra_ + } + printf("\n"); + #endif +- if (fill_endpoint(&endpoint, endpoint_prefix, source_name) == NULL) { +- goto err; +- } +- if (fill_http_data(&http_data, &key_hash) == NULL) { ++// generate random 32B, concate with public key hash, then base64_url_encode ++ ra_tls_buf_init(&challenge_raw, challenge_len + key_hash.filled); ++ res = get_random(challenge_raw.buf, challenge_len); ++ if (res < 0) { ++ printf("get random failed\n"); + goto err; + } +- res = http_request(endpoint, "GET", http_data, challenge); +- if (res < 0) { ++ memcpy(challenge_raw.buf + challenge_len, key_hash.buf, key_hash.filled); ++ challenge_raw.filled = challenge_len + key_hash.filled; ++ ++ base64 = (uint8_t*)kpsecl_base64urlencode(challenge_raw.buf, challenge_raw.filled, &base64_len); ++ if (base64 == NULL) { + goto err; + } ++ ++ ra_tls_buf_init(challenge, base64_len); ++ memcpy(challenge->buf, base64, base64_len); ++ challenge->filled = base64_len; + ret = 0; + err: +- if (endpoint) { +- free(endpoint); +- } +- if (http_data) { +- free(http_data); +- } + ra_tls_buf_free(&key_hash); ++ ra_tls_buf_free(&challenge_raw); ++ if (base64) { ++ free(base64); ++ } + return ret; + } + +diff --git a/component/ra_tls/ra_tls_imp.h b/component/ra_tls/ra_tls_imp.h +index 5d85ba9..7440a8d 100644 +--- a/component/ra_tls/ra_tls_imp.h ++++ b/component/ra_tls/ra_tls_imp.h +@@ -79,6 +79,7 @@ int generate_key_pair_der(key_size key_len, ra_tls_buf *public_key, ra_tls_buf * + // generate pem certificate,use evidence filled extension specified by oid + int generate_certificate_with_extension(ra_tls_buf *cert, ra_tls_buf *evidence, ra_tls_buf *public_key, + ra_tls_buf *private_key, const char *oid); ++int get_random(uint8_t *random, size_t len); + + #if defined(USE_OPENSSL) + /* +-- +2.33.0 + diff --git a/secGear.spec b/secGear.spec index efe58e11670a81182779848507b2e0765ae0a053..6459faa381059f56d2b01a041eb9c6af3731ac98 100644 --- a/secGear.spec +++ b/secGear.spec @@ -1,6 +1,6 @@ Name: secGear Version: 0.1.0 -Release: 57 +Release: 58 Summary: secGear is an SDK to develop confidential computing apps based on hardware enclave features @@ -109,6 +109,8 @@ Patch95: 0096-fix-use-default-vendor-for-resource-policy-if-it-is-.patch Patch96: 0097-fix-fix-incorrect-error-message-when-modifying-a-non.patch Patch97: 0098-fix-avoid-clear-resource-policies-if-illegal-vendor-.patch Patch98: 0099-fix-permit-dots-in-the-resource-policy-id.patch +Patch99: 0100-challenge-may-generate-by-requester-so-aa-and-as-may.patch +Patch100: 0101-generate-random-by-ra_tls-itself.patch BuildRequires: gcc python automake autoconf libtool BUildRequires: glibc glibc-devel cmake ocaml-dune rpm gcc-c++ compat-openssl11-libs compat-openssl11-devel @@ -349,6 +351,9 @@ popd systemctl restart rsyslog %changelog +* Tue Mar 11 2025 houmingyong - 0.1.0-58 +- fix ra_tls verify failed while use evidence + * Mon Mar 10 2025 chenjiayi - 0.1.0-57 - fix permit dots in the resource policy id