From 05a2b63e842e13444b2ec63b1694120544add4e4 Mon Sep 17 00:00:00 2001 From: Brandon Lum Date: Tue, 23 Jul 2019 23:47:37 -0400 Subject: [PATCH 1/2] Create CryptoConfig constructors in place of dcparameters Signed-off-by: Brandon Lum --- pkg/encryption/config/config.go | 42 +++++++++++++ pkg/encryption/config/constructors.go | 91 +++++++++++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 pkg/encryption/config/constructors.go diff --git a/pkg/encryption/config/config.go b/pkg/encryption/config/config.go index 937ba2513..487ea8e5b 100644 --- a/pkg/encryption/config/config.go +++ b/pkg/encryption/config/config.go @@ -61,3 +61,45 @@ func InitEncryption(parameters, dcparameters map[string][][]byte) *CryptoConfig }, } } + +// CombineCryptoConfigs takes a CryptoConfig list and creates a single CryptoConfig +// containing the crypto configuration of all the key bundles +func CombineCryptoConfigs(ccs []CryptoConfig) CryptoConfig { + ecparam := map[string][][]byte{} + ecdcparam := map[string][][]byte{} + dcparam := map[string][][]byte{} + + for _, cc := range ccs { + if ec := cc.EncryptConfig; ec != nil { + addToMap(ecparam, ec.Parameters) + addToMap(ecdcparam, ec.DecryptConfig.Parameters) + } + + if dc := cc.DecryptConfig; dc != nil { + addToMap(dcparam, dc.Parameters) + } + } + + return CryptoConfig{ + EncryptConfig: &EncryptConfig{ + Parameters: ecparam, + DecryptConfig: DecryptConfig{ + Parameters: ecdcparam, + }, + }, + DecryptConfig: &DecryptConfig{ + Parameters: dcparam, + }, + } + +} + +func addToMap(orig map[string][][]byte, add map[string][][]byte) { + for k, v := range add { + if ov, ok := orig[k]; ok { + orig[k] = append(ov, v...) + } else { + orig[k] = v + } + } +} diff --git a/pkg/encryption/config/constructors.go b/pkg/encryption/config/constructors.go new file mode 100644 index 000000000..0d36d11da --- /dev/null +++ b/pkg/encryption/config/constructors.go @@ -0,0 +1,91 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package config + +// NewJweCryptoConfig returns a CryptoConfig that contains the required configuration for using +// the jwe keyunwrap interface +func NewJweCryptoConfig(pubKey *[]byte, privKey *[]byte, privKeyPassword *string) CryptoConfig { + pubKeys := [][]byte{} + privKeys := [][]byte{} + privKeysPasswords := [][]byte{} + + if pubKey != nil { + pubKeys = append(pubKeys, *pubKey) + } + if privKey != nil { + privKeys = append(privKeys, *privKey) + } + if privKeyPassword != nil { + privKeysPasswords = append(privKeysPasswords, []byte(*privKeyPassword)) + } + + dc := DecryptConfig{ + Parameters: map[string][][]byte{ + "privkeys": privKeys, + "privkeys-passwords": privKeysPasswords, + }, + } + + ep := map[string][][]byte{ + "pubkeys": pubKeys, + } + + return CryptoConfig{ + EncryptConfig: &EncryptConfig{ + Parameters: ep, + DecryptConfig: dc, + }, + DecryptConfig: &dc, + } +} + +// NewPkcs7CryptoConfig returns a CryptoConfig that contains the required configuration for using +// the pkcs7 keyunwrap interface +func NewPkcs7CryptoConfig(x509 *[]byte, privKey *[]byte, privKeyPassword *string) CryptoConfig { + x509s := [][]byte{} + privKeys := [][]byte{} + privKeysPasswords := [][]byte{} + + if x509 != nil { + x509s = append(x509s, *x509) + } + if privKey != nil { + privKeys = append(privKeys, *privKey) + } + if privKeyPassword != nil { + privKeysPasswords = append(privKeysPasswords, []byte(*privKeyPassword)) + } + + dc := DecryptConfig{ + Parameters: map[string][][]byte{ + "privkeys": privKeys, + "privkeys-passwords": privKeysPasswords, + }, + } + + ep := map[string][][]byte{ + "x509s": x509s, + } + + return CryptoConfig{ + EncryptConfig: &EncryptConfig{ + Parameters: ep, + DecryptConfig: dc, + }, + DecryptConfig: &dc, + } +} From 3d1fa6969489061c03bd31b7c218b9d4e39fdeb4 Mon Sep 17 00:00:00 2001 From: Brandon Lum Date: Wed, 24 Jul 2019 16:13:26 -0400 Subject: [PATCH 2/2] Implemented constructors for both encryption and decryption Signed-off-by: Brandon Lum --- cmd/ctr/commands/images/crypt_utils.go | 61 +++++++---- cmd/ctr/commands/images/decrypt.go | 7 +- cmd/ctr/commands/images/encrypt.go | 60 ++++++----- image_enc_test.go | 21 ++-- images/encryption/encryption.go | 2 +- pkg/encryption/config/config.go | 17 ++- pkg/encryption/config/constructors.go | 139 ++++++++++++++++--------- pkg/encryption/gpg.go | 62 ++--------- 8 files changed, 194 insertions(+), 175 deletions(-) diff --git a/cmd/ctr/commands/images/crypt_utils.go b/cmd/ctr/commands/images/crypt_utils.go index 2f93c88fb..83946cdaf 100644 --- a/cmd/ctr/commands/images/crypt_utils.go +++ b/cmd/ctr/commands/images/crypt_utils.go @@ -191,10 +191,10 @@ func createGPGClient(context *cli.Context) (encryption.GPGClient, error) { return encryption.NewGPGClient(context.String("gpg-version"), context.String("gpg-homedir")) } -func getGPGPrivateKeys(context *cli.Context, gpgSecretKeyRingFiles [][]byte, descs []ocispec.Descriptor, mustFindKey bool, dcparameters map[string][][]byte) error { +func getGPGPrivateKeys(context *cli.Context, gpgSecretKeyRingFiles [][]byte, descs []ocispec.Descriptor, mustFindKey bool) (gpgPrivKeys [][]byte, gpgPrivKeysPwds [][]byte, err error) { gpgClient, err := createGPGClient(context) if err != nil { - return err + return nil, nil, err } var gpgVault encryption.GPGVault @@ -202,10 +202,10 @@ func getGPGPrivateKeys(context *cli.Context, gpgSecretKeyRingFiles [][]byte, des gpgVault = encryption.NewGPGVault() err = gpgVault.AddSecretKeyRingDataArray(gpgSecretKeyRingFiles) if err != nil { - return err + return nil, nil, err } } - return encryption.GPGGetPrivateKey(descs, gpgClient, gpgVault, mustFindKey, dcparameters) + return encryption.GPGGetPrivateKey(descs, gpgClient, gpgVault, mustFindKey) } func createLayerFilter(client *containerd.Client, ctx gocontext.Context, desc ocispec.Descriptor, layers []int32, platformList []ocispec.Platform) (imgenc.LayerFilter, error) { @@ -359,20 +359,21 @@ func filterLayerDescriptors(alldescs []ocispec.Descriptor, layers []int32, pl [] return layerInfos, descs } -// CreateDcParameters creates the decryption parameter map from command line options and possibly +// CreateDecryptCryptoConfig creates the CryptoConfig object that contains the necessary +// information to perform decryption from command line options and possibly // LayerInfos describing the image and helping us to query for the PGP decryption keys -func CreateDcParameters(context *cli.Context, descs []ocispec.Descriptor) (map[string][][]byte, error) { - dcparameters := make(map[string][][]byte) +func CreateDecryptCryptoConfig(context *cli.Context, descs []ocispec.Descriptor) (encconfig.CryptoConfig, error) { + ccs := []encconfig.CryptoConfig{} // x509 cert is needed for PKCS7 decryption _, _, x509s, err := processRecipientKeys(context.StringSlice("dec-recipient")) if err != nil { - return nil, err + return encconfig.CryptoConfig{}, err } gpgSecretKeyRingFiles, gpgSecretKeyPasswords, privKeys, privKeysPasswords, err := processPrivateKeyFiles(context.StringSlice("key")) if err != nil { - return nil, err + return encconfig.CryptoConfig{}, err } _, err = createGPGClient(context) @@ -380,26 +381,40 @@ func CreateDcParameters(context *cli.Context, descs []ocispec.Descriptor) (map[s if gpgInstalled { if len(gpgSecretKeyRingFiles) == 0 && len(privKeys) == 0 && descs != nil { // Get pgp private keys from keyring only if no private key was passed - err = getGPGPrivateKeys(context, gpgSecretKeyRingFiles, descs, true, dcparameters) + gpgPrivKeys, gpgPrivKeyPasswords, err := getGPGPrivateKeys(context, gpgSecretKeyRingFiles, descs, true) if err != nil { - return nil, err + return encconfig.CryptoConfig{}, err } - } else { - if len(gpgSecretKeyRingFiles) == 0 { - dcparameters["gpg-client"] = [][]byte{[]byte("1")} - dcparameters["gpg-client-version"] = [][]byte{[]byte(context.String("gpg-version"))} - dcparameters["gpg-client-homedir"] = [][]byte{[]byte(context.String("gpg-homedir"))} - } else { - dcparameters["gpg-privatekeys"] = gpgSecretKeyRingFiles - dcparameters["gpg-privatekeys-passwords"] = gpgSecretKeyPasswords + + gpgCc, err := encconfig.DecryptWithGpgPrivKeys(gpgPrivKeys, gpgPrivKeyPasswords) + if err != nil { + return encconfig.CryptoConfig{}, err } + ccs = append(ccs, gpgCc) + + } else if len(gpgSecretKeyRingFiles) > 0 { + gpgCc, err := encconfig.DecryptWithGpgPrivKeys(gpgSecretKeyRingFiles, gpgSecretKeyPasswords) + if err != nil { + return encconfig.CryptoConfig{}, err + } + ccs = append(ccs, gpgCc) + } } - dcparameters["privkeys"] = privKeys - dcparameters["privkeys-passwords"] = privKeysPasswords - dcparameters["x509s"] = x509s - return dcparameters, nil + x509sCc, err := encconfig.DecryptWithX509s(x509s) + if err != nil { + return encconfig.CryptoConfig{}, err + } + ccs = append(ccs, x509sCc) + + privKeysCc, err := encconfig.DecryptWithPrivKeys(privKeys, privKeysPasswords) + if err != nil { + return encconfig.CryptoConfig{}, err + } + ccs = append(ccs, privKeysCc) + + return encconfig.CombineCryptoConfigs(ccs), nil } // parsePlatformArray parses an array of specifiers and converts them into an array of specs.Platform diff --git a/cmd/ctr/commands/images/decrypt.go b/cmd/ctr/commands/images/decrypt.go index f0c2b203b..df20bd8bc 100644 --- a/cmd/ctr/commands/images/decrypt.go +++ b/cmd/ctr/commands/images/decrypt.go @@ -21,7 +21,6 @@ import ( "github.com/containerd/containerd/cmd/ctr/commands" imgenc "github.com/containerd/containerd/images/encryption" - encconfig "github.com/containerd/containerd/pkg/encryption/config" "github.com/pkg/errors" "github.com/urfave/cli" ) @@ -83,14 +82,12 @@ var decryptCommand = cli.Command{ return nil } - dcparameters, err := CreateDcParameters(context, descs) + cc, err := CreateDecryptCryptoConfig(context, descs) if err != nil { return err } - cc := encconfig.InitDecryption(dcparameters) - - _, err = decryptImage(client, ctx, local, newName, cc, layers32, context.StringSlice("platform")) + _, err = decryptImage(client, ctx, local, newName, &cc, layers32, context.StringSlice("platform")) return err }, diff --git a/cmd/ctr/commands/images/encrypt.go b/cmd/ctr/commands/images/encrypt.go index ac6b7abb2..eadc64839 100644 --- a/cmd/ctr/commands/images/encrypt.go +++ b/cmd/ctr/commands/images/encrypt.go @@ -77,45 +77,21 @@ var encryptCommand = cli.Command{ layers32 := commands.IntToInt32Array(context.IntSlice("layer")) - gpgSecretKeyRingFiles, _, privKeys, privKeysPasswords, err := processPrivateKeyFiles(context.StringSlice("key")) - if err != nil { - return err - } - gpgRecipients, pubKeys, x509s, err := processRecipientKeys(recipients) if err != nil { return err } - _, _, decX509s, err := processRecipientKeys(context.StringSlice("dec-recipient")) - if err != nil { - return err - } - - dcparameters := make(map[string][][]byte) - parameters := make(map[string][][]byte) - - parameters["pubkeys"] = pubKeys - parameters["x509s"] = x509s - _, descs, err := getImageLayerInfos(client, ctx, local, layers32, context.StringSlice("platform")) if err != nil { return err } + encryptCcs := []encconfig.CryptoConfig{} _, err = createGPGClient(context) gpgInstalled := err == nil - if len(privKeys) == 0 && gpgInstalled { - // Get pgp private keys from keyring only if no private key was passed - err = getGPGPrivateKeys(context, gpgSecretKeyRingFiles, descs, true, dcparameters) - if err != nil { - return err - } - } if len(gpgRecipients) > 0 && gpgInstalled { - parameters["gpg-recipients"] = gpgRecipients - gpgClient, err := createGPGClient(context) if err != nil { return err @@ -126,16 +102,38 @@ var encryptCommand = cli.Command{ return err } - parameters["gpg-pubkeyringfile"] = [][]byte{gpgPubRingFile} + gpgCc, err := encconfig.EncryptWithGpg(gpgRecipients, gpgPubRingFile) + if err != nil { + return err + } + encryptCcs = append(encryptCcs, gpgCc) + } - dcparameters["privkeys"] = privKeys - dcparameters["privkeys-passwords"] = privKeysPasswords - dcparameters["x509s"] = decX509s + // Create Encryption Crypto Config + pkcs7Cc, err := encconfig.EncryptWithPkcs7(x509s) + if err != nil { + return err + } + encryptCcs = append(encryptCcs, pkcs7Cc) - cc := encconfig.InitEncryption(parameters, dcparameters) + jweCc, err := encconfig.EncryptWithJwe(pubKeys) + if err != nil { + return err + } + encryptCcs = append(encryptCcs, jweCc) - _, err = encryptImage(client, ctx, local, newName, cc, layers32, context.StringSlice("platform")) + cc := encconfig.CombineCryptoConfigs(encryptCcs) + + // Create Decryption CryptoConfig for use in adding recipients to + // existing image if decryptable. + decryptCc, err := CreateDecryptCryptoConfig(context, descs) + if err != nil { + return err + } + cc.EncryptConfig.AttachDecryptConfig(decryptCc.DecryptConfig) + + _, err = encryptImage(client, ctx, local, newName, &cc, layers32, context.StringSlice("platform")) return err }, diff --git a/image_enc_test.go b/image_enc_test.go index d0cad1b96..bbadd3b3a 100644 --- a/image_enc_test.go +++ b/image_enc_test.go @@ -122,17 +122,13 @@ func TestImageEncryption(t *testing.T) { return false } - dcparameters := make(map[string][][]byte) - parameters := make(map[string][][]byte) - - parameters["pubkeys"] = [][]byte{publicKey} - dcparameters["privkeys"] = [][]byte{privateKey} - dcparameters["privkeys-passwords"] = [][]byte{{}} - - cc := encconfig.InitEncryption(parameters, dcparameters) + cc, err := encconfig.EncryptWithJwe([][]byte{publicKey}) + if err != nil { + t.Fatal(err) + } // Perform encryption of image - encSpec, modified, err := imgenc.EncryptImage(ctx, client.ContentStore(), image.Target, cc, lf) + encSpec, modified, err := imgenc.EncryptImage(ctx, client.ContentStore(), image.Target, &cc, lf) if err != nil { t.Fatal(err) } @@ -149,7 +145,10 @@ func TestImageEncryption(t *testing.T) { t.Fatalf("Unable to create image: %v", err) } - cc = encconfig.InitDecryption(dcparameters) + cc, err = encconfig.DecryptWithPrivKeys([][]byte{privateKey}, [][]byte{{}}) + if err != nil { + t.Fatal(err) + } // Clean up function cancels lease before deleting the image so the images are // properly deleted @@ -164,7 +163,7 @@ func TestImageEncryption(t *testing.T) { return true } - decSpec, modified, err := imgenc.DecryptImage(ctx, client.ContentStore(), encSpec, cc, lf) + decSpec, modified, err := imgenc.DecryptImage(ctx, client.ContentStore(), encSpec, &cc, lf) if err != nil { t.Fatal(err) } diff --git a/images/encryption/encryption.go b/images/encryption/encryption.go index 69fbf4941..d356c20cf 100644 --- a/images/encryption/encryption.go +++ b/images/encryption/encryption.go @@ -421,7 +421,7 @@ func CheckAuthorization(ctx context.Context, cs content.Store, desc ocispec.Desc return true } - _, _, err := cryptImage(ctx, cs, desc, cc, lf, cryptoOpUnwrapOnly) + _, _, err := cryptImage(ctx, cs, desc, &cc, lf, cryptoOpUnwrapOnly) if err != nil { return errors.Wrapf(err, "you are not authorized to use this image") } diff --git a/pkg/encryption/config/config.go b/pkg/encryption/config/config.go index 487ea8e5b..3c8a6a992 100644 --- a/pkg/encryption/config/config.go +++ b/pkg/encryption/config/config.go @@ -40,8 +40,8 @@ type CryptoConfig struct { } // InitDecryption initialized a CryptoConfig object with parameters used for decryption -func InitDecryption(dcparameters map[string][][]byte) *CryptoConfig { - return &CryptoConfig{ +func InitDecryption(dcparameters map[string][][]byte) CryptoConfig { + return CryptoConfig{ DecryptConfig: &DecryptConfig{ Parameters: dcparameters, }, @@ -51,8 +51,8 @@ func InitDecryption(dcparameters map[string][][]byte) *CryptoConfig { // InitEncryption initializes a CryptoConfig object with parameters used for encryption // It also takes dcparameters that may be needed for decryption when adding a recipient // to an already encrypted image -func InitEncryption(parameters, dcparameters map[string][][]byte) *CryptoConfig { - return &CryptoConfig{ +func InitEncryption(parameters, dcparameters map[string][][]byte) CryptoConfig { + return CryptoConfig{ EncryptConfig: &EncryptConfig{ Parameters: parameters, DecryptConfig: DecryptConfig{ @@ -94,6 +94,15 @@ func CombineCryptoConfigs(ccs []CryptoConfig) CryptoConfig { } +// AttachDecryptConfig adds DecryptConfig to the field of EncryptConfig so that +// the decryption parameters can be used to add recipients to an existing image +// if the user is able to decrypt it. +func (ec *EncryptConfig) AttachDecryptConfig(dc *DecryptConfig) { + if dc != nil { + addToMap(ec.DecryptConfig.Parameters, dc.Parameters) + } +} + func addToMap(orig map[string][][]byte, add map[string][][]byte) { for k, v := range add { if ov, ok := orig[k]; ok { diff --git a/pkg/encryption/config/constructors.go b/pkg/encryption/config/constructors.go index 0d36d11da..d1b0335a0 100644 --- a/pkg/encryption/config/constructors.go +++ b/pkg/encryption/config/constructors.go @@ -16,30 +16,13 @@ package config -// NewJweCryptoConfig returns a CryptoConfig that contains the required configuration for using -// the jwe keyunwrap interface -func NewJweCryptoConfig(pubKey *[]byte, privKey *[]byte, privKeyPassword *string) CryptoConfig { - pubKeys := [][]byte{} - privKeys := [][]byte{} - privKeysPasswords := [][]byte{} - - if pubKey != nil { - pubKeys = append(pubKeys, *pubKey) - } - if privKey != nil { - privKeys = append(privKeys, *privKey) - } - if privKeyPassword != nil { - privKeysPasswords = append(privKeysPasswords, []byte(*privKeyPassword)) - } - - dc := DecryptConfig{ - Parameters: map[string][][]byte{ - "privkeys": privKeys, - "privkeys-passwords": privKeysPasswords, - }, - } +import ( + "github.com/pkg/errors" +) +// EncryptWithJwe returns a CryptoConfig to encrypt with jwe public keys +func EncryptWithJwe(pubKeys [][]byte) (CryptoConfig, error) { + dc := DecryptConfig{} ep := map[string][][]byte{ "pubkeys": pubKeys, } @@ -50,32 +33,12 @@ func NewJweCryptoConfig(pubKey *[]byte, privKey *[]byte, privKeyPassword *string DecryptConfig: dc, }, DecryptConfig: &dc, - } + }, nil } -// NewPkcs7CryptoConfig returns a CryptoConfig that contains the required configuration for using -// the pkcs7 keyunwrap interface -func NewPkcs7CryptoConfig(x509 *[]byte, privKey *[]byte, privKeyPassword *string) CryptoConfig { - x509s := [][]byte{} - privKeys := [][]byte{} - privKeysPasswords := [][]byte{} - - if x509 != nil { - x509s = append(x509s, *x509) - } - if privKey != nil { - privKeys = append(privKeys, *privKey) - } - if privKeyPassword != nil { - privKeysPasswords = append(privKeysPasswords, []byte(*privKeyPassword)) - } - - dc := DecryptConfig{ - Parameters: map[string][][]byte{ - "privkeys": privKeys, - "privkeys-passwords": privKeysPasswords, - }, - } +// EncryptWithPkcs7 returns a CryptoConfig to encrypt with pkcs7 x509 certs +func EncryptWithPkcs7(x509s [][]byte) (CryptoConfig, error) { + dc := DecryptConfig{} ep := map[string][][]byte{ "x509s": x509s, @@ -87,5 +50,85 @@ func NewPkcs7CryptoConfig(x509 *[]byte, privKey *[]byte, privKeyPassword *string DecryptConfig: dc, }, DecryptConfig: &dc, - } + }, nil +} + +// EncryptWithGpg returns a CryptoConfig to encrypt with configured gpg parameters +func EncryptWithGpg(gpgRecipients [][]byte, gpgPubRingFile []byte) (CryptoConfig, error) { + dc := DecryptConfig{} + ep := map[string][][]byte{ + "gpg-recipients": gpgRecipients, + "gpg-pubkeyringfile": {gpgPubRingFile}, + } + + return CryptoConfig{ + EncryptConfig: &EncryptConfig{ + Parameters: ep, + DecryptConfig: dc, + }, + DecryptConfig: &dc, + }, nil +} + +// DecryptWithPrivKeys returns a CryptoConfig to decrypt with configured private keys +func DecryptWithPrivKeys(privKeys [][]byte, privKeysPasswords [][]byte) (CryptoConfig, error) { + if len(privKeys) != len(privKeysPasswords) { + return CryptoConfig{}, errors.New("Length of privKeys should match length of privKeysPasswords") + } + + dc := DecryptConfig{ + Parameters: map[string][][]byte{ + "privkeys": privKeys, + "privkeys-passwords": privKeysPasswords, + }, + } + + ep := map[string][][]byte{} + + return CryptoConfig{ + EncryptConfig: &EncryptConfig{ + Parameters: ep, + DecryptConfig: dc, + }, + DecryptConfig: &dc, + }, nil +} + +// DecryptWithX509s returns a CryptoConfig to decrypt with configured x509 certs +func DecryptWithX509s(x509s [][]byte) (CryptoConfig, error) { + dc := DecryptConfig{ + Parameters: map[string][][]byte{ + "x509s": x509s, + }, + } + + ep := map[string][][]byte{} + + return CryptoConfig{ + EncryptConfig: &EncryptConfig{ + Parameters: ep, + DecryptConfig: dc, + }, + DecryptConfig: &dc, + }, nil +} + +// DecryptWithGpgPrivKeys returns a CryptoConfig to decrypt with configured gpg private keys +func DecryptWithGpgPrivKeys(gpgPrivKeys, gpgPrivKeysPwds [][]byte) (CryptoConfig, error) { + dc := DecryptConfig{ + Parameters: map[string][][]byte{ + "gpg-privatekeys": gpgPrivKeys, + "gpg-privatekeys-passwords": gpgPrivKeysPwds, + }, + } + + ep := map[string][][]byte{} + + return CryptoConfig{ + EncryptConfig: &EncryptConfig{ + Parameters: ep, + DecryptConfig: dc, + }, + DecryptConfig: &dc, + }, nil } diff --git a/pkg/encryption/gpg.go b/pkg/encryption/gpg.go index 068481c4a..b525d35bc 100644 --- a/pkg/encryption/gpg.go +++ b/pkg/encryption/gpg.go @@ -322,7 +322,7 @@ func uint64ToStringArray(format string, in []uint64) []string { // in the GPGVault or on this system and prompts for the passwords for those // that are available. If we do not find a private key on the system for // getting to the symmetric key of a layer then an error is generated. -func GPGGetPrivateKey(descs []ocispec.Descriptor, gpgClient GPGClient, gpgVault GPGVault, mustFindKey bool, dcparameters map[string][][]byte) error { +func GPGGetPrivateKey(descs []ocispec.Descriptor, gpgClient GPGClient, gpgVault GPGVault, mustFindKey bool) (gpgPrivKeys [][]byte, gpgPrivKeysPwds [][]byte, err error) { // PrivateKeyData describes a private key type PrivateKeyData struct { KeyData []byte @@ -338,11 +338,11 @@ func GPGGetPrivateKey(descs []ocispec.Descriptor, gpgClient GPGClient, gpgVault } keywrapper := GetKeyWrapper(scheme) if keywrapper == nil { - return errors.Errorf("could not get KeyWrapper for %s\n", scheme) + return nil, nil, errors.Errorf("could not get KeyWrapper for %s\n", scheme) } keyIds, err := keywrapper.GetKeyIdsFromPacket(b64pgpPackets) if err != nil { - return err + return nil, nil, err } found := false @@ -376,11 +376,11 @@ func GPGGetPrivateKey(descs []ocispec.Descriptor, gpgClient GPGClient, gpgVault password, err := terminal.ReadPassword(int(os.Stdin.Fd())) fmt.Printf("\n") if err != nil { - return err + return nil, nil, err } keydata, err := gpgClient.GetGPGPrivateKey(keyid, string(password)) if err != nil { - return err + return nil, nil, err } pkd = PrivateKeyData{ KeyData: keydata, @@ -391,63 +391,21 @@ func GPGGetPrivateKey(descs []ocispec.Descriptor, gpgClient GPGClient, gpgVault } break } else { - return errors.Wrapf(errdefs.ErrInvalidArgument, "no GPGVault or GPGClient passed.") + return nil, nil, errors.Wrapf(errdefs.ErrInvalidArgument, "no GPGVault or GPGClient passed.") } } if !found && len(b64pgpPackets) > 0 && mustFindKey { ids := uint64ToStringArray("0x%x", keyIds) - return errors.Wrapf(errdefs.ErrNotFound, "missing key for decryption of layer %x of %s. Need one of the following keys: %s", desc.Digest, desc.Platform, strings.Join(ids, ", ")) + return nil, nil, errors.Wrapf(errdefs.ErrNotFound, "missing key for decryption of layer %x of %s. Need one of the following keys: %s", desc.Digest, desc.Platform, strings.Join(ids, ", ")) } } } - var ( - privKeys [][]byte - privKeysPwd [][]byte - ) for _, pkd := range keyIDPasswordMap { - privKeys = append(privKeys, pkd.KeyData) - privKeysPwd = append(privKeysPwd, pkd.KeyDataPassword) + gpgPrivKeys = append(gpgPrivKeys, pkd.KeyData) + gpgPrivKeysPwds = append(gpgPrivKeysPwds, pkd.KeyDataPassword) } - dcparameters["gpg-privatekeys"] = privKeys - dcparameters["gpg-privatekeys-passwords"] = privKeysPwd - return nil -} - -// GPGSetupPrivateKeys uses the gpg specific parameters in the dcparameters map -// to get the private keys needed for decryption the give layers -func GPGSetupPrivateKeys(dcparameters map[string][][]byte, descs []ocispec.Descriptor) error { - /* we have to find a GPG key until we also get other private keys passed */ - var ( - gpgVault GPGVault - gpgClient GPGClient - gpgVersion string - gpgHomeDir string - err error - ) - gpgPrivateKeys := dcparameters["gpg-privatekeys"] - if len(gpgPrivateKeys) > 0 { - gpgVault = NewGPGVault() - gpgVault.AddSecretKeyRingDataArray(gpgPrivateKeys) - } - - haveGPGClient := dcparameters["gpg-client"] - if len(haveGPGClient) > 0 { - item := dcparameters["gpg-client-version"] - if len(item) == 1 { - gpgVersion = string(item[0]) - } - item = dcparameters["gpg-client-homedir"] - if len(item) == 1 { - gpgHomeDir = string(item[0]) - } - gpgClient, err = NewGPGClient(gpgVersion, gpgHomeDir) - if err != nil { - return err - } - } - - return GPGGetPrivateKey(descs, gpgClient, gpgVault, false, dcparameters) + return gpgPrivKeys, gpgPrivKeysPwds, nil }