Skip to main content

DevelopmentNodeEnvironment_MicrosoftVSCodeDependency_22NodeVersion_Bundle_Clean_Debug_ElectronProfile_EsbuildCompiler_Mountain/IPC/WindServiceHandlers/Encryption/
Decrypt.rs

1#![allow(non_snake_case)]
2
3//! `encryption:decrypt(value: string) -> string`
4//!
5//! Reverses `encryption:encrypt`: base64-decodes, splits the 12-byte nonce
6//! from the ciphertext+tag, decrypts with AES-256-GCM, and returns the
7//! original plaintext string. Returns an empty string on any failure so the
8//! workbench treats a corrupt blob as "no stored secret" rather than crashing.
9
10use base64::{Engine, engine::general_purpose::STANDARD as B64};
11use ring::aead::{AES_256_GCM, Aad, LessSafeKey, Nonce, UnboundKey};
12use serde_json::{Value, json};
13
14use crate::dev_log;
15use super::super::Encryption::Key::DeriveKey;
16
17pub async fn Decrypt(Arguments:Vec<Value>) -> Result<Value, String> {
18	let Ciphertext = Arguments.first().and_then(|V| V.as_str()).unwrap_or("").to_string();
19
20	if Ciphertext.is_empty() {
21		return Ok(json!(""));
22	}
23
24	let Blob = match B64.decode(&Ciphertext) {
25		Ok(B) => B,
26		Err(_) => {
27			dev_log!("encryption", "warn: encryption:decrypt invalid base64 - returning empty");
28			return Ok(json!(""));
29		},
30	};
31
32	// Minimum: 12 (nonce) + 16 (GCM tag) = 28 bytes
33	if Blob.len() < 28 {
34		dev_log!("encryption", "warn: encryption:decrypt blob too short ({} bytes)", Blob.len());
35		return Ok(json!(""));
36	}
37
38	let KeyBytes = DeriveKey();
39
40	let UnboundK = match UnboundKey::new(&AES_256_GCM, &KeyBytes) {
41		Ok(K) => K,
42		Err(_) => return Ok(json!("")),
43	};
44
45	let Key = LessSafeKey::new(UnboundK);
46
47	let NonceBytes:[u8; 12] = Blob[..12].try_into().unwrap();
48
49	let NonceVal = Nonce::assume_unique_for_key(NonceBytes);
50
51	let mut Data = Blob[12..].to_vec();
52
53	match Key.open_in_place(NonceVal, Aad::empty(), &mut Data) {
54		Ok(Plaintext) => {
55			let S = String::from_utf8_lossy(Plaintext).into_owned();
56			dev_log!("encryption", "encryption:decrypt ok ({} bytes)", S.len());
57			Ok(json!(S))
58		},
59		Err(_) => {
60			dev_log!(
61				"encryption",
62				"warn: encryption:decrypt open_in_place failed (wrong key or corrupt)"
63			);
64			Ok(json!(""))
65		},
66	}
67}