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.
This commit is contained in:
Mikaël Cluseau 2023-11-09 08:59:27 +01:00
parent efa6193954
commit 40d08139db
3 changed files with 27 additions and 1 deletions

View File

@ -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

View File

@ -1,5 +1,7 @@
package secretstore
func Memzero(ba []byte) { memzero(ba) }
func memzero(ba []byte) {
for i := range ba {
ba[i] = 0

View File

@ -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