debian-forge-composer/vendor/github.com/containers/ocicrypt/config/constructors.go
Ondřej Budai 29f66a251f go.mod: update github.com/containers/image/v5
Version 5.22 introduced a new option to /etc/containers/policy.json called
keyPaths, see

https://github.com/containers/image/pull/1609

EL9 immediately took advantage of this new feature and started using it, see
04645c4a84

This quickly became an issue in our code: The go library (containers/image)
parses the configuration file very strictly and refuses to create a client
when policy.json with an unknown key is present on the filesystem. As we
used 5.21.1 that doesn't know the new key, our unit tests started to
failing when containers-common was present.

Reproducer:
podman run --pull=always --rm -it centos:stream9
dnf install -y dnf-plugins-core
dnf config-manager --set-enabled crb
dnf install -y gpgme-devel libassuan-devel krb5-devel golang git-core
git clone https://github.com/osbuild/osbuild-composer
cd osbuild-composer

# install the new containers-common and run the test
dnf install -y https://kojihub.stream.centos.org/kojifiles/packages/containers-common/1/44.el9/x86_64/containers-common-1-44.el9.x86_64.rpm
go test -count 1 ./...

# this returns:
--- FAIL: TestClientResolve (0.00s)
    client_test.go:31:
        	Error Trace:	client_test.go:31
        	Error:      	Received unexpected error:
        	            	Unknown key "keyPaths"
        	            	invalid policy in "/etc/containers/policy.json"
        	            	github.com/containers/image/v5/signature.NewPolicyFromFile
        	            		/osbuild-composer/vendor/github.com/containers/image/v5/signature/policy_config.go:88
        	            	github.com/osbuild/osbuild-composer/internal/container.NewClient
        	            		/osbuild-composer/internal/container/client.go:123
        	            	github.com/osbuild/osbuild-composer/internal/container_test.TestClientResolve
        	            		/osbuild-composer/internal/container/client_test.go:29
        	            	testing.tRunner
        	            		/usr/lib/golang/src/testing/testing.go:1439
        	            	runtime.goexit
        	            		/usr/lib/golang/src/runtime/asm_amd64.s:1571
        	Test:       	TestClientResolve
    client_test.go:32:
        	Error Trace:	client_test.go:32
        	Error:      	Expected value not to be nil.
        	Test:       	TestClientResolve

 When run with an older containers-common, it succeeds:
 dnf install -y https://kojihub.stream.centos.org/kojifiles/packages/containers-common/1/40.el9/x86_64/containers-common-1-40.el9.x86_64.rpm
 go test -count 1 ./...
 PASS

To sum it up, I had to upgrade github.com/containers/image/v5 to v5.22.0.
Unfortunately, this wasn't so simple, see

go get github.com/containers/image/v5@latest
go: github.com/containers/image/v5@v5.22.0 requires
	github.com/letsencrypt/boulder@v0.0.0-20220331220046-b23ab962616e requires
	github.com/honeycombio/beeline-go@v1.1.1 requires
	github.com/gobuffalo/pop/v5@v5.3.1 requires
	github.com/mattn/go-sqlite3@v2.0.3+incompatible: reading github.com/mattn/go-sqlite3/go.mod at revision v2.0.3: unknown revision v2.0.3

It turns out that github.com/mattn/go-sqlite3@v2.0.3+incompatible has been
recently retracted https://github.com/mattn/go-sqlite3/pull/998 and this
broke a ton of packages depending on it. I was able to fix it by adding

exclude github.com/mattn/go-sqlite3 v2.0.3+incompatible

to our go.mod, see
https://github.com/mattn/go-sqlite3/issues/975#issuecomment-955661657

After adding it,
go get github.com/containers/image/v5@latest
succeeded and tools/prepare-source.sh took care of the rest.

Signed-off-by: Ondřej Budai <ondrej@budai.cz>
2022-08-29 10:25:38 +02:00

245 lines
6.3 KiB
Go

/*
Copyright The ocicrypt 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
import (
"github.com/containers/ocicrypt/crypto/pkcs11"
"strings"
"github.com/pkg/errors"
"gopkg.in/yaml.v3"
)
// EncryptWithJwe returns a CryptoConfig to encrypt with jwe public keys
func EncryptWithJwe(pubKeys [][]byte) (CryptoConfig, error) {
dc := DecryptConfig{}
ep := map[string][][]byte{
"pubkeys": pubKeys,
}
return CryptoConfig{
EncryptConfig: &EncryptConfig{
Parameters: ep,
DecryptConfig: dc,
},
DecryptConfig: &dc,
}, nil
}
// EncryptWithPkcs7 returns a CryptoConfig to encrypt with pkcs7 x509 certs
func EncryptWithPkcs7(x509s [][]byte) (CryptoConfig, error) {
dc := DecryptConfig{}
ep := map[string][][]byte{
"x509s": x509s,
}
return CryptoConfig{
EncryptConfig: &EncryptConfig{
Parameters: ep,
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
}
// EncryptWithPkcs11 returns a CryptoConfig to encrypt with configured pkcs11 parameters
func EncryptWithPkcs11(pkcs11Config *pkcs11.Pkcs11Config, pkcs11Pubkeys, pkcs11Yamls [][]byte) (CryptoConfig, error) {
dc := DecryptConfig{}
ep := map[string][][]byte{}
if len(pkcs11Yamls) > 0 {
if pkcs11Config == nil {
return CryptoConfig{}, errors.New("pkcs11Config must not be nil")
}
p11confYaml, err := yaml.Marshal(pkcs11Config)
if err != nil {
return CryptoConfig{}, errors.Wrapf(err, "Could not marshal Pkcs11Config to Yaml")
}
dc = DecryptConfig{
Parameters: map[string][][]byte{
"pkcs11-config": {p11confYaml},
},
}
ep["pkcs11-yamls"] = pkcs11Yamls
}
if len(pkcs11Pubkeys) > 0 {
ep["pkcs11-pubkeys"] = pkcs11Pubkeys
}
return CryptoConfig{
EncryptConfig: &EncryptConfig{
Parameters: ep,
DecryptConfig: dc,
},
DecryptConfig: &dc,
}, nil
}
// EncryptWithKeyProvider returns a CryptoConfig to encrypt with configured keyprovider parameters
func EncryptWithKeyProvider(keyProviders [][]byte) (CryptoConfig, error) {
dc := DecryptConfig{}
ep := make(map[string][][]byte)
for _, keyProvider := range keyProviders {
keyProvidersStr := string(keyProvider)
idx := strings.Index(keyProvidersStr, ":")
if idx > 0 {
ep[keyProvidersStr[:idx]] = append(ep[keyProvidersStr[:idx]], []byte(keyProvidersStr[idx+1:]))
} else {
ep[keyProvidersStr] = append(ep[keyProvidersStr], []byte("Enabled"))
}
}
return CryptoConfig{
EncryptConfig: &EncryptConfig{
Parameters: ep,
DecryptConfig: dc,
},
DecryptConfig: &dc,
}, nil
}
// DecryptWithKeyProvider returns a CryptoConfig to decrypt with configured keyprovider parameters
func DecryptWithKeyProvider(keyProviders [][]byte) (CryptoConfig, error) {
dp := make(map[string][][]byte)
ep := map[string][][]byte{}
for _, keyProvider := range keyProviders {
keyProvidersStr := string(keyProvider)
idx := strings.Index(keyProvidersStr, ":")
if idx > 0 {
dp[keyProvidersStr[:idx]] = append(dp[keyProvidersStr[:idx]], []byte(keyProvidersStr[idx+1:]))
} else {
dp[keyProvidersStr] = append(dp[keyProvidersStr], []byte("Enabled"))
}
}
dc := DecryptConfig{
Parameters: dp,
}
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
}
// DecryptWithPkcs11Yaml returns a CryptoConfig to decrypt with pkcs11 YAML formatted key files
func DecryptWithPkcs11Yaml(pkcs11Config *pkcs11.Pkcs11Config, pkcs11Yamls [][]byte) (CryptoConfig, error) {
p11confYaml, err := yaml.Marshal(pkcs11Config)
if err != nil {
return CryptoConfig{}, errors.Wrapf(err, "Could not marshal Pkcs11Config to Yaml")
}
dc := DecryptConfig{
Parameters: map[string][][]byte{
"pkcs11-yamls": pkcs11Yamls,
"pkcs11-config": {p11confYaml},
},
}
ep := map[string][][]byte{}
return CryptoConfig{
EncryptConfig: &EncryptConfig{
Parameters: ep,
DecryptConfig: dc,
},
DecryptConfig: &dc,
}, nil
}