Hey folks,
in an attempt to write a store for cryptographic keys, I came up with a Keystore
implementation that abstracts most of the logic for saving keys in memory and removing them.
Here is the link to the corresponding Rust playground. I tried to reduce the example as much as possible. Unfortunately, some of the crates used are not available in the playground.
Therefore it uses a few layers of abstraction:
- a
RawKeystore
, which is just a hashmap that contains the keys with associated information - a
ShieldedKeystore
, which contains theRawKeystore
serialized into a byte format and encrypted with a crate calledshielded
- it is used when no keys are currently read (the keystore is at rest) - an
UnshieldedKeystore
, that is used to access the keys via theRawKeystore
I came up with the UnshieldedKeystore
that holds a reference to its shielded counterpart and contains the RawKeystore
, because I had to manually overwrite the encrypted memory each time I performed an operation on the RawKeystore. If I would not overwrite it, all changes would be lost and since it is an operation you forget easily, that part was prone to errors.
Currently, the Drop
implementation for the UnshieldedKeystore
takes care of refreshing the ShieldedKeystore
with the new contents.
I thought this could be a cool little library - the idea is to hide all the details and only expose a public Keystore
which again abstracts the other key stores.
You feed a KeyContainer
to the KeyStore
and it saves it. You can the access it by id and get it back.
A KeyContainer
looks like this. It is (de-)serializable.
pub struct KeyContainer {
key_id: Uuid,
key: String,
}
I now want to add custom attributes to it (since it should be a general purpose library, there could be custom attributes or there are none). I imagine something like this:
pub struct KeyContainer<'de, T> where T: Debug + Clone + Serialize + Deserialize<'de> {
key_id: Uuid,
key: String,
custom_attributes: Option<T>
}
where T is something like this:
#[derive(Debug, Clone, Serialize, Deserialize)]
struct CustomAttributes {
a: String,
}
I already tried to add these generic params to all of my other structs (as they all somehow contain the same T).
However, I run into lifetime issues with the lifetime of Deserialize
and the other structs. Maybe my approach is not the right one - I feel like I throw the lifetimes around not really thinking about what they mean.
Here is another playground with an intermediate version that doesn't compile because of the lifetime issues I mentioned.
I would really appreciate someone helping me out.