1
0
mirror of https://github.com/bitwarden/server synced 2026-02-27 09:53:42 +00:00
Files
server/akd/crates/akd_storage/src/vrf_key_database.rs
2026-01-05 12:49:50 -08:00

687 lines
25 KiB
Rust

use akd::ecvrf::{VRFKeyStorage, VrfError};
use async_trait::async_trait;
use chacha20poly1305::{
aead::{generic_array::GenericArray, Aead},
AeadCore, KeyInit, XChaCha20Poly1305,
};
use rsa::{pkcs1::DecodeRsaPrivateKey, Pkcs1v15Encrypt};
use thiserror::Error;
use tracing::{error, info};
use crate::{db_config::DatabaseType, vrf_key_config::VrfKeyConfig};
/// Represents a storage-layer error
#[derive(Debug, Error)]
pub enum VrfKeyRetrievalError {
/// No VRF key exists for the given root key
#[error("VRF key not found for the specified root key")]
KeyNotFound,
/// Database/storage layer failure (connection, query execution, etc.)
#[error("Database error during key retrieval")]
DatabaseError,
/// Data exists but is corrupted or invalid
#[error("Retrieved VRF key data is corrupted")]
CorruptedData,
}
#[derive(Debug, Error)]
#[error("VRF key creation error")]
pub struct VrfKeyCreationError;
#[derive(Debug, Error)]
#[error("Internal VRF key storage error")]
pub struct VrfKeyStorageError;
#[derive(Debug, Error)]
#[error(
"VRF key configuration error. Check root key settings are valid for the existing AKD database."
)]
pub struct VrfKeyConfigError;
#[derive(Debug, Clone)]
pub struct VrfKeyDatabase {
db: DatabaseType,
vrf_key_config: VrfKeyConfig,
cached_vrf_key: Option<Vec<u8>>,
}
impl VrfKeyDatabase {
pub async fn new(
db: DatabaseType,
config: VrfKeyConfig,
) -> Result<VrfKeyDatabase, VrfKeyConfigError> {
let new_key_database = VrfKeyDatabase {
db: db.clone(),
vrf_key_config: config.clone(),
cached_vrf_key: None,
};
let expected_key_hash = config.root_key_hash().map_err(|_| {
error!("Failed to compute root key hash from configuration. Likely due to invalid key material.");
VrfKeyConfigError
})?;
let existing_key_hash = db.get_existing_vrf_root_key_hash().await.map_err(|err| {
error!(%err, "Error checking for existing VRF key in database");
VrfKeyConfigError
})?;
match existing_key_hash {
Some(hash) => {
if hash != expected_key_hash {
error!(
"Existing VRF root key hash in database does not match configured root key hash. \
This indicates a misconfiguration or potential security issue."
);
return Err(VrfKeyConfigError);
}
Ok(new_key_database)
}
None => {
info!("No existing VRF key found in database. Proceeding to create a new key if needed.");
Ok(new_key_database)
}
}
}
async fn get_vrf_key(&self) -> Result<VrfKeyTableData, VrfKeyRetrievalError> {
match &self.db {
DatabaseType::MsSql(db) => db.get_vrf_key(&self.vrf_key_config).await,
}
}
async fn store_vrf_key(&self, table_data: &VrfKeyTableData) -> Result<(), VrfKeyStorageError> {
match &self.db {
DatabaseType::MsSql(db) => db.store_vrf_key(table_data).await,
}
}
}
#[async_trait]
impl VRFKeyStorage for VrfKeyDatabase {
async fn retrieve(&self) -> Result<Vec<u8>, VrfError> {
if let Some(cached_key) = &self.cached_vrf_key {
return Ok(cached_key.clone());
}
match &self.get_vrf_key().await {
Ok(table_data) => table_data
.to_vrf_key(&self.vrf_key_config)
.await
.map(|k| k.0)
.map_err(|err| {
VrfError::SigningKey(format!("Error decrypting signing key: {err}"))
}),
Err(VrfKeyRetrievalError::KeyNotFound) => {
// Make a new key
let (table_data, key) =
VrfKeyTableData::new(&self.vrf_key_config)
.await
.map_err(|err| {
VrfError::SigningKey(format!("Failed to create a new VRF key: {err}"))
})?;
// store store
self.store_vrf_key(&table_data).await.map_err(|err| {
VrfError::SigningKey(format!("Failed to store a new VRF key: {err}"))
})?;
// and return
Ok(key.0)
}
Err(err) => {
error!(%err, "Key retrieval error");
Err(VrfError::SigningKey("Key retrieval error".to_string()))
}
}
}
}
pub struct VrfKeyTableData {
pub root_key_hash: Vec<u8>,
pub root_key_type: VrfRootKeyType,
pub enc_sym_key: Option<Vec<u8>>,
pub sym_enc_vrf_key: Vec<u8>,
pub sym_enc_vrf_key_nonce: Vec<u8>,
}
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum VrfRootKeyType {
#[cfg(test)]
None = 0,
SymmetricKey = 1,
RsaKey = 2,
}
impl From<i16> for VrfRootKeyType {
fn from(value: i16) -> Self {
match value {
1 => VrfRootKeyType::SymmetricKey,
2 => VrfRootKeyType::RsaKey,
#[cfg(test)]
0 => VrfRootKeyType::None,
_ => panic!("Invalid VrfRootKeyType value: {}", value),
}
}
}
impl From<VrfRootKeyType> for i16 {
fn from(value: VrfRootKeyType) -> Self {
match value {
VrfRootKeyType::SymmetricKey => 1,
VrfRootKeyType::RsaKey => 2,
#[cfg(test)]
VrfRootKeyType::None => 0,
}
}
}
#[derive(Clone)]
pub struct VrfKey(pub Vec<u8>);
impl VrfKeyTableData {
pub async fn new(config: &VrfKeyConfig) -> Result<(Self, VrfKey), VrfKeyCreationError> {
info!("Generating new VRF key and table data");
// handle constant key case separately to avoid unnecessary key generation / parsing
#[cfg(test)]
if let VrfKeyConfig::ConstantVrfKey = config {
use akd::ecvrf::{HardCodedAkdVRF, VRFKeyStorage};
return Ok((
VrfKeyTableData {
root_key_hash: config.root_key_hash().expect("hard coded vrf key"),
root_key_type: VrfRootKeyType::None,
enc_sym_key: None,
sym_enc_vrf_key: vec![],
sym_enc_vrf_key_nonce: vec![],
},
VrfKey((HardCodedAkdVRF {}).retrieve().await.unwrap_or_default()),
));
}
let (sym, sym_key) = if let VrfKeyConfig::B64EncodedSymmetricKey { key: _ } = &config {
let raw_key = config.root_key_bytes().map_err(|_| VrfKeyCreationError)?;
(
XChaCha20Poly1305::new_from_slice(&raw_key).map_err(|err| {
error!(%err, "Invalid symmetric key length");
VrfKeyCreationError
})?,
raw_key,
)
} else {
let key = XChaCha20Poly1305::generate_key(rand::thread_rng());
(XChaCha20Poly1305::new(&key), key.to_vec())
};
let vrf_key = ed25519_dalek::SigningKey::generate(&mut rand::thread_rng())
.to_bytes()
.to_vec();
let nonce = XChaCha20Poly1305::generate_nonce(&mut rand::thread_rng());
let sym_enc_vrf_key = sym.encrypt(&nonce, &vrf_key[..]).map_err(|err| {
error!(%err, "Failed to encrypt VRF key with symmetric key");
VrfKeyCreationError
})?;
match &config {
#[cfg(test)]
VrfKeyConfig::ConstantVrfKey => unreachable!(), // handled above
VrfKeyConfig::B64EncodedSymmetricKey { key: _ } => {
let root_key_hash = config.root_key_hash().map_err(|_| VrfKeyCreationError)?;
error!(
rkh = root_key_hash.len(),
sevk = sym_enc_vrf_key.len(),
sevkn = nonce.len(),
"lengths of stuff!!!!!\n\n\n\n"
);
Ok((
VrfKeyTableData {
root_key_hash,
root_key_type: VrfRootKeyType::SymmetricKey,
enc_sym_key: None,
sym_enc_vrf_key,
sym_enc_vrf_key_nonce: nonce.to_vec(),
},
VrfKey(vrf_key),
))
}
VrfKeyConfig::PEMEncodedRSAKey { private_key } => {
let rsa_private_key =
rsa::RsaPrivateKey::from_pkcs1_pem(private_key).map_err(|err| {
error!(%err, "Failed to decode RSA private key from PEM format");
VrfKeyCreationError
})?;
let root_key_hash = config.root_key_hash().map_err(|_| VrfKeyCreationError)?;
let rsa_public_key = rsa_private_key.to_public_key();
let enc_sym_key = rsa_public_key
.encrypt(&mut rand::thread_rng(), Pkcs1v15Encrypt, &sym_key)
.map_err(|err| {
error!(%err, "Failed to encrypt symmetric key with RSA public key");
VrfKeyCreationError
})?;
Ok((
VrfKeyTableData {
root_key_hash,
root_key_type: VrfRootKeyType::RsaKey,
enc_sym_key: Some(enc_sym_key),
sym_enc_vrf_key,
sym_enc_vrf_key_nonce: nonce.to_vec(),
},
VrfKey(vrf_key),
))
}
}
}
pub async fn to_vrf_key(&self, config: &VrfKeyConfig) -> Result<VrfKey, VrfKeyCreationError> {
info!("Decrypting VrfKeyTableData to obtain VRF key");
// handle constant key case separately to avoid unnecessary key generation / parsing
#[cfg(test)]
if let VrfKeyConfig::ConstantVrfKey = config {
use akd::ecvrf::{HardCodedAkdVRF, VRFKeyStorage};
return Ok(VrfKey(
(HardCodedAkdVRF {}).retrieve().await.unwrap_or_default(),
));
}
if self.sym_enc_vrf_key_nonce.len() != 24 {
error!(
length = self.sym_enc_vrf_key.len(),
"Invalid nonce length for VRF key decryption"
);
return Err(VrfKeyCreationError);
}
let nonce = GenericArray::from_slice(self.sym_enc_vrf_key_nonce.as_ref());
let vrf_key = match &config {
#[cfg(test)]
VrfKeyConfig::ConstantVrfKey => unreachable!(), // handled above
VrfKeyConfig::B64EncodedSymmetricKey { key: _ } => {
let raw_key = config.root_key_bytes().map_err(|_| VrfKeyCreationError)?;
let sym = XChaCha20Poly1305::new_from_slice(&raw_key).map_err(|err| {
error!(%err, "Invalid symmetric key length");
VrfKeyCreationError
})?;
let vrf_key = sym
.decrypt(nonce, &self.sym_enc_vrf_key[..])
.map_err(|err| {
error!(%err, "Failed to decrypt VRF key with symmetric key");
VrfKeyCreationError
})?;
vrf_key
}
VrfKeyConfig::PEMEncodedRSAKey { private_key } => {
let rsa_private_key =
rsa::RsaPrivateKey::from_pkcs1_pem(private_key).map_err(|err| {
error!(%err, "Failed to decode RSA private key from PEM format");
VrfKeyCreationError
})?;
let enc_sym_key = self
.enc_sym_key
.as_ref()
.ok_or(VrfKeyCreationError)
.map_err(|err| {
error!(%err, "Missing encrypted symmetric key for RSA decryption");
err
})?;
let sym_key = rsa_private_key
.decrypt(Pkcs1v15Encrypt, enc_sym_key)
.map_err(|err| {
error!(%err, "Failed to decrypt symmetric key with RSA private key");
VrfKeyCreationError
})?;
let sym = XChaCha20Poly1305::new_from_slice(&sym_key).map_err(|err| {
error!(%err, "Invalid symmetric key length after RSA decryption");
VrfKeyCreationError
})?;
let vrf_key = sym
.decrypt(&nonce, &self.sym_enc_vrf_key[..])
.map_err(|err| {
error!(%err, "Failed to decrypt VRF key with symmetric key");
VrfKeyCreationError
})?;
vrf_key
}
};
Ok(VrfKey(vrf_key))
}
}
#[cfg(test)]
mod tests {
use std::str::FromStr;
use chacha20poly1305::{KeyInit, XChaCha20Poly1305};
use rsa::{
pkcs1::{DecodeRsaPrivateKey, EncodeRsaPrivateKey},
Pkcs1v15Encrypt,
};
// This is a sample RSA private key for testing purposes only.
// Please do not flag this as key leakage or use this key in
// any production system.
const TEST_RSA_PRIVATE_KEY: &str = r"-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCaPQBvavQC8o/A0map70QTqGz6ETMURzHaWIEjlS89ytjj+8Zs
K9L1HCy9SOShFcSYrGb47CdMhMKHa/1YRUVA653uO4rqlO+wPhOZEzljvp9zXvDz
ybLjF2aGZg61w1rC25l36M0NUx8HN+Ws+14mcVzllUiXbk9PMXhWFKoj2wIDAQAB
AoGAU61Sph/NQCgea0r6nakMMuoGLWjVYGP7nOy1KvvNxGVfY9h9XsQr0AS4FP0N
5IKtxPKLbvKXo4DHFLc2nAQAvI8kUPZM40jyVk2yUr2k48PMkssdQKXJ/qRi6PeI
LLLSh7IHDYWdVL7pHA1a7ghH+DIATkA83/++QON1btyKSNECQQDMkKZhqjP2OAbW
5xYrmJp3Q2TlXRjwuOdZLD8uXHl15vAxGokkawxkVlW5vI99tdnqS6Kp5U0THP6H
jc+Hii85AkEAwQTxM1Nr3McluiS5kXs8FjdlgUJ+zRAZWOHQqEazQXDlXFVODHFO
+Rh2sX9eqFUc07sJyjV1xLoN5Fe8DjUXswJABy91iKyv0pA5PUc0sidUFahaXOwe
OiZkie9R8NDyuz93ZGIoOw0/jC60KCgFakb+9ondltYlFOzJy/0hMwOZkQJAc+rB
5+8LcfVvZNC1WPdHaJgwL2Z9vC0U69oBc22yLXTdaYwZaUOLB/F3JrW1ZSZoP4eu
I2/joBeUTDOcTnP4HQJBAICmnHCopJ1sSfQG3fMDobOStJBvxQwLkGeRGzI2XsMw
k7UXX8Wh7AgrK4A/MuZXJL30Cd/dgtlHzJWtlQevTII=
-----END RSA PRIVATE KEY-----";
// This is a sample key for testing purposes only.
// Please do not flag this as key leakage or use this key in
// any production system.
const TEST_SYMMETRIC_KEY_B64: &str = "4AD95tg8tfveioyS/E2jAQw06FDTUCu+VSEZxa41wuM=";
fn create_test_symmetric_config() -> super::VrfKeyConfig {
super::VrfKeyConfig::B64EncodedSymmetricKey {
key: TEST_SYMMETRIC_KEY_B64.to_string(),
}
}
fn create_test_rsa_config() -> super::VrfKeyConfig {
super::VrfKeyConfig::PEMEncodedRSAKey {
private_key: TEST_RSA_PRIVATE_KEY.to_string(),
}
}
fn generate_random_symmetric_key_b64() -> String {
let key = XChaCha20Poly1305::generate_key(rand::thread_rng());
bitwarden_encoding::B64::from(key.to_vec()).to_string()
}
fn generate_random_rsa_key_pem() -> String {
let rsa_private_key = rsa::RsaPrivateKey::new(&mut rand::thread_rng(), 1024).unwrap();
rsa_private_key
.to_pkcs1_pem(Default::default())
.unwrap()
.to_string()
}
#[tokio::test]
pub async fn test_generation_from_symmetric_key() {
let config = create_test_symmetric_config();
let (table_data, vrf_key) = super::VrfKeyTableData::new(&config).await.unwrap();
let retrieved_vrf_key = table_data.to_vrf_key(&config).await.unwrap();
assert_eq!(table_data.enc_sym_key, None);
assert_eq!(
table_data.root_key_hash,
[
130, 153, 58, 122, 202, 166, 92, 56, 249, 28, 57, 171, 206, 187, 12, 81, 44, 166,
61, 41, 188, 84, 20, 43, 108, 211, 146, 152, 243, 155, 49, 66
]
);
assert_eq!(vrf_key.0, retrieved_vrf_key.0);
}
#[tokio::test]
pub async fn test_generation_from_rsa_key() {
let rsa_private_key = rsa::RsaPrivateKey::from_pkcs1_pem(TEST_RSA_PRIVATE_KEY).unwrap();
let config = create_test_rsa_config();
let (table_data, vrf_key) = super::VrfKeyTableData::new(&config.clone()).await.unwrap();
let retrieved_vrf_key = table_data.to_vrf_key(&config).await.unwrap();
assert_eq!(
table_data.root_key_hash,
[
124, 52, 131, 164, 108, 28, 127, 165, 58, 31, 40, 199, 182, 120, 247, 152, 191,
169, 215, 215, 230, 71, 154, 182, 30, 62, 209, 234, 2, 112, 150, 128
]
);
assert!(table_data.enc_sym_key.is_some());
let _ = rsa_private_key
.decrypt(Pkcs1v15Encrypt, table_data.enc_sym_key.as_ref().unwrap())
.unwrap();
assert_eq!(vrf_key.0, retrieved_vrf_key.0);
}
#[tokio::test]
pub async fn test_generation_from_constant_key() {
let config = super::VrfKeyConfig::ConstantVrfKey;
let (table_data, vrf_key) = super::VrfKeyTableData::new(&config.clone()).await.unwrap();
let retrieved_vrf_key = table_data.to_vrf_key(&config).await.unwrap();
assert_eq!(table_data.root_key_hash, vec![]);
assert_eq!(table_data.enc_sym_key, None);
assert_eq!(table_data.sym_enc_vrf_key, vec![]);
assert_eq!(table_data.sym_enc_vrf_key_nonce, vec![]);
assert_eq!(vrf_key.0, retrieved_vrf_key.0);
assert!(!vrf_key.0.is_empty());
}
#[tokio::test]
pub async fn test_invalid_base64_symmetric_key() {
let config = super::VrfKeyConfig::B64EncodedSymmetricKey {
key: "not!valid@base64#".to_string(),
};
let result = super::VrfKeyTableData::new(&config.clone()).await;
assert!(matches!(result, Err(super::VrfKeyCreationError)));
}
#[tokio::test]
pub async fn test_invalid_base64_during_retrieval() {
let config_valid = create_test_symmetric_config();
let (table_data, _) = super::VrfKeyTableData::new(&config_valid).await.unwrap();
let config_invalid = super::VrfKeyConfig::B64EncodedSymmetricKey {
key: "not!valid@base64#".to_string(),
};
let result = table_data.to_vrf_key(&config_invalid).await;
assert!(matches!(result, Err(super::VrfKeyCreationError)));
}
#[tokio::test]
pub async fn test_invalid_symmetric_key_length() {
let short_key = bitwarden_encoding::B64::from(vec![0u8; 16]).to_string();
let config = super::VrfKeyConfig::B64EncodedSymmetricKey { key: short_key };
let result = super::VrfKeyTableData::new(&config).await;
assert!(matches!(result, Err(super::VrfKeyCreationError)));
}
#[tokio::test]
pub async fn test_invalid_rsa_pem_format_malformed() {
let malformed_pem =
"-----BEGIN RSA PRIVATE KEY-----\nINVALID\n-----END RSA PRIVATE KEY-----";
let config = super::VrfKeyConfig::PEMEncodedRSAKey {
private_key: malformed_pem.to_string(),
};
let result = super::VrfKeyTableData::new(&config).await;
assert!(matches!(result, Err(super::VrfKeyCreationError)));
}
#[tokio::test]
pub async fn test_invalid_rsa_pem_format_missing_headers() {
let missing_headers = TEST_RSA_PRIVATE_KEY
.replace("-----BEGIN RSA PRIVATE KEY-----\n", "")
.replace("-----END RSA PRIVATE KEY-----", "");
let config = super::VrfKeyConfig::PEMEncodedRSAKey {
private_key: missing_headers.to_string(),
};
let result = super::VrfKeyTableData::new(&config).await;
assert!(matches!(result, Err(super::VrfKeyCreationError)));
}
#[tokio::test]
pub async fn test_wrong_symmetric_key_decryption() {
let config1 = create_test_symmetric_config();
let (table_data, _) = super::VrfKeyTableData::new(&config1).await.unwrap();
let config2 = super::VrfKeyConfig::B64EncodedSymmetricKey {
key: generate_random_symmetric_key_b64(),
};
let result = table_data.to_vrf_key(&config2).await;
assert!(matches!(result, Err(super::VrfKeyCreationError)));
}
#[tokio::test]
pub async fn test_wrong_rsa_key_decryption() {
let config1 = create_test_rsa_config();
let (table_data, _) = super::VrfKeyTableData::new(&config1).await.unwrap();
let config2 = super::VrfKeyConfig::PEMEncodedRSAKey {
private_key: generate_random_rsa_key_pem(),
};
let result = table_data.to_vrf_key(&config2).await;
assert!(result.is_err());
}
#[tokio::test]
pub async fn test_rsa_missing_enc_sym_key() {
let config = create_test_rsa_config();
let (mut table_data, _) = super::VrfKeyTableData::new(&config).await.unwrap();
table_data.enc_sym_key = None;
let result = table_data.to_vrf_key(&config).await;
assert!(matches!(result, Err(super::VrfKeyCreationError)));
}
#[tokio::test]
pub async fn test_wrong_nonce() {
let config = create_test_symmetric_config();
let (mut table_data, _) = super::VrfKeyTableData::new(&config).await.unwrap();
table_data.sym_enc_vrf_key_nonce.truncate(10);
let result = table_data.to_vrf_key(&config).await;
assert!(result.is_err());
}
#[tokio::test]
pub async fn test_nonce_size_validation() {
let config = create_test_symmetric_config();
let (table_data, _) = super::VrfKeyTableData::new(&config).await.unwrap();
assert_eq!(table_data.sym_enc_vrf_key_nonce.len(), 24);
}
#[tokio::test]
pub async fn test_empty_symmetric_key() {
let config = super::VrfKeyConfig::B64EncodedSymmetricKey { key: String::new() };
let result = super::VrfKeyTableData::new(&config).await;
assert!(result.is_err());
}
#[tokio::test]
pub async fn test_empty_rsa_key() {
let config = super::VrfKeyConfig::PEMEncodedRSAKey {
private_key: String::new(),
};
let result = super::VrfKeyTableData::new(&config).await;
assert!(matches!(result, Err(super::VrfKeyCreationError)));
}
#[tokio::test]
pub async fn test_vrf_key_randomness() {
let config1 = create_test_symmetric_config();
let config2 = create_test_symmetric_config();
let (table_data1, vrf_key1) = super::VrfKeyTableData::new(&config1).await.unwrap();
let (table_data2, vrf_key2) = super::VrfKeyTableData::new(&config2).await.unwrap();
assert_ne!(vrf_key1.0, vrf_key2.0);
assert_ne!(
table_data1.sym_enc_vrf_key_nonce,
table_data2.sym_enc_vrf_key_nonce
);
}
#[tokio::test]
pub async fn test_symmetric_key_not_persisted() {
let config = create_test_symmetric_config();
let (table_data, _) = super::VrfKeyTableData::new(&config).await.unwrap();
let symmetric_key_bytes =
bitwarden_encoding::B64::from_str(TEST_SYMMETRIC_KEY_B64).unwrap();
assert!(!table_data
.sym_enc_vrf_key
.contains(&symmetric_key_bytes.as_bytes()[0]));
assert_eq!(table_data.enc_sym_key, None);
}
#[tokio::test]
pub async fn test_rsa_private_key_not_persisted() {
let config = create_test_rsa_config();
let (table_data, _) = super::VrfKeyTableData::new(&config).await.unwrap();
let rsa_key = rsa::RsaPrivateKey::from_pkcs1_pem(TEST_RSA_PRIVATE_KEY).unwrap();
let rsa_der = rsa_key.to_pkcs1_der().unwrap();
assert!(!table_data
.sym_enc_vrf_key
.windows(4)
.any(|w| rsa_der.as_bytes().windows(4).any(|rw| w == rw)));
assert!(table_data.enc_sym_key.is_some());
}
#[tokio::test]
pub async fn test_vrf_key_is_encrypted_at_rest() {
let config = create_test_symmetric_config();
let (table_data, vrf_key) = super::VrfKeyTableData::new(&config).await.unwrap();
assert!(!table_data
.sym_enc_vrf_key
.windows(8)
.any(|w| vrf_key.0.windows(8).any(|vw| w == vw)));
}
#[tokio::test]
pub async fn test_symmetric_key_encryption_in_rsa_mode() {
let config = create_test_rsa_config();
let (table_data, _) = super::VrfKeyTableData::new(&config).await.unwrap();
let enc_sym_key = table_data.enc_sym_key.as_ref().unwrap();
let rsa_key = rsa::RsaPrivateKey::from_pkcs1_pem(TEST_RSA_PRIVATE_KEY).unwrap();
let decrypted_sym_key = rsa_key.decrypt(Pkcs1v15Encrypt, enc_sym_key).unwrap();
assert_ne!(enc_sym_key, &decrypted_sym_key);
assert_eq!(decrypted_sym_key.len(), 32);
}
#[tokio::test]
pub async fn test_cannot_decrypt_symmetric_with_rsa_config() {
let sym_config = create_test_symmetric_config();
let (table_data, _) = super::VrfKeyTableData::new(&sym_config).await.unwrap();
let rsa_config = create_test_rsa_config();
let result = table_data.to_vrf_key(&rsa_config).await;
assert!(matches!(result, Err(super::VrfKeyCreationError)));
}
#[tokio::test]
pub async fn test_cannot_decrypt_rsa_with_symmetric_config() {
let rsa_config = create_test_rsa_config();
let (table_data, _) = super::VrfKeyTableData::new(&rsa_config).await.unwrap();
let sym_config = create_test_symmetric_config();
let result = table_data.to_vrf_key(&sym_config).await;
assert!(matches!(result, Err(super::VrfKeyCreationError)));
}
}