From 2024008667763ab1d9ff67ff1b9d92d569150d9c Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Fri, 22 Jul 2022 11:38:25 -0700 Subject: [PATCH] types/key: add MachinePrecomputedSharedKey.Open Follow-up to cfdb8626738d Updates tailscale/corp#1709 Change-Id: I7af931a2cb55f9006e1029381663ac21d1794242 Signed-off-by: Brad Fitzpatrick --- types/key/machine.go | 15 +++++++++++++++ types/key/machine_test.go | 10 +++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/types/key/machine.go b/types/key/machine.go index 74eb24b5f..b0caf3a49 100644 --- a/types/key/machine.go +++ b/types/key/machine.go @@ -132,6 +132,21 @@ func (k MachinePrecomputedSharedKey) Seal(cleartext []byte) (ciphertext []byte) return box.SealAfterPrecomputation(nonce[:], cleartext, &nonce, &k.k) } +// Open opens the NaCl box ciphertext, which must be a value created by +// MachinePrecomputedSharedKey.Seal or MachinePrivate.SealTo, and returns the +// inner cleartext if ciphertext is a valid box for the shared key k. +func (k MachinePrecomputedSharedKey) Open(ciphertext []byte) (cleartext []byte, ok bool) { + if k == (MachinePrecomputedSharedKey{}) { + panic("can't open with zero keys") + } + if len(ciphertext) < 24 { + return nil, false + } + var nonce [24]byte + copy(nonce[:], ciphertext) + return box.OpenAfterPrecomputation(nil, ciphertext[len(nonce):], &nonce, &k.k) +} + // OpenFrom opens the NaCl box ciphertext, which must be a value // created by SealTo, and returns the inner cleartext if ciphertext is // a valid box from p to k. diff --git a/types/key/machine_test.go b/types/key/machine_test.go index 1ded5da86..ac6d74c8a 100644 --- a/types/key/machine_test.go +++ b/types/key/machine_test.go @@ -107,6 +107,14 @@ func TestSealViaSharedKey(t *testing.T) { t.Fatal("failed to decrypt") } if string(back) != clear { - t.Errorf("got %q; want cleartext %q", back, clear) + t.Errorf("OpenFrom got %q; want cleartext %q", back, clear) + } + + backShared, ok := shared.Open(enc) + if !ok { + t.Fatal("failed to decrypt from shared key") + } + if string(backShared) != clear { + t.Errorf("Open got %q; want cleartext %q", back, clear) } }