key_registry.go
key_registry.go - Overview
This file implements the Key Registry, which manages data encryption keys used by Badger. It handles key creation, storage, retrieval, and rotation, persisting them to disk with optional encryption.
Detailed Documentation
Constants
KeyRegistryFileName
const KeyRegistryFileName = "KEYREGISTRY"
- Purpose: Defines the filename used for the key registry file.
KeyRegistryRewriteFileName
const KeyRegistryRewriteFileName = "REWRITE-KEYREGISTRY"
- Purpose: Defines the filename used for the temporary key registry file during rewrite operations.
sanityText
var sanityText = []byte("Hello Badger")
- Purpose: Defines a byte array used as a sanity check to validate the encryption key.
Type: KeyRegistry
type KeyRegistry struct {
sync.RWMutex
dataKeys map[uint64]*pb.DataKey
lastCreated int64
nextKeyID uint64
fp *os.File
opt KeyRegistryOptions
}
- Purpose: Manages all data keys.
- Fields:
sync.RWMutex
: Read/write mutex for concurrent access.dataKeys
: A map of key IDs topb.DataKey
protobuf messages.lastCreated
: Timestamp of the last generated data key.nextKeyID
: The next available key ID.fp
: File pointer to the key registry file.opt
:KeyRegistryOptions
for configuring the registry.
Type: KeyRegistryOptions
type KeyRegistryOptions struct {
Dir string
ReadOnly bool
EncryptionKey []byte
EncryptionKeyRotationDuration time.Duration
InMemory bool
}
- Purpose: Configuration options for the
KeyRegistry
. - Fields:
Dir
: Directory where the key registry file is stored.ReadOnly
: Indicates if the key registry is opened in read-only mode.EncryptionKey
: Encryption key used to encrypt the data keys.EncryptionKeyRotationDuration
: Duration for key rotation.InMemory
: Indicates if the key registry is stored in memory only.
Function: newKeyRegistry
func newKeyRegistry(opt KeyRegistryOptions) *KeyRegistry {
return &KeyRegistry{
dataKeys: make(map[uint64]*pb.DataKey),
nextKeyID: 0,
opt: opt,
}
}
- Purpose: Creates a new
KeyRegistry
instance. - Parameters:
opt
:KeyRegistryOptions
to configure the registry.
- Returns: A pointer to the newly created
KeyRegistry
.
Function: OpenKeyRegistry
func OpenKeyRegistry(opt KeyRegistryOptions) (*KeyRegistry, error) {
// ...
}
- Purpose: Opens an existing key registry or creates a new one if it doesn't exist.
- Parameters:
opt
:KeyRegistryOptions
to configure the registry.
- Returns: A pointer to the
KeyRegistry
and an error, if any.
Type: keyRegistryIterator
type keyRegistryIterator struct {
encryptionKey []byte
fp *os.File
lenCrcBuf [8]byte
}
- Purpose: Iterator for reading data keys from the key registry file.
- Fields:
encryptionKey
: Encryption key used to decrypt the data keys.fp
: File pointer to the key registry file.lenCrcBuf
: Buffer to store the length and CRC of each data key entry.
Function: newKeyRegistryIterator
func newKeyRegistryIterator(fp *os.File, encryptionKey []byte) (*keyRegistryIterator, error) {
return &keyRegistryIterator{
encryptionKey: encryptionKey,
fp: fp,
lenCrcBuf: [8]byte{},
}, validRegistry(fp, encryptionKey)
}
- Purpose: Creates a new
keyRegistryIterator
instance. - Parameters:
fp
: File pointer to the key registry file.encryptionKey
: Encryption key used to decrypt the data keys.
- Returns: A pointer to the newly created
keyRegistryIterator
and an error, if any.
Function: validRegistry
func validRegistry(fp *os.File, encryptionKey []byte) error {
// ...
}
- Purpose: Checks if the provided encryption key is valid by verifying the sanity text in the registry file.
- Parameters:
fp
: File pointer to the key registry file.encryptionKey
: Encryption key to validate.
- Returns: An error if the key is invalid or if there are issues reading the file.
Function: (*keyRegistryIterator) next
func (kri *keyRegistryIterator) next() (*pb.DataKey, error) {
// ...
}
- Purpose: Reads the next data key from the key registry file.
- Returns: A pointer to the
pb.DataKey
and an error, if any. Returnsio.EOF
if the end of the file is reached.
Function: readKeyRegistry
func readKeyRegistry(fp *os.File, opt KeyRegistryOptions) (*KeyRegistry, error) {
// ...
}
- Purpose: Reads the key registry file and populates a
KeyRegistry
struct. - Parameters:
fp
: File pointer to the key registry file.opt
:KeyRegistryOptions
for configuring the registry.
- Returns: A pointer to the populated
KeyRegistry
and an error, if any.
Function: WriteKeyRegistry
func WriteKeyRegistry(reg *KeyRegistry, opt KeyRegistryOptions) error {
// ...
}
- Purpose: Writes the key registry data to a file, replacing the existing file.
- Parameters:
reg
: A pointer to theKeyRegistry
to write.opt
:KeyRegistryOptions
for configuring the registry.
- Returns: An error, if any.
Function: (*KeyRegistry) DataKey
func (kr *KeyRegistry) DataKey(id uint64) (*pb.DataKey, error) {
// ...
}
- Purpose: Retrieves a data key by its ID.
- Parameters:
id
: The ID of the data key to retrieve.
- Returns: A pointer to the
pb.DataKey
and an error, if any. Returnsnil
if the ID is 0 (representing plain text).
Function: (*KeyRegistry) LatestDataKey
func (kr *KeyRegistry) LatestDataKey() (*pb.DataKey, error) {
// ...
}
- Purpose: Returns the latest generated data key, creating a new one if the rotation period has passed.
- Returns: A pointer to the
pb.DataKey
and an error, if any. Returns nil if no encryption key is set.
Function: (*KeyRegistry) Close
func (kr *KeyRegistry) Close() error {
// ...
}
- Purpose: Closes the key registry file.
- Returns: An error, if any.
Function: storeDataKey
func storeDataKey(buf *bytes.Buffer, storageKey []byte, k *pb.DataKey) error {
// ...
}
- Purpose: Stores a data key in the given buffer, encrypting it if a storage key is provided.
- Parameters:
buf
: The buffer to store the data key in.storageKey
: The storage key to use for encryption.k
: A pointer to thepb.DataKey
to store.
- Returns: An error, if any.
Code Examples
None