From 1ad9785d0768f62614218d7240020c6ec9ede233 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mika=C3=ABl=20Cluseau?= Date: Mon, 16 Mar 2026 11:08:16 +0100 Subject: [PATCH] allow adding a raw key --- cmd/dkl-local-server/state.go | 2 ++ cmd/dkl-local-server/ws-store.go | 25 ++++++++++++++++--- ...5e84eaae7ce.js => app-e7fb26679b9aa0f2.js} | 7 +++++- html/ui/index.html | 10 ++++++-- secretstore/secret-store.go | 8 ++++-- ui/index.html | 8 +++++- ui/js/app.js | 7 +++++- 7 files changed, 56 insertions(+), 11 deletions(-) rename html/ui/{app-7f4645e84eaae7ce.js => app-e7fb26679b9aa0f2.js} (97%) diff --git a/cmd/dkl-local-server/state.go b/cmd/dkl-local-server/state.go index e8ff842..099fc1e 100644 --- a/cmd/dkl-local-server/state.go +++ b/cmd/dkl-local-server/state.go @@ -24,6 +24,7 @@ type State struct { Store struct { DownloadToken string KeyNames []string + Salt []byte } Clusters []ClusterState @@ -157,6 +158,7 @@ func updateState() { wState.Change(func(v *State) { v.HasConfig = true v.Store.KeyNames = keyNames + v.Store.Salt = secStore.Salt[:] v.Clusters = clusters v.Hosts = hosts v.HostTemplates = hostTemplates diff --git a/cmd/dkl-local-server/ws-store.go b/cmd/dkl-local-server/ws-store.go index bfcc44a..b981357 100644 --- a/cmd/dkl-local-server/ws-store.go +++ b/cmd/dkl-local-server/ws-store.go @@ -8,8 +8,13 @@ import ( "novit.tech/direktil/local-server/secretstore" ) +type AddKeyReq struct { + NamedPassphrase `json:",inline"` + Hash []byte `json:",omitempty"` +} + func wsStoreAddKey(req *restful.Request, resp *restful.Response) { - np := NamedPassphrase{} + np := AddKeyReq{} err := req.ReadEntity(&np) if err != nil { @@ -24,8 +29,13 @@ func wsStoreAddKey(req *restful.Request, resp *restful.Response) { return } - if len(np.Passphrase) == 0 { - wsBadRequest(resp, "no passphrase given") + if len(np.Hash) == 0 && len(np.Passphrase) == 0 { + wsBadRequest(resp, "no hash or passphrase given") + return + } + + if len(np.Hash) != 0 && len(np.Hash) != 32 { + wsBadRequest(resp, "hash of a wrong length") return } @@ -36,7 +46,14 @@ func wsStoreAddKey(req *restful.Request, resp *restful.Response) { } } - secStore.AddKey(np.Name, np.Passphrase) + if len(np.Hash) != 0 { + hash := [32]byte{} + copy(hash[:], np.Hash[:32]) + secStore.AddRawKey(np.Name, hash) + } else { + secStore.AddKey(np.Name, np.Passphrase) + } + defer updateState() err = secStore.SaveTo(secKeysStorePath()) diff --git a/html/ui/app-7f4645e84eaae7ce.js b/html/ui/app-e7fb26679b9aa0f2.js similarity index 97% rename from html/ui/app-7f4645e84eaae7ce.js rename to html/ui/app-e7fb26679b9aa0f2.js index edbf548..eb946c2 100644 --- a/html/ui/app-7f4645e84eaae7ce.js +++ b/html/ui/app-e7fb26679b9aa0f2.js @@ -103,7 +103,12 @@ createApp({ return {Name: this.forms.store.name, Passphrase: btoa(this.forms.store.pass1)} }, storeAddKey() { - this.apiPost('/store/add-key', this.namedPassphrase(), (v) => { + const params = this.namedPassphrase(); + if (this.forms.store.byHash) { + params.Hash = this.forms.store.hash; + } + + this.apiPost('/store/add-key', params, (v) => { this.forms.store = {} }) }, diff --git a/html/ui/index.html b/html/ui/index.html index 9e68416..bcba6f0 100644 --- a/html/ui/index.html +++ b/html/ui/index.html @@ -10,7 +10,7 @@ - + @@ -106,9 +106,15 @@

Add an unlock phrase:


+ +
+ + {{" "}}generate with dls hash '{{state.Store.Salt}}' +
- +
+

Remove an unlock phrase:

diff --git a/secretstore/secret-store.go b/secretstore/secret-store.go index 165b65f..59fa002 100644 --- a/secretstore/secret-store.go +++ b/secretstore/secret-store.go @@ -211,10 +211,13 @@ func (s *Store) Unlock(passphrase []byte) (ok bool) { } func (s *Store) AddKey(name string, passphrase []byte) { - key, hash := s.keyPairFromPassword(passphrase) + key, _ := s.keyPairFromPassword(passphrase) memzero(passphrase) + s.AddRawKey(name, key) +} - defer memzero(key[:]) +func (s *Store) AddRawKey(name string, key [32]byte) { + hash := sha512.Sum512(key[:]) k := KeyEntry{Name: name, Hash: hash} @@ -222,6 +225,7 @@ func (s *Store) AddKey(name string, passphrase []byte) { copy(k.EncKey[:], encKey) s.Keys = append(s.Keys, k) + memzero(key[:]) } func (s *Store) keyPairFromPassword(password []byte) (key [32]byte, hash [64]byte) { diff --git a/ui/index.html b/ui/index.html index 0d699ce..cd93e2e 100644 --- a/ui/index.html +++ b/ui/index.html @@ -106,9 +106,15 @@

Add an unlock phrase:


+ +
+ + {{" "}}generate with dls hash '{{state.Store.Salt}}' +
- +
+

Remove an unlock phrase:

diff --git a/ui/js/app.js b/ui/js/app.js index edbf548..eb946c2 100644 --- a/ui/js/app.js +++ b/ui/js/app.js @@ -103,7 +103,12 @@ createApp({ return {Name: this.forms.store.name, Passphrase: btoa(this.forms.store.pass1)} }, storeAddKey() { - this.apiPost('/store/add-key', this.namedPassphrase(), (v) => { + const params = this.namedPassphrase(); + if (this.forms.store.byHash) { + params.Hash = this.forms.store.hash; + } + + this.apiPost('/store/add-key', params, (v) => { this.forms.store = {} }) },