!229 [sync] PR-228: fix multi thread request-as generate challenge
From: @openeuler-sync-bot Reviewed-by: @houmingyong Signed-off-by: @houmingyong
This commit is contained in:
commit
00dfdff3db
438
0085-fix-multi-thread-request-as-generate-challenge-and-v.patch
Normal file
438
0085-fix-multi-thread-request-as-generate-challenge-and-v.patch
Normal file
@ -0,0 +1,438 @@
|
||||
From f495edff1e1077f209596bca7f83a614ea5cd139 Mon Sep 17 00:00:00 2001
|
||||
From: houmingyong <houmingyong@huawei.com>
|
||||
Date: Fri, 6 Sep 2024 10:38:09 +0800
|
||||
Subject: [PATCH] fix multi-thread request as generate challenge and verify
|
||||
report error
|
||||
|
||||
Signed-off-by: houmingyong <houmingyong@huawei.com>
|
||||
---
|
||||
.../attestation/attestation-agent/Cargo.toml | 1 +
|
||||
.../attestation-agent/agent/Cargo.toml | 2 +
|
||||
.../attestation-agent/agent/src/lib.rs | 92 ++++++++++++-------
|
||||
.../attestation-agent/agent/src/session.rs | 55 +++++++++++
|
||||
.../attestation-service/service/src/main.rs | 14 +++
|
||||
.../service/src/restapi/mod.rs | 32 ++++++-
|
||||
.../service/src/result/mod.rs | 7 +-
|
||||
.../attestation/attestation-types/src/lib.rs | 2 +
|
||||
8 files changed, 169 insertions(+), 36 deletions(-)
|
||||
create mode 100644 service/attestation/attestation-agent/agent/src/session.rs
|
||||
|
||||
diff --git a/service/attestation/attestation-agent/Cargo.toml b/service/attestation/attestation-agent/Cargo.toml
|
||||
index bdc7b120..f6f31b18 100644
|
||||
--- a/service/attestation/attestation-agent/Cargo.toml
|
||||
+++ b/service/attestation/attestation-agent/Cargo.toml
|
||||
@@ -24,6 +24,7 @@ jsonwebtoken = "9.3.0"
|
||||
thiserror = "1.0"
|
||||
actix-web = "4.5"
|
||||
clap = { version = "4.5.7", features = ["derive"] }
|
||||
+scc = "2.1"
|
||||
|
||||
verifier = {path = "../attestation-service/verifier", default-features = false}
|
||||
attestation-types = {path = "../attestation-types"}
|
||||
diff --git a/service/attestation/attestation-agent/agent/Cargo.toml b/service/attestation/attestation-agent/agent/Cargo.toml
|
||||
index e29f89be..d2450c87 100644
|
||||
--- a/service/attestation/attestation-agent/agent/Cargo.toml
|
||||
+++ b/service/attestation/attestation-agent/agent/Cargo.toml
|
||||
@@ -41,6 +41,8 @@ base64-url.workspace = true
|
||||
thiserror.workspace = true
|
||||
actix-web.workspace = true
|
||||
clap.workspace = true
|
||||
+scc.workspace = true
|
||||
+attestation-types.workspace = true
|
||||
|
||||
attester = { path = "../attester" }
|
||||
token_verifier = { path = "../token" }
|
||||
diff --git a/service/attestation/attestation-agent/agent/src/lib.rs b/service/attestation/attestation-agent/agent/src/lib.rs
|
||||
index 393914d6..f6e03c6c 100644
|
||||
--- a/service/attestation/attestation-agent/agent/src/lib.rs
|
||||
+++ b/service/attestation/attestation-agent/agent/src/lib.rs
|
||||
@@ -34,9 +34,16 @@ pub type TeeClaim = serde_json::Value;
|
||||
use verifier::{Verifier, VerifierAPIs};
|
||||
|
||||
#[cfg(not(feature = "no_as"))]
|
||||
-use {serde_json::json, reqwest, base64_url};
|
||||
+use {
|
||||
+ serde_json::json,
|
||||
+ reqwest::header::{HeaderMap, HeaderValue},
|
||||
+ base64_url
|
||||
+};
|
||||
|
||||
pub use attester::EvidenceRequest;
|
||||
+mod session;
|
||||
+use session::{SessionMap, Session};
|
||||
+use attestation_types::SESSION_TIMEOUT_MIN;
|
||||
|
||||
pub type AsTokenClaim = TokenRawData;
|
||||
|
||||
@@ -171,6 +178,7 @@ impl TryFrom<&Path> for AAConfig {
|
||||
#[derive(Debug)]
|
||||
pub struct AttestationAgent {
|
||||
config: AAConfig,
|
||||
+ as_client_sessions: SessionMap,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
@@ -186,8 +194,20 @@ impl AttestationAgent {
|
||||
AAConfig::default()
|
||||
}
|
||||
};
|
||||
+ let as_client_sessions = SessionMap::new();
|
||||
+ let sessions = as_client_sessions.clone();
|
||||
+ tokio::spawn(async move {
|
||||
+ loop {
|
||||
+ tokio::time::sleep(std::time::Duration::from_secs(60)).await;
|
||||
+ sessions
|
||||
+ .session_map
|
||||
+ .retain_async(|_, v| !v.is_expired())
|
||||
+ .await;
|
||||
+ }
|
||||
+ });
|
||||
Ok(AttestationAgent {
|
||||
config,
|
||||
+ as_client_sessions,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -197,16 +217,33 @@ impl AttestationAgent {
|
||||
evidence: &[u8],
|
||||
policy_id: Option<Vec<String>>
|
||||
) -> Result<String> {
|
||||
+ let challenge = base64_url::encode(challenge);
|
||||
let request_body = json!({
|
||||
- "challenge": base64_url::encode(challenge),
|
||||
+ "challenge": challenge,
|
||||
"evidence": base64_url::encode(evidence),
|
||||
"policy_id": policy_id,
|
||||
});
|
||||
+ let mut map = HeaderMap::new();
|
||||
+ map.insert("Content-Type", HeaderValue::from_static("application/json"));
|
||||
+ let mut client = reqwest::Client::new();
|
||||
+ if !self.as_client_sessions.session_map.is_empty() {
|
||||
+ let session = self.as_client_sessions
|
||||
+ .session_map
|
||||
+ .get_async(&challenge)
|
||||
+ .await;
|
||||
+ match session {
|
||||
+ Some(entry) => {
|
||||
+ map.insert("as-challenge", HeaderValue::from_static("as"));
|
||||
+ client = entry.get().as_client.clone()
|
||||
+ },
|
||||
+ None => log::info!("challenge is not as generate"),
|
||||
+ }
|
||||
+ }
|
||||
|
||||
let attest_endpoint = format!("{}/attestation", self.config.svr_url);
|
||||
- let res = reqwest::Client::new()
|
||||
+ let res = client
|
||||
.post(attest_endpoint)
|
||||
- .header("Content-Type", "application/json")
|
||||
+ .headers(map)
|
||||
.json(&request_body)
|
||||
.send()
|
||||
.await?;
|
||||
@@ -249,16 +286,18 @@ impl AttestationAgent {
|
||||
}
|
||||
async fn get_challenge_from_as(&self) -> Result<String> {
|
||||
let challenge_endpoint = format!("{}/challenge", self.config.svr_url);
|
||||
- let res = reqwest::Client::new()
|
||||
+ let client = reqwest::Client::builder()
|
||||
+ .cookie_store(true)
|
||||
+ .build()?;
|
||||
+ let res = client
|
||||
.get(challenge_endpoint)
|
||||
.header("Content-Type", "application/json")
|
||||
.header("content-length", 0)
|
||||
- //.json(&request_body)
|
||||
.send()
|
||||
.await?;
|
||||
let challenge = match res.status() {
|
||||
reqwest::StatusCode::OK => {
|
||||
- let respone = res.text().await?;
|
||||
+ let respone: String = res.json().await.unwrap();
|
||||
log::debug!("get challenge success, AS Response: {:?}", respone);
|
||||
respone
|
||||
}
|
||||
@@ -267,6 +306,8 @@ impl AttestationAgent {
|
||||
bail!("get challenge Failed")
|
||||
}
|
||||
};
|
||||
+ let session = Session::new(challenge.clone(), client, SESSION_TIMEOUT_MIN)?;
|
||||
+ self.as_client_sessions.insert(session);
|
||||
Ok(challenge)
|
||||
}
|
||||
}
|
||||
@@ -274,12 +315,19 @@ impl AttestationAgent {
|
||||
|
||||
// attestation agent c interface
|
||||
use safer_ffi::prelude::*;
|
||||
-use futures::executor::block_on;
|
||||
use tokio::runtime::Runtime;
|
||||
|
||||
+#[ffi_export]
|
||||
+pub fn init_env_logger(c_level: Option<&repr_c::String>) {
|
||||
+ let level = match c_level {
|
||||
+ Some(level) => &level,
|
||||
+ None => "info",
|
||||
+ };
|
||||
+ env_logger::init_from_env(env_logger::Env::new().default_filter_or(level));
|
||||
+}
|
||||
+
|
||||
#[ffi_export]
|
||||
pub fn get_report(c_challenge: Option<&repr_c::Vec<u8>>, c_ima: &repr_c::TaggedOption<bool>) -> repr_c::Vec<u8> {
|
||||
- env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
|
||||
log::debug!("input challenge: {:?}, ima: {:?}", c_challenge, c_ima);
|
||||
let ima = match c_ima {
|
||||
repr_c::TaggedOption::None => false,
|
||||
@@ -295,11 +343,12 @@ pub fn get_report(c_challenge: Option<&repr_c::Vec<u8>>, c_ima: &repr_c::TaggedO
|
||||
challenge: challenge,
|
||||
ima: Some(ima),
|
||||
};
|
||||
-
|
||||
+ let rt = Runtime::new().unwrap();
|
||||
let fut = async {
|
||||
AttestationAgent::new(Some(DEFAULT_AACONFIG_FILE.to_string())).unwrap().get_evidence(input).await
|
||||
};
|
||||
- let report: Vec<u8> = match block_on(fut) {
|
||||
+ let ret = rt.block_on(fut);
|
||||
+ let report: Vec<u8> = match ret {
|
||||
Ok(report) => report,
|
||||
Err(e) => {
|
||||
log::error!("get report failed {:?}", e);
|
||||
@@ -357,24 +406,3 @@ pub fn generate_headers() -> ::std::io::Result<()> {
|
||||
.to_file("./c_header/rust_attestation_agent.h")?
|
||||
.generate()
|
||||
}
|
||||
-
|
||||
-
|
||||
-#[cfg(test)]
|
||||
-mod tests {
|
||||
- use crate::*;
|
||||
-
|
||||
- #[test]
|
||||
- fn aa_new_no_conf_path() {
|
||||
- let aa = AttestationAgent::new(None).unwrap();
|
||||
- assert_eq!(aa.config.svr_url, "http://127.0.0.1:8080");
|
||||
- assert_eq!(aa.config.token_cfg.cert, "/etc/attestation/attestation-agent/as_cert.pem");
|
||||
- assert_eq!(aa.config.token_cfg.iss, "openEulerAS");
|
||||
- }
|
||||
-
|
||||
- #[test]
|
||||
- fn aa_new_with_example_conf() {
|
||||
- let aa = AttestationAgent::new(Some("attestation-agent.conf".to_string())).unwrap();
|
||||
- assert_eq!(aa.config.token_cfg.cert, "/home/cert/as_cert.pem");
|
||||
- assert_eq!(aa.config.token_cfg.iss, "oeas");
|
||||
- }
|
||||
-}
|
||||
diff --git a/service/attestation/attestation-agent/agent/src/session.rs b/service/attestation/attestation-agent/agent/src/session.rs
|
||||
new file mode 100644
|
||||
index 00000000..5e1c1fc5
|
||||
--- /dev/null
|
||||
+++ b/service/attestation/attestation-agent/agent/src/session.rs
|
||||
@@ -0,0 +1,55 @@
|
||||
+/*
|
||||
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
|
||||
+ * secGear is licensed under the Mulan PSL v2.
|
||||
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
+ * You may obtain a copy of Mulan PSL v2 at:
|
||||
+ * http://license.coscl.org.cn/MulanPSL2
|
||||
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||
+ * PURPOSE.
|
||||
+ * See the Mulan PSL v2 for more details.
|
||||
+ */
|
||||
+use actix_web::cookie::{time::{Duration, OffsetDateTime}};
|
||||
+use scc::HashMap;
|
||||
+use anyhow::Result;
|
||||
+
|
||||
+#[derive(Debug, Clone)]
|
||||
+pub struct Session {
|
||||
+ pub challenge: String,
|
||||
+ pub as_client: reqwest::Client,
|
||||
+ timeout: OffsetDateTime,
|
||||
+ // pub token: Option<String>,
|
||||
+}
|
||||
+
|
||||
+impl Session {
|
||||
+ pub fn new(challenge: String, as_client: reqwest::Client, timeout_m: i64) -> Result<Self> {
|
||||
+
|
||||
+ let timeout = OffsetDateTime::now_utc() + Duration::minutes(timeout_m);
|
||||
+ // let token = None;
|
||||
+ Ok(Session {
|
||||
+ challenge,
|
||||
+ as_client,
|
||||
+ timeout,
|
||||
+ // token,
|
||||
+ })
|
||||
+ }
|
||||
+ pub fn is_expired(&self) -> bool {
|
||||
+ return self.timeout < OffsetDateTime::now_utc();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+#[derive(Debug, Clone)]
|
||||
+pub struct SessionMap {
|
||||
+ pub session_map: HashMap<String, Session>,
|
||||
+}
|
||||
+
|
||||
+impl SessionMap {
|
||||
+ pub fn new() -> Self {
|
||||
+ SessionMap {
|
||||
+ session_map: HashMap::new(),
|
||||
+ }
|
||||
+ }
|
||||
+ pub fn insert(&self, session: Session) {
|
||||
+ let _ = self.session_map.insert(session.challenge.clone(), session);
|
||||
+ }
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/service/attestation/attestation-service/service/src/main.rs b/service/attestation/attestation-service/service/src/main.rs
|
||||
index 3ced10b9..88941b84 100644
|
||||
--- a/service/attestation/attestation-service/service/src/main.rs
|
||||
+++ b/service/attestation/attestation-service/service/src/main.rs
|
||||
@@ -15,6 +15,7 @@ use attestation_service::AttestationService;
|
||||
mod restapi;
|
||||
use restapi::{get_challenge, attestation, reference, get_policy, set_policy};
|
||||
mod session;
|
||||
+use session::SessionMap;
|
||||
|
||||
use anyhow::Result;
|
||||
use env_logger;
|
||||
@@ -54,11 +55,24 @@ async fn main() -> Result<()> {
|
||||
|
||||
let cli = Cli::parse();
|
||||
let server:AttestationService = AttestationService::new(Some(cli.config)).unwrap();
|
||||
+ let session_map = web::Data::new(SessionMap::new());
|
||||
+
|
||||
+ let sessions_clone = session_map.clone();
|
||||
+ tokio::spawn(async move {
|
||||
+ loop {
|
||||
+ tokio::time::sleep(std::time::Duration::from_secs(60)).await;
|
||||
+ sessions_clone
|
||||
+ .session_map
|
||||
+ .retain_async(|_, v| !v.is_expired())
|
||||
+ .await;
|
||||
+ }
|
||||
+ });
|
||||
|
||||
let service = web::Data::new(Arc::new(RwLock::new(server)));
|
||||
HttpServer::new(move || {
|
||||
App::new()
|
||||
.app_data(web::Data::clone(&service))
|
||||
+ .app_data(web::Data::clone(&session_map))
|
||||
.service(get_challenge)
|
||||
.service(attestation)
|
||||
.service(reference)
|
||||
diff --git a/service/attestation/attestation-service/service/src/restapi/mod.rs b/service/attestation/attestation-service/service/src/restapi/mod.rs
|
||||
index 291b8657..a7e6012b 100644
|
||||
--- a/service/attestation/attestation-service/service/src/restapi/mod.rs
|
||||
+++ b/service/attestation/attestation-service/service/src/restapi/mod.rs
|
||||
@@ -10,7 +10,7 @@
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
use attestation_service::AttestationService;
|
||||
-use attestation_service::result::{Result};
|
||||
+use attestation_service::result::{Result, Error};
|
||||
|
||||
use actix_web::{ post, get, web, HttpResponse, HttpRequest};
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -18,6 +18,8 @@ use std::sync::Arc;
|
||||
use tokio::sync::RwLock;
|
||||
use log;
|
||||
use base64_url;
|
||||
+use attestation_types::SESSION_TIMEOUT_MIN;
|
||||
+use crate::session::{Session, SessionMap};
|
||||
|
||||
const DEFAULT_POLICY_DIR: &str = "/etc/attestation/attestation-service/policy";
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
@@ -25,12 +27,19 @@ pub struct ChallengeRequest {}
|
||||
|
||||
#[get("/challenge")]
|
||||
pub async fn get_challenge(
|
||||
+ map: web::Data<SessionMap>,
|
||||
service: web::Data<Arc<RwLock<AttestationService>>>,
|
||||
) -> Result<HttpResponse> {
|
||||
log::debug!("challenge request");
|
||||
|
||||
let challenge = service.read().await.generate_challenge().await;
|
||||
- Ok(HttpResponse::Ok().body(challenge))
|
||||
+ let session = Session::new(challenge, SESSION_TIMEOUT_MIN);
|
||||
+ let response = HttpResponse::Ok()
|
||||
+ .cookie(session.cookie())
|
||||
+ .json(session.challenge.clone());
|
||||
+ map.insert(session);
|
||||
+
|
||||
+ Ok(response)
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
@@ -42,6 +51,8 @@ pub struct AttestationRequest {
|
||||
|
||||
#[post("/attestation")]
|
||||
pub async fn attestation(
|
||||
+ http_req: HttpRequest,
|
||||
+ map: web::Data<SessionMap>,
|
||||
request: web::Json<AttestationRequest>,
|
||||
service: web::Data<Arc<RwLock<AttestationService>>>,
|
||||
) -> Result<HttpResponse> {
|
||||
@@ -49,6 +60,23 @@ pub async fn attestation(
|
||||
let request = request.0;
|
||||
let challenge = request.challenge;
|
||||
|
||||
+ if http_req.headers().contains_key("as-challenge") {
|
||||
+ log::info!("sessions map len:{}", map.session_map.len());
|
||||
+ let cookie = http_req.cookie("oeas-session-id").ok_or(Error::CookieMissing)?;
|
||||
+ let session = map
|
||||
+ .session_map
|
||||
+ .get_async(cookie.value())
|
||||
+ .await
|
||||
+ .ok_or(Error::SessionNotFound)?;
|
||||
+ if session.is_expired() {
|
||||
+ return Err(Error::SessionExpired);
|
||||
+ }
|
||||
+ if challenge != session.challenge {
|
||||
+ log::error!("request challenge:{} does not match session challenge:{}", challenge, session.challenge);
|
||||
+ return Err(Error::ChallengeInvalid);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
let nonce = base64_url::decode(&challenge).expect("base64 decode nonce");
|
||||
let evidence = base64_url::decode(&request.evidence).expect("base64 decode evidence");
|
||||
let ids = request.policy_id;
|
||||
diff --git a/service/attestation/attestation-service/service/src/result/mod.rs b/service/attestation/attestation-service/service/src/result/mod.rs
|
||||
index 667e80f5..fcb1c123 100644
|
||||
--- a/service/attestation/attestation-service/service/src/result/mod.rs
|
||||
+++ b/service/attestation/attestation-service/service/src/result/mod.rs
|
||||
@@ -38,12 +38,15 @@ pub enum Error {
|
||||
#[error("Request cookie is missing")]
|
||||
CookieMissing,
|
||||
|
||||
- #[error("Request cookie is not found")]
|
||||
- CookieNotFound,
|
||||
+ #[error("Request cookie session is not found")]
|
||||
+ SessionNotFound,
|
||||
|
||||
#[error("The session of request cookie is expired")]
|
||||
SessionExpired,
|
||||
|
||||
+ #[error("Request challenge is invalid")]
|
||||
+ ChallengeInvalid,
|
||||
+
|
||||
#[error(transparent)]
|
||||
Other(#[from] anyhow::Error),
|
||||
}
|
||||
diff --git a/service/attestation/attestation-types/src/lib.rs b/service/attestation/attestation-types/src/lib.rs
|
||||
index fcf1d3ee..67dcf9f8 100644
|
||||
--- a/service/attestation/attestation-types/src/lib.rs
|
||||
+++ b/service/attestation/attestation-types/src/lib.rs
|
||||
@@ -12,6 +12,8 @@
|
||||
use serde::{Serialize, Deserialize};
|
||||
use serde_json::Value;
|
||||
|
||||
+pub const SESSION_TIMEOUT_MIN: i64 = 1;
|
||||
+
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct VirtccaEvidence {
|
||||
pub evidence: Vec<u8>,
|
||||
--
|
||||
2.46.0
|
||||
|
||||
680
0086-add-error-type-for-api.patch
Normal file
680
0086-add-error-type-for-api.patch
Normal file
@ -0,0 +1,680 @@
|
||||
From fae0b444629f5cd20a544d5513870d9435f72ef0 Mon Sep 17 00:00:00 2001
|
||||
From: xuraoqing <xuraoqing@huawei.com>
|
||||
Date: Mon, 9 Sep 2024 19:23:48 +0800
|
||||
Subject: [PATCH] add error type for api
|
||||
|
||||
Signed-off-by: houmingyong <houmingyong@huawei.com>
|
||||
---
|
||||
.../agent/src/bin/aa-test/main.rs | 1 +
|
||||
.../attestation-agent/agent/src/lib.rs | 24 +++++++--
|
||||
.../agent/src/restapi/mod.rs | 31 +++++++-----
|
||||
.../attestation-agent/agent/src/result/mod.rs | 8 +++
|
||||
.../attestation-agent/token/Cargo.toml | 3 +-
|
||||
.../attestation-agent/token/src/lib.rs | 49 +++++++++----------
|
||||
.../policy/src/policy_engine.rs | 3 ++
|
||||
.../attestation-service/reference/Cargo.toml | 3 +-
|
||||
.../reference/src/reference/mod.rs | 39 ++++-----------
|
||||
.../reference/src/store/mod.rs | 9 ++++
|
||||
.../attestation-service/service/src/lib.rs | 9 ++--
|
||||
.../service/src/restapi/mod.rs | 25 +++-------
|
||||
.../service/src/result/mod.rs | 20 ++++++++
|
||||
.../attestation-service/token/Cargo.toml | 3 +-
|
||||
.../attestation-service/token/src/lib.rs | 33 +++++++++----
|
||||
15 files changed, 153 insertions(+), 107 deletions(-)
|
||||
|
||||
diff --git a/service/attestation/attestation-agent/agent/src/bin/aa-test/main.rs b/service/attestation/attestation-agent/agent/src/bin/aa-test/main.rs
|
||||
index 48e3e68e..4867a234 100644
|
||||
--- a/service/attestation/attestation-agent/agent/src/bin/aa-test/main.rs
|
||||
+++ b/service/attestation/attestation-agent/agent/src/bin/aa-test/main.rs
|
||||
@@ -169,6 +169,7 @@ async fn aa_proc(i: i64) {
|
||||
}
|
||||
status => {
|
||||
log::error!("thread {} case6 verify token failed response: {:?}", i, status);
|
||||
+ log::error!("thread case6 verify token failed response:{}", res.text().await.unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/service/attestation/attestation-agent/agent/src/lib.rs b/service/attestation/attestation-agent/agent/src/lib.rs
|
||||
index f6e03c6c..f1c4510b 100644
|
||||
--- a/service/attestation/attestation-agent/agent/src/lib.rs
|
||||
+++ b/service/attestation/attestation-agent/agent/src/lib.rs
|
||||
@@ -22,6 +22,7 @@ use async_trait::async_trait;
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
use rand::RngCore;
|
||||
+use thiserror;
|
||||
|
||||
use attester::{Attester, AttesterAPIs};
|
||||
use token_verifier::{TokenVerifyConfig, TokenVerifier, TokenRawData};
|
||||
@@ -30,6 +31,22 @@ pub mod result;
|
||||
use result::Error;
|
||||
pub type TeeClaim = serde_json::Value;
|
||||
|
||||
+#[derive(Debug, thiserror::Error)]
|
||||
+pub enum AgentError {
|
||||
+ #[error("challenge error: {0}")]
|
||||
+ ChallengeError(String),
|
||||
+ #[error("get evidence error: {0}")]
|
||||
+ DecodeError(String),
|
||||
+ #[error("get evidence error: {0}")]
|
||||
+ GetEvidenceError(String),
|
||||
+ #[error("verify evidence error: {0}")]
|
||||
+ VerifyEvidenceError(String),
|
||||
+ #[error("get token error: {0}")]
|
||||
+ GetTokenError(String),
|
||||
+ #[error("verify token error: {0}")]
|
||||
+ VerifyTokenError(String),
|
||||
+}
|
||||
+
|
||||
#[cfg(feature = "no_as")]
|
||||
use verifier::{Verifier, VerifierAPIs};
|
||||
|
||||
@@ -136,11 +153,8 @@ impl AttestationAgentAPIs for AttestationAgent {
|
||||
|
||||
async fn verify_token(&self, token: String) -> Result<AsTokenClaim> {
|
||||
let verifier = TokenVerifier::new(self.config.token_cfg.clone())?;
|
||||
- let result = verifier.verify(&token);
|
||||
- match result {
|
||||
- Ok(raw_token) => Ok(raw_token as AsTokenClaim),
|
||||
- Err(e) => bail!("verify token failed {:?}", e),
|
||||
- }
|
||||
+ let result = verifier.verify(&token)?;
|
||||
+ Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/service/attestation/attestation-agent/agent/src/restapi/mod.rs b/service/attestation/attestation-agent/agent/src/restapi/mod.rs
|
||||
index 490242aa..0570060b 100644
|
||||
--- a/service/attestation/attestation-agent/agent/src/restapi/mod.rs
|
||||
+++ b/service/attestation/attestation-agent/agent/src/restapi/mod.rs
|
||||
@@ -9,7 +9,7 @@
|
||||
* PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
-use attestation_agent::{AttestationAgent, AttestationAgentAPIs, TokenRequest};
|
||||
+use attestation_agent::{AttestationAgent, AttestationAgentAPIs, TokenRequest, AgentError};
|
||||
use attestation_agent::result::Result;
|
||||
|
||||
use actix_web::{ post, get, web, HttpResponse};
|
||||
@@ -18,7 +18,6 @@ use serde::{Deserialize, Serialize};
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::RwLock;
|
||||
use log;
|
||||
-use base64_url;
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
struct GetChallengeRequest {}
|
||||
@@ -30,7 +29,8 @@ pub async fn get_challenge(
|
||||
) -> Result<HttpResponse> {
|
||||
//let request = request.0;
|
||||
log::debug!("get challenge request");
|
||||
- let challenge = agent.read().await.get_challenge().await?;
|
||||
+ let challenge = agent.read().await.get_challenge().await
|
||||
+ .map_err(|err| AgentError::ChallengeError(err.to_string()))?;
|
||||
|
||||
Ok(HttpResponse::Ok().body(challenge))
|
||||
}
|
||||
@@ -49,7 +49,8 @@ pub async fn get_evidence(
|
||||
) -> Result<HttpResponse> {
|
||||
let request = request.0;
|
||||
log::debug!("get evidence request: {:?}", request);
|
||||
- let challenge = base64_url::decode(&request.challenge).expect("base64 decode challenge");
|
||||
+ let challenge = base64_url::decode(&request.challenge)
|
||||
+ .map_err(|err|AgentError::DecodeError(err.to_string()))?;
|
||||
let uuid = request.uuid;
|
||||
let ima = request.ima;
|
||||
let input = EvidenceRequest {
|
||||
@@ -57,7 +58,8 @@ pub async fn get_evidence(
|
||||
challenge: challenge,
|
||||
ima: ima,
|
||||
};
|
||||
- let evidence = agent.read().await.get_evidence(input).await?;
|
||||
+ let evidence = agent.read().await.get_evidence(input).await
|
||||
+ .map_err(|err|AgentError::GetEvidenceError(err.to_string()))?;
|
||||
|
||||
|
||||
Ok(HttpResponse::Ok().body(evidence))
|
||||
@@ -76,11 +78,13 @@ pub async fn verify_evidence(
|
||||
) -> Result<HttpResponse> {
|
||||
let request = request.0;
|
||||
log::debug!("verify evidence request: {:?}", request);
|
||||
- let challenge = base64_url::decode(&request.challenge).expect("base64 decode challenge");
|
||||
+ let challenge = base64_url::decode(&"request.challenge".to_string())
|
||||
+ .map_err(|err|AgentError::DecodeError(err.to_string()))?;
|
||||
let evidence = request.evidence;
|
||||
let policy_id = request.policy_id;
|
||||
|
||||
- let claim = agent.read().await.verify_evidence(&challenge, evidence.as_bytes(), policy_id).await?;
|
||||
+ let claim = agent.read().await.verify_evidence(&challenge, evidence.as_bytes(), policy_id).await
|
||||
+ .map_err(|err|AgentError::VerifyEvidenceError(err.to_string()))?;
|
||||
let string_claim = serde_json::to_string(&claim)?;
|
||||
|
||||
Ok(HttpResponse::Ok().body(string_claim))
|
||||
@@ -101,7 +105,8 @@ pub async fn get_token(
|
||||
) -> Result<HttpResponse> {
|
||||
let request = request.0;
|
||||
log::debug!("get token request: {:?}", request);
|
||||
- let challenge = base64_url::decode(&request.challenge).expect("base64 decode challenge");
|
||||
+ let challenge = base64_url::decode(&request.challenge)
|
||||
+ .map_err(|err|AgentError::DecodeError(err.to_string()))?;
|
||||
let uuid = request.uuid;
|
||||
let ima = request.ima;
|
||||
let policy_id = request.policy_id;
|
||||
@@ -115,8 +120,8 @@ pub async fn get_token(
|
||||
policy_id: policy_id,
|
||||
};
|
||||
|
||||
- let token = agent.read().await.get_token(input).await?;
|
||||
-
|
||||
+ let token = agent.read().await.get_token(input).await
|
||||
+ .map_err(|err|AgentError::GetTokenError(err.to_string()))?;
|
||||
|
||||
Ok(HttpResponse::Ok().body(token))
|
||||
}
|
||||
@@ -133,8 +138,10 @@ pub async fn verify_token(
|
||||
let request = request.0;
|
||||
log::debug!("verify token request: {:?}", request);
|
||||
|
||||
- let claim = agent.read().await.verify_token(request.token).await?;
|
||||
- let string_claim = serde_json::to_string(&claim)?;
|
||||
+ let claim = agent.read().await.verify_token(request.token).await
|
||||
+ .map_err(|err|AgentError::VerifyTokenError(err.to_string()))?;
|
||||
+ let string_claim = serde_json::to_string(&claim)
|
||||
+ .map_err(|err|AgentError::VerifyTokenError(err.to_string()))?;
|
||||
|
||||
Ok(HttpResponse::Ok().body(string_claim))
|
||||
}
|
||||
\ No newline at end of file
|
||||
diff --git a/service/attestation/attestation-agent/agent/src/result/mod.rs b/service/attestation/attestation-agent/agent/src/result/mod.rs
|
||||
index f06f064b..a33be0cb 100644
|
||||
--- a/service/attestation/attestation-agent/agent/src/result/mod.rs
|
||||
+++ b/service/attestation/attestation-agent/agent/src/result/mod.rs
|
||||
@@ -11,6 +11,8 @@
|
||||
*/
|
||||
use actix_web::{body::BoxBody, HttpResponse, ResponseError};
|
||||
|
||||
+use crate::AgentError;
|
||||
+
|
||||
pub type Result<T, E = Error> = std::result::Result<T, E>;
|
||||
|
||||
/// libdevice error
|
||||
@@ -30,6 +32,12 @@ pub enum Error {
|
||||
source: actix_web::error::Error,
|
||||
},
|
||||
|
||||
+ #[error("Agent error: {source:?}")]
|
||||
+ Agent {
|
||||
+ #[from]
|
||||
+ source: AgentError,
|
||||
+ },
|
||||
+
|
||||
#[error("Deserialize error: {source:?}")]
|
||||
Deserialize {
|
||||
#[from]
|
||||
diff --git a/service/attestation/attestation-agent/token/Cargo.toml b/service/attestation/attestation-agent/token/Cargo.toml
|
||||
index aa5cafcf..916f2a2e 100644
|
||||
--- a/service/attestation/attestation-agent/token/Cargo.toml
|
||||
+++ b/service/attestation/attestation-agent/token/Cargo.toml
|
||||
@@ -10,4 +10,5 @@ jsonwebtoken.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
anyhow.workspace = true
|
||||
-attestation-types.workspace = true
|
||||
\ No newline at end of file
|
||||
+attestation-types.workspace = true
|
||||
+thiserror.workspace = true
|
||||
\ No newline at end of file
|
||||
diff --git a/service/attestation/attestation-agent/token/src/lib.rs b/service/attestation/attestation-agent/token/src/lib.rs
|
||||
index 50a7a7a0..37aab9eb 100644
|
||||
--- a/service/attestation/attestation-agent/token/src/lib.rs
|
||||
+++ b/service/attestation/attestation-agent/token/src/lib.rs
|
||||
@@ -9,12 +9,23 @@
|
||||
* PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
-use anyhow::{Result, bail};
|
||||
use std::path::Path;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use jsonwebtoken::{decode, decode_header, Algorithm, DecodingKey, Validation };
|
||||
use attestation_types::Claims;
|
||||
|
||||
+#[derive(thiserror::Error, Debug)]
|
||||
+pub enum VerifyError {
|
||||
+ #[error("parse fail:{0:?}")]
|
||||
+ CommError(#[from] jsonwebtoken::errors::Error),
|
||||
+ #[error("unknown algorithm:{0}")]
|
||||
+ UnknownAlg(String),
|
||||
+ #[error("certificate not exist:{0}")]
|
||||
+ CertNotExist(String),
|
||||
+ #[error("serialize fail:{0}")]
|
||||
+ SerializeFail(#[from] serde_json::error::Error),
|
||||
+}
|
||||
+
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct TokenVerifyConfig {
|
||||
pub cert: String, // Attestation Service cert to verify jwt token signature
|
||||
@@ -52,7 +63,7 @@ pub struct TokenRawData {
|
||||
}
|
||||
|
||||
impl TokenVerifier {
|
||||
- pub fn new(config: TokenVerifyConfig) -> Result<Self> {
|
||||
+ pub fn new(config: TokenVerifyConfig) -> Result<Self, VerifyError> {
|
||||
Ok(TokenVerifier { config })
|
||||
}
|
||||
fn support_rs(alg: &Algorithm) -> bool
|
||||
@@ -72,43 +83,29 @@ impl TokenVerifier {
|
||||
pub fn verify(
|
||||
&self,
|
||||
token: &String
|
||||
- ) -> Result<TokenRawData> {
|
||||
- let header = match decode_header(&token) {
|
||||
- Ok(h) => h,
|
||||
- Err(e) => bail!("decode jwt header error {:?}", e),
|
||||
- };
|
||||
+ ) -> Result<TokenRawData, VerifyError> {
|
||||
+ let header = decode_header(&token)?;
|
||||
let alg: Algorithm = header.alg;
|
||||
|
||||
if !Self::support_rs(&alg) && !Self::support_ps(&alg) {
|
||||
- bail!("unknown algrithm {:?}", alg);
|
||||
+ return Err(VerifyError::UnknownAlg(format!("unknown algrithm {:?}", alg)));
|
||||
}
|
||||
if !Path::new(&self.config.cert).exists() {
|
||||
- bail!("token verfify failed, {:?} cert not exist", self.config.cert);
|
||||
+ return Err(VerifyError::CertNotExist(format!("{:?} not exist", self.config.cert)));
|
||||
}
|
||||
let cert = std::fs::read(&self.config.cert).unwrap();
|
||||
|
||||
/* 使用配置的公钥 */
|
||||
- let key_value: DecodingKey = match DecodingKey::from_rsa_pem(&cert)
|
||||
- {
|
||||
- Ok(key) => key,
|
||||
- Err(e) => bail!("get key from pem error {:?}", e),
|
||||
- };
|
||||
+ let key_value: DecodingKey = DecodingKey::from_rsa_pem(&cert)?;
|
||||
|
||||
let mut validation = Validation::new(alg);
|
||||
validation.set_issuer(&[self.config.iss.clone()]);
|
||||
validation.validate_exp = true;
|
||||
|
||||
- let data = decode::<Claims>(&token, &key_value, &validation);
|
||||
- match data {
|
||||
- Ok(d) => {
|
||||
- let header = d.header.clone();
|
||||
- let claims = d.claims.clone();
|
||||
- Ok(TokenRawData {
|
||||
- header: serde_json::to_string(&header).unwrap(),
|
||||
- claim: serde_json::to_string(&claims).unwrap(),
|
||||
- })
|
||||
- }
|
||||
- Err(e) => bail!("verfiy jwt failed {:?}", e),
|
||||
- }
|
||||
+ let data = decode::<Claims>(&token, &key_value, &validation)?;
|
||||
+ Ok(TokenRawData {
|
||||
+ header: serde_json::to_string(&data.header)?,
|
||||
+ claim: serde_json::to_string(&data.claims)?,
|
||||
+ })
|
||||
}
|
||||
}
|
||||
diff --git a/service/attestation/attestation-service/policy/src/policy_engine.rs b/service/attestation/attestation-service/policy/src/policy_engine.rs
|
||||
index a03a8cc8..7a8508ef 100644
|
||||
--- a/service/attestation/attestation-service/policy/src/policy_engine.rs
|
||||
+++ b/service/attestation/attestation-service/policy/src/policy_engine.rs
|
||||
@@ -10,6 +10,7 @@
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
use std::{collections::HashMap, fmt::Display};
|
||||
+
|
||||
#[derive(Debug)]
|
||||
pub enum PolicyEngineError {
|
||||
InvalidPolicy(String),
|
||||
@@ -50,6 +51,8 @@ impl Display for PolicyEngineError {
|
||||
}
|
||||
}
|
||||
|
||||
+impl std::error::Error for PolicyEngineError {}
|
||||
+
|
||||
pub trait PolicyEngine {
|
||||
fn evaluate(
|
||||
&self,
|
||||
diff --git a/service/attestation/attestation-service/reference/Cargo.toml b/service/attestation/attestation-service/reference/Cargo.toml
|
||||
index b36991e7..fb0a4bbb 100644
|
||||
--- a/service/attestation/attestation-service/reference/Cargo.toml
|
||||
+++ b/service/attestation/attestation-service/reference/Cargo.toml
|
||||
@@ -13,4 +13,5 @@ base64.workspace = true
|
||||
sled.workspace = true
|
||||
openssl.workspace = true
|
||||
hex.workspace = true
|
||||
-lazy_static.workspace = true
|
||||
\ No newline at end of file
|
||||
+lazy_static.workspace = true
|
||||
+thiserror.workspace = true
|
||||
\ No newline at end of file
|
||||
diff --git a/service/attestation/attestation-service/reference/src/reference/mod.rs b/service/attestation/attestation-service/reference/src/reference/mod.rs
|
||||
index bf56c854..6ec43714 100644
|
||||
--- a/service/attestation/attestation-service/reference/src/reference/mod.rs
|
||||
+++ b/service/attestation/attestation-service/reference/src/reference/mod.rs
|
||||
@@ -15,6 +15,7 @@ use crate::store::{KvError, KvStore};
|
||||
use openssl::sha::sha256;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::{json, Value};
|
||||
+use thiserror::{self, Error};
|
||||
|
||||
pub struct ReferenceOps {
|
||||
store: Box<dyn KvStore>,
|
||||
@@ -40,16 +41,12 @@ pub struct Ref {
|
||||
pub value: Value,
|
||||
}
|
||||
|
||||
-#[derive(Debug, PartialEq)]
|
||||
+#[derive(Error, Debug, PartialEq)]
|
||||
pub enum RefOpError {
|
||||
+ #[error("reference operation error {0}")]
|
||||
Err(String),
|
||||
-}
|
||||
-impl From<KvError> for RefOpError {
|
||||
- fn from(value: KvError) -> Self {
|
||||
- match value {
|
||||
- KvError::Err(v) => RefOpError::Err(v),
|
||||
- }
|
||||
- }
|
||||
+ #[error("reference store error: {0:?}")]
|
||||
+ StoreErr(#[from] KvError)
|
||||
}
|
||||
|
||||
impl ReferenceOps {
|
||||
@@ -68,36 +65,20 @@ impl ReferenceOps {
|
||||
fn register_reference(&mut self, reference: &Ref) -> Result<(), RefOpError> {
|
||||
// generate reference key
|
||||
let key = Self::generate_reference_key(reference);
|
||||
- match self.store.write(
|
||||
+ self.store.write(
|
||||
&key,
|
||||
serde_json::to_string(&reference)
|
||||
.unwrap()
|
||||
.as_bytes()
|
||||
.as_ref(),
|
||||
- ) {
|
||||
- Ok(_) => {
|
||||
- return Ok(());
|
||||
- }
|
||||
- Err(err) => match err {
|
||||
- KvError::Err(err) => {
|
||||
- return Err(RefOpError::Err(err));
|
||||
- }
|
||||
- },
|
||||
- }
|
||||
+ )?;
|
||||
+ Ok(())
|
||||
}
|
||||
|
||||
fn unregister_reference(&mut self, reference: &Ref) -> Result<(), RefOpError> {
|
||||
let key = Self::generate_reference_key(reference);
|
||||
- match self.store.delete(&key) {
|
||||
- Ok(_) => {
|
||||
- return Ok(());
|
||||
- }
|
||||
- Err(err) => match err {
|
||||
- KvError::Err(err) => {
|
||||
- return Err(RefOpError::Err(err));
|
||||
- }
|
||||
- },
|
||||
- }
|
||||
+ self.store.delete(&key)?;
|
||||
+ Ok(())
|
||||
}
|
||||
|
||||
fn query_reference(&mut self, reference: &Ref) -> Option<Vec<u8>> {
|
||||
diff --git a/service/attestation/attestation-service/reference/src/store/mod.rs b/service/attestation/attestation-service/reference/src/store/mod.rs
|
||||
index c8c82607..c9597f6a 100644
|
||||
--- a/service/attestation/attestation-service/reference/src/store/mod.rs
|
||||
+++ b/service/attestation/attestation-service/reference/src/store/mod.rs
|
||||
@@ -9,9 +9,18 @@
|
||||
* PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
+#[derive(Debug, PartialEq)]
|
||||
pub enum KvError {
|
||||
Err(String),
|
||||
}
|
||||
+impl std::fmt::Display for KvError {
|
||||
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
+ match self {
|
||||
+ KvError::Err(msg) => write!(f, "kv store error:{}", msg)
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+impl std::error::Error for KvError {}
|
||||
pub trait KvStore {
|
||||
fn write(&mut self, key: &str, value: &[u8]) -> Result<(), KvError>;
|
||||
fn read(&mut self, key: &str) -> Option<Vec<u8>>;
|
||||
diff --git a/service/attestation/attestation-service/service/src/lib.rs b/service/attestation/attestation-service/service/src/lib.rs
|
||||
index 3ec73d3d..31e6305d 100644
|
||||
--- a/service/attestation/attestation-service/service/src/lib.rs
|
||||
+++ b/service/attestation/attestation-service/service/src/lib.rs
|
||||
@@ -134,7 +134,7 @@ impl AttestationService {
|
||||
Ok(eval) => {
|
||||
for id in eval.keys() {
|
||||
let val = Value::from_str(&eval[id].clone())?;
|
||||
- let refs = match val.as_object().ok_or(Err(anyhow!(""))) {
|
||||
+ let refs = match val.as_object().ok_or(Err(anyhow!("json value to map fail"))) {
|
||||
Err(err) => { return Err(err.unwrap()); }
|
||||
Ok(ret) => { ret }
|
||||
};
|
||||
@@ -165,7 +165,7 @@ impl AttestationService {
|
||||
// demo get signer, todo default signer
|
||||
let signer = TokenSigner::new(self.config.token_cfg.clone())?;
|
||||
|
||||
- signer.sign(&evl_report)
|
||||
+ Ok(signer.sign(&evl_report)?)
|
||||
}
|
||||
|
||||
pub async fn generate_challenge(&self) -> String {
|
||||
@@ -174,7 +174,6 @@ impl AttestationService {
|
||||
base64_url::encode(&nonce)
|
||||
}
|
||||
|
||||
- // todo pub fun set policy
|
||||
pub async fn set_policy(&self,
|
||||
id: &String,
|
||||
policy: &String,
|
||||
@@ -185,7 +184,7 @@ impl AttestationService {
|
||||
.set_policy(id, policy)
|
||||
.await
|
||||
}
|
||||
- // todo pub fun get policy
|
||||
+
|
||||
pub async fn get_policy(&self,
|
||||
policy_dir: &String,
|
||||
) -> Result<String, PolicyEngineError> {
|
||||
@@ -203,7 +202,7 @@ impl AttestationService {
|
||||
Err(err) => Err(err)
|
||||
}
|
||||
}
|
||||
- // todo pub fun import reference value
|
||||
+
|
||||
pub async fn register_reference(&self,
|
||||
ref_set: &String
|
||||
) -> Result<(), RefOpError> {
|
||||
diff --git a/service/attestation/attestation-service/service/src/restapi/mod.rs b/service/attestation/attestation-service/service/src/restapi/mod.rs
|
||||
index a7e6012b..f49d1755 100644
|
||||
--- a/service/attestation/attestation-service/service/src/restapi/mod.rs
|
||||
+++ b/service/attestation/attestation-service/service/src/restapi/mod.rs
|
||||
@@ -77,8 +77,8 @@ pub async fn attestation(
|
||||
}
|
||||
}
|
||||
|
||||
- let nonce = base64_url::decode(&challenge).expect("base64 decode nonce");
|
||||
- let evidence = base64_url::decode(&request.evidence).expect("base64 decode evidence");
|
||||
+ let nonce = base64_url::decode(&challenge)?;
|
||||
+ let evidence = base64_url::decode(&request.evidence)?;
|
||||
let ids = request.policy_id;
|
||||
let token = service.read().await.evaluate(&nonce, &evidence, &ids).await?;
|
||||
|
||||
@@ -97,10 +97,8 @@ pub async fn reference(
|
||||
) -> Result<HttpResponse> {
|
||||
let request = request.0;
|
||||
log::debug!("reference request: {:?}", request);
|
||||
- match service.read().await.register_reference(&request.refs).await {
|
||||
- Ok(_) => Ok(HttpResponse::Ok().body("set reference success")),
|
||||
- Err(_err) => Ok(HttpResponse::Ok().body("set reference fail")),
|
||||
- }
|
||||
+ service.read().await.register_reference(&request.refs).await?;
|
||||
+ Ok(HttpResponse::Ok().body("set reference success"))
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
@@ -120,13 +118,8 @@ pub async fn set_policy(
|
||||
let policy_id = request.id.clone();
|
||||
let policy = request.policy.clone();
|
||||
let dir:String = String::from(DEFAULT_POLICY_DIR);
|
||||
- match service.read().await.set_policy(&policy_id, &policy, &dir).await {
|
||||
- Ok(_) => Ok(HttpResponse::Ok().body("set policy success")),
|
||||
- Err(err) => {
|
||||
- log::debug!("set policy error: {:?}", err);
|
||||
- Ok(HttpResponse::Ok().body("set policy fail"))
|
||||
- }
|
||||
- }
|
||||
+ service.read().await.set_policy(&policy_id, &policy, &dir).await?;
|
||||
+ Ok(HttpResponse::Ok().body("set policy success"))
|
||||
}
|
||||
|
||||
#[get("/policy")]
|
||||
@@ -136,8 +129,6 @@ pub async fn get_policy(
|
||||
) -> Result<HttpResponse> {
|
||||
log::debug!("get policy request: {:?}", request);
|
||||
let dir:String = String::from(DEFAULT_POLICY_DIR);
|
||||
- match service.read().await.get_policy(&dir).await {
|
||||
- Ok(ret) => Ok(HttpResponse::Ok().body(ret)),
|
||||
- Err(_err) => Ok(HttpResponse::Ok().body("get policy fail")),
|
||||
- }
|
||||
+ let ret = service.read().await.get_policy(&dir).await?;
|
||||
+ Ok(HttpResponse::Ok().body(ret))
|
||||
}
|
||||
diff --git a/service/attestation/attestation-service/service/src/result/mod.rs b/service/attestation/attestation-service/service/src/result/mod.rs
|
||||
index fcb1c123..7261d19b 100644
|
||||
--- a/service/attestation/attestation-service/service/src/result/mod.rs
|
||||
+++ b/service/attestation/attestation-service/service/src/result/mod.rs
|
||||
@@ -22,6 +22,26 @@ pub enum Error {
|
||||
#[from]
|
||||
source: std::io::Error,
|
||||
},
|
||||
+ #[error("attestation error: {source:?}")]
|
||||
+ DecodeError {
|
||||
+ #[from]
|
||||
+ source: base64::DecodeError,
|
||||
+ },
|
||||
+ #[error("Policy Engine error: {source:?}")]
|
||||
+ PolicyEngine {
|
||||
+ #[from]
|
||||
+ source: policy::policy_engine::PolicyEngineError,
|
||||
+ },
|
||||
+ #[error("Reference error: {source:?}")]
|
||||
+ Reference {
|
||||
+ #[from]
|
||||
+ source: reference::reference::RefOpError,
|
||||
+ },
|
||||
+ #[error("Sign error: {source:?}")]
|
||||
+ Sign {
|
||||
+ #[from]
|
||||
+ source: token_signer::SignError,
|
||||
+ },
|
||||
|
||||
#[error("Web error: {source:?}")]
|
||||
Web {
|
||||
diff --git a/service/attestation/attestation-service/token/Cargo.toml b/service/attestation/attestation-service/token/Cargo.toml
|
||||
index c4b885c0..029008a1 100644
|
||||
--- a/service/attestation/attestation-service/token/Cargo.toml
|
||||
+++ b/service/attestation/attestation-service/token/Cargo.toml
|
||||
@@ -10,4 +10,5 @@ jsonwebtoken.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
anyhow.workspace = true
|
||||
-attestation-types.workspace = true
|
||||
\ No newline at end of file
|
||||
+attestation-types.workspace = true
|
||||
+thiserror.workspace = true
|
||||
\ No newline at end of file
|
||||
diff --git a/service/attestation/attestation-service/token/src/lib.rs b/service/attestation/attestation-service/token/src/lib.rs
|
||||
index ed41a4ec..3ee785e5 100644
|
||||
--- a/service/attestation/attestation-service/token/src/lib.rs
|
||||
+++ b/service/attestation/attestation-service/token/src/lib.rs
|
||||
@@ -9,7 +9,7 @@
|
||||
* PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
-use anyhow::{Result, bail};
|
||||
+use anyhow::{Result};
|
||||
use jsonwebtoken::{encode, get_current_timestamp,
|
||||
Algorithm, EncodingKey, Header,
|
||||
};
|
||||
@@ -17,7 +17,21 @@ use std::path::Path;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
use attestation_types::{EvlResult, Claims};
|
||||
+use thiserror;
|
||||
|
||||
+#[derive(thiserror::Error, Debug)]
|
||||
+pub enum SignError {
|
||||
+ #[error("get unix time fail:{0:?}")]
|
||||
+ ToUnixTimeFail(#[from] std::num::TryFromIntError),
|
||||
+ #[error("unsupport algorith:{0}")]
|
||||
+ UnsupportAlg(String),
|
||||
+ #[error("key not exist:{0}")]
|
||||
+ KeyNotExist(String),
|
||||
+ #[error("key content read fail:{0}")]
|
||||
+ ReadKeyFail(String),
|
||||
+ #[error("sign fail:{0:?}")]
|
||||
+ SignFail(#[from] jsonwebtoken::errors::Error)
|
||||
+}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct TokenSignConfig {
|
||||
@@ -79,36 +93,35 @@ impl TokenSigner {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
- pub fn sign(&self, report: &EvlReport) -> Result<String> {
|
||||
+ pub fn sign(&self, report: &EvlReport) -> Result<String, SignError> {
|
||||
let alg: Algorithm = self.config.alg;
|
||||
let mut header = Header::new(alg);
|
||||
header.typ = Some("JWT".to_string());
|
||||
let unix_time = get_current_timestamp();
|
||||
let claims: Claims = Claims {
|
||||
iss: self.config.iss.clone(),
|
||||
- iat: usize::try_from(unix_time).expect("unix time to usize error"),
|
||||
- nbf: usize::try_from(unix_time).expect("unix time to usize error"),
|
||||
- exp: usize::try_from(unix_time).expect("unix time to usize error")
|
||||
- + self.config.valid_duration,
|
||||
+ iat: usize::try_from(unix_time)?,
|
||||
+ nbf: usize::try_from(unix_time)?,
|
||||
+ exp: usize::try_from(unix_time)? + self.config.valid_duration,
|
||||
evaluation_reports: report.result.clone(),
|
||||
tee: report.tee.clone(),
|
||||
tcb_status: report.tcb_status.clone(),
|
||||
};
|
||||
if !Self::support_rs(&alg) && !Self::support_ps(&alg) {
|
||||
- bail!("unknown algrithm {:?}", alg);
|
||||
+ return Err(SignError::UnsupportAlg(format!("unknown algrithm {:?}", alg)));
|
||||
}
|
||||
if !Path::new(&self.config.key).exists() {
|
||||
- bail!("token verfify failed, {:?} cert not exist", self.config.key);
|
||||
+ return Err(SignError::UnsupportAlg(format!("token verfify failed, {:?} cert not exist", self.config.key)));
|
||||
}
|
||||
let key = std::fs::read(&self.config.key).unwrap();
|
||||
let key_value: EncodingKey = match EncodingKey::from_rsa_pem(&key) {
|
||||
Ok(val) => val,
|
||||
- _ => bail!("get key from input error"),
|
||||
+ _ => {return Err(SignError::ReadKeyFail(format!("get key from input error")));}
|
||||
};
|
||||
|
||||
let token = match encode(&header, &claims, &key_value) {
|
||||
Ok(val) => val,
|
||||
- Err(e) => bail!("sign jwt token error {:?}", e),
|
||||
+ Err(e) => {return Err(SignError::SignFail(e));}
|
||||
};
|
||||
Ok(token)
|
||||
}
|
||||
--
|
||||
2.46.0
|
||||
|
||||
10
secGear.spec
10
secGear.spec
@ -1,6 +1,6 @@
|
||||
Name: secGear
|
||||
Version: 0.1.0
|
||||
Release: 48
|
||||
Release: 50
|
||||
Summary: secGear is an SDK to develop confidential computing apps based on hardware enclave features
|
||||
|
||||
|
||||
@ -94,6 +94,8 @@ Patch80: 0081-modify-default-agent-config.patch
|
||||
Patch81: 0082-optimize-ima-verify.patch
|
||||
Patch82: 0083-optimize-log-level.patch
|
||||
Patch83: 0084-fix-concurrent-request-error-to-aa-or-as.patch
|
||||
Patch84: 0085-fix-multi-thread-request-as-generate-challenge-and-v.patch
|
||||
Patch85: 0086-add-error-type-for-api.patch
|
||||
|
||||
|
||||
BuildRequires: gcc python automake autoconf libtool
|
||||
@ -291,6 +293,12 @@ popd
|
||||
systemctl restart rsyslog
|
||||
|
||||
%changelog
|
||||
* Tue Nov 26 2024 houmingyong<houmingyong@huawei.com> - 0.1.0-50
|
||||
- add error type for api
|
||||
|
||||
* Tue Nov 26 2024 houmingyong<houmingyong@huawei.com> - 0.1.0-49
|
||||
- fix multi thread request-as generate challenge
|
||||
|
||||
* Tue Nov 26 2024 houmingyong<houmingyong@huawei.com> - 0.1.0-48
|
||||
- fix concurrent request error to aa or as
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user