package localapi import ( "crypto/sha256" "encoding/hex" "path/filepath" "testing" ) // The leaf is generated once and its fingerprint stays STABLE across "restarts" (re-loads from // disk) — a fresh cert each boot would invalidate every already-baked bootstrap pin. func TestEnsureLeaf_StableFingerprintAcrossReload(t *testing.T) { dir := t.TempDir() certPath := filepath.Join(dir, "leaf.crt") keyPath := filepath.Join(dir, "leaf.key") cert1, fp1, gen1, err := EnsureLeaf(certPath, keyPath, "192.168.0.162") if err != nil { t.Fatalf("first ensure: %v", err) } // B.1/B.3: first call GENERATES; second call LOADS (generated=false) with the SAME fingerprint — // persistence keeps the pin stable. A regression that regenerated would flip gen2 true AND change // the fp, failing both asserts (the prevention this change exists for). if !gen1 { t.Fatal("first EnsureLeaf must report generated=true") } cert2, fp2, gen2, err := EnsureLeaf(certPath, keyPath, "192.168.0.162") if err != nil { t.Fatalf("second ensure: %v", err) } if gen2 { t.Fatal("second EnsureLeaf must report generated=false (LOADED, not regenerated)") } if fp1 != fp2 { t.Fatalf("fingerprint changed across reload: %s != %s", fp1, fp2) } // The reported fingerprint must equal the SHA-256 of the served leaf DER (the pin the // controller checks against). got := sha256.Sum256(cert2.Certificate[0]) if hex.EncodeToString(got[:]) != fp2 { t.Fatal("reported fingerprint does not match the served leaf DER") } if len(fp1) != 64 { t.Fatalf("fingerprint is not a 64-hex SHA-256: %q", fp1) } _ = cert1 } // The generated leaf is a usable TLS server cert whose presented leaf matches the pin. func TestEnsureLeaf_ServesPinnableLeaf(t *testing.T) { dir := t.TempDir() cert, fp, _, err := EnsureLeaf(filepath.Join(dir, "c"), filepath.Join(dir, "k"), "10.0.0.1") if err != nil { t.Fatalf("ensure: %v", err) } if len(cert.Certificate) == 0 { t.Fatal("no leaf in cert chain") } if cert.PrivateKey == nil { t.Fatal("generated cert has no private key") } sum := sha256.Sum256(cert.Certificate[0]) if hex.EncodeToString(sum[:]) != fp { t.Fatal("pin mismatch against served leaf") } }