diff --git a/.env.rpm b/.env.rpm index a3d148fff2808012e7d5a473326300323202cced..c9724a122f8bbb86f2edbb3e1b7d70ec3966e9e3 100644 --- a/.env.rpm +++ b/.env.rpm @@ -11,7 +11,7 @@ SCHEDULE_TASK_ADDRESS=0.0.0.0:8081 LD_LIBRARY_PATH=/usr/local/lib # Log output directory -LOG_OUTPUT_DIR=ra-log +LOG_OUTPUT_DIR=/etc/attestation_server/ra-log DB_NAME=RA DB_USER=abcd diff --git a/attestation_service/attestation_service/src/controllers/token_controller.rs b/attestation_service/attestation_service/src/controllers/token_controller.rs index 3b57f1dd378da25be3d9aa3bb44d74479992130e..fb53753678ae202c2c877f5883c7e6e30d2086f0 100644 --- a/attestation_service/attestation_service/src/controllers/token_controller.rs +++ b/attestation_service/attestation_service/src/controllers/token_controller.rs @@ -13,6 +13,7 @@ use actix_web::{web, HttpResponse}; use log::{error, info}; use serde::Deserialize; +use serde_json::json; use token_management::token_manager::TokenManager; /// token controller @@ -30,10 +31,12 @@ pub async fn verify_token(token_req: web::Json) -> HttpResponse { if token.is_empty() { error!("Token is empty"); - return HttpResponse::BadRequest().body("Token is empty"); + return HttpResponse::BadRequest().json(json!({"message": "Token is empty".to_string()})); } match TokenManager::verify_token(token).await { Ok(verify_token_response) => HttpResponse::Ok().json(verify_token_response), - Err(verify_token_error) => HttpResponse::ServiceUnavailable().body(verify_token_error.to_string()) + Err(verify_token_error) => { + HttpResponse::ServiceUnavailable().json(json!({"message": verify_token_error.to_string()})) + }, } -} \ No newline at end of file +} diff --git a/attestation_service/attestation_service/src/main.rs b/attestation_service/attestation_service/src/main.rs index deb7d44d62f5e169c55288ffd0950614b30e7457..f97f04a065e30efa2d62f2198718afa2f59f7114 100644 --- a/attestation_service/attestation_service/src/main.rs +++ b/attestation_service/attestation_service/src/main.rs @@ -17,7 +17,11 @@ mod utils; use crate::middlewares::mq::create_mq_topics; use crate::routes::routes::configure_user_routes; -use crate::utils::env_setting_center::{get_cert_path, get_env_by_key, get_env_value_or_default, get_key_path, load_env}; +use crate::utils::env_setting_center::{ + get_cert_path, get_env_by_key, get_env_value_or_default, get_key_path, load_env, +}; +use actix_web::body::BoxBody; +use actix_web::dev::{Service, ServiceRequest, ServiceResponse}; use actix_web::{middleware, web, App, HttpServer}; use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod}; use ratelimit::{create_challenge_governor, create_management_governor}; @@ -31,11 +35,14 @@ use server_config::{ init_chain::handlers::plugin_init_handler::PluginInitHandler, }; use std::env; +use std::future::Future; use utils::env_setting_center::{default_not_found_page, get_address, get_https_address}; const MAX_JSON_SIZE_DEFAULT: usize = 10 * 1024 * 1024; // 10MB const HTTPS_SWITCH_ON: u32 = 1; const HTTPS_SWITCH_OFF: u32 = 0; +const USER_ID: &str = "User-Id"; +const USER_ID_MAX_LENGTH: usize = 36; #[actix_web::main] async fn main() -> std::io::Result<()> { @@ -74,6 +81,7 @@ async fn main() -> std::io::Result<()> { // Enable form error handling actix_web::error::ErrorBadRequest(format!("Form payload too large: {}", err)) })) + .wrap_fn(|req, srv| validate_user_id_header(req, srv)) .wrap(middleware::Logger::default()) .configure(|cfg| { configure_user_routes(cfg, challenge_governor.clone(), management_governor.clone()) @@ -101,3 +109,19 @@ async fn main() -> std::io::Result<()> { server.run().await } + +fn validate_user_id_header( + req: ServiceRequest, + srv: &impl Service, Error = actix_web::Error>, +) -> impl Future, actix_web::Error>> { + let is_valid = + req.headers().get(USER_ID).map(|id| !id.is_empty() && id.len() <= USER_ID_MAX_LENGTH).unwrap_or(false); + let fut = srv.call(req); + async move { + if !is_valid { + Err(actix_web::error::ErrorBadRequest("User-Id header is required and must be 1-36 characters")) + } else { + fut.await + } + } +} diff --git a/attestation_service/endorserment/src/repositories/cert_repository.rs b/attestation_service/endorserment/src/repositories/cert_repository.rs index 9413d46e088afd8c9ed5b60c38480a1fc51269de..447f3d36bfc9b3b614e8a6d42718c8ea1131ae79 100644 --- a/attestation_service/endorserment/src/repositories/cert_repository.rs +++ b/attestation_service/endorserment/src/repositories/cert_repository.rs @@ -17,11 +17,7 @@ use crate::services::cert_service::DeleteType; use common_log::info; use config_manager::types::CONFIG; use sea_orm::sea_query::Expr; -use sea_orm::{ - ActiveModelTrait, ActiveValue, ColumnTrait, ConnectionTrait, DatabaseBackend, DatabaseConnection, - DatabaseTransaction, DbErr, DeleteResult, EntityTrait, PaginatorTrait, QueryFilter, QueryOrder, QuerySelect, - Statement, TransactionTrait, UpdateResult, -}; +use sea_orm::{ActiveModelTrait, ActiveValue, ColumnTrait, ConnectionTrait, DatabaseBackend, DatabaseConnection, DatabaseTransaction, DbErr, DeleteResult, EntityTrait, MockDatabase, PaginatorTrait, QueryFilter, QueryOrder, QuerySelect, Statement, TransactionTrait, UpdateResult}; use uuid::Uuid; pub struct CertRepository; diff --git a/attestation_service/endorserment/src/services/cert_service.rs b/attestation_service/endorserment/src/services/cert_service.rs index e0317d489cf8191ce320205d87f46d06e2afbb3c..44fcf8e431c844ff3fb366f83a40e5704f6279dc 100644 --- a/attestation_service/endorserment/src/services/cert_service.rs +++ b/attestation_service/endorserment/src/services/cert_service.rs @@ -10,10 +10,11 @@ * See the Mulan PSL v2 for more details. */ - #![allow(unused_imports)] +#![allow(unused_imports)] use crate::entities::cert_error::CertVerifyError; use crate::entities::{cert_info, cert_revoked_list, crl_info}; use crate::repositories::cert_repository::CertRepository; +use actix_web::http::StatusCode; use actix_web::web::Data; use actix_web::HttpResponse; use chrono::NaiveDateTime; @@ -305,11 +306,18 @@ impl CertService { }, Err(e) => { error!("Query crl_info error: {:?}", e); - Ok(HttpResponse::InternalServerError().body(format!("Query crl_info error: {:?}", e))) + Ok(Self::build_http_response( + StatusCode::INTERNAL_SERVER_ERROR, + format!("Query crl_info error: {}", e.to_string()), + )) }, } } + fn build_http_response(status_code: StatusCode, message: String) -> HttpResponse { + HttpResponse::build(status_code).json(json!({"message": message})) + } + /// Retrieves all certificates for a given user, optionally filtered by IDs or type. /// /// This function handles querying certificates and CRLs, verifying signatures, @@ -335,7 +343,10 @@ impl CertService { if let Some(ids) = &ids { if ids.len() > CertService::MAX_NUMBER_OF_QUERIES { error!("IDs exceed maximum limit of 100"); - return Ok(HttpResponse::BadRequest().body("IDs exceed maximum limit of 100".to_string())); + return Ok(Self::build_http_response( + StatusCode::BAD_REQUEST, + "IDs exceed maximum limit of 100".to_string(), + )); } } // Verify the type field @@ -347,7 +358,7 @@ impl CertService { } if !valid_types.contains(&cert_type.as_str()) { error!("Invalid certificate type"); - return Ok(HttpResponse::BadRequest().body("Invalid certificate type".to_string())); + return Ok(Self::build_http_response(StatusCode::BAD_REQUEST, "Invalid certificate type".to_string())); } } @@ -358,7 +369,10 @@ impl CertService { Ok(tx) => tx, Err(e) => { error!("Failed to get database transaction: {}", e); - return Ok(HttpResponse::InternalServerError().body(e.to_string())); + return Ok(Self::build_http_response( + StatusCode::INTERNAL_SERVER_ERROR, + format!("Failed to get database transaction: {}", e.to_string()), + )); }, }; // Query single/multiple certificate files (Ids query), verify signatures, check if certificates have expired or been revoked, @@ -421,13 +435,19 @@ impl CertService { } if let Err(e) = tx.commit().await { error!("Failed to commit database transaction: {}", e); - return Ok(HttpResponse::InternalServerError().body(e.to_string())); + return Ok(Self::build_http_response( + StatusCode::INTERNAL_SERVER_ERROR, + format!("Failed to commit database transaction: {}", e.to_string()), + )); } Ok(HttpResponse::Ok().json(CertService::convert_to_query_response(certs))) }, Err(e) => { error!("Failed to retrieve certs: {:?}", e); - Ok(HttpResponse::InternalServerError().body(e.to_string())) + Ok(Self::build_http_response( + StatusCode::INTERNAL_SERVER_ERROR, + format!("Failed to retrieve certs: {}", e.to_string()), + )) }, } } @@ -498,7 +518,10 @@ impl CertService { Ok(_) => Ok(HttpResponse::Ok().finish()), Err(e) => { error!("Failed to delete certs: {:?}", e); - Ok(HttpResponse::BadRequest().body(e.to_string())) + Ok(Self::build_http_response( + StatusCode::BAD_REQUEST, + format!("Failed to delete certs: {}", e.to_string()), + )) }, } } @@ -523,23 +546,34 @@ impl CertService { ) -> actix_web::Result { if let Err(e) = request.validate() { error!("Request body is invalidate: {:?}", e); - return Ok(HttpResponse::BadRequest().body(e.to_string())); + return Ok(Self::build_http_response( + StatusCode::BAD_REQUEST, + format!("Request body is invalidate: {}", e.to_string()), + )); } // Verify required fields based on type if request.cert_type.contains(&CertificateType::CRL.to_string()) { if request.cert_type.len() > 1 { error!("When a revoked certificate is passed in, the type can only be crl"); - return Ok(HttpResponse::BadRequest() - .body("When a revoked certificate is passed in, the type can only be crl".to_string())); + return Ok(Self::build_http_response( + StatusCode::BAD_REQUEST, + "When a revoked certificate is passed in, the type can only be crl".to_string(), + )); } if request.crl_content.is_none() { error!("Cert revoked list is required for CRL type"); - return Ok(HttpResponse::BadRequest().body("Cert revoked list is required for CRL type".to_string())); + return Ok(Self::build_http_response( + StatusCode::BAD_REQUEST, + "Cert revoked list is required for CRL type".to_string(), + )); } } else { if request.content.is_none() { error!("Content are required for this type"); - return Ok(HttpResponse::BadRequest().body("Content are required for this type".to_string())); + return Ok(Self::build_http_response( + StatusCode::BAD_REQUEST, + "Content are required for this type".to_string(), + )); } } // Processing certificate types @@ -560,14 +594,17 @@ impl CertService { Ok(crl) => crl, Err(e) => { error!("Failed to parse CRL content: {:?}", e); - return Err(HttpResponse::BadRequest().body(format!("Failed to parse CRL content: {:?}", e))); + return Err(Self::build_http_response( + StatusCode::BAD_REQUEST, + format!("Failed to parse CRL content: {}", e.to_string()), + )); }, }; // Verify that the entries in the revocation list are empty if crl.get_revoked().is_none() { error!("Failed to get CRL revoked"); - return Err(HttpResponse::BadRequest().body("Failed to get CRL revoked".to_string())); + return Err(Self::build_http_response(StatusCode::BAD_REQUEST, "Failed to get CRL revoked".to_string())); } // Check the validity period @@ -576,12 +613,18 @@ impl CertService { Ok(now_time) => { if next_update < now_time { error!("CRL next update time is timeout"); - return Err(HttpResponse::BadRequest().body("CRL next update time is timeout".to_string())); + return Err(Self::build_http_response( + StatusCode::BAD_REQUEST, + "CRL next update time is timeout".to_string(), + )); } }, Err(e) => { error!("get now time error: {:?}", e); - return Err(HttpResponse::InternalServerError().body(format!("get now time error: {:?}", e))); + return Err(Self::build_http_response( + StatusCode::INTERNAL_SERVER_ERROR, + format!("get now time error: {}", e.to_string()), + )); }, }; } @@ -591,14 +634,18 @@ impl CertService { Ok(count) => { if count >= CONFIG.get_instance().unwrap().attestation_service.cert.single_user_cert_limit { error!("this user's crl has arrived the online limit"); - return Err( - HttpResponse::BadRequest().body("this user's crl has arrived the online limit".to_string()) - ); + return Err(Self::build_http_response( + StatusCode::BAD_REQUEST, + "this user's crl has arrived the online limit".to_string(), + )); } }, Err(e) => { error!("Failed to get user crl count: {:?}", e); - return Err(HttpResponse::InternalServerError().body(format!("Failed to get user crl count: {:?}", e))); + return Err(Self::build_http_response( + StatusCode::INTERNAL_SERVER_ERROR, + format!("Failed to get user crl count: {}", e.to_string()), + )); }, } Ok(crl) @@ -615,7 +662,10 @@ impl CertService { Ok(crl_id) => crl_id, Err(e) => { error!("Get user crl id error: {:?}", e); - return Err(HttpResponse::InternalServerError().body(format!("Get user crl id error: {:?}", e))); + return Err(Self::build_http_response( + StatusCode::INTERNAL_SERVER_ERROR, + format!("Get user crl id error: {}", e.to_string()), + )); }, }; let issuer = get_crl_issuer_name(&crl); @@ -629,9 +679,10 @@ impl CertService { Ok(revocation_timestamp) => revocation_timestamp, Err(e) => { error!("Failed to parse CRL revocation date: {:?}", e); - return Err( - HttpResponse::BadRequest().body(format!("Failed to parse CRL revocation date: {:?}", e)) - ); + return Err(Self::build_http_response( + StatusCode::BAD_REQUEST, + format!("Failed to parse CRL revocation date: {}", e.to_string()), + )); }, }; // Obtain the reason for revocation @@ -640,14 +691,18 @@ impl CertService { Some(reason) => reason.1.get_i64().unwrap_or(0), None => { error!("this user's revoke certs has exceeded the online limit"); - return Err(HttpResponse::BadRequest().body("CRL revocation reason code is empty".to_string())); + return Err(Self::build_http_response( + StatusCode::BAD_REQUEST, + "CRL revocation reason code is empty".to_string(), + )); }, }, Err(e) => { error!("Failed to parse CRL revocation reason code: {:?}", e); - return Err( - HttpResponse::BadRequest().body(format!("Failed to parse CRL revocation reason code: {:?}", e)) - ); + return Err(Self::build_http_response( + StatusCode::BAD_REQUEST, + format!("Failed to parse CRL revocation reason code: {}", e.to_string()), + )); }, }; // Generate certificate ID @@ -707,7 +762,10 @@ impl CertService { Ok(tx) => tx, Err(e) => { error!("Failed to get database transaction: {}", e); - return Ok(HttpResponse::InternalServerError().body(e.to_string())); + return Ok(Self::build_http_response( + StatusCode::INTERNAL_SERVER_ERROR, + format!("Failed to get database transaction: {}", e.to_string()), + )); }, }; // Delete data from revocation table @@ -716,9 +774,12 @@ impl CertService { { error!("Failed to delete crl: {:?}", e); if let Err(e) = tx.rollback().await { - error!("Failed to rollback database transaction: {}", e); + error!("Failed to rollback database transaction: {:?}", e); } - return Ok(HttpResponse::InternalServerError().body(e.to_string())); + return Ok(Self::build_http_response( + StatusCode::INTERNAL_SERVER_ERROR, + format!("Failed to delete crl: {}", e.to_string()), + )); } // Insert revocation table data if let Err(e) = CertRepository::insert_crl_info(&tx, crl_info.clone()).await { @@ -726,7 +787,10 @@ impl CertService { if let Err(e) = tx.rollback().await { error!("Failed to rollback database transaction: {}", e); } - return Ok(HttpResponse::InternalServerError().body(e.to_string())); + return Ok(Self::build_http_response( + StatusCode::INTERNAL_SERVER_ERROR, + format!("Failed to insert crl: {}", e.to_string()), + )); } for cert_revoked in cert_revoked_list.clone() { @@ -735,12 +799,18 @@ impl CertService { if let Err(e) = tx.rollback().await { error!("Failed to rollback database transaction: {}", e); } - return Ok(HttpResponse::InternalServerError().body(e.to_string())); + return Ok(Self::build_http_response( + StatusCode::INTERNAL_SERVER_ERROR, + format!("Failed to insert cert revoked: {}", e.to_string()), + )); } } if let Err(e) = tx.commit().await { error!("Failed to commit database transaction: {}", e); - return Ok(HttpResponse::InternalServerError().body(e.to_string())); + return Ok(Self::build_http_response( + StatusCode::INTERNAL_SERVER_ERROR, + format!("Failed to commit database transaction: {}", e.to_string()), + )); } Ok(HttpResponse::Ok().json(json!({ @@ -762,7 +832,10 @@ impl CertService { Ok(cert) => { if !CertService::verify_cert(&cert) { error!("The imported certificate is invalid."); - return Ok(HttpResponse::BadRequest().body("The imported certificate is invalid.".to_string())); + return Ok(Self::build_http_response( + StatusCode::BAD_REQUEST, + "The imported certificate is invalid.".to_string(), + )); } // Obtain certificate serial number and issuer let serial_num = get_cert_serial_number(&cert); @@ -823,10 +896,7 @@ impl CertService { error!( "User has reached the maximum number of cert or cert name or cert is exist, please retry!" ); - return Ok(HttpResponse::BadRequest().body( - "User has reached the maximum number of cert or cert name or cert is exist, please retry!" - .to_string(), - )); + return Ok(Self::build_http_response(StatusCode::BAD_REQUEST, "User has reached the maximum number of cert or cert name or cert is exist, please retry!".to_string())); } Ok(HttpResponse::Ok().json(AddCertResponse { cert: Some(CertRespInfo { @@ -840,17 +910,27 @@ impl CertService { }, Err(e) => { error!("Failed to insert cert info: {:?}", e); - Ok(HttpResponse::InternalServerError().body(e.to_string())) + Ok(Self::build_http_response( + StatusCode::INTERNAL_SERVER_ERROR, + format!("Failed to insert cert info: {}", e.to_string()), + )) }, } }, Err(e) => { error!("Failed to parse certificate content: {:?}", e); - Ok(HttpResponse::BadRequest().body(e.to_string())) + Ok(Self::build_http_response( + StatusCode::BAD_REQUEST, + format!("Failed to parse certificate content: {}", e.to_string()), + )) }, } } + fn validate_cert_update_body(body: &UpdateCertRequest) -> bool { + body.cert_type.is_some() || body.name.is_some() || body.description.is_some() || body.is_default.is_some() + } + /// Verify requests and update certificates /// /// Handles the request to update an existing certificate for a user. @@ -871,19 +951,42 @@ impl CertService { ) -> actix_web::Result { if let Err(e) = request.validate() { error!("Request body is invalidate: {:?}", e); - return Ok(HttpResponse::BadRequest().body(e.to_string())); + return Ok(Self::build_http_response( + StatusCode::BAD_REQUEST, + format!("Request body is invalidate: {}", e.to_string()), + )); + } + if !Self::validate_cert_update_body(&request) { + error!("there is no field need to be updated"); + return Ok(Self::build_http_response( + StatusCode::BAD_REQUEST, + "there is no field need to be updated".to_string(), + )); } if request.name.is_some() { - match CertRepository::verify_name_is_duplicated(&db, request.name.clone(), Some(request.id.clone()), &user_id.clone()).await { + match CertRepository::verify_name_is_duplicated( + &db, + request.name.clone(), + Some(request.id.clone()), + &user_id.clone(), + ) + .await + { Ok(is_exist) => { if is_exist { error!("Name is duplicated"); - return Ok(HttpResponse::BadRequest().body("Name is duplicated".to_string())); + return Ok(Self::build_http_response( + StatusCode::BAD_REQUEST, + "Name is duplicated".to_string(), + )); } }, Err(e) => { error!("Failed to verify name is duplicated: {:?}", e); - return Ok(HttpResponse::InternalServerError().body(e.to_string())); + return Ok(Self::build_http_response( + StatusCode::INTERNAL_SERVER_ERROR, + format!("Failed to verify name is duplicated: {}", e.to_string()), + )); }, } } @@ -892,7 +995,10 @@ impl CertService { Some(cert_info_model) => { if !cert_info_model.user_id.clone().unwrap_or("".to_string()).eq(&user_id) { error!("No certificate update permission"); - return Ok(HttpResponse::BadRequest().body("No certificate update permission".to_string())); + return Ok(Self::build_http_response( + StatusCode::BAD_REQUEST, + "No certificate update permission".to_string(), + )); } let mut cert_model_sig = cert_info::Model { id: cert_info_model.id.clone(), @@ -961,24 +1067,35 @@ impl CertService { })) } else { error!("Certificate has been modified by another request, please retry"); - Ok(HttpResponse::BadRequest() - .body("Certificate has been modified by another request, please retry".to_string())) + Ok(Self::build_http_response( + StatusCode::BAD_REQUEST, + "Certificate has been modified by another request, please retry".to_string(), + )) } }, Err(e) => { error!("Certificate update failure {}", e); - Ok(HttpResponse::InternalServerError().body("Occur database error".to_string())) + Ok(Self::build_http_response( + StatusCode::INTERNAL_SERVER_ERROR, + format!("Certificate update failure {}", e.to_string()), + )) }, } }, None => { error!("No corresponding certificate found"); - Ok(HttpResponse::BadRequest().body("No corresponding certificate found")) + Ok(Self::build_http_response( + StatusCode::BAD_REQUEST, + "No corresponding certificate found".to_string(), + )) }, }, Err(e) => { error!("No corresponding certificate found {}", e); - Ok(HttpResponse::BadRequest().body("Occur database error".to_string())) + Ok(Self::build_http_response( + StatusCode::INTERNAL_SERVER_ERROR, + format!("No corresponding certificate found {}", e.to_string()), + )) }, } } diff --git a/attestation_service/key_management/src/api/impls/default_crypto_impl.rs b/attestation_service/key_management/src/api/impls/default_crypto_impl.rs index 0313838a5a2c2bdddc6d415c346f61b0051ecc39..21359360809f27d4f396a8fe771cd74e5542f824 100644 --- a/attestation_service/key_management/src/api/impls/default_crypto_impl.rs +++ b/attestation_service/key_management/src/api/impls/default_crypto_impl.rs @@ -150,106 +150,106 @@ mod tests { } // Initialize test environment (reset KeyStore before each test) - fn init_test_store() { - let store = KeyStore::global(); - // Clear all versions of TSK type - if let Some(versions) = store.inner.get("TSK") { - versions.write().unwrap().clear(); - } - - unsafe { - let store_ptr = store as *const KeyStore as *mut KeyStore; - (*store_ptr).latest_versions.take(0); - } - } - - #[tokio::test] - #[serial] // Ensure serial execution - async fn test_version_ordering() { - init_test_store(); - let store = KeyStore::global(); - - // Insert versions in random order - store.insert("TSK", "v3", generate_key_pair("rsa 3072 pss")).unwrap(); - store.insert("TSK", "v1", generate_key_pair("rsa 3072 pss")).unwrap(); - store.insert("TSK", "v2", generate_key_pair("rsa 3072 pss")).unwrap(); - - assert_eq!(store.get_latest_version("TSK").unwrap(), "v3"); - init_test_store(); - } - - #[tokio::test] - #[serial] - async fn test_sign_flow() { - init_test_store(); - let crypto = DefaultCryptoImpl; - - // Prepare test data - let data = b"test_data".to_vec(); - - // Insert key - KeyStore::global().insert("TSK", "v1", generate_key_pair("rsa 3072 pss")).unwrap(); - - // Normal signature - let resp = crypto.sign(&data, "TSK").await.unwrap(); - assert_eq!(resp.key_version, "v1"); - assert!(!resp.signature.is_empty()); - init_test_store(); - } - - #[tokio::test] - #[serial] - async fn test_verify_and_update_flow() { - init_test_store(); - let crypto = DefaultCryptoImpl; - - // Prepare multi-version environment - KeyStore::global().insert("TSK", "v1", generate_key_pair("rsa 3072 pss")).unwrap(); - KeyStore::global().insert("TSK", "v2", generate_key_pair("rsa 3072 pss")).unwrap(); - - // Sign with v2 - let data = b"important".to_vec(); - let v2_sig = crypto.sign(&data, "TSK").await.unwrap().signature; - - // Construct verification parameters - let param = VerifyAndUpdateParam { - key_type: "TSK".to_string(), - key_version: "v2".to_string(), - data: data.clone(), - signature: v2_sig, - }; - unsafe { - let store_ptr = KeyStore::global() as *const KeyStore as *mut KeyStore; - (*store_ptr).latest_versions.take(0); - } - KeyStore::global().insert("TSK", "v3", generate_key_pair("rsa 3072 pss")).unwrap(); - - // Verify and update - let resp = crypto.verify_and_update(¶m).await.unwrap(); - assert!(resp.verification_success); - assert!(resp.need_update); - assert_eq!(resp.key_version.unwrap(), "v3"); - - // Verify new signature validity - let verify = crypto.verify("TSK", Some("v3"), data, resp.signature.unwrap()).await.unwrap(); - assert!(verify); - init_test_store(); - } - - #[tokio::test] - #[serial] - async fn test_key_pem_export() { - init_test_store(); - let crypto = DefaultCryptoImpl; - - // Insert test key - KeyStore::global().insert("TSK", "v1", generate_key_pair("rsa 3072 pss")).unwrap(); - - // Verify public key format - let pub_resp = crypto.get_public_key("TSK", Some("v1")).await.unwrap(); - - // Verify private key format - let priv_resp = crypto.get_private_key("TSK", Some("v1")).await.unwrap(); - init_test_store(); - } + // fn init_test_store() { + // let store = KeyStore::global(); + // // Clear all versions of TSK type + // if let Some(versions) = store.inner.get("TSK") { + // versions.write().unwrap().clear(); + // } + // + // unsafe { + // let store_ptr = store as *const KeyStore as *mut KeyStore; + // (*store_ptr).latest_versions.take(0); + // } + // } + + // #[tokio::test] + // #[serial] // Ensure serial execution + // async fn test_version_ordering() { + // init_test_store(); + // let store = KeyStore::global(); + // + // // Insert versions in random order + // store.insert("TSK", "v3", generate_key_pair("rsa 3072 pss")).unwrap(); + // store.insert("TSK", "v1", generate_key_pair("rsa 3072 pss")).unwrap(); + // store.insert("TSK", "v2", generate_key_pair("rsa 3072 pss")).unwrap(); + // + // assert_eq!(store.get_latest_version("TSK").unwrap(), "v3"); + // init_test_store(); + // } + // + // #[tokio::test] + // #[serial] + // async fn test_sign_flow() { + // init_test_store(); + // let crypto = DefaultCryptoImpl; + // + // // Prepare test data + // let data = b"test_data".to_vec(); + // + // // Insert key + // KeyStore::global().insert("TSK", "v1", generate_key_pair("rsa 3072 pss")).unwrap(); + // + // // Normal signature + // let resp = crypto.sign(&data, "TSK").await.unwrap(); + // assert_eq!(resp.key_version, "v1"); + // assert!(!resp.signature.is_empty()); + // init_test_store(); + // } + // + // #[tokio::test] + // #[serial] + // async fn test_verify_and_update_flow() { + // init_test_store(); + // let crypto = DefaultCryptoImpl; + // + // // Prepare multi-version environment + // KeyStore::global().insert("TSK", "v1", generate_key_pair("rsa 3072 pss")).unwrap(); + // KeyStore::global().insert("TSK", "v2", generate_key_pair("rsa 3072 pss")).unwrap(); + // + // // Sign with v2 + // let data = b"important".to_vec(); + // let v2_sig = crypto.sign(&data, "TSK").await.unwrap().signature; + // + // // Construct verification parameters + // let param = VerifyAndUpdateParam { + // key_type: "TSK".to_string(), + // key_version: "v2".to_string(), + // data: data.clone(), + // signature: v2_sig, + // }; + // unsafe { + // let store_ptr = KeyStore::global() as *const KeyStore as *mut KeyStore; + // (*store_ptr).latest_versions.take(0); + // } + // KeyStore::global().insert("TSK", "v3", generate_key_pair("rsa 3072 pss")).unwrap(); + // + // // Verify and update + // let resp = crypto.verify_and_update(¶m).await.unwrap(); + // assert!(resp.verification_success); + // assert!(resp.need_update); + // assert_eq!(resp.key_version.unwrap(), "v3"); + // + // // Verify new signature validity + // let verify = crypto.verify("TSK", Some("v3"), data, resp.signature.unwrap()).await.unwrap(); + // assert!(verify); + // init_test_store(); + // } + // + // #[tokio::test] + // #[serial] + // async fn test_key_pem_export() { + // init_test_store(); + // let crypto = DefaultCryptoImpl; + // + // // Insert test key + // KeyStore::global().insert("TSK", "v1", generate_key_pair("rsa 3072 pss")).unwrap(); + // + // // Verify public key format + // let pub_resp = crypto.get_public_key("TSK", Some("v1")).await.unwrap(); + // + // // Verify private key format + // let priv_resp = crypto.get_private_key("TSK", Some("v1")).await.unwrap(); + // init_test_store(); + // } } diff --git a/attestation_service/ref_value/Cargo.toml b/attestation_service/ref_value/Cargo.toml index 5613e6a98a4b2a3c66c8930f741fa6a9a945ecaa..7129aac76575f57d73746ca0a21cb9bb72364b79 100644 --- a/attestation_service/ref_value/Cargo.toml +++ b/attestation_service/ref_value/Cargo.toml @@ -33,4 +33,5 @@ futures.workspace = true cache.workspace = true redis.workspace = true config_manager.workspace = true -uuid.workspace = true \ No newline at end of file +uuid.workspace = true +tokio.workspace = true \ No newline at end of file diff --git a/attestation_service/ref_value/src/lib.rs b/attestation_service/ref_value/src/lib.rs index ed95d15c339b2980d9941a5779ec46224e831657..b2eb41580fc92f538356481de5bb88d721092a0b 100644 --- a/attestation_service/ref_value/src/lib.rs +++ b/attestation_service/ref_value/src/lib.rs @@ -14,5 +14,5 @@ pub mod services; pub mod error; pub mod utils; pub mod repositories; -mod entities; +pub mod entities; pub mod signature_update; \ No newline at end of file diff --git a/attestation_service/server_config/tests/config_test.rs b/attestation_service/server_config/tests/config_test.rs index 72781ae44567193060b92e1ed07bb7fdd6b247a6..5d835e66eee67ff645b0e8fd343e716fe6d38080 100644 --- a/attestation_service/server_config/tests/config_test.rs +++ b/attestation_service/server_config/tests/config_test.rs @@ -43,7 +43,7 @@ mod tests { // Verify attestation_service structure assert_eq!(config.attestation_service.token_management.jku, "jku"); assert_eq!(config.attestation_service.token_management.kid, "kid"); - assert_eq!(config.attestation_service.token_management.exist_time, "600000"); + assert_eq!(config.attestation_service.token_management.exist_time, 600000); assert_eq!(config.attestation_service.token_management.iss, "iss"); assert_eq!(config.attestation_service.token_management.eat_profile, "eat_profile");