A node generates the key it serves TLS with
A fourth key, reported at enrolment like the others. The reasoning is the one this file's neighbours already give twice: a key used for two purposes is one rotation away from breaking the other. The private half never leaves the machine. The mesh is told the public half and signs a certificate binding it to this node's name inside the mesh — so there is nothing to seal, and a copy of what the mesh holds certifies nothing it did not already certify. It does not make one on demand, for the same reason the sealing key does not: a key the mesh has never certified is a key nothing will trust, so a node that quietly generated one would serve a certificate for a key it no longer has and fail in a way that names neither.
This commit is contained in:
@@ -40,6 +40,11 @@ type EnrolRequest struct {
|
||||
// nothing else can read, and it must never be able to read it either.
|
||||
SealingKey string `json:"sealing_key,omitempty"`
|
||||
|
||||
// ServingKey is the public half of the key this node serves TLS with on its internal name.
|
||||
// The mesh signs a certificate binding it; the private half never leaves the machine, so
|
||||
// there is nothing to seal and nothing that could be stolen from the mesh's copy.
|
||||
ServingKey string `json:"serving_key,omitempty"`
|
||||
|
||||
Profile map[string]any `json:"profile,omitempty"`
|
||||
}
|
||||
|
||||
@@ -70,7 +75,8 @@ var ErrRefused = errors.New("the mesh refused this enrolment")
|
||||
// says once it is in, and the secret travels again because the control plane must not have to ask
|
||||
// the broker who connected.
|
||||
func Enrol(ctx context.Context, address, pin, node, secret string, public []byte,
|
||||
overlayKey, sealingKey string, profile map[string]any, timeout time.Duration) (EnrolReply, error) {
|
||||
overlayKey, sealingKey, servingKey string, profile map[string]any,
|
||||
timeout time.Duration) (EnrolReply, error) {
|
||||
|
||||
config, err := PinnedConfig(pin)
|
||||
if err != nil {
|
||||
@@ -116,7 +122,7 @@ func Enrol(ctx context.Context, address, pin, node, secret string, public []byte
|
||||
}
|
||||
|
||||
request := EnrolRequest{Node: node, Secret: secret, PublicKey: public,
|
||||
OverlayKey: overlayKey, SealingKey: sealingKey, Profile: profile}
|
||||
OverlayKey: overlayKey, SealingKey: sealingKey, ServingKey: servingKey, Profile: profile}
|
||||
body, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return EnrolReply{}, err
|
||||
|
||||
@@ -37,6 +37,10 @@ func TestWhatThisNodeSaysWhenItJoins(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
serving, err := identity.GenerateServingKey()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
request := EnrolRequest{
|
||||
Node: "workstation",
|
||||
@@ -44,6 +48,7 @@ func TestWhatThisNodeSaysWhenItJoins(t *testing.T) {
|
||||
PublicKey: mine.Public,
|
||||
OverlayKey: overlay.Public,
|
||||
SealingKey: sealing.Public,
|
||||
ServingKey: serving.Public,
|
||||
Profile: map[string]any{"seat": true},
|
||||
}
|
||||
body, err := json.MarshalIndent(request, "", " ")
|
||||
|
||||
Reference in New Issue
Block a user