// Put adds a new key to the vault. The Key object passed in should be // fully formed with the Secret field containing the secret to secure. func (v *KeyVault) Put(k *Key, check ContextCheck, authInfo ...interface{}) (err error) { if v == nil { return ErrVaultFailure } var logmeta = Metadata{ "id": k.ID, "success": "false", "label": k.Label, } defer func() { if err != nil { logmeta["error"] = err.Error() } v.LogNow("put", logmeta) }() if k.Label == "" { err = ErrInvalidSecret return } else if k.ID == "" { err = ErrInvalidSecret return } else if _, ok := v.secrets[k.ID]; ok { err = ErrInvalidSecret return } else if ctx, ok := v.contexts[k.Label]; !ok { err = ErrContextFailure return } else if !checkCtx(*ctx, check, authInfo...) { err = ErrContextFailure return } box := tkdf.Encrypt(v.metadata.Kek, k.Secret) var newKey = &key{ Secret: box.Data, Timestamp: int64(box.Timestamp), Tag: box.Tag, Label: k.Label, ID: k.ID, Metadata: make(Metadata), } for mk, mv := range k.Metadata { newKey.Metadata[mk] = mv } v.metadata.Locks.Secrets.Lock() v.secrets[k.ID] = newKey v.metadata.Locks.Secrets.Unlock() logmeta["success"] = "true" return }
// SecureSecret encrypts an existing secret, and returns a messages.Secret // ready for storage. func SecureSecret(secret []byte, ident, role string) (*messages.Secret, error) { box := tkdf.Encrypt(kek, secret) if box == nil { return nil, errors.New("TKDF failure") } return &messages.Secret{ Data: box.Data, Timestamp: box.Timestamp, Tag: box.Tag, Role: role, Ident: ident, }, nil }
// ProvisionSecret generates a new secret, and returns both a // messages.Secret containing the secured secret (ready for storage) // and a byte slice containing the secret (for sending immediately to // the requester). func ProvisionSecret(length int, ident, role string) (*messages.Secret, []byte, error) { secretBytes := make([]byte, length) _, err := io.ReadFull(prng, secretBytes) if err != nil { return nil, nil, err } box := tkdf.Encrypt(kek, secretBytes) if box == nil { return nil, nil, errors.New("TKDF failure") } return &messages.Secret{ Data: box.Data, Timestamp: box.Timestamp, Tag: box.Tag, Role: role, Ident: ident, }, secretBytes, nil }