flare_core/common/platform/
encryption.rs1use std::sync::{Arc, Mutex, OnceLock};
4
5use crate::common::encryption::{Aes256GcmEncryptor, EncryptionUtil};
6use crate::common::error::{FlareError, Result};
7
8use super::env::optional_env;
9
10pub const AES256_KEY_LEN: usize = 32;
12
13static RUNTIME_ENCRYPTION_KEY: OnceLock<Mutex<Option<Vec<u8>>>> = OnceLock::new();
14
15fn encryption_key_slot() -> &'static Mutex<Option<Vec<u8>>> {
16 RUNTIME_ENCRYPTION_KEY.get_or_init(|| Mutex::new(None))
17}
18
19pub fn set_runtime_encryption_key(key: Vec<u8>) -> Result<()> {
21 if key.len() != AES256_KEY_LEN {
22 return Err(FlareError::protocol_error(format!(
23 "encryption key must be exactly {AES256_KEY_LEN} bytes, got {}",
24 key.len()
25 )));
26 }
27 *encryption_key_slot()
28 .lock()
29 .map_err(|_| FlareError::general_error("encryption key lock poisoned"))? = Some(key);
30 Ok(())
31}
32
33pub fn clear_runtime_encryption_key() {
35 if let Ok(mut slot) = encryption_key_slot().lock() {
36 *slot = None;
37 }
38}
39
40pub fn has_runtime_encryption_key() -> bool {
42 encryption_key_slot()
43 .lock()
44 .ok()
45 .and_then(|slot| slot.as_ref().map(|key| !key.is_empty()))
46 .unwrap_or(false)
47}
48
49pub fn parse_encryption_key_utf8(key: &str) -> Result<Vec<u8>> {
51 let bytes = key.as_bytes();
52 if bytes.len() != AES256_KEY_LEN {
53 return Err(FlareError::protocol_error(format!(
54 "encryption key string must be exactly {AES256_KEY_LEN} UTF-8 bytes, got {}",
55 bytes.len()
56 )));
57 }
58 Ok(bytes.to_vec())
59}
60
61pub fn parse_encryption_key_hex(hex: &str) -> Result<Vec<u8>> {
63 let bytes = crate::common::utils::hex_to_bytes(hex).map_err(|error| {
64 FlareError::protocol_error(format!("invalid encryption key hex: {error}"))
65 })?;
66 if bytes.len() != AES256_KEY_LEN {
67 return Err(FlareError::protocol_error(format!(
68 "encryption key hex must decode to {AES256_KEY_LEN} bytes, got {}",
69 bytes.len()
70 )));
71 }
72 Ok(bytes)
73}
74
75pub fn resolve_encryption_key_bytes(default_demo_key: Option<&[u8; AES256_KEY_LEN]>) -> Vec<u8> {
77 if let Ok(slot) = encryption_key_slot().lock()
78 && let Some(key) = slot.as_ref()
79 {
80 return key.clone();
81 }
82 if let Some(value) = optional_env("ENCRYPTION_KEY") {
83 return value.into_bytes();
84 }
85 default_demo_key.map(|key| key.to_vec()).unwrap_or_default()
86}
87
88pub fn register_aes256_encryption(default_demo_key: Option<&[u8; AES256_KEY_LEN]>) -> Result<()> {
90 let key = resolve_encryption_key_bytes(default_demo_key);
91 if key.len() != AES256_KEY_LEN {
92 return Err(FlareError::protocol_error(format!(
93 "encryption key must be exactly {AES256_KEY_LEN} bytes, got {} (set flare_set_encryption_key or ENCRYPTION_KEY)",
94 key.len()
95 )));
96 }
97 let encryptor = Aes256GcmEncryptor::new(&key)?;
98 EncryptionUtil::register_custom(Arc::new(encryptor));
99 Ok(())
100}