Added tests and readme
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGenerateAndLoadKeyPair(t *testing.T) {
|
||||
t.Setenv("QUPTIME_DIR", t.TempDir())
|
||||
|
||||
priv, err := GenerateKeyPair("node-1")
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateKeyPair: %v", err)
|
||||
}
|
||||
if priv.N.BitLen() < KeySize-8 {
|
||||
t.Errorf("key too small: %d bits", priv.N.BitLen())
|
||||
}
|
||||
|
||||
// Refusing to overwrite existing material is part of the contract.
|
||||
if _, err := GenerateKeyPair("node-1"); err == nil {
|
||||
t.Error("expected error on re-generate")
|
||||
}
|
||||
|
||||
loaded, err := LoadPrivateKey()
|
||||
if err != nil {
|
||||
t.Fatalf("LoadPrivateKey: %v", err)
|
||||
}
|
||||
if loaded.N.Cmp(priv.N) != 0 {
|
||||
t.Error("loaded key modulus differs from generated")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFingerprintDeterminismAndUniqueness(t *testing.T) {
|
||||
t.Setenv("QUPTIME_DIR", t.TempDir())
|
||||
priv, err := GenerateKeyPair("node-x")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
certPEM, err := LoadCertPEM()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
block, _ := pem.Decode(certPEM)
|
||||
if block == nil {
|
||||
t.Fatal("no PEM block in cert")
|
||||
}
|
||||
cert, err := x509.ParseCertificate(block.Bytes)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
fp1 := Fingerprint(cert)
|
||||
fp2 := Fingerprint(cert)
|
||||
if fp1 != fp2 {
|
||||
t.Errorf("non-deterministic: %s vs %s", fp1, fp2)
|
||||
}
|
||||
if !strings.HasPrefix(fp1, "sha256:") {
|
||||
t.Errorf("missing sha256: prefix: %s", fp1)
|
||||
}
|
||||
|
||||
pemFP, err := FingerprintFromCertPEM(certPEM)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if pemFP != fp1 {
|
||||
t.Errorf("PEM-derived fingerprint differs: %s vs %s", pemFP, fp1)
|
||||
}
|
||||
|
||||
// Now generate a fresh cert from the same key — fingerprint must
|
||||
// match (SPKI is identical).
|
||||
derSame, err := buildSelfSignedCert(priv, "node-x")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
certSame, _ := x509.ParseCertificate(derSame)
|
||||
if Fingerprint(certSame) != fp1 {
|
||||
t.Error("fingerprint changed across cert regen with same key")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFingerprintDiffersAcrossKeys(t *testing.T) {
|
||||
dirA := t.TempDir()
|
||||
dirB := t.TempDir()
|
||||
|
||||
t.Setenv("QUPTIME_DIR", dirA)
|
||||
if _, err := GenerateKeyPair("a"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
pemA, _ := LoadCertPEM()
|
||||
fpA, _ := FingerprintFromCertPEM(pemA)
|
||||
|
||||
t.Setenv("QUPTIME_DIR", dirB)
|
||||
if _, err := GenerateKeyPair("b"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
pemB, _ := LoadCertPEM()
|
||||
fpB, _ := FingerprintFromCertPEM(pemB)
|
||||
|
||||
if fpA == fpB {
|
||||
t.Error("two independent keys produced the same fingerprint")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFingerprintFromCertPEMRejectsGarbage(t *testing.T) {
|
||||
if _, err := FingerprintFromCertPEM([]byte("not a pem")); err == nil {
|
||||
t.Error("expected error on non-PEM input")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user