use hyper::body::Buf; use hyper::{Body, Request, Response, StatusCode}; use rust_util::XResult; use serde::{Deserialize, Serialize}; use serde_json::{json, Map, Value}; use crate::jose; use crate::serve_common::{self, byte_to_multi_view_map, MultipleViewValue, Result}; use crate::{do_response, require_master_key}; #[derive(Serialize, Deserialize)] struct DecryptRequest { encrypted_value: String, } pub async fn decrypt(req: Request) -> Result> { do_response!(inner_decrypt(req).await) } async fn inner_decrypt(req: Request) -> XResult<(StatusCode, Value)> { let whole_body = hyper::body::aggregate(req).await?; let data: DecryptRequest = serde_json::from_reader(whole_body.reader())?; log::debug!("To be decrypted value: {}", &data.encrypted_value); let key = require_master_key!(); let decrypted_value = jose::deserialize_jwe_aes(&data.encrypted_value, &key.read()); drop(key); let (data, header) = decrypted_value?; if let Some(false) = header.exportable { return serve_common::client_error("data_not_exportable"); } let mut map = byte_to_multi_view_map(&data, true); let mut header_map = Map::new(); header_map.insert("enc".to_string(), Value::String(header.enc.clone())); header_map.insert("alg".to_string(), Value::String(header.alg.clone())); if let Some(version) = &header.version { header_map.insert("version".to_string(), Value::String(version.to_string())); } if let Some(data_type) = &header.data_type { header_map.insert("data_type".to_string(), Value::String(data_type.to_string())); } if !header_map.is_empty() { map.insert("header".to_string(), Value::Object(header_map)); } Ok((StatusCode::OK, Value::Object(map))) } pub async fn encrypt(req: Request) -> Result> { do_response!(inner_encrypt(req).await) } async fn inner_encrypt(req: Request) -> XResult<(StatusCode, Value)> { let whole_body = hyper::body::aggregate(req).await?; let data: MultipleViewValue = serde_json::from_reader(whole_body.reader())?; let value = data.to_bytes()?; let key = require_master_key!(); let encrypt_result = jose::serialize_jwe_aes(&value, &key.read()); drop(key); encrypt_result.map(|e| { (StatusCode::OK, json!({ "encrypted_value": e, })) }) }