From deb3c67d8035926bf82be75d2ff50ed49462bdde Mon Sep 17 00:00:00 2001 From: maze Date: Thu, 4 Sep 2025 23:46:47 +0200 Subject: [PATCH] Add support for NaCL SecretBox --- decryption.go => decrypt.go | 31 ++++++++++++++++++++++++ decryption_test.go => decrypt_test.go | 35 +++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) rename decryption.go => decrypt.go (71%) rename decryption_test.go => decrypt_test.go (80%) diff --git a/decryption.go b/decrypt.go similarity index 71% rename from decryption.go rename to decrypt.go index ea98741..ff4a0c6 100644 --- a/decryption.go +++ b/decrypt.go @@ -6,6 +6,7 @@ import ( "errors" "golang.org/x/crypto/chacha20poly1305" + "golang.org/x/crypto/nacl/secretbox" ) type aead struct { @@ -74,3 +75,33 @@ func (p aead) GetSecret(key string) (value []byte, err error) { nonce, ciphertext := value[:nonceSize], value[nonceSize:] return p.aead.Open(nil, nonce, ciphertext, nil) } + +type secretBox struct { + Provider + key [32]byte +} + +func WithSecretBox(p Provider, key [32]byte) Provider { + return &secretBox{ + Provider: p, + key: key, + } +} + +func (p secretBox) GetSecret(key string) (value []byte, err error) { + if value, err = p.Provider.GetSecret(key); err != nil { + return + } + + var nonce [24]byte + if copy(nonce[:], value) < 24 { + return nil, errors.New("secret: encrypted secretbox value is too short") + } + + var ok bool + if value, ok = secretbox.Open(nil, value[24:], &nonce, &p.key); !ok { + return nil, errors.New("secret: encrypted secretbox open failed") + } + + return +} diff --git a/decryption_test.go b/decrypt_test.go similarity index 80% rename from decryption_test.go rename to decrypt_test.go index 54784ff..d80bb1c 100644 --- a/decryption_test.go +++ b/decrypt_test.go @@ -150,3 +150,38 @@ func TestWithChaCha20Poly1305X(t *testing.T) { t.Errorf("expected:\n%s\n\ngot:\n%s", hex.Dump(msg), hex.Dump(v)) } } + +func TestWithSecretBox(t *testing.T) { + var ( + key [32]byte + nonce [24]byte + box []byte + ) + key = [32]uint8{ + 0x90, 0x93, 0x6b, 0x91, 0x79, 0xac, 0xa2, 0x0d, + 0x7d, 0xf7, 0x8c, 0x29, 0x93, 0x5f, 0xd4, 0xf3, + 0x9e, 0x61, 0xe3, 0x6d, 0xb0, 0x30, 0x31, 0xac, + 0xa5, 0xd6, 0x7e, 0xb5, 0x04, 0xe8, 0x1b, 0x87, + } + nonce = [24]uint8{ + 0xaa, 0xe6, 0x05, 0x6b, 0x18, 0xb9, 0x05, 0xc8, + 0x9e, 0x53, 0x25, 0x79, 0xbe, 0x79, 0x9d, 0x9b, + 0xbe, 0x1e, 0x34, 0x11, 0xbb, 0x21, 0x51, 0x3c, + } + box = append(nonce[:], + 0x8b, 0x0a, 0x66, 0x4f, 0xb3, 0x1f, 0x78, 0xfd, + 0xcb, 0x41, 0x9e, 0x4b, 0x1a, 0x9e, 0x34, 0x20, + 0xef, 0x2c, 0x64, 0xb3, 0x00, 0x6f, 0xf1, 0x9e, + 0xe1, 0xbd, 0xfe, 0xd3, 0x86, 0x12, 0x8d, 0x09, + 0x85, 0x34, 0xae, 0xa3, 0xfd) + + p := WithSecretBox(environment{"test": box}, key) + v, err := p.GetSecret("test") + if err != nil { + t.Fatal(err) + return + } + if string(v) != "Hello, boxed Gophers!" { + t.Errorf(`expected "Hello, boxed Gophers!", got %q`, v) + } +}