Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.25.0

require (
github.com/cenkalti/backoff/v4 v4.3.0
github.com/cert-manager/go-pkcs12 v0.0.0-20251218073410-44b982790b7c
github.com/coreos/go-iptables v0.8.0
github.com/kelseyhightower/envconfig v1.4.0
github.com/onsi/ginkgo/v2 v2.27.5
Expand All @@ -14,7 +15,7 @@ require (
github.com/projectcalico/api v0.0.0-20230602153125-fb7148692637
github.com/prometheus-community/pro-bing v0.7.0
github.com/prometheus/client_golang v1.23.2
github.com/submariner-io/admiral v0.23.0-m0.0.20260121163245-60a10fed6460
github.com/submariner-io/admiral v0.23.0-m0.0.20260127154930-464f66697354
github.com/submariner-io/shipyard v0.23.0-m0.0.20260121161247-366b31d697ca
github.com/tigera/operator/api v0.0.0-20250829192342-96fd517a8419
github.com/vishvananda/netlink v1.3.1
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ github.com/cenkalti/hub v1.0.1 h1:UMtjc6dHSaOQTO15SVA50MBIR9zQwvsukQupDrkIRtg=
github.com/cenkalti/hub v1.0.1/go.mod h1:tcYwtS3a2d9NO/0xDXVJWx3IedurUjYCqFCmpi0lpHs=
github.com/cenkalti/rpc2 v0.0.0-20210604223624-c1acbc6ec984 h1:CNwZyGS6KpfaOWbh2yLkSy3rSTUh3jub9CzpFpP6PVQ=
github.com/cenkalti/rpc2 v0.0.0-20210604223624-c1acbc6ec984/go.mod h1:v2npkhrXyk5BCnkNIiPdRI23Uq6uWPUQGL2hnRcRr/M=
github.com/cert-manager/go-pkcs12 v0.0.0-20251218073410-44b982790b7c h1:19zT0oEfVkTB3COjNmwcwS0q+rxD1/kClDp9Me3nggY=
github.com/cert-manager/go-pkcs12 v0.0.0-20251218073410-44b982790b7c/go.mod h1:Y/slpytWkfXJRipZINyf9Ub2pxh2goBeEpsPtI4dHKk=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/containernetworking/cni v0.8.1 h1:7zpDnQ3T3s4ucOuJ/ZCLrYBxzkg0AELFfII3Epo9TmI=
Expand Down Expand Up @@ -185,8 +187,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/submariner-io/admiral v0.23.0-m0.0.20260121163245-60a10fed6460 h1:rlvdzpXIatTx1+4bWuWn8GTKwe97dXxGREAP/SKLvLM=
github.com/submariner-io/admiral v0.23.0-m0.0.20260121163245-60a10fed6460/go.mod h1:7OgtUvSZrwkK6uGIZRWfU57vOuz0X/MyQCyOE58olVU=
github.com/submariner-io/admiral v0.23.0-m0.0.20260127154930-464f66697354 h1:ozFYPYRQlUyTiv0My5A+deAU0sKcR89V3qxncquLslc=
github.com/submariner-io/admiral v0.23.0-m0.0.20260127154930-464f66697354/go.mod h1:7OgtUvSZrwkK6uGIZRWfU57vOuz0X/MyQCyOE58olVU=
github.com/submariner-io/shipyard v0.23.0-m0.0.20260121161247-366b31d697ca h1:xZs0XkIh1zDP+I5Va8kuYezeBAfBRhZQ2AvUrTsGNI0=
github.com/submariner-io/shipyard v0.23.0-m0.0.20260121161247-366b31d697ca/go.mod h1:RxZ0WiJQqJSdbjobbL1Q1kmKWSx24mBNZA4gD+4UxDE=
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
Expand Down
80 changes: 52 additions & 28 deletions pkg/cable/libreswan/certificate_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,14 @@ import (
"bytes"
"context"
"crypto/sha256"
"crypto/x509"
"encoding/pem"
"fmt"
"os"
"os/exec"
"time"

"github.com/cert-manager/go-pkcs12"
"github.com/pkg/errors"
"github.com/submariner-io/admiral/pkg/certificate"
"github.com/submariner-io/admiral/pkg/command"
Expand Down Expand Up @@ -91,53 +94,74 @@ func (c *CertificateHandler) loadCertificate(ctx context.Context, certData []byt
return errors.Wrapf(err, "failed to load certificate %q", nickname)
}

//nolint:gosec // openssl/pk12util args are from trusted config
//nolint:gosec // pk12util args are from trusted config
func (c *CertificateHandler) loadPrivateKey(ctx context.Context, certData, keyData []byte, nickname string) error {
// Write cert and key to temporary files
certFile, err := os.CreateTemp(RootDir, "submariner-cert-*.crt")
if err != nil {
return errors.Wrap(err, "failed to create temporary cert file")
// Parse certificate data
var parsedCert *x509.Certificate
var err error

for block, rest := pem.Decode(certData); block != nil; block, rest = pem.Decode(rest) {
switch block.Type {
case "CERTIFICATE":
parsedCert, err = x509.ParseCertificate(block.Bytes)
if err != nil {
return errors.Wrap(err, "error parsing certificate data")
}
default:
return fmt.Errorf("unexpected block type %q in certificate data", block.Type)
}
}
defer os.Remove(certFile.Name())

if _, err := certFile.Write(certData); err != nil {
return errors.Wrap(err, "failed to write certificate to temporary file")
if parsedCert == nil {
return errors.New("no certificate found in certificate data")
}

certFile.Close()

keyFile, err := os.CreateTemp(RootDir, "submariner-key-*.key")
if err != nil {
return errors.Wrap(err, "failed to create temporary key file")
// Parse key data
var parsedKey any

for block, rest := pem.Decode(keyData); block != nil; block, rest = pem.Decode(rest) {
switch block.Type {
case "PRIVATE KEY":
parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
return errors.Wrap(err, "error parsing key data")
}
case "RSA PRIVATE KEY":
parsedKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return errors.Wrap(err, "error parsing key data")
}
default:
return fmt.Errorf("unexpected block type %q in key data", block.Type)
}
}
defer os.Remove(keyFile.Name())

if _, err := keyFile.Write(keyData); err != nil {
return errors.Wrap(err, "failed to write key to temporary file")
if parsedKey == nil {
return errors.New("no private key found in key data")
}

keyFile.Close()

// Create PKCS#12 file with openssl
// Export PKCS#12 file
p12File, err := os.CreateTemp(RootDir, "submariner-client-*.p12")
if err != nil {
return errors.Wrap(err, "failed to create temporary pkcs12 file")
}

defer os.Remove(p12File.Name())
p12File.Close()

// Use empty password for PKCS#12
pkcs12Password := ""

opensslCmd := exec.CommandContext(ctx, "openssl", "pkcs12", "-export",
"-in", certFile.Name(),
"-inkey", keyFile.Name(),
"-out", p12File.Name(),
"-name", nickname,
"-passout", "pass:"+pkcs12Password)
if err := execWithOutput(command.New(opensslCmd)); err != nil {
return errors.Wrap(err, "failed to create PKCS#12 file")
pkcsData, err := pkcs12.Modern.EncodeWithFriendlyName(nickname, parsedKey, parsedCert, []*x509.Certificate{}, pkcs12Password)
if err != nil {
return errors.Wrap(err, "error encoding to PKCS#12")
}

if _, err := p12File.Write(pkcsData); err != nil {
return errors.Wrap(err, "error writing PKCS#12 file")
}

if err := p12File.Close(); err != nil {
return errors.Wrap(err, "error closing PKCS#12 file")
}
Comment on lines +99 to 165
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n pkg/cable/libreswan/certificate_handler.go | sed -n '99,165p'

Repository: submariner-io/submariner

Length of output: 2413


🌐 Web query:

go-pkcs12 EncodeWithFriendlyName additionalCerts parameter chain order

💡 Result:

In github.com/cert-manager/go-pkcs12, EncodeWithFriendlyName(..., caCerts, ...) (your “additionalCerts”) does not build or sort a chain for you—it just encodes the leaf plus whatever you pass in. The expected/compatible ordering is:

  1. Leaf (end-entity) cert (certificate)
  2. Then caCerts in the slice order you provide

This matches the library’s own decode expectation: DecodeChain treats the first certificate as the leaf and subsequent certificates as the CA chain. Therefore, when encoding, pass caCerts in proper chain order (typically: intermediate closest to the leaf → up toward the root, optionally including the root). [1]

Source: pkg.go.dev docs for EncodeWithFriendlyName / Encode and DecodeChain. [1]

[1] (pkg.go.dev)

Citations:


🌐 Web query:

X.509 certificate chain PEM encoding order leaf intermediate root

💡 Result:

For a PEM-encoded certificate chain (multiple -----BEGIN CERTIFICATE----- blocks concatenated), the conventional and standards-aligned order is:

  1. Leaf / end-entity certificate (the server/client cert)
  2. Intermediate CA certificate(s), in sequence so that each cert signs the one immediately before it
  3. Root CA certificate (typically omitted because clients are expected to already have trust anchors)

This matches TLS requirements: the sender’s certificate must be first, and each following certificate should/must certify the preceding one, with the root allowed to be omitted. [1], [2]

In OpenSSL terms: intermediates go in the “untrusted”/chain bundle (concatenated PEMs), while roots belong in the “trusted” store/CAfile. [3]

So the usual PEM bundle is: leaf -> intermediate(s) (no root). [1], [2], [3]

Sources
[1] RFC 8446 (TLS 1.3), Certificate message ordering and root omission: https://www.ietf.org/rfc/rfc8446.html
[2] IETF Datatracker (TLS 1.2 bis draft) quoting TLS 1.2 Certificate message rules (sender first; each following cert certifies previous; root may be omitted): https://datatracker.ietf.org/doc/html/draft-ietf-tls-rfc5246-bis
[3] OpenSSL verify documentation (separate untrusted intermediates vs trusted roots; multiple PEM certs concatenated): https://docs.openssl.org/master/man1/openssl-verify/


Handle PEM chains so the leaf certificate is used and intermediates preserved.

The certificate parsing loop (lines 103–113) overwrites parsedCert on each CERTIFICATE block. In a multi-certificate PEM file, this means the last certificate becomes the leaf cert passed to EncodeWithFriendlyName, while earlier certificates (including the actual leaf) are discarded. According to go-pkcs12 and standard PEM chain ordering, the first certificate is the leaf and subsequent ones form the chain.

The fix captures the first certificate as the leaf, collects remaining certificates into a chain slice, and passes that chain to EncodeWithFriendlyName:

Proposed fix (leaf + chain handling)
-	// Parse certificate data
-	var parsedCert *x509.Certificate
-	var err error
+	// Parse certificate data
+	var (
+		parsedCert *x509.Certificate
+		certChain  []*x509.Certificate
+		err        error
+	)

 	for block, rest := pem.Decode(certData); block != nil; block, rest = pem.Decode(rest) {
-		switch block.Type {
-		case "CERTIFICATE":
-			parsedCert, err = x509.ParseCertificate(block.Bytes)
-			if err != nil {
-				return errors.Wrap(err, "error parsing certificate data")
-			}
-		default:
-			return fmt.Errorf("unexpected block type %q in certificate data", block.Type)
-		}
+		if block.Type != "CERTIFICATE" {
+			return fmt.Errorf("unexpected block type %q in certificate data", block.Type)
+		}
+
+		cert, err := x509.ParseCertificate(block.Bytes)
+		if err != nil {
+			return errors.Wrap(err, "error parsing certificate data")
+		}
+
+		if parsedCert == nil {
+			parsedCert = cert
+		} else {
+			certChain = append(certChain, cert)
+		}
 	}

 	if parsedCert == nil {
 		return errors.New("no certificate found in certificate data")
 	}

@@
-	pkcsData, err := pkcs12.Modern.EncodeWithFriendlyName(nickname, parsedKey, parsedCert, []*x509.Certificate{}, pkcs12Password)
+	pkcsData, err := pkcs12.Modern.EncodeWithFriendlyName(nickname, parsedKey, parsedCert, certChain, pkcs12Password)
 	if err != nil {
 		return errors.Wrap(err, "error encoding to PKCS#12")
 	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Parse certificate data
var parsedCert *x509.Certificate
var err error
for block, rest := pem.Decode(certData); block != nil; block, rest = pem.Decode(rest) {
switch block.Type {
case "CERTIFICATE":
parsedCert, err = x509.ParseCertificate(block.Bytes)
if err != nil {
return errors.Wrap(err, "error parsing certificate data")
}
default:
return fmt.Errorf("unexpected block type %q in certificate data", block.Type)
}
}
defer os.Remove(certFile.Name())
if _, err := certFile.Write(certData); err != nil {
return errors.Wrap(err, "failed to write certificate to temporary file")
if parsedCert == nil {
return errors.New("no certificate found in certificate data")
}
certFile.Close()
keyFile, err := os.CreateTemp(RootDir, "submariner-key-*.key")
if err != nil {
return errors.Wrap(err, "failed to create temporary key file")
// Parse key data
var parsedKey any
for block, rest := pem.Decode(keyData); block != nil; block, rest = pem.Decode(rest) {
switch block.Type {
case "PRIVATE KEY":
parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
return errors.Wrap(err, "error parsing key data")
}
case "RSA PRIVATE KEY":
parsedKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return errors.Wrap(err, "error parsing key data")
}
default:
return fmt.Errorf("unexpected block type %q in key data", block.Type)
}
}
defer os.Remove(keyFile.Name())
if _, err := keyFile.Write(keyData); err != nil {
return errors.Wrap(err, "failed to write key to temporary file")
if parsedKey == nil {
return errors.New("no private key found in key data")
}
keyFile.Close()
// Create PKCS#12 file with openssl
// Export PKCS#12 file
p12File, err := os.CreateTemp(RootDir, "submariner-client-*.p12")
if err != nil {
return errors.Wrap(err, "failed to create temporary pkcs12 file")
}
defer os.Remove(p12File.Name())
p12File.Close()
// Use empty password for PKCS#12
pkcs12Password := ""
opensslCmd := exec.CommandContext(ctx, "openssl", "pkcs12", "-export",
"-in", certFile.Name(),
"-inkey", keyFile.Name(),
"-out", p12File.Name(),
"-name", nickname,
"-passout", "pass:"+pkcs12Password)
if err := execWithOutput(command.New(opensslCmd)); err != nil {
return errors.Wrap(err, "failed to create PKCS#12 file")
pkcsData, err := pkcs12.Modern.EncodeWithFriendlyName(nickname, parsedKey, parsedCert, []*x509.Certificate{}, pkcs12Password)
if err != nil {
return errors.Wrap(err, "error encoding to PKCS#12")
}
if _, err := p12File.Write(pkcsData); err != nil {
return errors.Wrap(err, "error writing PKCS#12 file")
}
if err := p12File.Close(); err != nil {
return errors.Wrap(err, "error closing PKCS#12 file")
}
// Parse certificate data
var (
parsedCert *x509.Certificate
certChain []*x509.Certificate
err error
)
for block, rest := pem.Decode(certData); block != nil; block, rest = pem.Decode(rest) {
if block.Type != "CERTIFICATE" {
return fmt.Errorf("unexpected block type %q in certificate data", block.Type)
}
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return errors.Wrap(err, "error parsing certificate data")
}
if parsedCert == nil {
parsedCert = cert
} else {
certChain = append(certChain, cert)
}
}
if parsedCert == nil {
return errors.New("no certificate found in certificate data")
}
// Parse key data
var parsedKey any
for block, rest := pem.Decode(keyData); block != nil; block, rest = pem.Decode(rest) {
switch block.Type {
case "PRIVATE KEY":
parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
return errors.Wrap(err, "error parsing key data")
}
case "RSA PRIVATE KEY":
parsedKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return errors.Wrap(err, "error parsing key data")
}
default:
return fmt.Errorf("unexpected block type %q in key data", block.Type)
}
}
if parsedKey == nil {
return errors.New("no private key found in key data")
}
// Export PKCS#12 file
p12File, err := os.CreateTemp(RootDir, "submariner-client-*.p12")
if err != nil {
return errors.Wrap(err, "failed to create temporary pkcs12 file")
}
defer os.Remove(p12File.Name())
// Use empty password for PKCS#12
pkcs12Password := ""
pkcsData, err := pkcs12.Modern.EncodeWithFriendlyName(nickname, parsedKey, parsedCert, certChain, pkcs12Password)
if err != nil {
return errors.Wrap(err, "error encoding to PKCS#12")
}
if _, err := p12File.Write(pkcsData); err != nil {
return errors.Wrap(err, "error writing PKCS#12 file")
}
if err := p12File.Close(); err != nil {
return errors.Wrap(err, "error closing PKCS#12 file")
}
🤖 Prompt for AI Agents
In `@pkg/cable/libreswan/certificate_handler.go` around lines 99 - 165, The
certificate parsing currently overwrites parsedCert for each "CERTIFICATE"
block, so change the loop that processes certData to treat the first parsed
CERTIFICATE as the leaf (set parsedCert only if nil) and append subsequent
parsed certificates to a certChain slice ([]*x509.Certificate); then pass
certChain (not an empty slice) as the intermediate chain argument to
pkcs12.Modern.EncodeWithFriendlyName along with parsedKey and parsedCert. Ensure
parsedCert is checked for nil after the loop as before and keep existing error
handling around pem.Block types and pkcs12/p12 file creation (references:
parsedCert, certData, certChain, pkcs12.Modern.EncodeWithFriendlyName,
parsedKey, p12File).


// Import PKCS#12 into NSS using pk12util
Expand Down
86 changes: 63 additions & 23 deletions pkg/cable/libreswan/certificate_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,17 @@ package libreswan_test

import (
"context"
"maps"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
_ "embed"
"encoding/pem"
"math/big"
"os"
"os/exec"
"path/filepath"
"time"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
Expand All @@ -34,17 +41,59 @@ import (
)

var _ = Describe("CertificateHandler", func() {
certData := map[string][]byte{
certificate.CADataKey: []byte("-----BEGIN CERTIFICATE-----\nMOCK_CA_CERT\n-----END CERTIFICATE-----"),
certificate.TLSDataKey: []byte("-----BEGIN CERTIFICATE-----\nMOCK_CLIENT_CERT\n-----END CERTIFICATE-----"),
certificate.PrivateKeyDataKey: []byte("-----BEGIN PRIVATE KEY-----\nMOCK_CLIENT_KEY\n-----END PRIVATE KEY-----"),
}

var (
cmdExecutor *fakecommand.Executor
handler *libreswan.CertificateHandler
cmdExecutor *fakecommand.Executor
handler *libreswan.CertificateHandler
testCertData map[string][]byte
newCertData map[string][]byte
)

BeforeEach(func() {
if testCertData == nil || newCertData == nil {
// CA
caKey, caCert, err := certificate.CreateCAKeyAndCertificate("CA", 24*365*10*time.Hour)
Expect(err).NotTo(HaveOccurred())
caDER, err := x509.CreateCertificate(rand.Reader, caCert, caCert, &caKey.PublicKey, caKey)
Expect(err).NotTo(HaveOccurred())
caPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: caDER})

createSignedCertificate := func(name string) map[string][]byte {
privateKey, err := rsa.GenerateKey(rand.Reader, certificate.RSABitSize)
Expect(err).NotTo(HaveOccurred())

serialNumber, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128))
Expect(err).NotTo(HaveOccurred())

cert := &x509.Certificate{
SerialNumber: serialNumber,
Subject: pkix.Name{
CommonName: name,
Organization: []string{"submariner.io"},
},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(10, 0, 0),
KeyUsage: x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
}

certDER, err := x509.CreateCertificate(rand.Reader, cert, caCert, &privateKey.PublicKey, caKey)
Expect(err).NotTo(HaveOccurred())

return map[string][]byte{
certificate.CADataKey: caPEM,
certificate.TLSDataKey: pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER}),
certificate.PrivateKeyDataKey: pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey)}),
}
}

// First test certificate
testCertData = createSignedCertificate("test")

// New test certificate
newCertData = createSignedCertificate("new")
}
})

BeforeEach(func() {
setupTempDir()

Expand All @@ -64,22 +113,15 @@ var _ = Describe("CertificateHandler", func() {
}

It("should successfully load the certificates into the NSS database", func() {
Expect(handler.OnSignedCallback(certData)).To(Succeed())
Expect(handler.OnSignedCallback(testCertData)).To(Succeed())

cmdExecutor.AwaitCommand(ContainSubstring("certutil"), "-N", "-d", "sql:"+handler.NSSDatabaseDir())
assertCmdStdIn(cmdExecutor.AwaitCommand(ContainSubstring("certutil"), "-A", libreswan.CACertName,
"-d", "sql:"+handler.NSSDatabaseDir()), certData[certificate.CADataKey])
cmdExecutor.AwaitCommand(ContainSubstring("openssl"), "pkcs12", "-export", "-name", libreswan.ClientCertName)
"-d", "sql:"+handler.NSSDatabaseDir()), testCertData[certificate.CADataKey])
cmdExecutor.AwaitCommand(ContainSubstring("pk12util"), "-d", "sql:"+handler.NSSDatabaseDir())
cmdExecutor.Clear()

By("Invoking OnSignedCallback with new cert data")

newCertData := map[string][]byte{
certificate.CADataKey: []byte("NEW_CA_CERT"),
certificate.TLSDataKey: []byte("NEW_CLIENT_CERT"),
certificate.PrivateKeyDataKey: []byte("NEW_CLIENT_KEY"),
}
Expect(handler.OnSignedCallback(newCertData)).To(Succeed())

cmdExecutor.AwaitCommand(ContainSubstring("certutil"), "-A", libreswan.CACertName)
Expand All @@ -103,7 +145,7 @@ var _ = Describe("CertificateHandler", func() {
return fakecommand.InterceptorFuncs{}
})

Expect(handler.OnSignedCallback(certData)).NotTo(Succeed())
Expect(handler.OnSignedCallback(testCertData)).NotTo(Succeed())
})

It("should handle certificate loading failure", func() {
Expand All @@ -117,11 +159,11 @@ var _ = Describe("CertificateHandler", func() {
return fakecommand.InterceptorFuncs{}
})

Expect(handler.OnSignedCallback(certData)).NotTo(Succeed())
Expect(handler.OnSignedCallback(testCertData)).NotTo(Succeed())
})

It("should only initialize the NSS database once", func() {
Expect(handler.OnSignedCallback(certData)).To(Succeed())
Expect(handler.OnSignedCallback(testCertData)).To(Succeed())

cmdExecutor.AwaitCommand(ContainSubstring("certutil"), "-N")
cmdExecutor.Clear()
Expand All @@ -131,8 +173,6 @@ var _ = Describe("CertificateHandler", func() {
_, err := os.Create(nssDBFile)
Expect(err).NotTo(HaveOccurred())

newCertData := maps.Clone(certData)
newCertData[certificate.CADataKey] = []byte("NEW_CA_CERT")
Expect(handler.OnSignedCallback(newCertData)).To(Succeed())

cmdExecutor.EnsureNoCommand(ContainSubstring("certutil"), "-N")
Expand Down
Loading