Updates #5972 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>main
parent
d0b7a44840
commit
18c61afeb9
@ -0,0 +1,78 @@ |
||||
// Copyright (c) 2022 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 ( |
||||
"errors" |
||||
|
||||
"tailscale.com/types/structs" |
||||
) |
||||
|
||||
const ( |
||||
// chalPublicHexPrefix is the prefix used to identify a
|
||||
// hex-encoded challenge public key.
|
||||
//
|
||||
// This prefix is used in the control protocol, so cannot be
|
||||
// changed.
|
||||
chalPublicHexPrefix = "chalpub:" |
||||
) |
||||
|
||||
// ChallengePrivate is a challenge key, used to test whether clients control a
|
||||
// key they want to prove ownership of.
|
||||
//
|
||||
// A ChallengePrivate is ephemeral and not serialized to the disk or network.
|
||||
type ChallengePrivate struct { |
||||
_ structs.Incomparable // because == isn't constant-time
|
||||
k [32]byte |
||||
} |
||||
|
||||
// NewChallenge creates and returns a new node private key.
|
||||
func NewChallenge() ChallengePrivate { |
||||
return ChallengePrivate(NewNode()) |
||||
} |
||||
|
||||
// Public returns the ChallengePublic for k.
|
||||
// Panics if ChallengePublic is zero.
|
||||
func (k ChallengePrivate) Public() ChallengePublic { |
||||
pub := NodePrivate(k).Public() |
||||
return ChallengePublic(pub) |
||||
} |
||||
|
||||
// MarshalText implements encoding.TextMarshaler, but by returning an error.
|
||||
// It shouldn't need to be marshalled anywhere.
|
||||
func (k ChallengePrivate) MarshalText() ([]byte, error) { |
||||
return nil, errors.New("refusing to marshal") |
||||
} |
||||
|
||||
// SealToChallenge is like SealTo, but for a ChallengePublic.
|
||||
func (k NodePrivate) SealToChallenge(p ChallengePublic, cleartext []byte) (ciphertext []byte) { |
||||
return k.SealTo(NodePublic(p), cleartext) |
||||
} |
||||
|
||||
// OpenFrom opens the NaCl box ciphertext, which must be a value
|
||||
// created by NodePrivate.SealToChallenge, and returns the inner cleartext if
|
||||
// ciphertext is a valid box from p to k.
|
||||
func (k ChallengePrivate) OpenFrom(p NodePublic, ciphertext []byte) (cleartext []byte, ok bool) { |
||||
return NodePrivate(k).OpenFrom(p, ciphertext) |
||||
} |
||||
|
||||
// ChallengePublic is the public portion of a ChallengePrivate.
|
||||
type ChallengePublic struct { |
||||
k [32]byte |
||||
} |
||||
|
||||
// String returns the output of MarshalText as a string.
|
||||
func (k ChallengePublic) String() string { |
||||
bs, err := k.MarshalText() |
||||
if err != nil { |
||||
panic(err) |
||||
} |
||||
return string(bs) |
||||
} |
||||
|
||||
// MarshalText implements encoding.TextMarshaler.
|
||||
func (k ChallengePublic) MarshalText() ([]byte, error) { |
||||
return toHex(k.k[:], chalPublicHexPrefix), nil |
||||
} |
||||
Loading…
Reference in new issue