(t *testing.T)
| 85 | } |
| 86 | |
| 87 | func TestSignCSR_Success(t *testing.T) { |
| 88 | dir := t.TempDir() |
| 89 | ca, err := LoadOrCreateNodeCA(filepath.Join(dir, "c.pem"), filepath.Join(dir, "k.pem")) |
| 90 | if err != nil { |
| 91 | t.Fatalf("create CA: %v", err) |
| 92 | } |
| 93 | |
| 94 | csrPEM, _ := mustGenCSR(t, "attacker-claims-this-cn") |
| 95 | const nodeID = "node-abc" |
| 96 | |
| 97 | certPEM, err := ca.SignCSR(csrPEM, nodeID, time.Hour) |
| 98 | if err != nil { |
| 99 | t.Fatalf("sign: %v", err) |
| 100 | } |
| 101 | block, _ := pem.Decode(certPEM) |
| 102 | if block == nil { |
| 103 | t.Fatalf("decode signed cert") |
| 104 | } |
| 105 | signed, err := x509.ParseCertificate(block.Bytes) |
| 106 | if err != nil { |
| 107 | t.Fatalf("parse signed: %v", err) |
| 108 | } |
| 109 | if signed.Subject.CommonName != nodeID { |
| 110 | t.Fatalf("CN = %q, want %q (CSR CN must be overridden)", signed.Subject.CommonName, nodeID) |
| 111 | } |
| 112 | if signed.Issuer.CommonName != ca.cert.Subject.CommonName { |
| 113 | t.Fatalf("issuer CN = %q, want %q", signed.Issuer.CommonName, ca.cert.Subject.CommonName) |
| 114 | } |
| 115 | if len(signed.URIs) != 1 || signed.URIs[0].String() != "pulse-node://"+nodeID { |
| 116 | t.Fatalf("URIs = %v, want pulse-node://%s", signed.URIs, nodeID) |
| 117 | } |
| 118 | foundClientAuth := false |
| 119 | for _, eku := range signed.ExtKeyUsage { |
| 120 | if eku == x509.ExtKeyUsageClientAuth { |
| 121 | foundClientAuth = true |
| 122 | } |
| 123 | } |
| 124 | if !foundClientAuth { |
| 125 | t.Fatalf("missing ClientAuth EKU") |
| 126 | } |
| 127 | if signed.KeyUsage&x509.KeyUsageDigitalSignature == 0 { |
| 128 | t.Fatalf("missing DigitalSignature KU") |
| 129 | } |
| 130 | if signed.IsCA { |
| 131 | t.Fatalf("signed cert must not be CA") |
| 132 | } |
| 133 | if !signed.NotBefore.Before(time.Now()) { |
| 134 | t.Fatalf("NotBefore = %s should be in the past", signed.NotBefore) |
| 135 | } |
| 136 | if signed.NotAfter.Sub(time.Now()) > time.Hour+time.Minute { |
| 137 | t.Fatalf("NotAfter %s too far", signed.NotAfter) |
| 138 | } |
| 139 | } |
| 140 | |
| 141 | func TestSignCSR_InvalidPEM(t *testing.T) { |
| 142 | dir := t.TempDir() |
nothing calls this directly
no test coverage detected