mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-25 19:15:34 +00:00
types/key: add naclbox shared key wrapper type + Seal method
So the control plane can stop doing precomputations on each naclbox message. Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
6f5096fa61
commit
cfdb862673
@ -105,6 +105,33 @@ func (k MachinePrivate) SealTo(p MachinePublic, cleartext []byte) (ciphertext []
|
|||||||
return box.Seal(nonce[:], cleartext, &nonce, &p.k, &k.k)
|
return box.Seal(nonce[:], cleartext, &nonce, &p.k, &k.k)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SharedKey returns the precomputed Nacl box shared key between k and p.
|
||||||
|
func (k MachinePrivate) SharedKey(p MachinePublic) MachinePrecomputedSharedKey {
|
||||||
|
var shared MachinePrecomputedSharedKey
|
||||||
|
box.Precompute(&shared.k, &p.k, &k.k)
|
||||||
|
return shared
|
||||||
|
}
|
||||||
|
|
||||||
|
// MachinePrecomputedSharedKey is a precomputed shared NaCl box shared key.
|
||||||
|
type MachinePrecomputedSharedKey struct {
|
||||||
|
k [32]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seal wraps cleartext into a NaCl box (see
|
||||||
|
// golang.org/x/crypto/nacl) using the shared key k as generated
|
||||||
|
// by MachinePrivate.SharedKey.
|
||||||
|
//
|
||||||
|
// The returned ciphertext is a 24-byte nonce concatenated with the
|
||||||
|
// box value.
|
||||||
|
func (k MachinePrecomputedSharedKey) Seal(cleartext []byte) (ciphertext []byte) {
|
||||||
|
if k == (MachinePrecomputedSharedKey{}) {
|
||||||
|
panic("can't seal with zero keys")
|
||||||
|
}
|
||||||
|
var nonce [24]byte
|
||||||
|
rand(nonce[:])
|
||||||
|
return box.SealAfterPrecomputation(nonce[:], cleartext, &nonce, &k.k)
|
||||||
|
}
|
||||||
|
|
||||||
// OpenFrom opens the NaCl box ciphertext, which must be a value
|
// OpenFrom opens the NaCl box ciphertext, which must be a value
|
||||||
// created by SealTo, and returns the inner cleartext if ciphertext is
|
// created by SealTo, and returns the inner cleartext if ciphertext is
|
||||||
// a valid box from p to k.
|
// a valid box from p to k.
|
||||||
|
@ -90,3 +90,23 @@ type keypair struct {
|
|||||||
t.Error("json serialization doesn't roundtrip")
|
t.Error("json serialization doesn't roundtrip")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSealViaSharedKey(t *testing.T) {
|
||||||
|
// encrypt a message from a to b
|
||||||
|
a := NewMachine()
|
||||||
|
b := NewMachine()
|
||||||
|
apub, bpub := a.Public(), b.Public()
|
||||||
|
|
||||||
|
shared := a.SharedKey(bpub)
|
||||||
|
|
||||||
|
const clear = "the eagle flies at midnight"
|
||||||
|
enc := shared.Seal([]byte(clear))
|
||||||
|
|
||||||
|
back, ok := b.OpenFrom(apub, enc)
|
||||||
|
if !ok {
|
||||||
|
t.Fatal("failed to decrypt")
|
||||||
|
}
|
||||||
|
if string(back) != clear {
|
||||||
|
t.Errorf("got %q; want cleartext %q", back, clear)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user