Browse Source

feat: add support for certs only in pkcs12 (#4875)

* feat: add support for certs only in pkcs12

Signed-off-by: devnopt <4581945+devnopt@users.noreply.github.com>

* Addresses review feedback

Signed-off-by: devnopt <4581945+devnopt@users.noreply.github.com>

---------

Signed-off-by: devnopt <4581945+devnopt@users.noreply.github.com>
Co-authored-by: Gustavo Fernandes de Carvalho <17139678+gusfcarvalho@users.noreply.github.com>
Co-authored-by: Gergely Brautigam <skarlso777@gmail.com>
devnopt 7 months ago
parent
commit
7bee4ab183
4 changed files with 68 additions and 20 deletions
  1. 2 0
      docs/guides/templating.md
  2. 42 14
      pkg/template/v2/pkcs12.go
  3. 18 2
      pkg/template/v2/pkcs12_test.go
  4. 6 4
      pkg/template/v2/template.go

+ 2 - 0
docs/guides/templating.md

@@ -168,6 +168,8 @@ In addition to that you can use over 200+ [sprig functions](http://masterminds.g
 | pemToPkcs12Pass  | Same as `pemToPkcs12`. Uses the provided password to encrypt the PKCS#12 archive.                                                                                                                                            |
 | fullPemToPkcs12      | Takes a PEM encoded certificates chain and key and creates a base64 encoded PKCS#12 archive.                                                                                                                                         |
 | fullPemToPkcs12Pass  | Same as `fullPemToPkcs12`. Uses the provided password to encrypt the PKCS#12 archive.                                                                                                                                            |
+| pemTruststoreToPKCS12    | Takes a PEM encoded certificates and creates a base64 encoded PKCS#12 archive.                                                                                                                                         |
+| pemTruststoreToPKCS12Pass| Same as `pemTruststoreToPKCS12`. Uses the provided password to encrypt the PKCS#12 archive.                                                                                                                                            |
 | filterPEM        | Filters PEM blocks with a specific type from a list of PEM blocks.                                                                                                                                                           |
 | filterCertChain  | Filters PEM block(s) with a specific certificate type (`leaf`, `intermediate` or `root`)  from a certificate chain of PEM blocks (PEM blocks with type `CERTIFICATE`). |
 | jwkPublicKeyPem  | Takes an json-serialized JWK and returns an PEM block of type `PUBLIC KEY` that contains the public key. [See here](https://golang.org/pkg/crypto/x509/#MarshalPKIXPublicKey) for details.                                   |

+ 42 - 14
pkg/template/v2/pkcs12.go

@@ -118,7 +118,7 @@ func pemToPkcs12Pass(cert, key, pass string) (string, error) {
 		return "", err
 	}
 
-	return certsToPkcs12(parsedCert, key, nil, pass)
+	return certsKeyToPkcs12(parsedCert, key, nil, pass)
 }
 
 func fullPemToPkcs12(cert, key string) (string, error) {
@@ -133,23 +133,15 @@ func fullPemToPkcs12Pass(cert, key, pass string) (string, error) {
 		return "", err
 	}
 
-	caCerts := make([]*x509.Certificate, 0)
-	for len(rest) > 0 {
-		caPem, restBytes := pem.Decode(rest)
-		rest = restBytes
-
-		caCert, err := x509.ParseCertificate(caPem.Bytes)
-		if err != nil {
-			return "", err
-		}
-
-		caCerts = append(caCerts, caCert)
+	caCerts, err := parseCaCerts(rest)
+	if err != nil {
+		return "", err
 	}
 
-	return certsToPkcs12(parsedCert, key, caCerts, pass)
+	return certsKeyToPkcs12(parsedCert, key, caCerts, pass)
 }
 
-func certsToPkcs12(cert *x509.Certificate, key string, caCerts []*x509.Certificate, password string) (string, error) {
+func certsKeyToPkcs12(cert *x509.Certificate, key string, caCerts []*x509.Certificate, password string) (string, error) {
 	keyPem, _ := pem.Decode([]byte(key))
 	parsedKey, err := parsePrivateKey(keyPem.Bytes)
 	if err != nil {
@@ -163,3 +155,39 @@ func certsToPkcs12(cert *x509.Certificate, key string, caCerts []*x509.Certifica
 
 	return base64.StdEncoding.EncodeToString(pfx), nil
 }
+
+func pemTruststoreToPKCS12(cert string) (string, error) {
+	return pemTruststoreToPKCS12Pass(cert, "")
+}
+
+func pemTruststoreToPKCS12Pass(cert, password string) (string, error) {
+	caCerts, err := parseCaCerts([]byte(cert))
+	if err != nil {
+		return "", err
+	}
+
+	pfx, err := gopkcs12.Modern.EncodeTrustStore(caCerts, password)
+	if err != nil {
+		return "", err
+	}
+
+	return base64.StdEncoding.EncodeToString(pfx), nil
+}
+
+func parseCaCerts(certs []byte) ([]*x509.Certificate, error) {
+	caCerts := make([]*x509.Certificate, 0)
+	rest := certs
+	for len(rest) > 0 {
+		caPem, restBytes := pem.Decode(rest)
+		rest = restBytes
+
+		caCert, err := x509.ParseCertificate(caPem.Bytes)
+		if err != nil {
+			return nil, err
+		}
+
+		caCerts = append(caCerts, caCert)
+	}
+
+	return caCerts, nil
+}

File diff suppressed because it is too large
+ 18 - 2
pkg/template/v2/pkcs12_test.go


+ 6 - 4
pkg/template/v2/template.go

@@ -34,10 +34,12 @@ var tplFuncs = tpl.FuncMap{
 	"pkcs12cert":     pkcs12cert,
 	"pkcs12certPass": pkcs12certPass,
 
-	"pemToPkcs12":         pemToPkcs12,
-	"pemToPkcs12Pass":     pemToPkcs12Pass,
-	"fullPemToPkcs12":     fullPemToPkcs12,
-	"fullPemToPkcs12Pass": fullPemToPkcs12Pass,
+	"pemToPkcs12":               pemToPkcs12,
+	"pemToPkcs12Pass":           pemToPkcs12Pass,
+	"fullPemToPkcs12":           fullPemToPkcs12,
+	"fullPemToPkcs12Pass":       fullPemToPkcs12Pass,
+	"pemTruststoreToPKCS12":     pemTruststoreToPKCS12,
+	"pemTruststoreToPKCS12Pass": pemTruststoreToPKCS12Pass,
 
 	"filterPEM":       filterPEM,
 	"filterCertChain": filterCertChain,