ostension/internal/rotator/main_test.go

105 lines
3.3 KiB
Go
Raw Normal View History

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
}