@@ -22,6 +22,8 @@ import (
2222 "bytes"
2323 "context"
2424 "crypto/sha256"
25+ "crypto/x509"
26+ "encoding/pem"
2527 "fmt"
2628 "os"
2729 "os/exec"
@@ -32,6 +34,7 @@ import (
3234 "github.com/submariner-io/admiral/pkg/command"
3335 "github.com/submariner-io/admiral/pkg/log"
3436 logf "sigs.k8s.io/controller-runtime/pkg/log"
37+ "software.sslmate.com/src/go-pkcs12"
3538)
3639
3740var certLogger = log.Logger {Logger : logf .Log .WithName ("CertHandler" )}
@@ -91,55 +94,61 @@ func (c *CertificateHandler) loadCertificate(ctx context.Context, certData []byt
9194 return errors .Wrapf (err , "failed to load certificate %q" , nickname )
9295}
9396
94- //nolint:gosec // openssl/ pk12util args are from trusted config
97+ //nolint:gosec // pk12util args are from trusted config
9598func (c * CertificateHandler ) loadPrivateKey (ctx context.Context , certData , keyData []byte , nickname string ) error {
96- // Write cert and key to temporary files
97- certFile , err := os .CreateTemp (RootDir , "submariner-cert-*.crt" )
98- if err != nil {
99- return errors .Wrap (err , "failed to create temporary cert file" )
100- }
101- defer os .Remove (certFile .Name ())
102-
103- if _ , err := certFile .Write (certData ); err != nil {
104- return errors .Wrap (err , "failed to write certificate to temporary file" )
105- }
106-
107- certFile .Close ()
108-
109- keyFile , err := os .CreateTemp (RootDir , "submariner-key-*.key" )
110- if err != nil {
111- return errors .Wrap (err , "failed to create temporary key file" )
99+ // Parse certificate data
100+ var parsedCert * x509.Certificate
101+ var err error
102+
103+ for block , rest := pem .Decode (certData ); block != nil ; block , rest = pem .Decode (rest ) {
104+ switch block .Type {
105+ case "CERTIFICATE" :
106+ parsedCert , err = x509 .ParseCertificate (block .Bytes )
107+ if err != nil {
108+ return errors .Wrap (err , "error parsing certificate data" )
109+ }
110+ default :
111+ return fmt .Errorf ("unexpected block type %q in certificate data" , block .Type )
112+ }
112113 }
113- defer os .Remove (keyFile .Name ())
114114
115- if _ , err := keyFile .Write (keyData ); err != nil {
116- return errors .Wrap (err , "failed to write key to temporary file" )
115+ // Parse key data
116+ var parsedKey any
117+
118+ for block , rest := pem .Decode (keyData ); block != nil ; block , rest = pem .Decode (rest ) {
119+ switch block .Type {
120+ case "PRIVATE KEY" :
121+ parsedKey , err = x509 .ParsePKCS8PrivateKey (block .Bytes )
122+ if err != nil {
123+ return errors .Wrap (err , "error parsing key data" )
124+ }
125+ default :
126+ return fmt .Errorf ("unexpected block type %q in key data" , block .Type )
127+ }
117128 }
118129
119- keyFile .Close ()
120-
121- // Create PKCS#12 file with openssl
130+ // Export PKCS#12 file
122131 p12File , err := os .CreateTemp (RootDir , "submariner-client-*.p12" )
123132 if err != nil {
124133 return errors .Wrap (err , "failed to create temporary pkcs12 file" )
125134 }
126135
127136 defer os .Remove (p12File .Name ())
128- p12File .Close ()
129137
130138 // Use empty password for PKCS#12
131139 pkcs12Password := ""
132140
133- opensslCmd := exec .CommandContext (ctx , "openssl" , "pkcs12" , "-export" ,
134- "-in" , certFile .Name (),
135- "-inkey" , keyFile .Name (),
136- "-out" , p12File .Name (),
137- "-name" , nickname ,
138- "-passout" , "pass:" + pkcs12Password )
139- if err := execWithOutput (command .New (opensslCmd )); err != nil {
140- return errors .Wrap (err , "failed to create PKCS#12 file" )
141+ pkcsData , err := pkcs12 .Modern .EncodeWithFriendlyName (nickname , parsedKey , parsedCert , []* x509.Certificate {}, pkcs12Password )
142+ if err != nil {
143+ return errors .Wrap (err , "error encoding to PKCS#12" )
144+ }
145+
146+ if _ , err := p12File .Write (pkcsData ); err != nil {
147+ return errors .Wrap (err , "error writing PKCS#12 file" )
141148 }
142149
150+ p12File .Close ()
151+
143152 // Import PKCS#12 into NSS using pk12util
144153 pk12Cmd := exec .CommandContext (ctx , "pk12util" , "-i" , p12File .Name (), "-d" , "sql:" + c .nssDBDir , "-W" , pkcs12Password )
145154 err = execWithOutput (command .New (pk12Cmd ))
0 commit comments