From 40d08139dbc3c6922177f1e0e2800e914e5a133e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mika=C3=ABl=20Cluseau?= Date: Thu, 9 Nov 2023 08:59:27 +0100 Subject: [PATCH] public/unlock-store: idempotent call for passphrases This allows the user to call it even after the store has been unlock in order to get the admin token. --- cmd/dkl-local-server/ws-public.go | 12 ++++++++++++ secretstore/mem.go | 2 ++ secretstore/secret-store.go | 14 +++++++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/cmd/dkl-local-server/ws-public.go b/cmd/dkl-local-server/ws-public.go index e7e52f1..1c676b5 100644 --- a/cmd/dkl-local-server/ws-public.go +++ b/cmd/dkl-local-server/ws-public.go @@ -12,6 +12,7 @@ import ( restful "github.com/emicklei/go-restful" "m.cluseau.fr/go/httperr" + "novit.tech/direktil/local-server/secretstore" ) type NamedPassphrase struct { @@ -27,6 +28,8 @@ func wsUnlockStore(req *restful.Request, resp *restful.Response) { return } + defer secretstore.Memzero(np.Passphrase) + if secStore.IsNew() { if len(np.Name) == 0 { wsBadRequest(resp, "no name given") @@ -39,6 +42,15 @@ func wsUnlockStore(req *restful.Request, resp *restful.Response) { return } + if secStore.Unlocked() { + if secStore.HasKey(np.Passphrase) { + resp.WriteEntity(adminToken) + } else { + wsError(resp, ErrUnauthorized) + } + return + } + if err := unlockSecretStore(np.Name, np.Passphrase); err.Any() { err.WriteJSON(resp.ResponseWriter) return diff --git a/secretstore/mem.go b/secretstore/mem.go index 6d32dc2..8a52e24 100644 --- a/secretstore/mem.go +++ b/secretstore/mem.go @@ -1,5 +1,7 @@ package secretstore +func Memzero(ba []byte) { memzero(ba) } + func memzero(ba []byte) { for i := range ba { ba[i] = 0 diff --git a/secretstore/secret-store.go b/secretstore/secret-store.go index 66e4bd1..165b65f 100644 --- a/secretstore/secret-store.go +++ b/secretstore/secret-store.go @@ -175,9 +175,21 @@ func (s *Store) WriteTo(out io.Writer) (n int64, err error) { var ErrNoSuchKey = errors.New("no such key") +func (s *Store) HasKey(passphrase []byte) bool { + key, hash := s.keyPairFromPassword(passphrase) + defer memzero(key[:]) + + for _, k := range s.Keys { + if k.Hash == hash { + return true + } + } + + return false +} + func (s *Store) Unlock(passphrase []byte) (ok bool) { key, hash := s.keyPairFromPassword(passphrase) - memzero(passphrase) defer memzero(key[:]) var idx = -1