mirror of
https://github.com/tailscale/tailscale.git
synced 2024-12-01 22:15:51 +00:00
980acc38ba
* Revert "Revert "types/key: add MachinePrivate and MachinePublic.""
This reverts commit 61c3b98a24
.
Signed-off-by: David Anderson <danderson@tailscale.com>
* types/key: add ControlPrivate, with custom serialization.
ControlPrivate is just a MachinePrivate that serializes differently
in JSON, to be compatible with how the Tailscale control plane
historically serialized its private key.
Signed-off-by: David Anderson <danderson@tailscale.com>
65 lines
2.1 KiB
Go
65 lines
2.1 KiB
Go
// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package key
|
|
|
|
import "encoding/json"
|
|
|
|
// ControlPrivate is a Tailscale control plane private key.
|
|
//
|
|
// It is functionally equivalent to a MachinePrivate, but serializes
|
|
// to JSON as a byte array rather than a typed string, because our
|
|
// control plane database stores the key that way.
|
|
//
|
|
// Deprecated: this type should only be used in Tailscale's control
|
|
// plane, where existing database serializations require this
|
|
// less-good serialization format to persist. Other control plane
|
|
// implementations can use MachinePrivate with no downsides.
|
|
type ControlPrivate struct {
|
|
mkey MachinePrivate // unexported so we can limit the API surface to only exactly what we need
|
|
}
|
|
|
|
// NewControl generates and returns a new control plane private key.
|
|
func NewControl() ControlPrivate {
|
|
return ControlPrivate{NewMachine()}
|
|
}
|
|
|
|
// IsZero reports whether k is the zero value.
|
|
func (k ControlPrivate) IsZero() bool {
|
|
return k.mkey.IsZero()
|
|
}
|
|
|
|
// Public returns the MachinePublic for k.
|
|
// Panics if ControlPrivate is zero.
|
|
func (k ControlPrivate) Public() MachinePublic {
|
|
return k.mkey.Public()
|
|
}
|
|
|
|
// MarshalJSON implements json.Marshaler.
|
|
func (k ControlPrivate) MarshalJSON() ([]byte, error) {
|
|
return json.Marshal(k.mkey.k)
|
|
}
|
|
|
|
// UnmarshalJSON implements json.Unmarshaler.
|
|
func (k *ControlPrivate) UnmarshalJSON(bs []byte) error {
|
|
return json.Unmarshal(bs, &k.mkey.k)
|
|
}
|
|
|
|
// SealTo wraps cleartext into a NaCl box (see
|
|
// golang.org/x/crypto/nacl) to p, authenticated from k, using a
|
|
// random nonce.
|
|
//
|
|
// The returned ciphertext is a 24-byte nonce concatenated with the
|
|
// box value.
|
|
func (k ControlPrivate) SealTo(p MachinePublic, cleartext []byte) (ciphertext []byte) {
|
|
return k.mkey.SealTo(p, cleartext)
|
|
}
|
|
|
|
// 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.
|
|
func (k ControlPrivate) OpenFrom(p MachinePublic, ciphertext []byte) (cleartext []byte, ok bool) {
|
|
return k.mkey.OpenFrom(p, ciphertext)
|
|
}
|