Documentation ¶
Overview ¶
Package pkcs12 implements some of PKCS#12 (also known as P12 or PFX). It is intended for decoding DER-encoded P12/PFX files for use with the crypto/tls package, and for encoding P12/PFX files for use by legacy applications which do not support newer formats. Since PKCS#12 uses weak encryption primitives, it SHOULD NOT be used for new applications.
Note that only DER-encoded PKCS#12 files are supported, even though PKCS#12 allows BER encoding. This is because encoding/asn1 only supports DER.
This package is forked from golang.org/x/crypto/pkcs12, which is frozen. The implementation is distilled from https://tools.ietf.org/html/rfc7292 and referenced documents.
By definition, the Fingerprint is a hash of the public key bytes, hence one can use the Fingerprint returned from reading a p12 file to match the key with the certificate, as they will have the same hash. This is important as when a p12 file is loaded, it may have multiple keys and certificates, which can be provided in any order.
Before loading the proper cert with key to make a tls.Certificate, it is a good idea to do something like the following:
ce := p12.CertEntries[0] // After we have determined this is the needed cert for _, k := range p12.KeyEntries { if bytes.Match(k.Fingerprint, ce.Fingerprint) { t := tls.Certificate{ Certificate: [][]byte{ce.Cert.Raw}, Leaf: ce.Cert, PrivateKey: k.Key, } } }
Index ¶
- Constants
- Variables
- func Decode(pfxData []byte, password string) (privateKey interface{}, certificate *x509.Certificate, err error)
- func DecodeAttribute(attribute *pkcs12Attribute) (key, value string, err error)
- func DecodeChain(pfxData []byte, password string) (privateKey interface{}, certificate *x509.Certificate, ...)
- func DecodePkcs8ShroudedKeyBagWithPassword(asn1Data []byte, password interface{}) (privateKey interface{}, algorithm asn1.ObjectIdentifier, err error)
- func DecodeTrustStore(pfxData []byte, password string) (certs []*x509.Certificate, err error)
- func Encode(rand io.Reader, privateKey interface{}, certificate *x509.Certificate, ...) (pfxData []byte, err error)
- func EncodePkcs8ShroudedKeyBagWithPassword(rand io.Reader, privateKey, password interface{}, ...) (asn1Data []byte, err error)
- func EncodeTrustStore(rand io.Reader, certs []*x509.Certificate, password string) (pfxData []byte, err error)
- func EncodeTrustStoreEntries(rand io.Reader, entries []TrustStoreEntry, password string) (pfxData []byte, err error)
- func Marshal(p12 *P12) (pfxData []byte, err error)
- func MarshalTrustStore(ts *TrustStore) (pfxData []byte, err error)
- func ToPEM(pfxData []byte, password string) ([]*pem.Block, error)deprecated
- func Unmarshal(pfxData []byte, p12 *P12) (err error)
- func UnmarshalTrustStore(pfxData []byte, ts *TrustStore) (err error)
- type CertEntry
- type KeyEntry
- type NotImplementedError
- type P12
- type TrustStore
- type TrustStoreEntry
Constants ¶
const DefaultPassword = "changeit"
DefaultPassword is the string "changeit", a commonly-used password for PKCS#12 files. Due to the weak encryption used by PKCS#12, it is RECOMMENDED that you use DefaultPassword when encoding PKCS#12 files, and protect the PKCS#12 files using other means.
Variables ¶
var ( OidPBEWithSHAAnd128BitRC4 = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 1, 1}) OidPBEWithSHAAnd40BitRC4 = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 1, 2}) OidPBEWithSHAAnd3KeyTripleDESCBC = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 1, 3}) OidPBEWithSHAAnd2KeyTripleDESCBC = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 1, 4}) OidPBEWithSHAAnd128BitRC2CBC = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 1, 5}) OidPBEWithSHAAnd40BitRC2CBC = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 1, 6}) OidHmacWithSHA1 = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 2, 7}) OidHmacWithSHA256 = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 2, 9}) OidAES128CBC = asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 1, 2}) OidAES192CBC = asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 1, 22}) OidAES256CBC = asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 1, 42}) )
var ( // ErrDecryption represents a failure to decrypt the input. ErrDecryption = errors.New("pkcs12: decryption error, incorrect padding") // ErrIncorrectPassword is returned when an incorrect password is detected. // Usually, P12/PFX data is signed to be able to verify the password. ErrIncorrectPassword = errors.New("pkcs12: decryption password incorrect") )
var ( OidSHA1 = asn1.ObjectIdentifier([]int{1, 3, 14, 3, 2, 26}) OidSHA256 = asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 1}) OidSHA384 = asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 2}) OidSHA512 = asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 3}) )
var (
OidDataContentType = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 7, 1})
)
Functions ¶
func Decode ¶
func Decode(pfxData []byte, password string) (privateKey interface{}, certificate *x509.Certificate, err error)
Decode extracts a certificate and private key from pfxData, which must be a DER-encoded PKCS#12 file. This function assumes that there is only one certificate and only one private key in the pfxData. Since PKCS#12 files often contain more than one certificate, you probably want to use DecodeChain instead.
func DecodeAttribute ¶ added in v0.0.2
func DecodeChain ¶
func DecodeChain(pfxData []byte, password string) (privateKey interface{}, certificate *x509.Certificate, caCerts []*x509.Certificate, err error)
DecodeChain extracts a certificate, a CA certificate chain, and private key from pfxData, which must be a DER-encoded PKCS#12 file. This function assumes that there is at least one certificate and only one private key in the pfxData. The first certificate is assumed to be the leaf certificate, and subsequent certificates, if any, are assumed to comprise the CA certificate chain.
func DecodePkcs8ShroudedKeyBagWithPassword ¶ added in v0.0.2
func DecodePkcs8ShroudedKeyBagWithPassword(asn1Data []byte, password interface{}) (privateKey interface{}, algorithm asn1.ObjectIdentifier, err error)
Function which decodes a keybag, for use in a Custom Key Decoder with a string input (password)
func DecodeTrustStore ¶
func DecodeTrustStore(pfxData []byte, password string) (certs []*x509.Certificate, err error)
DecodeTrustStore extracts the certificates from pfxData, which must be a DER-encoded PKCS#12 file containing exclusively certificates with attribute 2.16.840.1.113894.746875.1.1, which is used by Java to designate a trust anchor.
func Encode ¶
func Encode(rand io.Reader, privateKey interface{}, certificate *x509.Certificate, caCerts []*x509.Certificate, password string) (pfxData []byte, err error)
Encode produces pfxData containing one private key (privateKey), an end-entity certificate (certificate), and any number of CA certificates (caCerts).
The private key is encrypted with the provided password, but due to the weak encryption primitives used by PKCS#12, it is RECOMMENDED that you specify a hard-coded password (such as DefaultPassword) and protect the resulting pfxData using other means.
The rand argument is used to provide entropy for the encryption, and can be set to crypto/rand.Reader.
Encode emulates the behavior of OpenSSL's PKCS12_create: it creates two SafeContents: one that's encrypted with RC2 (can be changed by altering Algorithms in the p12 struct) and contains the certificates, and another that is unencrypted and contains the private key shrouded with 3DES The private key bag and the end-entity certificate bag have the LocalKeyId attribute set to the SHA-1 fingerprint of the end-entity certificate.
func EncodePkcs8ShroudedKeyBagWithPassword ¶ added in v0.0.2
func EncodeTrustStore ¶
func EncodeTrustStore(rand io.Reader, certs []*x509.Certificate, password string) (pfxData []byte, err error)
EncodeTrustStore produces pfxData containing any number of CA certificates (certs) to be trusted. The certificates will be marked with a special OID that allow it to be used as a Java TrustStore in Java 1.8 and newer.
Due to the weak encryption primitives used by PKCS#12, it is RECOMMENDED that you specify a hard-coded password (such as DefaultPassword) and protect the resulting pfxData using other means.
The rand argument is used to provide entropy for the encryption, and can be set to crypto/rand.Reader.
EncodeTrustStore creates a single SafeContents that's encrypted with RC2 and contains the certificates.
The Subject of the certificates are used as the Friendly Names (Aliases) within the resulting pfxData. If certificates share a Subject, then the resulting Friendly Names (Aliases) will be identical, which Java may treat as the same entry when used as a Java TrustStore, e.g. with `keytool`. To customize the Friendly Names, use EncodeTrustStoreEntries.
func EncodeTrustStoreEntries ¶
func EncodeTrustStoreEntries(rand io.Reader, entries []TrustStoreEntry, password string) (pfxData []byte, err error)
EncodeTrustStoreEntries produces pfxData containing any number of CA certificates (entries) to be trusted. The certificates will be marked with a special OID that allow it to be used as a Java TrustStore in Java 1.8 and newer.
This is identical to EncodeTrustStore, but also allows for setting specific Friendly Names (Aliases) to be used per certificate, by specifying a slice of TrustStoreEntry.
If the same Friendly Name is used for more than one certificate, then the resulting Friendly Names (Aliases) in the pfxData will be identical, which Java may treat as the same entry when used as a Java TrustStore, e.g. with `keytool`.
Due to the weak encryption primitives used by PKCS#12, it is RECOMMENDED that you specify a hard-coded password (such as DefaultPassword) and protect the resulting pfxData using other means.
The rand argument is used to provide entropy for the encryption, and can be set to crypto/rand.Reader.
EncodeTrustStoreEntries creates a single SafeContents that's encrypted with RC2 and contains the certificates.
func Marshal ¶ added in v0.0.2
Marshal produces pfxData containing private keys (PrivateKeys), an entity certificates (CertEntries), and any number of CA certificates included as CertEntries.
The private key is encrypted with the provided password, but due to the weak encryption primitives used by PKCS#12, it is RECOMMENDED that you specify a hard-coded password (such as DefaultPassword) and protect the resulting pfxData using other means.
The p12.Rand argument is used to provide entropy for the encryption, and can be set to crypto/rand.Reader.
Encode uses the P12 structure with all the Algorithm specifications for for securing the PFX.
Example usage:
p := pkcs12.NewP12WithPassword("mypass") p.KeyEntries = append(p.KeyEntries, pkcs12.KeyEntry{Key: myKey}) p.CertEntries = append(p.CertEntries, pkcs12.CertEntry{Certificate: myCert}) derBytes, err := pkcs12.Marshal(p12)
Example definition of a P12 with custom algorithms:
p := &pkcs12.P12{ Random: rand.Reader, Password: "myPassword", HasPassword: true, KeyBagAlgorithm: pkcs12.OidPBEWithSHAAnd3KeyTripleDESCBC, CertBagAlgorithm: pkcs12.OidPBEWithSHAAnd40BitRC2CBC, MACAlgorithm: pkcs12.OidSHA1, })
func MarshalTrustStore ¶ added in v0.0.2
func MarshalTrustStore(ts *TrustStore) (pfxData []byte, err error)
MarshalTrustStore produces pfxData containing any number of CA certificates (entries) to be trusted. The certificates will be marked with a special OID that allow it to be used as a Java TrustStore in Java 1.8 and newer.
This is identical to EncodeTrustStore, but also allows for setting specific Friendly Names (Aliases) to be used per certificate, by specifying a slice of TrustStoreEntry and Algorithm for key/cert storage.
If the same Friendly Name is used for more than one certificate, then the resulting Friendly Names (Aliases) in the pfxData will be identical, which Java may treat as the same entry when used as a Java TrustStore, e.g. with `keytool`.
Due to the weak encryption primitives used by PKCS#12, it is RECOMMENDED that you specify a hard-coded password (such as DefaultPassword) and protect the resulting pfxData using other means.
The rand argument is used to provide entropy for the encryption, and can be set to crypto/rand.Reader.
Example definition of a TrustStore:
ts := &pkcs12.TrustStore{ Random: rand.Reader, Password: "myPassword", HasPassword: true, CertBagAlgorithm: pkcs12.OidPBEWithSHAAnd40BitRC2CBC, MACAlgorithm: pkcs12.OidSHA1, })
MarshalTrustStore takes a TrustStore structure with Algorithm specifications to use for for securing the PFX.
func ToPEM
deprecated
ToPEM converts all "safe bags" contained in pfxData to PEM blocks.
Deprecated: ToPEM creates invalid PEM blocks (private keys are encoded as raw RSA or EC private keys rather than PKCS#8 despite being labeled "PRIVATE KEY"). To decode a PKCS#12 file, use DecodeChain instead, and use the encoding/pem package to convert to PEM if necessary.
func Unmarshal ¶ added in v0.0.2
Unmarshal extracts a certificate, a CA certificate chain, and private key from pfxData, which must be a DER-encoded PKCS#12 file. This function assumes that there is at least one certificate and only one private key in the pfxData. The first certificate is assumed to be the leaf certificate, and subsequent certificates, if any, are assumed to comprise the CA certificate chain.
Note:
Password []byte is updated to show the password used in the file (if different than given)
The P12 output will be filled with the actual settings of the encryption methods used in the PKCS#12
func UnmarshalTrustStore ¶ added in v0.0.2
func UnmarshalTrustStore(pfxData []byte, ts *TrustStore) (err error)
UnmarshalTrustStore extracts the TrustStoreEntries from pfxData, which must be a DER-encoded PKCS#12 file containing exclusively certificates with attribute 2.16.840.1.113894.746875.1.1, which is used by Java to designate a trust anchor.
Types ¶
type CertEntry ¶ added in v0.0.2
type CertEntry struct { Cert *x509.Certificate KeyID []byte FriendlyName string Attributes []pkcs12Attribute }
type KeyEntry ¶ added in v0.0.2
type NotImplementedError ¶
type NotImplementedError string
NotImplementedError indicates that the input is not currently supported.
func (NotImplementedError) Error ¶
func (e NotImplementedError) Error() string
type P12 ¶ added in v0.0.2
type P12 struct { SkipDecodeErrors bool CertEntries []CertEntry KeyEntries []KeyEntry MACAlgorithm, CertBagAlgorithm, KeyBagAlgorithm asn1.ObjectIdentifier Password string HasPassword bool Random io.Reader CustomKeyEncrypt func(*KeyEntry) ([]byte, error) CustomKeyDecrypt func(*KeyEntry, []byte) error }
When doing key level custom encryption, one can provide a call back function to handle individual keys. If no function is provided the settings Password, HasPassword, and KeyBagAlgorithm will be used for all the key bags.
func NewWithPassword ¶ added in v0.0.2
Create a new P12 with defaults and set the password
type TrustStore ¶ added in v0.0.2
type TrustStore struct { Entries []TrustStoreEntry MACAlgorithm asn1.ObjectIdentifier CertBagAlgorithm asn1.ObjectIdentifier Random io.Reader Password string HasPassword bool }
TrustStore represents a Java TrustStore in P12 format.
func NewTrustStoreWithPassword ¶ added in v0.0.2
func NewTrustStoreWithPassword(password string) *TrustStore
type TrustStoreEntry ¶
type TrustStoreEntry struct { Cert *x509.Certificate FriendlyName string Fingerprint []byte KeyID []byte Attributes []pkcs12Attribute }
TrustStoreEntry represents an entry in a Java TrustStore.