Skip to main content

DevelopmentNodeEnvironment_MicrosoftVSCodeDependency_22NodeVersion_Bundle_Clean_Debug_ElectronProfile_EsbuildCompiler_Mountain/IPC/WindServiceHandlers/Encryption/
Encrypt.rs

1#![allow(non_snake_case)]
2
3//! `encryption:encrypt(value: string) -> string`
4//!
5//! Encrypts a plaintext string with AES-256-GCM and returns a base64-encoded
6//! `<12-byte nonce><ciphertext+tag>` blob that `encryption:decrypt` can
7//! reverse. Called by VS Code's `EncryptionMainService` to store extension
8//! secrets and auth tokens safely at rest.
9
10use base64::{Engine, engine::general_purpose::STANDARD as B64};
11use ring::{
12	aead::{AES_256_GCM, Aad, LessSafeKey, Nonce, UnboundKey},
13	rand::{SecureRandom, SystemRandom},
14};
15use serde_json::{Value, json};
16
17use crate::dev_log;
18use super::super::Encryption::Key::DeriveKey;
19
20pub async fn Encrypt(Arguments:Vec<Value>) -> Result<Value, String> {
21	let Plaintext = Arguments.first().and_then(|V| V.as_str()).unwrap_or("").to_string();
22
23	if Plaintext.is_empty() {
24		return Ok(json!(""));
25	}
26
27	let KeyBytes = DeriveKey();
28
29	let UnboundK = UnboundKey::new(&AES_256_GCM, &KeyBytes).map_err(|E| format!("encrypt key: {E:?}"))?;
30
31	let Key = LessSafeKey::new(UnboundK);
32
33	let Rng = SystemRandom::new();
34
35	let mut NonceBytes = [0u8; 12];
36
37	Rng.fill(&mut NonceBytes).map_err(|E| format!("encrypt rng: {E:?}"))?;
38
39	let NonceVal = Nonce::assume_unique_for_key(NonceBytes);
40
41	let mut Data = Plaintext.into_bytes();
42
43	Key.seal_in_place_append_tag(NonceVal, Aad::empty(), &mut Data)
44		.map_err(|E| format!("encrypt seal: {E:?}"))?;
45
46	let mut Out = NonceBytes.to_vec();
47
48	Out.extend_from_slice(&Data);
49
50	dev_log!(
51		"encryption",
52		"encryption:encrypt {} bytes → {} bytes",
53		Out.len() - 12 - 16,
54		Out.len()
55	);
56
57	Ok(json!(B64.encode(&Out)))
58}