Add Vault certificate rotation operator
This commit is contained in:
parent
c685229437
commit
8009b5fd9c
1 changed files with 1013 additions and 0 deletions
105
internal/rotator/main_test.go
Normal file
105
internal/rotator/main_test.go
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
package rotator
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"math/big"
|
||||
"net"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestGenerateRequest(t *testing.T) {
|
||||
addresses := []net.IP{net.ParseIP("10.0.0.1"), net.ParseIP("172.30.1.1")}
|
||||
privateKey, encoded, err := generateRequest(addresses)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
block, _ := pem.Decode(encoded)
|
||||
request, err := x509.ParseCertificateRequest(block.Bytes)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := request.CheckSignature(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(request.IPAddresses) != len(addresses) || !request.IPAddresses[0].Equal(addresses[0]) || !request.IPAddresses[1].Equal(addresses[1]) {
|
||||
t.Fatalf("unexpected IP SANs: %v", request.IPAddresses)
|
||||
}
|
||||
publicKey := request.PublicKey.(*ecdsa.PublicKey)
|
||||
if !publicKey.Equal(&privateKey.PublicKey) {
|
||||
t.Fatal("request does not contain the generated public key")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRequiredURL(t *testing.T) {
|
||||
t.Setenv("OPNSENSE_URL", "https://172.30.1.1:8443")
|
||||
if value, err := requiredURL("OPNSENSE_URL"); err != nil || value != "https://172.30.1.1:8443" {
|
||||
t.Fatalf("unexpected URL result: value=%q error=%v", value, err)
|
||||
}
|
||||
|
||||
for _, value := range []string{"", "http://172.30.1.1:8443", "https://[email protected]:8443", "https://172.30.1.1:8443/api"} {
|
||||
t.Run(value, func(t *testing.T) {
|
||||
t.Setenv("OPNSENSE_URL", value)
|
||||
if _, err := requiredURL("OPNSENSE_URL"); err == nil {
|
||||
t.Fatalf("accepted invalid URL %q", value)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifySignedCertificate(t *testing.T) {
|
||||
addresses := []net.IP{net.ParseIP("10.0.0.1"), net.ParseIP("172.30.1.1")}
|
||||
now := time.Now()
|
||||
rootKey, root := createCertificate(t, nil, nil, &x509.Certificate{
|
||||
SerialNumber: big.NewInt(1),
|
||||
Subject: pkix.Name{CommonName: "root"},
|
||||
NotBefore: now.Add(-time.Hour),
|
||||
NotAfter: now.Add(24 * time.Hour),
|
||||
IsCA: true,
|
||||
BasicConstraintsValid: true,
|
||||
KeyUsage: x509.KeyUsageCertSign,
|
||||
})
|
||||
leafKey, leaf := createCertificate(t, root, rootKey, &x509.Certificate{
|
||||
SerialNumber: big.NewInt(2),
|
||||
NotBefore: now.Add(-time.Hour),
|
||||
NotAfter: now.Add(12 * time.Hour),
|
||||
IPAddresses: addresses,
|
||||
KeyUsage: x509.KeyUsageDigitalSignature,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||
})
|
||||
rootPEM := string(pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: root.Raw}))
|
||||
trustedRoots := x509.NewCertPool()
|
||||
trustedRoots.AddCert(root)
|
||||
if err := verifySignedCertificate(leaf, []string{rootPEM}, trustedRoots, addresses, leafKey); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := verifySignedCertificate(leaf, []string{rootPEM}, trustedRoots, []net.IP{net.ParseIP("10.0.0.1"), net.ParseIP("172.30.1.2")}, leafKey); err == nil {
|
||||
t.Fatal("wrong IP SAN was accepted")
|
||||
}
|
||||
}
|
||||
|
||||
func createCertificate(t *testing.T, parent *x509.Certificate, parentKey *ecdsa.PrivateKey, template *x509.Certificate) (*ecdsa.PrivateKey, *x509.Certificate) {
|
||||
t.Helper()
|
||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if parent == nil {
|
||||
parent = template
|
||||
parentKey = key
|
||||
}
|
||||
encoded, err := x509.CreateCertificate(rand.Reader, template, parent, &key.PublicKey, parentKey)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
certificate, err := x509.ParseCertificate(encoded)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return key, certificate
|
||||
}
|
||||
Loading…
Reference in a new issue