diff --git a/go.mod b/go.mod index a52d91c..c4e931a 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/spf13/pflag v1.0.10 go.uber.org/zap v1.27.1 - software.sslmate.com/src/go-pkcs12 v0.6.0 + software.sslmate.com/src/go-pkcs12 v0.7.0 ) require ( diff --git a/go.sum b/go.sum index 8d67d38..cf60b1f 100644 --- a/go.sum +++ b/go.sum @@ -24,5 +24,5 @@ golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -software.sslmate.com/src/go-pkcs12 v0.6.0 h1:f3sQittAeF+pao32Vb+mkli+ZyT+VwKaD014qFGq6oU= -software.sslmate.com/src/go-pkcs12 v0.6.0/go.mod h1:Qiz0EyvDRJjjxGyUQa2cCNZn/wMyzrRJ/qcDXOQazLI= +software.sslmate.com/src/go-pkcs12 v0.7.0 h1:Db8W44cB54TWD7stUFFSWxdfpdn6fZVcDl0w3R4RVM0= +software.sslmate.com/src/go-pkcs12 v0.7.0/go.mod h1:Qiz0EyvDRJjjxGyUQa2cCNZn/wMyzrRJ/qcDXOQazLI= diff --git a/vendor/modules.txt b/vendor/modules.txt index f7d716a..69b098d 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -30,7 +30,7 @@ go.uber.org/zap/zapcore # golang.org/x/crypto v0.45.0 ## explicit; go 1.24.0 golang.org/x/crypto/pbkdf2 -# software.sslmate.com/src/go-pkcs12 v0.6.0 +# software.sslmate.com/src/go-pkcs12 v0.7.0 ## explicit; go 1.19 software.sslmate.com/src/go-pkcs12 software.sslmate.com/src/go-pkcs12/internal/rc2 diff --git a/vendor/software.sslmate.com/src/go-pkcs12/mac.go b/vendor/software.sslmate.com/src/go-pkcs12/mac.go index 23623bb..1ba366f 100644 --- a/vendor/software.sslmate.com/src/go-pkcs12/mac.go +++ b/vendor/software.sslmate.com/src/go-pkcs12/mac.go @@ -13,6 +13,7 @@ import ( "crypto/x509/pkix" "encoding/asn1" "errors" + "fmt" "hash" "golang.org/x/crypto/pbkdf2" @@ -38,6 +39,27 @@ type pbmac1Params struct { MacAlg pkix.AlgorithmIdentifier } +func makePBMAC1Parameters(salt []byte, iterations int) ([]byte, error) { + var err error + + var kdfparams pbkdf2Params + if kdfparams.Salt.FullBytes, err = asn1.Marshal(salt); err != nil { + return nil, err + } + kdfparams.Iterations = iterations + kdfparams.KeyLength = 32 + kdfparams.Prf.Algorithm = oidHmacWithSHA256 + + var params pbmac1Params + params.Kdf.Algorithm = oidPBKDF2 + if params.Kdf.Parameters.FullBytes, err = asn1.Marshal(kdfparams); err != nil { + return nil, err + } + params.MacAlg.Algorithm = oidHmacWithSHA256 + + return asn1.Marshal(params) +} + var ( oidSHA1 = asn1.ObjectIdentifier([]int{1, 3, 14, 3, 2, 26}) oidSHA256 = asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 1}) @@ -52,7 +74,7 @@ var ( func doPBMAC1(algorithm pkix.AlgorithmIdentifier, message, password []byte) ([]byte, error) { var params pbmac1Params if err := unmarshal(algorithm.Parameters.FullBytes, ¶ms); err != nil { - return nil, err + return nil, fmt.Errorf("error decoding PBMAC1 parameters: %w", err) } // Only PBKDF2 is supported as KDF diff --git a/vendor/software.sslmate.com/src/go-pkcs12/pkcs12.go b/vendor/software.sslmate.com/src/go-pkcs12/pkcs12.go index 6c8afac..446dc3f 100644 --- a/vendor/software.sslmate.com/src/go-pkcs12/pkcs12.go +++ b/vendor/software.sslmate.com/src/go-pkcs12/pkcs12.go @@ -165,6 +165,33 @@ var Modern2023 = &Encoder{ rand: rand.Reader, } +// Modern2026 encodes PKCS#12 files using algorithms that are considered modern +// as of 2026. Private keys and certificates are encrypted using PBES2 with +// PBKDF2-HMAC-SHA-256 and AES-256-CBC. The MAC algorithm is PBMAC1 with +// PBKDF2-HMAC-SHA-256 and HMAC-SHA256. +// +// Files produced with this encoder can be read by OpenSSL 3.4.0 and higher and +// Java 26 and higher. +// +// For passwords, it is RECOMMENDED that you do one of the following: +// 1) Use [DefaultPassword] and protect the file using other means, or +// 2) Use a high-entropy password, such as one generated with `openssl rand -hex 16`. +// +// You SHOULD NOT use a lower-entropy password with this encoder because the number of KDF +// iterations is only 2048 and doesn't provide meaningful protection against +// brute-forcing. You can increase the number of iterations using [Encoder.WithIterations], +// but as https://neilmadden.blog/2023/01/09/on-pbkdf2-iterations/ explains, this doesn't +// help as much as you think. +var Modern2026 = &Encoder{ + macAlgorithm: oidPBMAC1, + certAlgorithm: oidPBES2, + keyAlgorithm: oidPBES2, + macIterations: 2048, + encryptionIterations: 2048, + saltLen: 16, + rand: rand.Reader, +} + // Legacy encodes PKCS#12 files using weak, legacy parameters that work in // a wide variety of software. // @@ -699,13 +726,21 @@ func (enc *Encoder) Encode(privateKey interface{}, certificate *x509.Certificate } if enc.macAlgorithm != nil { - // compute the MAC - pfx.MacData.Mac.Algorithm.Algorithm = enc.macAlgorithm - pfx.MacData.MacSalt = make([]byte, enc.saltLen) - if _, err = enc.rand.Read(pfx.MacData.MacSalt); err != nil { + macSalt := make([]byte, enc.saltLen) + if _, err = enc.rand.Read(macSalt); err != nil { return nil, err } - pfx.MacData.Iterations = enc.macIterations + pfx.MacData.Mac.Algorithm.Algorithm = enc.macAlgorithm + if enc.macAlgorithm.Equal(oidPBMAC1) { + var err error + pfx.MacData.Mac.Algorithm.Parameters.FullBytes, err = makePBMAC1Parameters(macSalt, enc.macIterations) + if err != nil { + return nil, err + } + } else { + pfx.MacData.MacSalt = macSalt + pfx.MacData.Iterations = enc.macIterations + } if err = computeMac(&pfx.MacData, authenticatedSafeBytes, encodedPassword); err != nil { return nil, err }