pub struct KeyRing { /* private fields */ }Expand description
A set of key-encryption keys, one of them current.
Holds every KEK that can still open data, plus which one new seals use.
Rotation is therefore additive: add a KEK, point current at it, and old
ciphertext keeps opening under its own kek_id until it is re-sealed.
Implementations§
Source§impl KeyRing
impl KeyRing
Sourcepub fn new<I>(keys: I, current: impl Into<String>) -> Result<Self, CryptoError>
pub fn new<I>(keys: I, current: impl Into<String>) -> Result<Self, CryptoError>
Build a key ring from (id, raw 32-byte key) pairs, with current
naming the KEK new seals use.
§Errors
CryptoError::InvalidKek if any key is not KEK_LEN bytes, or if
current is not among the supplied ids — a ring that cannot seal is a
configuration error worth failing at startup rather than at first write.
Sourcepub fn current_kek_id(&self) -> &str
pub fn current_kek_id(&self) -> &str
The id new seals are written under.
Sourcepub fn seal(
&self,
plaintext: &[u8],
binding: SecretBinding<'_>,
) -> Result<SealedSecret, CryptoError>
pub fn seal( &self, plaintext: &[u8], binding: SecretBinding<'_>, ) -> Result<SealedSecret, CryptoError>
Encrypt plaintext under the current KEK, bound to binding.
§Errors
CryptoError::SealFailed if the RNG or the AEAD fails.
Sourcepub fn open(
&self,
sealed: &SealedSecret,
binding: SecretBinding<'_>,
) -> Result<Zeroizing<Vec<u8>>, CryptoError>
pub fn open( &self, sealed: &SealedSecret, binding: SecretBinding<'_>, ) -> Result<Zeroizing<Vec<u8>>, CryptoError>
Decrypt sealed, which must have been sealed under the same binding.
The plaintext comes back in a Zeroizing buffer so it is wiped when
the caller drops it rather than lingering in freed memory.
§Errors
CryptoError::UnknownKekId when no configured KEK matches — the
operator removed a key that still has data under it.
CryptoError::OpenFailed for a wrong key, tampered ciphertext, or a
binding that does not match the one it was sealed with.
Sourcepub fn reseal(
&self,
sealed: &SealedSecret,
binding: SecretBinding<'_>,
) -> Result<SealedSecret, CryptoError>
pub fn reseal( &self, sealed: &SealedSecret, binding: SecretBinding<'_>, ) -> Result<SealedSecret, CryptoError>
Re-seal sealed under the current KEK. Used by rotation: open with the
old key, seal with the new, same binding.
§Errors
As Self::open and Self::seal.
Source§impl KeyRing
impl KeyRing
Sourcepub fn from_spec(spec: &str, current: &str) -> Result<Self, CryptoError>
pub fn from_spec(spec: &str, current: &str) -> Result<Self, CryptoError>
Build a ring from a deploy-time spec: id:hex,id:hex,…, with current
naming which id new seals use.
Hex rather than base64 so no encoding dependency is needed for 32 bytes,
and so a malformed value fails loudly instead of decoding to the wrong
length. Generate one with openssl rand -hex 32.
§Errors
CryptoError::InvalidKek on a malformed entry, a key that is not
KEK_LEN bytes, or a current id absent from the spec.