SSLMate / go-pkcs12

Go library for encoding and decoding PKCS#12 files

Home Page:https://pkg.go.dev/software.sslmate.com/src/go-pkcs12

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Friendly name for `Encode()`

deitch opened this issue · comments

EncodeTrustStore() supports using the CN as the friendly name. Encode() does not. Is there a chance it can be added?

If you use openssl, you can do it for key+cert, not just truststore (cert-only); actually you can provide the friendly name separately, which might be an even easier solution:

openssl pkcs12 -export -in cert.pem -inkey key.pem -name "friendlyName" -out new.p12

So perhaps:

func EncodeTrustStore(rand Reader, certs []*x509Certificate, password, friendlyName string) (pfxData []byte, err error)
func Encode(rand Reader, privateKey interface{}, certs []*x509Certificate, password, friendlyName string) (pfxData []byte, err error)

@deitch Heads up here, #39 adds the ability to set the friendly name for a certificate and get the friendly name upon reading.

Until #39 is merged in you can use it now by doing the following.

Inside of go.mod

require (
    software.sslmate.com/src/go-pkcs12 v0.2.1-0.20220610195639-426fe5a3b19a
)

replace software.sslmate.com/src/go-pkcs12 => github.com/pschou/go-pkcs12 master

Then inside of whatever utility file you use for random functions put this in

import "software.sslmate.com/src/go-pkcs12"  // github.com/pschou/go-pkcs12

...
 
func Encode(rand io.Reader, privateKey interface{}, certificate *x509.Certificate, caCerts []*x509.Certificate, password string, friendlyName string) (pfxData []byte, err error) {
    entries := []pkcs12.CertEntry{pkcs12.CertEntry{
	    Cert: certificate,
    }}
    for _, c := range caCerts {
	    entries = append(entries, pkcs12.CertEntry{
		    Cert: c,
		    FriendlyName: friendlyName,
	    })
    }

    return pkcs12.Marshal(&pkcs12.P12{
	    KeyEntries: []pkcs12.KeyEntry{pkcs12.KeyEntry{
		    Key: privateKey,
	    }},
	    KeyBagAlgorithm:  pkcs12.OidPBEWithSHAAnd3KeyTripleDESCBC,
	    CertBagAlgorithm: pkcs12.OidPBEWithSHAAnd40BitRC2CBC,
	    MACAlgorithm:     pkcs12.OidSHA1,
	    Random:           rand,
	    Password:         password,
	    HasPassword:      true,
	    CertEntries:      entries,
    })
}

Then call it like this, without the pkcs12. prefix because it's defined in your current package.

pfxData, err := Encode(rand.Reader, privateKey, cert, caChain, pkcs12.DefaultPassword, "friendlyName")

I'll put in a vote for adding support for a customizable friendly name (alias) as part of the Encode() function.

While in general, as long as there is only one entry, the alias (friendly name) of the key doesn't matter, there are at least some use cases where it does matter.

For example, the PostgreSQL JDBC driver (used for Java applications to communicate with a PostgreSQL database) requires that the entry in the PKCS#12 file has a name/alias of user or else it won't find the key/cert.

When you create the key the alias or the name must be user. The test codes uses the following to create a .p12 key openssl pkcs12 -export -in $< -inkey $*.key -out $@ -name user -CAfile $(SERVER_CRT_DIR)root.crt -caname local -passout pass:$(P12_PASSWORD)

Source: https://jdbc.postgresql.org/documentation/use/#connection-parameters