Skip to content

Commit

Permalink
chore: cargo fmt
Browse files Browse the repository at this point in the history
  • Loading branch information
bittermandel committed Sep 25, 2024
1 parent d92d1fc commit 45a4511
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 89 deletions.
35 changes: 22 additions & 13 deletions crates/valv/src/api/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ impl MasterKeyManagementService for API {
) -> Result<tonic::Response<CreateMasterKeyResponse>, tonic::Status> {
let key = self
.valv
.create_key(request.get_ref().keyring_name.clone(), request.get_ref().master_key_id.clone())
.create_key(
request.get_ref().keyring_name.clone(),
request.get_ref().master_key_id.clone(),
)
.await;

let reply = CreateMasterKeyResponse {
Expand Down Expand Up @@ -85,15 +88,18 @@ impl MasterKeyManagementService for API {
&self,
request: tonic::Request<EncryptRequest>,
) -> Result<tonic::Response<EncryptResponse>, tonic::Status> {
let encrypted_value = self.valv.encrypt(
request.get_ref().keyring_name.clone(),
request.get_ref().master_key_id.clone(),
request.get_ref().plaintext.clone().to_vec(),
).await;
let encrypted_value = self
.valv
.encrypt(
request.get_ref().keyring_name.clone(),
request.get_ref().master_key_id.clone(),
request.get_ref().plaintext.clone().to_vec(),
)
.await;

let reply = crate::valv::valv::v1::EncryptResponse {
name: request.get_ref().master_key_id.clone(),
ciphertext: encrypted_value.into()
ciphertext: encrypted_value.into(),
};

Ok(tonic::Response::new(reply))
Expand All @@ -103,11 +109,14 @@ impl MasterKeyManagementService for API {
&self,
request: tonic::Request<DecryptRequest>,
) -> Result<tonic::Response<DecryptResponse>, tonic::Status> {
let decrypted_result = self.valv.decrypt(
request.get_ref().keyring_name.clone(),
request.get_ref().master_key_id.clone(),
request.get_ref().ciphertext.clone().to_vec(),
).await;
let decrypted_result = self
.valv
.decrypt(
request.get_ref().keyring_name.clone(),
request.get_ref().master_key_id.clone(),
request.get_ref().ciphertext.clone().to_vec(),
)
.await;
match decrypted_result {
Ok(decrypted_value) => {
let reply = DecryptResponse {
Expand All @@ -116,7 +125,7 @@ impl MasterKeyManagementService for API {
return Ok(tonic::Response::new(reply));
}
Err(err) => {
println!("Failed to decrypt ciphertext {err}");
println!("Failed to decrypt ciphertext {err}");
return Err(tonic::Status::new(
tonic::Code::InvalidArgument,
"Invalid ciphertext",
Expand Down
7 changes: 3 additions & 4 deletions crates/valv/src/cmd/main.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use std::sync::Arc;

use clap::Parser;
use secrecy::{ExposeSecret, Secret};
use tonic::transport::Server;
use valv::{
api,
valv::valv::v1::master_key_management_service_server::MasterKeyManagementServiceServer,
api, valv::valv::v1::master_key_management_service_server::MasterKeyManagementServiceServer,
Valv,
};
use secrecy::{ExposeSecret, Secret};
use tonic::transport::Server;

#[derive(Parser)]
struct Cli {
Expand Down
98 changes: 70 additions & 28 deletions crates/valv/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

use boring::error::ErrorStack;
use gen::valv::internal;
use prost::bytes::Buf;
Expand Down Expand Up @@ -44,10 +43,20 @@ pub trait ValvAPI: Send + Sync {
async fn list_keys(&self, tenant: String) -> Option<Vec<internal::Key>>;
async fn update_key(&self, tenant: String, key: internal::Key) -> internal::Key;

async fn get_key_version(&self, tenant: String, key_name: String, version_id: u32) -> Option<internal::KeyVersion>;
async fn get_key_version(
&self,
tenant: String,
key_name: String,
version_id: u32,
) -> Option<internal::KeyVersion>;

async fn encrypt(&self, tenant: String, key_name: String, plaintext: Vec<u8>) -> Vec<u8>;
async fn decrypt(&self, tenant: String, key_name: String, ciphertext: Vec<u8>) -> Result<Vec<u8>, ErrorStack>;
async fn decrypt(
&self,
tenant: String,
key_name: String,
ciphertext: Vec<u8>,
) -> Result<Vec<u8>, ErrorStack>;
}

pub struct Valv {
Expand Down Expand Up @@ -102,12 +111,8 @@ impl ValvAPI for Valv {
)
.unwrap();

let mut encrypted_result = Vec::with_capacity(
iv.len() +
encrypted_key.len() +
tag.len()
);

let mut encrypted_result = Vec::with_capacity(iv.len() + encrypted_key.len() + tag.len());

// Add IV, key material and tag to result
encrypted_result.extend_from_slice(&iv);
encrypted_result.extend_from_slice(&encrypted_key);
Expand All @@ -129,7 +134,9 @@ impl ValvAPI for Valv {
};

self.db
.update_key_metadata(tenant.as_str(), key.clone()).await.unwrap();
.update_key_metadata(tenant.as_str(), key.clone())
.await
.unwrap();

let key_version = internal::KeyVersion {
key_id: name.clone(),
Expand All @@ -144,31 +151,51 @@ impl ValvAPI for Valv {
};

self.db
.append_key_version(
tenant.as_str(),
key.clone(),
key_version,
)
.append_key_version(tenant.as_str(), key.clone(), key_version)
.await
.unwrap();

key
}

async fn update_key(&self, tenant: String, key: internal::Key) -> internal::Key {
self.db.update_key_metadata(tenant.as_str(), key.clone()).await.unwrap();

self.db
.update_key_metadata(tenant.as_str(), key.clone())
.await
.unwrap();

key
}

async fn get_key_version(&self, tenant: String, key_name: String, version_id: u32) -> Option<internal::KeyVersion> {
let key_version = self.db.get_key_version(tenant.as_str(), &key_name, version_id).await.unwrap();
async fn get_key_version(
&self,
tenant: String,
key_name: String,
version_id: u32,
) -> Option<internal::KeyVersion> {
let key_version = self
.db
.get_key_version(tenant.as_str(), &key_name, version_id)
.await
.unwrap();
Some(key_version)
}

async fn encrypt(&self, tenant: String, key_name: String, plaintext: Vec<u8>) -> Vec<u8> {
let key = self.db.get_key_metadata(tenant.as_str(), &key_name).await.unwrap();
let key_version = self.db.get_key_version(tenant.as_str(), &key.key_id, key.primary_version_id.parse().unwrap()).await.unwrap();
let key = self
.db
.get_key_metadata(tenant.as_str(), &key_name)
.await
.unwrap();
let key_version = self
.db
.get_key_version(
tenant.as_str(),
&key.key_id,
key.primary_version_id.parse().unwrap(),
)
.await
.unwrap();

let (iv, remainder) = key_version.key_material.split_at(12);
let (cipher, tag) = remainder.split_at(remainder.len() - 16);
Expand All @@ -180,7 +207,8 @@ impl ValvAPI for Valv {
&[],
&cipher,
tag,
).expect("Failed to decrypt key material");
)
.expect("Failed to decrypt key material");

let mut iv = [0; 12];
boring::rand::rand_bytes(&mut iv).unwrap();
Expand All @@ -201,9 +229,9 @@ impl ValvAPI for Valv {
4 + // Key version (u32)
iv.len() +
encrypted_key.len() +
tag.len()
tag.len(),
);

// Add version, IV and encrypted key to result
encrypted_result.extend_from_slice(&(key_version.version as u32).to_be_bytes());

Expand All @@ -214,14 +242,27 @@ impl ValvAPI for Valv {
encrypted_result
}

async fn decrypt(&self, tenant: String, key_name: String, ciphertext: Vec<u8>) -> Result<Vec<u8>, ErrorStack> {
async fn decrypt(
&self,
tenant: String,
key_name: String,
ciphertext: Vec<u8>,
) -> Result<Vec<u8>, ErrorStack> {
let (key_version_id, remainder) = ciphertext.split_at(4);
let (iv, remainder) = remainder.split_at(12);
let (cipher, tag) = remainder.split_at(remainder.len() - 16);

let key = self.db.get_key_metadata(tenant.as_str(), &key_name).await.unwrap();
let key = self
.db
.get_key_metadata(tenant.as_str(), &key_name)
.await
.unwrap();
let key_version_id = std::io::Cursor::new(key_version_id).get_u32();
let key_version = self.db.get_key_version(tenant.as_str(), &key.key_id, key_version_id).await.unwrap();
let key_version = self
.db
.get_key_version(tenant.as_str(), &key.key_id, key_version_id)
.await
.unwrap();

let (kv_iv, kv_remainder) = key_version.key_material.split_at(12);
let (kv_cipher, kv_tag) = kv_remainder.split_at(kv_remainder.len() - 16);
Expand All @@ -233,7 +274,8 @@ impl ValvAPI for Valv {
&[],
&kv_cipher,
kv_tag,
).expect("Failed to decrypt key material");
)
.expect("Failed to decrypt key material");

boring::symm::decrypt_aead(
boring::symm::Cipher::aes_256_gcm(),
Expand Down
48 changes: 23 additions & 25 deletions crates/valv/src/storage/fdb.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
use anyhow::anyhow;
use async_trait::async_trait;
use foundationdb::{
directory::Directory,
tuple::unpack,
FdbError, RangeOption,
};
use foundationdb::{directory::Directory, tuple::unpack, FdbError, RangeOption};
use prost::Message;

use crate::gen::valv::internal;
Expand Down Expand Up @@ -101,11 +97,7 @@ impl FoundationDB {

#[async_trait]
impl ValvStorage for FoundationDB {
async fn get_key_metadata(
&self,
tenant: &str,
key_id: &str,
) -> anyhow::Result<internal::Key> {
async fn get_key_metadata(&self, tenant: &str, key_id: &str) -> anyhow::Result<internal::Key> {
let trx = self.database.create_trx()?;
let key = self.get_metadata_fdb_key(&trx, tenant, key_id).await;

Expand Down Expand Up @@ -153,7 +145,7 @@ impl ValvStorage for FoundationDB {
for key_value in key_values.into_iter() {
// Skip if the key is not a metadata key
if !key_value.key().ends_with(b"metadata\x00") {
continue
continue;
}

let key = internal::Key::decode(&key_value.value()[..]).expect("Failed to decode key");
Expand All @@ -163,11 +155,7 @@ impl ValvStorage for FoundationDB {
Ok(keys)
}

async fn update_key_metadata(
&self,
tenant: &str,
key: internal::Key,
) -> anyhow::Result<()> {
async fn update_key_metadata(&self, tenant: &str, key: internal::Key) -> anyhow::Result<()> {
let trx = self.database.create_trx()?;
let path = self.get_metadata_fdb_key(&trx, tenant, &key.key_id).await;

Expand All @@ -184,21 +172,28 @@ impl ValvStorage for FoundationDB {
version_id: u32,
) -> anyhow::Result<internal::KeyVersion> {
let trx = self.database.create_trx()?;

let version_key = self.get_version_fdb_key(&trx, tenant, key_id, version_id).await;

let version_key = self
.get_version_fdb_key(&trx, tenant, key_id, version_id)
.await;

let key_value = trx.get(&version_key, false).await?;

match key_value {
Some(key_value) => {
let version = internal::KeyVersion::decode(&key_value[..]).expect("Failed to decode key");
let version =
internal::KeyVersion::decode(&key_value[..]).expect("Failed to decode key");
Ok(version)
}
None => Err(anyhow!("Key not found")),
}
}

async fn get_key_versions(&self, tenant: &str, key_id: &str) -> anyhow::Result<Vec<internal::KeyVersion>> {
async fn get_key_versions(
&self,
tenant: &str,
key_id: &str,
) -> anyhow::Result<Vec<internal::KeyVersion>> {
let trx = self.database.create_trx()?;
let directory = foundationdb::directory::DirectoryLayer::default();

Expand Down Expand Up @@ -232,7 +227,8 @@ impl ValvStorage for FoundationDB {

for key_value in key_values.iter() {
let test: Vec<u8> = unpack(&key_value.value()).expect("Failed to unpack key value");
let version = internal::KeyVersion::decode(&test[..]).expect("Failed to decode key version");
let version =
internal::KeyVersion::decode(&test[..]).expect("Failed to decode key version");
key_versions.push(version);
}

Expand All @@ -243,11 +239,13 @@ impl ValvStorage for FoundationDB {
&self,
tenant: &str,
key: internal::Key,
key_version: internal::KeyVersion
key_version: internal::KeyVersion,
) -> anyhow::Result<()> {
let trx = self.database.create_trx()?;

let version_key = self.get_version_fdb_key(&trx, tenant, &key.key_id, key_version.version).await;

let version_key = self
.get_version_fdb_key(&trx, tenant, &key.key_id, key_version.version)
.await;

trx.set(&version_key, &key_version.encode_to_vec());
trx.commit().await.unwrap();
Expand All @@ -260,7 +258,7 @@ impl ValvStorage for FoundationDB {
tenant: &str,
key_id: &str,
version_id: u32,
version: internal::KeyVersion
version: internal::KeyVersion,
) -> anyhow::Result<()> {
todo!()
}
Expand Down
Loading

0 comments on commit 45a4511

Please sign in to comment.