1
0
mirror of https://github.com/smallstep/cli.git synced 2025-08-09 03:22:43 +03:00

Upgrade go-pkcs12 and use modern encoders

This PR upgrades go-pkcs12 and switches the default encoder to a modern
version PBES2 with PBKDF2-HMAC-SHA-256 and AES-256-CBC. It also adds
a legacy flag to use the previous version.

This PR also fixes some linter issues.

Fixes #1061
This commit is contained in:
Mariano Cano
2023-11-28 17:58:48 -08:00
parent 7683b8725f
commit 0b51ad0f70
6 changed files with 33 additions and 15 deletions

View File

@@ -150,7 +150,8 @@ func panicHandler() {
fmt.Fprintf(os.Stderr, "%s\n", step.Version()) fmt.Fprintf(os.Stderr, "%s\n", step.Version())
fmt.Fprintf(os.Stderr, "Release Date: %s\n\n", step.ReleaseDate()) fmt.Fprintf(os.Stderr, "Release Date: %s\n\n", step.ReleaseDate())
panic(r) panic(r)
} else { }
fmt.Fprintln(os.Stderr, "Something unexpected happened.") fmt.Fprintln(os.Stderr, "Something unexpected happened.")
fmt.Fprintln(os.Stderr, "If you want to help us debug the problem, please run:") fmt.Fprintln(os.Stderr, "If you want to help us debug the problem, please run:")
fmt.Fprintf(os.Stderr, "STEPDEBUG=1 %s\n", strings.Join(os.Args, " ")) fmt.Fprintf(os.Stderr, "STEPDEBUG=1 %s\n", strings.Join(os.Args, " "))
@@ -158,7 +159,6 @@ func panicHandler() {
os.Exit(2) os.Exit(2)
} }
} }
}
func flagValue(f cli.Flag) reflect.Value { func flagValue(f cli.Flag) reflect.Value {
fv := reflect.ValueOf(f) fv := reflect.ValueOf(f)

View File

@@ -1,7 +1,6 @@
package certificate package certificate
import ( import (
"crypto/rand"
"crypto/x509" "crypto/x509"
"fmt" "fmt"
@@ -23,7 +22,7 @@ func p12Command() cli.Command {
Action: command.ActionFunc(p12Action), Action: command.ActionFunc(p12Action),
Usage: `package a certificate and keys into a .p12 file`, Usage: `package a certificate and keys into a .p12 file`,
UsageText: `step certificate p12 <p12-path> [<crt-path>] [<key-path>] UsageText: `step certificate p12 <p12-path> [<crt-path>] [<key-path>]
[**--ca**=<file>] [**--password-file**=<file>]`, [**--ca**=<file>] [**--password-file**=<file>] [**--legacy**]`,
Description: `**step certificate p12** creates a .p12 (PFX / PKCS12) Description: `**step certificate p12** creates a .p12 (PFX / PKCS12)
file containing certificates and keys. This can then be used to import file containing certificates and keys. This can then be used to import
into Windows / Firefox / Java applications. into Windows / Firefox / Java applications.
@@ -56,7 +55,15 @@ Package a certificate and private key with an empty password:
''' '''
$ step certificate p12 --no-password --insecure foo.p12 foo.crt foo.key $ step certificate p12 --no-password --insecure foo.p12 foo.crt foo.key
'''`, '''
Package a certificate and private key using a legacy encoder,
'''
$ step certificate p12 --legacy foo.p12 foo.crt foo.key
'''
`,
Flags: []cli.Flag{ Flags: []cli.Flag{
cli.StringSliceFlag{ cli.StringSliceFlag{
Name: "ca", Name: "ca",
@@ -69,6 +76,10 @@ multiple CAs or intermediates.`,
Usage: `The path to the <file> containing the password to encrypt the .p12 file.`, Usage: `The path to the <file> containing the password to encrypt the .p12 file.`,
}, },
flags.NoPassword, flags.NoPassword,
cli.BoolFlag{
Name: "legacy",
Usage: "Encodes PKCS#12 files using the algorithms that were traditionally used, PBE+SHA1+RC2 for certificates and PBE+SHA1+3DES for keys.",
},
flags.Force, flags.Force,
flags.Insecure, flags.Insecure,
}, },
@@ -86,6 +97,11 @@ func p12Action(ctx *cli.Context) error {
caFiles := ctx.StringSlice("ca") caFiles := ctx.StringSlice("ca")
hasKeyAndCert := crtFile != "" && keyFile != "" hasKeyAndCert := crtFile != "" && keyFile != ""
encoder := pkcs12.Modern
if ctx.Bool("legacy") {
encoder = pkcs12.LegacyRC2
}
// If either key or cert are provided, both must be provided // If either key or cert are provided, both must be provided
if !hasKeyAndCert && (crtFile != "" || keyFile != "") { if !hasKeyAndCert && (crtFile != "" || keyFile != "") {
return errs.MissingArguments(ctx, "key_file") return errs.MissingArguments(ctx, "key_file")
@@ -150,7 +166,7 @@ func p12Action(ctx *cli.Context) error {
// Any remaining certs will be intermediates for the server // Any remaining certs will be intermediates for the server
x509CAs = append(x509CAs, x509CertBundle[1:]...) x509CAs = append(x509CAs, x509CertBundle[1:]...)
pkcs12Data, err = pkcs12.Encode(rand.Reader, key, x509Cert, x509CAs, password) pkcs12Data, err = encoder.Encode(key, x509Cert, x509CAs, password)
if err != nil { if err != nil {
return errs.Wrap(err, "failed to encode PKCS12 data") return errs.Wrap(err, "failed to encode PKCS12 data")
} }
@@ -163,7 +179,7 @@ func p12Action(ctx *cli.Context) error {
FriendlyName: fmt.Sprintf("%s - %s", cert.Subject.String(), x509util.Fingerprint(cert)), FriendlyName: fmt.Sprintf("%s - %s", cert.Subject.String(), x509util.Fingerprint(cert)),
}) })
} }
pkcs12Data, err = pkcs12.EncodeTrustStoreEntries(rand.Reader, certsWithFriendlyNames, password) pkcs12Data, err = encoder.EncodeTrustStoreEntries(certsWithFriendlyNames, password)
if err != nil { if err != nil {
return errs.Wrap(err, "failed to encode PKCS12 data") return errs.Wrap(err, "failed to encode PKCS12 data")
} }

View File

@@ -44,10 +44,12 @@ import (
// Google is also distributing the client ID and secret on the cloud SDK // Google is also distributing the client ID and secret on the cloud SDK
// available here https://cloud.google.com/sdk/docs/quickstarts // available here https://cloud.google.com/sdk/docs/quickstarts
const ( const (
//nolint:gosec // This is a client meant for open source testing. The client has no security access or roles.
defaultClientID = "1087160488420-8qt7bavg3qesdhs6it824mhnfgcfe8il.apps.googleusercontent.com" defaultClientID = "1087160488420-8qt7bavg3qesdhs6it824mhnfgcfe8il.apps.googleusercontent.com"
//nolint:gosec // This is a client meant for open source testing. The client has no security access or roles. //nolint:gosec // This is a client meant for open source testing. The client has no security access or roles.
defaultClientNotSoSecret = "udTrOT3gzrO7W9fDPgZQLfYJ" defaultClientNotSoSecret = "udTrOT3gzrO7W9fDPgZQLfYJ"
//nolint:gosec // This is a client meant for open source testing. The client has no security access or roles.
defaultDeviceAuthzClientID = "1087160488420-1u0jqoulmv3mfomfh6fhkfs4vk4bdjih.apps.googleusercontent.com" defaultDeviceAuthzClientID = "1087160488420-1u0jqoulmv3mfomfh6fhkfs4vk4bdjih.apps.googleusercontent.com"
//nolint:gosec // This is a client meant for open source testing. The client has no security access or roles. //nolint:gosec // This is a client meant for open source testing. The client has no security access or roles.
defaultDeviceAuthzClientNotSoSecret = "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" defaultDeviceAuthzClientNotSoSecret = "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"

2
go.mod
View File

@@ -32,7 +32,7 @@ require (
golang.org/x/term v0.15.0 golang.org/x/term v0.15.0
google.golang.org/protobuf v1.31.0 google.golang.org/protobuf v1.31.0
gopkg.in/square/go-jose.v2 v2.6.0 gopkg.in/square/go-jose.v2 v2.6.0
software.sslmate.com/src/go-pkcs12 v0.2.1 software.sslmate.com/src/go-pkcs12 v0.4.0
) )
require ( require (

4
go.sum
View File

@@ -613,5 +613,5 @@ howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM=
howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
software.sslmate.com/src/go-pkcs12 v0.2.1 h1:tbT1jjaeFOF230tzOIRJ6U5S1jNqpsSyNjzDd58H3J8= software.sslmate.com/src/go-pkcs12 v0.4.0 h1:H2g08FrTvSFKUj+D309j1DPfk5APnIdAQAB8aEykJ5k=
software.sslmate.com/src/go-pkcs12 v0.2.1/go.mod h1:Qiz0EyvDRJjjxGyUQa2cCNZn/wMyzrRJ/qcDXOQazLI= software.sslmate.com/src/go-pkcs12 v0.4.0/go.mod h1:Qiz0EyvDRJjjxGyUQa2cCNZn/wMyzrRJ/qcDXOQazLI=