A certificate is issued once and kept
Every signing carries a fresh random serial, so a mesh that signed per composition composed a different declaration every time it was asked what a machine should be. Every machine carrying a certificate then stood eternally "waiting" — pushed seconds ago and already behind — and the forge test, the first to wait for settledness on such a machine, failed four runs in a row wearing three other faults' clothes. Found live on a kept mesh, which is what settled it: two plans seconds apart, identical to the byte but for one serial, in the certificate file. Deduction had four theories; the diff had one line. The keeping columns had existed since the serving key's migration — "and what was issued for it" — and were written by nothing, the same shape ReleasePorts was found in this morning. Kept beside the serving key it certifies, and it stands while the name, the key and the clock agree: a node rejoining with a new key or renamed gets a fresh signing, exactly as if nothing were kept, and so does one whose certificate is into its last stretch of life. The port's rule and the secret's, applied to the third thing composed fresh each time.
This commit is contained in:
@@ -204,3 +204,48 @@ func TestTwoProcessesStartingTogetherAgreeOnOneAuthority(t *testing.T) {
|
||||
t.Errorf("%d authorities exist; exactly one may", count)
|
||||
}
|
||||
}
|
||||
|
||||
// Asking twice gives the same certificate, to the byte.
|
||||
//
|
||||
// Every signing carries a fresh random serial, so a mesh that signed per composition composed a
|
||||
// different declaration each time it was asked what a machine should be — and every machine
|
||||
// carrying a certificate stood eternally "waiting", pushed seconds ago and already behind. Found
|
||||
// live on a kept mesh: two plans seconds apart, identical but for one serial.
|
||||
func TestACertificateIsIssuedOnceAndKept(t *testing.T) {
|
||||
ident := fresh(t)
|
||||
ctx := context.Background()
|
||||
public, _ := aServingKey(t)
|
||||
|
||||
if _, err := ident.RecordNodeKey(ctx, "1b7e0000-0000-4000-8000-000000000001", make(ed25519.PublicKey, ed25519.PublicKeySize)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := ident.RecordServingKey(ctx, "1b7e0000-0000-4000-8000-000000000001", public); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
first, err := ident.Certify(ctx, "a", "a.internal", public)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
second, err := ident.Certify(ctx, "a", "a.internal", public)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if first != second {
|
||||
t.Fatal("two askings gave two certificates; every composition then differs by a serial " +
|
||||
"and a machine carrying one is eternally behind")
|
||||
}
|
||||
|
||||
// And a new key is a new world: the kept answer must not outlive what it certifies.
|
||||
fresh2, _ := aServingKey(t)
|
||||
if err := ident.RecordServingKey(ctx, "1b7e0000-0000-4000-8000-000000000001", fresh2); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
third, err := ident.Certify(ctx, "a", "a.internal", fresh2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if third == first {
|
||||
t.Fatal("the node rejoined with a new key and was handed the certificate of its old one")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user