Documentation ¶
Index ¶
- Constants
- type KMS
- type Remote
- type Secret
- func (s Secret) MarshalJSON() ([]byte, error)
- func (s *Secret) ParseString(v string) error
- func (s Secret) String() string
- func (s *Secret) UnmarshalJSON(b []byte) error
- func (s Secret) Unwrap(ciphertext []byte, associatedData []byte) ([]byte, error)
- func (s Secret) Wrap(plaintext, associatedData []byte) ([]byte, error)
- type Store
- Bugs
Constants ¶
const MaxSize = 1 << 20 // 1 MiB
MaxSize is the max. size of a (encrypted) secret.
Neither a secret nor an encrypted secret should be larger than 1 MiB.
Implementions of Remote should use this to limit the amount of data they read from the key-value store.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type KMS ¶ added in v0.7.0
type KMS interface { // Encrypt encrypts the given plaintext with the // cryptographic key referenced by the given key name. // It returns the encrypted plaintext as ciphertext. // If the encryption fails Encrypt returns a non-nil // error. Encrypt(key string, plaintext []byte) (ciphertext []byte, err error) // Decrypt tries to decrypt the given ciphertext // and returns the secret plaintext on success. // If the decryption fails Decrypt returns a non-nil // error. Decrypt(key string, ciphertext []byte) (plaintext []byte, err error) }
KMS is a key management system that holds a set of cryptographic secret keys. The KMS interface specifies what operations can be performed with these secret keys.
In particularly, a KMS can encrypt a value, i.e. a secret, with one of its cryptographic keys and returns the encrypted value as ciphertext. The ciphertext can then be passed to the KMS again - together with the same key name - which then tries to decrypt it and returns the plaintext on success.
type Remote ¶ added in v0.7.0
type Remote interface { // Create adds the given key-value pair to // the remote store if and only if no entry // for the given key exists already. // // If key already exists at the remote store // it does not replace the secret and returns // kes.ErrKeyExists. // // Create returns the first error it encounters // while trying to add the given key-value pair // to the store, if any. Create(key string, value string) error // Delete deletes the given key and the associated // value from the remote store. It does not return // an non-nil error if the key does not exist. // // Delete returns the first error it encounters // while trying to delete the given key from the // store, if any. Delete(key string) error // Get returns the value associated with the given // key. If no value is associated with key then Get // returns kes.ErrKeyNotFound. // // Get returns the first error it encounters while // trying to add the given key-value pair to the // store, if any. Get(key string) (value string, err error) }
Remote is a key-value store for plain or encrypted secrets. Therefore, it stores keys and values as strings.
Remote is the interface that must be implemented by secret store backends, like Vault or AWS SecretsManager.
type Secret ¶
type Secret [32]byte
Secret is a 256 bit secret key. It can wrap and unwrap session or data keys.
func (Secret) MarshalJSON ¶ added in v0.7.0
func (*Secret) ParseString ¶
ParseString parses v and sets the secret key to the parsed value, on success.
ParseString will always be able to successfully parse a string produced by Secret.String().
func (Secret) String ¶
String returns the string representation of the secret key.
It is guaranteed that the returned string is valid JSON.
func (*Secret) UnmarshalJSON ¶ added in v0.7.0
func (Secret) Unwrap ¶
Unwrap decrypts and verifies the ciphertext, verifies the associated data and, if successful, returns the resuting plaintext. It returns an error if ciphertext is malformed or not authentic.
func (Secret) Wrap ¶
Wrap encrypts and authenticates the plaintext, authenticates the associatedData and returns the resulting ciphertext.
It should be used to encrypt a session or data key provided as plaintext.
If the executing CPU provides AES hardware support, Wrap derives keys using AES and encrypts plaintexts using AES-GCM. Otherwise, Wrap derives keys using HChaCha20 and encrypts plaintexts using ChaCha20-Poly1305.
type Store ¶
type Store struct { // Key is the name of the cryptographic key // at the KMS used to encrypt newly created // secrets before sending them to the remote // key-value store. // // If KMS is nil it will be ignored. // It must not be modified once the Store // has been used to fetch or store secrets. Key string // KMS is the KMS implementation used to // encrypt secrets before sending them to // the remove key-value store. // // It uses the Store.Key as the default // cryptographic key for encrypting new // secrets // // If the KMS is nil then all newly created // secrets will be stored as plaintext. // // If KMS is present and the remote key-value // store returns a plaintext value then the // Store still tries to decrypt the plaintext // value - which should fail. // Similarly, if no KMS is present and the // remote key-value store returns an encrypted // value then the Store does not try to decrypt // the value. // Basically, the remote store must return only // plaintext values or ciphertext values - but // not both. // // It must not be modified once the Store has been // used to fetch or store secrets. KMS KMS // Remote is the remote key-value store. Secrets // will be fetched from or written to this store. // // It must not be modified once the Store has been // used to fetch or store secrets. Remote Remote // contains filtered or unexported fields }
Store is the local secret store connected to a remote key-value store.
It is responsible for en/decrypting secrets if a KMS is present and for caching secrets fetched from the remote key value store.
func (*Store) Create ¶
Create adds the given secret with the given name to the secret store. If there is already a secret with this name then it does not replacce the secret and returns kes.ErrKeyExists.
func (*Store) Get ¶
Get returns the secret associated with the given name, if any. If no such secret exists it returns kes.ErrKeyNotFound.
func (*Store) StartGC ¶ added in v0.7.0
StartGC starts the cache garbage collection background process. The GC will discard all cached secrets after expiry. Further, it will discard all entries that havn't been used for unusedExpiry.
If expiry is 0 the GC will not discard any secrets. Similarly, if the unusedExpiry is 0 then the GC will not discard unused secrets.
There is only one garbage collection background process. Calling StartGC more than once has no effect.
Notes ¶
Bugs ¶
The KDF implemented by insecureAESDeriveKey is not a PRF. The following example shows that there exists a relation between 4 generated keys:
iv0 = 0¹⁶ iv1 = 1 || 0¹⁵ iv2 = 0¹⁵ || 1 iv3 = 1 || 0¹⁴ || 1
Generating 4 derived keys with these 4 iv values using the same key `K` gives:
k0 = insecureAESDeriveKey(K, iv0) k1 = insecureAESDeriveKey(K, iv1) k2 = insecureAESDeriveKey(K, iv2) k3 = insecureAESDeriveKey(K, iv3)
Now, the following statement holds (^ is XOR):
k0 ^ k1 ^ k2 == k3
This shows that insecureAESDeriveKey is not a PRF.