mirror of
https://github.com/rustfs/rustfs.git
synced 2026-09-01 01:38:18 +00:00
feat(kms): add the data key rewrap primitive (#5607)
* feat(kms): add data key rewrap and wrapping inspection primitives Rewrap re-protects an existing data key envelope with the master key's current version without touching the data key itself, which is the precondition for ever retiring an older version: until every envelope a version wrapped has been moved off it, destroying that version orphans every object whose data key it wrapped. Adds KmsBackend::rewrap_data_key and its read-only counterpart describe_data_key_wrapping, both gated by a new BackendCapabilities::rewrap flag and defaulting to UnsupportedCapability. Vault KV2 unwraps with the frozen version record that wrapped the envelope and re-wraps with the current material; Vault Transit uses the native transit/rewrap endpoint so the data key never enters this process. No read or write path changes: nothing calls these yet. * test(kms): cover the rewrap primitive against a scripted Vault * fix(kms): resolve both key materials before the data key is unwrapped Keeps every fallible step out of the window in which the plaintext data key exists, so no error path can drop it without zeroizing it first.
This commit is contained in:
@@ -23,8 +23,10 @@ use crate::error::{KmsError, Result};
|
||||
use crate::types::{
|
||||
CancelKeyDeletionRequest, CancelKeyDeletionResponse, CreateKeyRequest, CreateKeyResponse,
|
||||
DEFAULT_PENDING_DELETION_WINDOW_DAYS, DecryptRequest, DecryptResponse, DeleteKeyRequest, DeleteKeyResponse,
|
||||
DescribeKeyRequest, DescribeKeyResponse, EncryptRequest, EncryptResponse, GenerateDataKeyRequest, GenerateDataKeyResponse,
|
||||
ListKeysRequest, ListKeysResponse, MAX_PENDING_DELETION_WINDOW_DAYS, MIN_PENDING_DELETION_WINDOW_DAYS, OperationContext,
|
||||
DescribeDataKeyWrappingRequest, DescribeDataKeyWrappingResponse, DescribeKeyRequest, DescribeKeyResponse, EncryptRequest,
|
||||
EncryptResponse, GenerateDataKeyRequest, GenerateDataKeyResponse, ListKeysRequest, ListKeysResponse,
|
||||
MAX_PENDING_DELETION_WINDOW_DAYS, MIN_PENDING_DELETION_WINDOW_DAYS, OperationContext, RewrapDataKeyRequest,
|
||||
RewrapDataKeyResponse,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
@@ -167,6 +169,29 @@ impl KmsManager {
|
||||
self.backend.generate_data_key(request).await
|
||||
}
|
||||
|
||||
/// Re-wrap an existing data key envelope onto the master key's current
|
||||
/// version, leaving the data key — and therefore every object body it
|
||||
/// protects — untouched.
|
||||
///
|
||||
/// Backends without retained version history reject this with
|
||||
/// [`KmsError::UnsupportedCapability`]; check
|
||||
/// [`Self::backend_capabilities`] before offering it.
|
||||
pub async fn rewrap_data_key(&self, request: RewrapDataKeyRequest) -> Result<RewrapDataKeyResponse> {
|
||||
self.backend.rewrap_data_key(request).await
|
||||
}
|
||||
|
||||
/// Report which master key version wraps an existing data key envelope.
|
||||
///
|
||||
/// The read-only side of [`Self::rewrap_data_key`], and the supported way to
|
||||
/// ask that question: where the version is recorded differs per backend, so
|
||||
/// callers must not inspect envelopes themselves.
|
||||
pub async fn describe_data_key_wrapping(
|
||||
&self,
|
||||
request: DescribeDataKeyWrappingRequest,
|
||||
) -> Result<DescribeDataKeyWrappingResponse> {
|
||||
self.backend.describe_data_key_wrapping(request).await
|
||||
}
|
||||
|
||||
/// Describe a key
|
||||
///
|
||||
/// Audited as an internal operation; callers serving an authenticated
|
||||
|
||||
Reference in New Issue
Block a user