Skip to content

Commit

Permalink
added a key wrapper using cocoon
Browse files Browse the repository at this point in the history
  • Loading branch information
Christiantyemele committed Nov 20, 2024
1 parent 7240052 commit 4463b8c
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 5 deletions.
1 change: 1 addition & 0 deletions crates/database/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ async-trait.workspace = true
serde.workspace = true
thiserror.workspace = true
tokio.workspace = true
cocoon = "0.4.3"
50 changes: 48 additions & 2 deletions crates/database/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
use async_trait::async_trait;
use cocoon::MiniCocoon;
use mongodb::{
bson::{self, doc, oid::ObjectId, Bson, Document as BsonDocument},
error::Error as MongoError,
options::{ClientOptions, FindOptions},
options::{ClientOptions, CountOptions, FindOptions},

Check warning on line 6 in crates/database/src/lib.rs

View workflow job for this annotation

GitHub Actions / Build and Test

unused import: `CountOptions`

Check warning on line 6 in crates/database/src/lib.rs

View workflow job for this annotation

GitHub Actions / Build and Test

unused import: `CountOptions`
Client, Collection, Database,
};
use once_cell::sync::OnceCell;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use std::{borrow::Borrow, f64::consts::E, sync::Arc};

Check warning on line 11 in crates/database/src/lib.rs

View workflow job for this annotation

GitHub Actions / Build and Test

unused import: `f64::consts::E`

Check warning on line 11 in crates/database/src/lib.rs

View workflow job for this annotation

GitHub Actions / Build and Test

unused import: `f64::consts::E`
use thiserror::Error;
use tokio::sync::RwLock;

/// A trait that ensures the entity has an `id` field.
pub trait Identifiable {
fn id(&self) -> Option<ObjectId>;
fn set_id(&mut self, id: ObjectId);
fn get_secret(&self) -> Option<Vec<u8>>;
}

/// Definition of custom errors for repository operations.
Expand Down Expand Up @@ -60,6 +62,50 @@ pub fn get_or_init_database() -> Arc<RwLock<Database>> {
.clone()
}

/// Definition of a trait for secure repository operations.
#[async_trait]
pub trait SecureRepository<Entity>: Sync + Send
where
Entity: Sized + Clone + Send + Sync + 'static,
Entity: Identifiable + Unpin,
Entity: Serialize + for<'de> Deserialize<'de>,
Vec<u8>: Borrow<Entity>,
{
fn get_collection(&self) -> Arc<RwLock<Collection<Entity>>>;
/// Stores a new entity.
async fn wrap_store(&self, mut entity: Entity) -> Result<Entity, RepositoryError> {
let collection = self.get_collection();

// Lock the Mutex and get the Collection
let collection = collection.read().await;

// read master key for encryption
let master_key = std::env::var("MASTER_KEY").unwrap_or_default();

let seed = &[0; 32];
let mut cocoon = MiniCocoon::from_key(master_key.as_bytes(), seed);
let secret = entity.get_secret().unwrap_or_default();
let wrapped_key = cocoon.wrap(&secret).unwrap_or_default();

// Insert the new entity into the database
let metadata = collection.insert_one(wrapped_key, None).await?;

// Set the ID if it was inserted and return the updated entity
if let Bson::ObjectId(oid) = metadata.inserted_id {
entity.set_id(oid);
}

Ok(entity)
}
async fn unwrap_find_one_by(&self, filter: BsonDocument) -> Result<Option<Entity>, RepositoryError> {
let collection = self.get_collection();

// Lock the Mutex and get the Collection
let collection = collection.read().await;
Ok(collection.find_one(filter, None).await?)
}

}
/// Definition of a trait for repository operations.
#[async_trait]
pub trait Repository<Entity>: Sync + Send
Expand Down
10 changes: 7 additions & 3 deletions crates/keystore/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use async_trait::async_trait;
use database::{Identifiable, Repository};
use did_utils::jwk::Jwk;
use database::{Identifiable, Repository, RepositoryError};

Check warning on line 2 in crates/keystore/src/lib.rs

View workflow job for this annotation

GitHub Actions / Build and Test

unused import: `RepositoryError`

Check warning on line 2 in crates/keystore/src/lib.rs

View workflow job for this annotation

GitHub Actions / Build and Test

unused import: `RepositoryError`
use did_utils::jwk::{Bytes, Jwk};

Check warning on line 3 in crates/keystore/src/lib.rs

View workflow job for this annotation

GitHub Actions / Build and Test

unused import: `Bytes`

Check warning on line 3 in crates/keystore/src/lib.rs

View workflow job for this annotation

GitHub Actions / Build and Test

unused import: `Bytes`
use mongodb::{bson::oid::ObjectId, Collection};
use once_cell::sync::OnceCell;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use std::{io::Read, sync::Arc};

Check warning on line 7 in crates/keystore/src/lib.rs

View workflow job for this annotation

GitHub Actions / Build and Test

unused import: `io::Read`

Check warning on line 7 in crates/keystore/src/lib.rs

View workflow job for this annotation

GitHub Actions / Build and Test

unused import: `io::Read`
use tokio::sync::RwLock;

static SECRETS_COLLECTION: OnceCell<Collection<Secrets>> = OnceCell::new();
Expand All @@ -28,6 +28,10 @@ impl Identifiable for Secrets {
fn set_id(&mut self, id: ObjectId) {
self.id = Some(id);
}
fn get_secret(&self) -> Option<Vec<u8>> {
let secret: String = serde_json::from_reader(&self.secret_material.key).unwrap_or_default();

Check failure on line 32 in crates/keystore/src/lib.rs

View workflow job for this annotation

GitHub Actions / Build and Test

the trait bound `&Key: std::io::Read` is not satisfied

Check failure on line 32 in crates/keystore/src/lib.rs

View workflow job for this annotation

GitHub Actions / Build and Test

the trait bound `&Key: std::io::Read` is not satisfied
Some(secret.as_bytes().to_owned())
}
}

#[derive(Debug, Clone)]
Expand Down

0 comments on commit 4463b8c

Please sign in to comment.