summaryrefslogtreecommitdiff
path: root/vendor/github.com/containers
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/containers')
-rw-r--r--vendor/github.com/containers/ocicrypt/.travis.yml10
-rw-r--r--vendor/github.com/containers/ocicrypt/Makefile7
-rw-r--r--vendor/github.com/containers/ocicrypt/README.md11
-rw-r--r--vendor/github.com/containers/ocicrypt/config/constructors.go111
-rw-r--r--vendor/github.com/containers/ocicrypt/config/keyprovider-config/config.go81
-rw-r--r--vendor/github.com/containers/ocicrypt/config/pkcs11config/config.go124
-rw-r--r--vendor/github.com/containers/ocicrypt/crypto/pkcs11/common.go134
-rw-r--r--vendor/github.com/containers/ocicrypt/crypto/pkcs11/pkcs11helpers.go487
-rw-r--r--vendor/github.com/containers/ocicrypt/crypto/pkcs11/pkcs11helpers_nocgo.go31
-rw-r--r--vendor/github.com/containers/ocicrypt/crypto/pkcs11/utils.go114
-rw-r--r--vendor/github.com/containers/ocicrypt/encryption.go28
-rw-r--r--vendor/github.com/containers/ocicrypt/go.mod20
-rw-r--r--vendor/github.com/containers/ocicrypt/go.sum105
-rw-r--r--vendor/github.com/containers/ocicrypt/gpg.go8
-rw-r--r--vendor/github.com/containers/ocicrypt/helpers/parse_helpers.go166
-rw-r--r--vendor/github.com/containers/ocicrypt/keywrap/keyprovider/keyprovider.go242
-rw-r--r--vendor/github.com/containers/ocicrypt/keywrap/pkcs11/keywrapper_pkcs11.go147
-rw-r--r--vendor/github.com/containers/ocicrypt/utils/ioutils.go25
-rw-r--r--vendor/github.com/containers/ocicrypt/utils/keyprovider/keyprovider.pb.go243
-rw-r--r--vendor/github.com/containers/ocicrypt/utils/keyprovider/keyprovider.proto17
-rw-r--r--vendor/github.com/containers/ocicrypt/utils/utils.go30
21 files changed, 2065 insertions, 76 deletions
diff --git a/vendor/github.com/containers/ocicrypt/.travis.yml b/vendor/github.com/containers/ocicrypt/.travis.yml
index a5fc8651c..7031d938a 100644
--- a/vendor/github.com/containers/ocicrypt/.travis.yml
+++ b/vendor/github.com/containers/ocicrypt/.travis.yml
@@ -1,4 +1,4 @@
-dist: xenial
+dist: bionic
language: go
os:
@@ -11,10 +11,16 @@ matrix:
include:
- os: linux
+addons:
+ apt:
+ packages:
+ - gnutls-bin
+ - softhsm2
+
go_import_path: github.com/containers/ocicrypt
install:
- - curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.19.1
+ - curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.30.0
script:
- make
diff --git a/vendor/github.com/containers/ocicrypt/Makefile b/vendor/github.com/containers/ocicrypt/Makefile
index 49fa80d74..dc9d98537 100644
--- a/vendor/github.com/containers/ocicrypt/Makefile
+++ b/vendor/github.com/containers/ocicrypt/Makefile
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-.PHONY: check build decoder
+.PHONY: check build decoder generate-protobuf
all: build
@@ -28,4 +28,7 @@ vendor:
go mod tidy
test:
- go test ./...
+ go test ./... -test.v
+
+generate-protobuf:
+ protoc -I utils/keyprovider/ utils/keyprovider/keyprovider.proto --go_out=plugins=grpc:utils/keyprovider
diff --git a/vendor/github.com/containers/ocicrypt/README.md b/vendor/github.com/containers/ocicrypt/README.md
index 9f64bddcc..84cab7a40 100644
--- a/vendor/github.com/containers/ocicrypt/README.md
+++ b/vendor/github.com/containers/ocicrypt/README.md
@@ -11,7 +11,7 @@ Consumers of OCIcrypt:
## Usage
-There are various levels of usage for this library. The main consumers of these would be runtime/buil tools, and a more specific use would be in the ability to extend cryptographic function.
+There are various levels of usage for this library. The main consumers of these would be runtime/build tools, and a more specific use would be in the ability to extend cryptographic function.
### Runtime/Build tool usage
@@ -23,12 +23,12 @@ func EncryptLayer(ec *config.EncryptConfig, encOrPlainLayerReader io.Reader, des
func DecryptLayer(dc *config.DecryptConfig, encLayerReader io.Reader, desc ocispec.Descriptor, unwrapOnly bool) (io.Reader, digest.Digest, error)
```
-The settings/parameters to these functions can be specified via creation of an encryption config with the `github.com/containers/ocicrypt/config` package. We note that because setting of annotations and other fields of the layer descriptor is done through various means in different runtimes/build tools, it is the resposibility of the caller to still ensure that the layer descriptor follows the OCI specification (i.e. encoding, setting annotations, etc.).
+The settings/parameters to these functions can be specified via creation of an encryption config with the `github.com/containers/ocicrypt/config` package. We note that because setting of annotations and other fields of the layer descriptor is done through various means in different runtimes/build tools, it is the responsibility of the caller to still ensure that the layer descriptor follows the OCI specification (i.e. encoding, setting annotations, etc.).
### Crypto Agility and Extensibility
-The implementation for both symmetric and assymetric encryption used in this library are behind 2 main interfaces, which users can extend if need be. These are in the following packages:
+The implementation for both symmetric and asymmetric encryption used in this library are behind 2 main interfaces, which users can extend if need be. These are in the following packages:
- github.com/containers/ocicrypt/blockcipher - LayerBlockCipher interface for block ciphers
- github.com/containers/ocicrypt/keywrap - KeyWrapper interface for key wrapping
@@ -37,3 +37,8 @@ We note that adding interfaces here is risky outside the OCI spec is not recomme
## Security Issues
We consider security issues related to this library critical. Please report and security related issues by emailing maintainers in the [MAINTAINERS](MAINTAINERS) file.
+
+
+## Ocicrypt Pkcs11 Support
+
+Ocicrypt Pkcs11 support is currently experiemental. For more details, please refer to the [this document](docs/pkcs11.md).
diff --git a/vendor/github.com/containers/ocicrypt/config/constructors.go b/vendor/github.com/containers/ocicrypt/config/constructors.go
index 44adcdb35..a789d052d 100644
--- a/vendor/github.com/containers/ocicrypt/config/constructors.go
+++ b/vendor/github.com/containers/ocicrypt/config/constructors.go
@@ -17,7 +17,11 @@
package config
import (
+ "github.com/containers/ocicrypt/crypto/pkcs11"
+ "strings"
+
"github.com/pkg/errors"
+ "gopkg.in/yaml.v2"
)
// EncryptWithJwe returns a CryptoConfig to encrypt with jwe public keys
@@ -70,6 +74,88 @@ func EncryptWithGpg(gpgRecipients [][]byte, gpgPubRingFile []byte) (CryptoConfig
}, 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) {
@@ -132,3 +218,28 @@ func DecryptWithGpgPrivKeys(gpgPrivKeys, gpgPrivKeysPwds [][]byte) (CryptoConfig
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
+}
diff --git a/vendor/github.com/containers/ocicrypt/config/keyprovider-config/config.go b/vendor/github.com/containers/ocicrypt/config/keyprovider-config/config.go
new file mode 100644
index 000000000..b454b3716
--- /dev/null
+++ b/vendor/github.com/containers/ocicrypt/config/keyprovider-config/config.go
@@ -0,0 +1,81 @@
+/*
+ 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 (
+ "encoding/json"
+ "github.com/pkg/errors"
+ "io/ioutil"
+ "os"
+)
+
+// Command describes the structure of command, it consist of path and args, where path defines the location of
+// binary executable and args are passed on to the binary executable
+type Command struct {
+ Path string `json:"path,omitempty"`
+ Args []string `json:"args,omitempty"`
+}
+
+// KeyProviderAttrs describes the structure of key provider, it defines the way of invocation to key provider
+type KeyProviderAttrs struct {
+ Command *Command `json:"cmd,omitempty"`
+ Grpc string `json:"grpc,omitempty"`
+}
+
+// OcicryptConfig represents the format of an ocicrypt_provider.conf config file
+type OcicryptConfig struct {
+ KeyProviderConfig map[string]KeyProviderAttrs `json:"key-providers"`
+}
+
+const ENVVARNAME = "OCICRYPT_KEYPROVIDER_CONFIG"
+
+// parseConfigFile parses a configuration file; it is not an error if the configuration file does
+// not exist, so no error is returned.
+func parseConfigFile(filename string) (*OcicryptConfig, error) {
+ // a non-existent config file is not an error
+ _, err := os.Stat(filename)
+ if os.IsNotExist(err) {
+ return nil, nil
+ }
+
+ data, err := ioutil.ReadFile(filename)
+ if err != nil {
+ return nil, err
+ }
+
+ ic := &OcicryptConfig{}
+ err = json.Unmarshal(data, ic)
+ return ic, err
+}
+
+// getConfiguration tries to read the configuration file at the following locations
+// ${OCICRYPT_KEYPROVIDER_CONFIG} == "/etc/ocicrypt_keyprovider.yaml"
+// If no configuration file could be found or read a null pointer is returned
+func GetConfiguration() (*OcicryptConfig, error) {
+ var ic *OcicryptConfig
+ var err error
+ filename := os.Getenv(ENVVARNAME)
+ if len(filename) > 0 {
+ ic, err = parseConfigFile(filename)
+ if err != nil {
+ return nil, errors.Wrap(err, "Error while parsing keyprovider config file")
+ }
+ } else {
+ return nil, nil
+ }
+ return ic, nil
+}
diff --git a/vendor/github.com/containers/ocicrypt/config/pkcs11config/config.go b/vendor/github.com/containers/ocicrypt/config/pkcs11config/config.go
new file mode 100644
index 000000000..76be34138
--- /dev/null
+++ b/vendor/github.com/containers/ocicrypt/config/pkcs11config/config.go
@@ -0,0 +1,124 @@
+/*
+ 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 pkcs11config
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path"
+
+ "github.com/containers/ocicrypt/crypto/pkcs11"
+ "github.com/pkg/errors"
+ "gopkg.in/yaml.v2"
+)
+
+// OcicryptConfig represents the format of an imgcrypt.conf config file
+type OcicryptConfig struct {
+ Pkcs11Config pkcs11.Pkcs11Config `yaml:"pkcs11"`
+}
+
+const CONFIGFILE = "ocicrypt.conf"
+const ENVVARNAME = "OCICRYPT_CONFIG"
+
+// parseConfigFile parses a configuration file; it is not an error if the configuration file does
+// not exist, so no error is returned.
+// A config file may look like this:
+// module-directories:
+// - /usr/lib64/pkcs11/
+// - /usr/lib/pkcs11/
+// allowed-module-paths:
+// - /usr/lib64/pkcs11/
+// - /usr/lib/pkcs11/
+func parseConfigFile(filename string) (*OcicryptConfig, error) {
+ // a non-existent config file is not an error
+ _, err := os.Stat(filename)
+ if os.IsNotExist(err) {
+ return nil, nil
+ }
+
+ data, err := ioutil.ReadFile(filename)
+ if err != nil {
+ return nil, err
+ }
+
+ ic := &OcicryptConfig{}
+ err = yaml.Unmarshal(data, ic)
+ return ic, err
+}
+
+// getConfiguration tries to read the configuration file at the following locations
+// 1) ${OCICRYPT_CONFIG} == "internal": use internal default allow-all policy
+// 2) ${OCICRYPT_CONFIG}
+// 3) ${XDG_CONFIG_HOME}/ocicrypt-pkcs11.conf
+// 4) ${HOME}/.config/ocicrypt-pkcs11.conf
+// 5) /etc/ocicrypt-pkcs11.conf
+// If no configuration file could be found or read a null pointer is returned
+func getConfiguration() (*OcicryptConfig, error) {
+ filename := os.Getenv(ENVVARNAME)
+ if len(filename) > 0 {
+ if filename == "internal" {
+ return getDefaultCryptoConfigOpts()
+ }
+ ic, err := parseConfigFile(filename)
+ if err != nil || ic != nil {
+ return ic, err
+ }
+ }
+ envvar := os.Getenv("XDG_CONFIG_HOME")
+ if len(envvar) > 0 {
+ ic, err := parseConfigFile(path.Join(envvar, CONFIGFILE))
+ if err != nil || ic != nil {
+ return ic, err
+ }
+ }
+ envvar = os.Getenv("HOME")
+ if len(envvar) > 0 {
+ ic, err := parseConfigFile(path.Join(envvar, ".config", CONFIGFILE))
+ if err != nil || ic != nil {
+ return ic, err
+ }
+ }
+ return parseConfigFile(path.Join("etc", CONFIGFILE))
+}
+
+// getDefaultCryptoConfigOpts returns default crypto config opts needed for pkcs11 module access
+func getDefaultCryptoConfigOpts() (*OcicryptConfig, error) {
+ mdyaml := pkcs11.GetDefaultModuleDirectoriesYaml("")
+ config := fmt.Sprintf("module-directories:\n"+
+ "%s"+
+ "allowed-module-paths:\n"+
+ "%s", mdyaml, mdyaml)
+ p11conf, err := pkcs11.ParsePkcs11ConfigFile([]byte(config))
+ return &OcicryptConfig{
+ Pkcs11Config: *p11conf,
+ }, err
+}
+
+// GetUserPkcs11Config gets the user's Pkcs11Conig either from a configuration file or if none is
+// found the default ones are returned
+func GetUserPkcs11Config() (*pkcs11.Pkcs11Config, error) {
+ fmt.Print("Note: pkcs11 support is currently experimental\n")
+ ic, err := getConfiguration()
+ if err != nil {
+ return &pkcs11.Pkcs11Config{}, err
+ }
+ if ic == nil {
+ return &pkcs11.Pkcs11Config{}, errors.New("No ocicrypt config file was found")
+ }
+ return &ic.Pkcs11Config, nil
+}
diff --git a/vendor/github.com/containers/ocicrypt/crypto/pkcs11/common.go b/vendor/github.com/containers/ocicrypt/crypto/pkcs11/common.go
new file mode 100644
index 000000000..7fcd2e3af
--- /dev/null
+++ b/vendor/github.com/containers/ocicrypt/crypto/pkcs11/common.go
@@ -0,0 +1,134 @@
+/*
+ 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 pkcs11
+
+import (
+ "fmt"
+ "github.com/pkg/errors"
+ pkcs11uri "github.com/stefanberger/go-pkcs11uri"
+ "gopkg.in/yaml.v2"
+)
+
+// Pkcs11KeyFile describes the format of the pkcs11 (private) key file.
+// It also carries pkcs11 module related environment variables that are transferred to the
+// Pkcs11URI object and activated when the pkcs11 module is used.
+type Pkcs11KeyFile struct {
+ Pkcs11 struct {
+ Uri string `yaml:"uri"`
+ } `yaml:"pkcs11"`
+ Module struct {
+ Env map[string]string `yaml:"env,omitempty"`
+ } `yaml:"module"`
+}
+
+// Pkcs11KeyFileObject is a representation of the Pkcs11KeyFile with the pkcs11 URI as an object
+type Pkcs11KeyFileObject struct {
+ Uri *pkcs11uri.Pkcs11URI
+}
+
+// ParsePkcs11Uri parses a pkcs11 URI
+func ParsePkcs11Uri(uri string) (*pkcs11uri.Pkcs11URI, error) {
+ p11uri := pkcs11uri.New()
+ err := p11uri.Parse(uri)
+ if err != nil {
+ return nil, errors.Wrapf(err, "Could not parse Pkcs11URI from file")
+ }
+ return p11uri, err
+}
+
+// ParsePkcs11KeyFile parses a pkcs11 key file holding a pkcs11 URI describing a private key.
+// The file has the following yaml format:
+// pkcs11:
+// - uri : <pkcs11 uri>
+// An error is returned if the pkcs11 URI is malformed
+func ParsePkcs11KeyFile(yamlstr []byte) (*Pkcs11KeyFileObject, error) {
+ p11keyfile := Pkcs11KeyFile{}
+
+ err := yaml.Unmarshal([]byte(yamlstr), &p11keyfile)
+ if err != nil {
+ return nil, errors.Wrapf(err, "Could not unmarshal pkcs11 keyfile")
+ }
+
+ p11uri, err := ParsePkcs11Uri(p11keyfile.Pkcs11.Uri)
+ if err != nil {
+ return nil, err
+ }
+ p11uri.SetEnvMap(p11keyfile.Module.Env)
+
+ return &Pkcs11KeyFileObject{Uri: p11uri}, err
+}
+
+// IsPkcs11PrivateKey checks whether the given YAML represents a Pkcs11 private key
+func IsPkcs11PrivateKey(yamlstr []byte) bool {
+ _, err := ParsePkcs11KeyFile(yamlstr)
+ return err == nil
+}
+
+// IsPkcs11PublicKey checks whether the given YAML represents a Pkcs11 public key
+func IsPkcs11PublicKey(yamlstr []byte) bool {
+ _, err := ParsePkcs11KeyFile(yamlstr)
+ return err == nil
+}
+
+// Pkcs11Config describes the layout of a pkcs11 config file
+// The file has the following yaml format:
+// module-directories:
+// - /usr/lib64/pkcs11/
+// allowd-module-paths
+// - /usr/lib64/pkcs11/libsofthsm2.so
+type Pkcs11Config struct {
+ ModuleDirectories []string `yaml:"module-directories"`
+ AllowedModulePaths []string `yaml:"allowed-module-paths"`
+}
+
+// GetDefaultModuleDirectories returns module directories covering
+// a variety of Linux distros
+func GetDefaultModuleDirectories() []string {
+ dirs := []string{
+ "/usr/lib64/pkcs11/", // Fedora,RHEL,openSUSE
+ "/usr/lib/pkcs11/", // Fedora,ArchLinux
+ "/usr/local/lib/pkcs11/",
+ "/usr/lib/softhsm/", // Debian,Ubuntu
+ }
+
+ // Debian directory: /usr/lib/(x86_64|aarch64|arm|powerpc64le|s390x)-linux-gnu/
+ hosttype, ostype, q := getHostAndOsType()
+ if len(hosttype) > 0 {
+ dir := fmt.Sprintf("/usr/lib/%s-%s-%s/", hosttype, ostype, q)
+ dirs = append(dirs, dir)
+ }
+ return dirs
+}
+
+// GetDefaultModuleDirectoresFormatted returns the default module directories formatted for YAML
+func GetDefaultModuleDirectoriesYaml(indent string) string {
+ res := ""
+
+ for _, dir := range GetDefaultModuleDirectories() {
+ res += indent + "- " + dir + "\n"
+ }
+ return res
+}
+
+// ParsePkcs11ConfigFile parses a pkcs11 config file hat influences the module search behavior
+// as well as the set of modules that users are allowed to use
+func ParsePkcs11ConfigFile(yamlstr []byte) (*Pkcs11Config, error) {
+ p11conf := Pkcs11Config{}
+
+ err := yaml.Unmarshal([]byte(yamlstr), &p11conf)
+ if err != nil {
+ return &p11conf, errors.Wrapf(err, "Could not parse Pkcs11Config")
+ }
+ return &p11conf, nil
+}
diff --git a/vendor/github.com/containers/ocicrypt/crypto/pkcs11/pkcs11helpers.go b/vendor/github.com/containers/ocicrypt/crypto/pkcs11/pkcs11helpers.go
new file mode 100644
index 000000000..448e88c7c
--- /dev/null
+++ b/vendor/github.com/containers/ocicrypt/crypto/pkcs11/pkcs11helpers.go
@@ -0,0 +1,487 @@
+// +build cgo
+
+/*
+ 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 pkcs11
+
+import (
+ "crypto/rand"
+ "crypto/rsa"
+ "crypto/sha1"
+ "crypto/sha256"
+ "encoding/base64"
+ "encoding/json"
+ "fmt"
+ "hash"
+ "net/url"
+ "os"
+ "strconv"
+ "strings"
+
+ "github.com/miekg/pkcs11"
+ "github.com/pkg/errors"
+ pkcs11uri "github.com/stefanberger/go-pkcs11uri"
+)
+
+var (
+ // OAEPLabel defines the label we use for OAEP encryption; this cannot be changed
+ OAEPLabel = []byte("")
+ // OAEPDefaultHash defines the default hash used for OAEP encryption; this cannot be changed
+ OAEPDefaultHash = "sha1"
+
+ // OAEPSha1Params describes the OAEP parameters with sha1 hash algorithm; needed by SoftHSM
+ OAEPSha1Params = &pkcs11.OAEPParams{
+ HashAlg: pkcs11.CKM_SHA_1,
+ MGF: pkcs11.CKG_MGF1_SHA1,
+ SourceType: pkcs11.CKZ_DATA_SPECIFIED,
+ SourceData: OAEPLabel,
+ }
+ // OAEPSha256Params describes the OAEP parameters with sha256 hash algorithm
+ OAEPSha256Params = &pkcs11.OAEPParams{
+ HashAlg: pkcs11.CKM_SHA256,
+ MGF: pkcs11.CKG_MGF1_SHA256,
+ SourceType: pkcs11.CKZ_DATA_SPECIFIED,
+ SourceData: OAEPLabel,
+ }
+)
+
+// rsaPublicEncryptOAEP encrypts the given plaintext with the given *rsa.PublicKey; the
+// environment variable OCICRYPT_OAEP_HASHALG can be set to 'sha1' to force usage of sha1 for OAEP (SoftHSM).
+// This function is needed by clients who are using a public key file for pkcs11 encryption
+func rsaPublicEncryptOAEP(pubKey *rsa.PublicKey, plaintext []byte) ([]byte, string, error) {
+ var (
+ hashfunc hash.Hash
+ hashalg string
+ )
+
+ oaephash := os.Getenv("OCICRYPT_OAEP_HASHALG")
+ // The default is 'sha1'
+ switch strings.ToLower(oaephash) {
+ case "sha1", "":
+ hashfunc = sha1.New()
+ hashalg = "sha1"
+ case "sha256":
+ hashfunc = sha256.New()
+ hashalg = "sha256"
+ default:
+ return nil, "", errors.Errorf("Unsupported OAEP hash '%s'", oaephash)
+ }
+ ciphertext, err := rsa.EncryptOAEP(hashfunc, rand.Reader, pubKey, plaintext, OAEPLabel)
+ if err != nil {
+ return nil, "", errors.Wrapf(err, "rss.EncryptOAEP failed")
+ }
+
+ return ciphertext, hashalg, nil
+}
+
+// pkcs11UriGetLoginParameters gets the parameters necessary for login from the Pkcs11URI
+// PIN and module are mandatory; slot-id is optional and if not found -1 will be returned
+// For a privateKeyOperation a PIN is required and if none is given, this function will return an error
+func pkcs11UriGetLoginParameters(p11uri *pkcs11uri.Pkcs11URI, privateKeyOperation bool) (string, string, int64, error) {
+ var (
+ pin string
+ err error
+ )
+ if privateKeyOperation {
+ if !p11uri.HasPIN() {
+ return "", "", 0, errors.New("Missing PIN for private key operation")
+ }
+ }
+ // some devices require a PIN to find a *public* key object, others don't
+ pin, _ = p11uri.GetPIN()
+
+ module, err := p11uri.GetModule()
+ if err != nil {
+ return "", "", 0, errors.Wrap(err, "No module available in pkcs11 URI")
+ }
+
+ slotid := int64(-1)
+
+ slot, ok := p11uri.GetPathAttribute("slot-id", false)
+ if ok {
+ slotid, err = strconv.ParseInt(slot, 10, 64)
+ if err != nil {
+ return "", "", 0, errors.Wrap(err, "slot-id is not a valid number")
+ }
+ if slotid < 0 {
+ return "", "", 0, fmt.Errorf("slot-id is a negative number")
+ }
+ if uint64(slotid) > 0xffffffff {
+ return "", "", 0, fmt.Errorf("slot-id is larger than 32 bit")
+ }
+ }
+
+ return pin, module, slotid, nil
+}
+
+// pkcs11UriGetKeyIdAndLabel gets the key label by retrieving the value of the 'object' attribute
+func pkcs11UriGetKeyIdAndLabel(p11uri *pkcs11uri.Pkcs11URI) (string, string, error) {
+ keyid, ok2 := p11uri.GetPathAttribute("id", false)
+ label, ok1 := p11uri.GetPathAttribute("object", false)
+ if !ok1 && !ok2 {
+ return "", "", errors.New("Neither 'id' nor 'object' attributes were found in pkcs11 URI")
+ }
+ return keyid, label, nil
+}
+
+// pkcs11OpenSession opens a session with a pkcs11 device at the given slot and logs in with the given PIN
+func pkcs11OpenSession(p11ctx *pkcs11.Ctx, slotid uint, pin string) (session pkcs11.SessionHandle, err error) {
+ session, err = p11ctx.OpenSession(uint(slotid), pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION)
+ if err != nil {
+ return 0, errors.Wrapf(err, "OpenSession to slot %d failed", slotid)
+ }
+ if len(pin) > 0 {
+ err = p11ctx.Login(session, pkcs11.CKU_USER, pin)
+ if err != nil {
+ _ = p11ctx.CloseSession(session)
+ return 0, errors.Wrap(err, "Could not login to device")
+ }
+ }
+ return session, nil
+}
+
+// pkcs11UriLogin uses the given pkcs11 URI to select the pkcs11 module (share libary) and to get
+// the PIN to use for login; if the URI contains a slot-id, the given slot-id will be used, otherwise
+// one slot after the other will be attempted and the first one where login succeeds will be used
+func pkcs11UriLogin(p11uri *pkcs11uri.Pkcs11URI, privateKeyOperation bool) (ctx *pkcs11.Ctx, session pkcs11.SessionHandle, err error) {
+ pin, module, slotid, err := pkcs11UriGetLoginParameters(p11uri, privateKeyOperation)
+ if err != nil {
+ return nil, 0, err
+ }
+
+ p11ctx := pkcs11.New(module)
+ if p11ctx == nil {
+ return nil, 0, errors.New("Please check module path, input is: " + module)
+ }
+
+ err = p11ctx.Initialize()
+ if err != nil {
+ p11Err := err.(pkcs11.Error)
+ if p11Err != pkcs11.CKR_CRYPTOKI_ALREADY_INITIALIZED {
+ return nil, 0, errors.Wrap(err, "Initialize failed")
+ }
+ }
+
+ if slotid >= 0 {
+ session, err := pkcs11OpenSession(p11ctx, uint(slotid), pin)
+ return p11ctx, session, err
+ } else {
+ slots, err := p11ctx.GetSlotList(true)
+ if err != nil {
+ return nil, 0, errors.Wrap(err, "GetSlotList failed")
+ }
+
+ tokenlabel, ok := p11uri.GetPathAttribute("token", false)
+ if !ok {
+ return nil, 0, errors.New("Missing 'token' attribute since 'slot-id' was not given")
+ }
+
+ for _, slot := range slots {
+ ti, err := p11ctx.GetTokenInfo(slot)
+ if err != nil || ti.Label != tokenlabel {
+ continue
+ }
+
+ session, err = pkcs11OpenSession(p11ctx, slot, pin)
+ if err == nil {
+ return p11ctx, session, err
+ }
+ }
+ if len(pin) > 0 {
+ return nil, 0, errors.New("Could not create session to any slot and/or log in")
+ }
+ return nil, 0, errors.New("Could not create session to any slot")
+ }
+}
+
+func pkcs11Logout(ctx *pkcs11.Ctx, session pkcs11.SessionHandle) {
+ _ = ctx.Logout(session)
+ _ = ctx.CloseSession(session)
+ _ = ctx.Finalize()
+ ctx.Destroy()
+}
+
+// findObject finds an object of the given class with the given keyid and/or label
+func findObject(p11ctx *pkcs11.Ctx, session pkcs11.SessionHandle, class uint, keyid, label string) (pkcs11.ObjectHandle, error) {
+ msg := ""
+
+ template := []*pkcs11.Attribute{
+ pkcs11.NewAttribute(pkcs11.CKA_CLASS, class),
+ }
+ if len(label) > 0 {
+ template = append(template, pkcs11.NewAttribute(pkcs11.CKA_LABEL, label))
+ msg = fmt.Sprintf("label '%s'", label)
+ }
+ if len(keyid) > 0 {
+ template = append(template, pkcs11.NewAttribute(pkcs11.CKA_ID, keyid))
+ if len(msg) > 0 {
+ msg += " and "
+ }
+ msg += url.PathEscape(keyid)
+ }
+
+ if err := p11ctx.FindObjectsInit(session, template); err != nil {
+ return 0, errors.Wrap(err, "FindObjectsInit failed")
+ }
+
+ obj, _, err := p11ctx.FindObjects(session, 100)
+ if err != nil {
+ return 0, errors.Wrap(err, "FindObjects failed")
+ }
+
+ if err := p11ctx.FindObjectsFinal(session); err != nil {
+ return 0, errors.Wrap(err, "FindObjectsFinal failed")
+ }
+ if len(obj) > 1 {
+ return 0, errors.Errorf("There are too many (=%d) keys with %s", len(obj), msg)
+ } else if len(obj) == 1 {
+ return obj[0], nil
+ }
+
+ return 0, errors.Errorf("Could not find any object with %s", msg)
+}
+
+// publicEncryptOAEP uses a public key described by a pkcs11 URI to OAEP encrypt the given plaintext
+func publicEncryptOAEP(pubKey *Pkcs11KeyFileObject, plaintext []byte) ([]byte, string, error) {
+ oldenv, err := setEnvVars(pubKey.Uri.GetEnvMap())
+ if err != nil {
+ return nil, "", err
+ }
+ defer restoreEnv(oldenv)
+
+ p11ctx, session, err := pkcs11UriLogin(pubKey.Uri, false)
+ if err != nil {
+ return nil, "", err
+ }
+ defer pkcs11Logout(p11ctx, session)
+
+ keyid, label, err := pkcs11UriGetKeyIdAndLabel(pubKey.Uri)
+ if err != nil {
+ return nil, "", err
+ }
+
+ p11PubKey, err := findObject(p11ctx, session, pkcs11.CKO_PUBLIC_KEY, keyid, label)
+ if err != nil {
+ return nil, "", err
+ }
+
+ var hashalg string
+
+ var oaep *pkcs11.OAEPParams
+ oaephash := os.Getenv("OCICRYPT_OAEP_HASHALG")
+ // the default is sha1
+ switch strings.ToLower(oaephash) {
+ case "sha1", "":
+ oaep = OAEPSha1Params
+ hashalg = "sha1"
+ case "sha256":
+ oaep = OAEPSha256Params
+ hashalg = "sha256"
+ default:
+ return nil, "", errors.Errorf("Unsupported OAEP hash '%s'", oaephash)
+ }
+
+ err = p11ctx.EncryptInit(session, []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS_OAEP, oaep)}, p11PubKey)
+ if err != nil {
+ return nil, "", errors.Wrap(err, "EncryptInit error")
+ }
+
+ ciphertext, err := p11ctx.Encrypt(session, plaintext)
+ if err != nil {
+ return nil, "", errors.Wrap(err, "Encrypt failed")
+ }
+ return ciphertext, hashalg, nil
+}
+
+// privateDecryptOAEP uses a pkcs11 URI describing a private key to OAEP decrypt a ciphertext
+func privateDecryptOAEP(privKeyObj *Pkcs11KeyFileObject, ciphertext []byte, hashalg string) ([]byte, error) {
+ oldenv, err := setEnvVars(privKeyObj.Uri.GetEnvMap())
+ if err != nil {
+ return nil, err
+ }
+ defer restoreEnv(oldenv)
+
+ p11ctx, session, err := pkcs11UriLogin(privKeyObj.Uri, true)
+ if err != nil {
+ return nil, err
+ }
+ defer pkcs11Logout(p11ctx, session)
+
+ keyid, label, err := pkcs11UriGetKeyIdAndLabel(privKeyObj.Uri)
+ if err != nil {
+ return nil, err
+ }
+
+ p11PrivKey, err := findObject(p11ctx, session, pkcs11.CKO_PRIVATE_KEY, keyid, label)
+ if err != nil {
+ return nil, err
+ }
+
+ var oaep *pkcs11.OAEPParams
+
+ // the default is sha1
+ switch hashalg {
+ case "sha1", "":
+ oaep = OAEPSha1Params
+ case "sha256":
+ oaep = OAEPSha256Params
+ default:
+ return nil, errors.Errorf("Unsupported hash algorithm '%s' for decryption", hashalg)
+ }
+
+ err = p11ctx.DecryptInit(session, []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS_OAEP, oaep)}, p11PrivKey)
+ if err != nil {
+ return nil, errors.Wrapf(err, "DecryptInit failed")
+ }
+ plaintext, err := p11ctx.Decrypt(session, ciphertext)
+ if err != nil {
+ return nil, errors.Wrapf(err, "Decrypt failed")
+ }
+ return plaintext, err
+}
+
+//
+// The following part deals with the JSON formatted message for multiple pkcs11 recipients
+//
+
+// Pkcs11Blob holds the encrypted blobs for all recipients; this is what we will put into the image's annotations
+type Pkcs11Blob struct {
+ Version uint `json:"version"`
+ Recipients []Pkcs11Recipient `json:"recipients"`
+}
+
+// Pkcs11Recipient holds the b64-encoded and encrypted blob for a particular recipient
+type Pkcs11Recipient struct {
+ Version uint `json:"version"`
+ Blob string `json:"blob"`
+ Hash string `json:"hash,omitempty"`
+}
+
+// EncryptMultiple encrypts for one or multiple pkcs11 devices; the public keys passed to this function
+// may either be *rsa.PublicKey or *pkcs11uri.Pkcs11URI; the returned byte array is a JSON string of the
+// following format:
+// {
+// recipients: [ // recipient list
+// {
+// "version": 0,
+// "blob": <base64 encoded RSA OAEP encrypted blob>,
+// "hash": <hash used for OAEP other than 'sha256'>
+// } ,
+// {
+// "version": 0,
+// "blob": <base64 encoded RSA OAEP encrypted blob>,
+// "hash": <hash used for OAEP other than 'sha256'>
+// } ,
+// [...]
+// ]
+// }
+func EncryptMultiple(pubKeys []interface{}, data []byte) ([]byte, error) {
+ var (
+ ciphertext []byte
+ err error
+ pkcs11blob Pkcs11Blob = Pkcs11Blob{Version: 0}
+ hashalg string
+ )
+
+ for _, pubKey := range pubKeys {
+ switch pkey := pubKey.(type) {
+ case *rsa.PublicKey:
+ ciphertext, hashalg, err = rsaPublicEncryptOAEP(pkey, data)
+ case *Pkcs11KeyFileObject:
+ ciphertext, hashalg, err = publicEncryptOAEP(pkey, data)
+ default:
+ err = errors.Errorf("Unsupported key object type for pkcs11 public key")
+ }
+ if err != nil {
+ return nil, err
+ }
+
+ if hashalg == OAEPDefaultHash {
+ hashalg = ""
+ }
+ recipient := Pkcs11Recipient{
+ Version: 0,
+ Blob: base64.StdEncoding.EncodeToString(ciphertext),
+ Hash: hashalg,
+ }
+
+ pkcs11blob.Recipients = append(pkcs11blob.Recipients, recipient)
+ }
+ return json.Marshal(&pkcs11blob)
+}
+
+// Decrypt tries to decrypt one of the recipients' blobs using a pkcs11 private key.
+// The input pkcs11blobstr is a string with the following format:
+// {
+// recipients: [ // recipient list
+// {
+// "version": 0,
+// "blob": <base64 encoded RSA OAEP encrypted blob>,
+// "hash": <hash used for OAEP other than 'sha256'>
+// } ,
+// {
+// "version": 0,
+// "blob": <base64 encoded RSA OAEP encrypted blob>,
+// "hash": <hash used for OAEP other than 'sha256'>
+// } ,
+// [...]
+// }
+func Decrypt(privKeyObjs []*Pkcs11KeyFileObject, pkcs11blobstr []byte) ([]byte, error) {
+ pkcs11blob := Pkcs11Blob{}
+ err := json.Unmarshal(pkcs11blobstr, &pkcs11blob)
+ if err != nil {
+ return nil, errors.Wrapf(err, "Could not parse Pkcs11Blob")
+ }
+ switch pkcs11blob.Version {
+ case 0:
+ // latest supported version
+ default:
+ return nil, errors.Errorf("Found Pkcs11Blob with version %d but maximum supported version is 0.", pkcs11blob.Version)
+ }
+ // since we do trial and error, collect all encountered errors
+ errs := ""
+
+ for _, recipient := range pkcs11blob.Recipients {
+ switch recipient.Version {
+ case 0:
+ // last supported version
+ default:
+ return nil, errors.Errorf("Found Pkcs11Recipient with version %d but maximum supported version is 0.", recipient.Version)
+ }
+
+ ciphertext, err := base64.StdEncoding.DecodeString(recipient.Blob)
+ if err != nil || len(ciphertext) == 0 {
+ // This should never happen... we skip over decoding issues
+ errs += fmt.Sprintf("Base64 decoding failed: %s\n", err)
+ continue
+ }
+ // try all keys until one works
+ for _, privKeyObj := range privKeyObjs {
+ plaintext, err := privateDecryptOAEP(privKeyObj, ciphertext, recipient.Hash)
+ if err == nil {
+ return plaintext, nil
+ }
+ if uri, err2 := privKeyObj.Uri.Format(); err2 == nil {
+ errs += fmt.Sprintf("%s : %s\n", uri, err)
+ } else {
+ errs += fmt.Sprintf("%s\n", err)
+ }
+ }
+ }
+
+ return nil, errors.Errorf("Could not find a pkcs11 key for decryption:\n%s", errs)
+}
diff --git a/vendor/github.com/containers/ocicrypt/crypto/pkcs11/pkcs11helpers_nocgo.go b/vendor/github.com/containers/ocicrypt/crypto/pkcs11/pkcs11helpers_nocgo.go
new file mode 100644
index 000000000..6edf75269
--- /dev/null
+++ b/vendor/github.com/containers/ocicrypt/crypto/pkcs11/pkcs11helpers_nocgo.go
@@ -0,0 +1,31 @@
+// +build !cgo
+
+/*
+ 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 pkcs11
+
+import (
+ "github.com/pkg/errors"
+)
+
+func EncryptMultiple(pubKeys []interface{}, data []byte) ([]byte, error) {
+ return nil, errors.Errorf("ocicrypt pkcs11 not supported on this build")
+}
+
+func Decrypt(privKeyObjs []*Pkcs11KeyFileObject, pkcs11blobstr []byte) ([]byte, error) {
+ return nil, errors.Errorf("ocicrypt pkcs11 not supported on this build")
+}
diff --git a/vendor/github.com/containers/ocicrypt/crypto/pkcs11/utils.go b/vendor/github.com/containers/ocicrypt/crypto/pkcs11/utils.go
new file mode 100644
index 000000000..306e372d5
--- /dev/null
+++ b/vendor/github.com/containers/ocicrypt/crypto/pkcs11/utils.go
@@ -0,0 +1,114 @@
+/*
+ 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 pkcs11
+
+import (
+ "os"
+ "runtime"
+ "strings"
+ "sync"
+
+ "github.com/pkg/errors"
+)
+
+var (
+ envLock sync.Mutex
+)
+
+// setEnvVars sets the environment variables given in the map and locks the environment from
+// modification with the same function; if successful, you *must* call restoreEnv with the return
+// value from this function
+func setEnvVars(env map[string]string) ([]string, error) {
+ envLock.Lock()
+
+ if len(env) == 0 {
+ return nil, nil
+ }
+
+ oldenv := os.Environ()
+
+ for k, v := range env {
+ err := os.Setenv(k, v)
+ if err != nil {
+ restoreEnv(oldenv)
+ return nil, errors.Wrapf(err, "Could not set environment variable '%s' to '%s'", k, v)
+ }
+ }
+
+ return oldenv, nil
+}
+
+func arrayToMap(elements []string) map[string]string {
+ o := make(map[string]string)
+
+ for _, element := range elements {
+ p := strings.SplitN(element, "=", 2)
+ if len(p) == 2 {
+ o[p[0]] = p[1]
+ }
+ }
+
+ return o
+}
+
+// restoreEnv restores the environment to be exactly as given in the array of strings
+// and unlocks the lock
+func restoreEnv(envs []string) {
+ if envs != nil && len(envs) >= 0 {
+ target := arrayToMap(envs)
+ curr := arrayToMap(os.Environ())
+
+ for nc, vc := range curr {
+ vt, ok := target[nc]
+ if !ok {
+ os.Unsetenv(nc)
+ } else if vc == vt {
+ delete(target, nc)
+ }
+ }
+
+ for nt, vt := range target {
+ os.Setenv(nt, vt)
+ }
+ }
+
+ envLock.Unlock()
+}
+
+func getHostAndOsType() (string, string, string) {
+ ht := ""
+ ot := ""
+ st := ""
+ switch runtime.GOOS {
+ case "linux":
+ ot = "linux"
+ st = "gnu"
+ switch runtime.GOARCH {
+ case "arm":
+ ht = "arm"
+ case "arm64":
+ ht = "aarch64"
+ case "amd64":
+ ht = "x86_64"
+ case "ppc64le":
+ ht = "powerpc64le"
+ case "s390x":
+ ht = "s390x"
+ }
+ }
+ return ht, ot, st
+}
diff --git a/vendor/github.com/containers/ocicrypt/encryption.go b/vendor/github.com/containers/ocicrypt/encryption.go
index 3153b63d7..f5142cc8d 100644
--- a/vendor/github.com/containers/ocicrypt/encryption.go
+++ b/vendor/github.com/containers/ocicrypt/encryption.go
@@ -19,6 +19,9 @@ package ocicrypt
import (
"encoding/base64"
"encoding/json"
+ "fmt"
+ keyproviderconfig "github.com/containers/ocicrypt/config/keyprovider-config"
+ "github.com/containers/ocicrypt/keywrap/keyprovider"
"io"
"strings"
@@ -27,8 +30,10 @@ import (
"github.com/containers/ocicrypt/keywrap"
"github.com/containers/ocicrypt/keywrap/jwe"
"github.com/containers/ocicrypt/keywrap/pgp"
+ "github.com/containers/ocicrypt/keywrap/pkcs11"
"github.com/containers/ocicrypt/keywrap/pkcs7"
"github.com/opencontainers/go-digest"
+ log "github.com/sirupsen/logrus"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
)
@@ -43,6 +48,15 @@ func init() {
RegisterKeyWrapper("pgp", pgp.NewKeyWrapper())
RegisterKeyWrapper("jwe", jwe.NewKeyWrapper())
RegisterKeyWrapper("pkcs7", pkcs7.NewKeyWrapper())
+ RegisterKeyWrapper("pkcs11", pkcs11.NewKeyWrapper())
+ ic, err := keyproviderconfig.GetConfiguration()
+ if err != nil {
+ log.Error(err)
+ } else if ic != nil {
+ for provider, attrs := range ic.KeyProviderConfig {
+ RegisterKeyWrapper("provider."+provider, keyprovider.NewKeyWrapper(provider, attrs))
+ }
+ }
}
var keyWrappers map[string]keywrap.KeyWrapper
@@ -128,6 +142,7 @@ func EncryptLayer(ec *config.EncryptConfig, encOrPlainLayerReader io.Reader, des
}
newAnnotations := make(map[string]string)
+ keysWrapped := false
for annotationsID, scheme := range keyWrapperAnnotations {
b64Annotations := desc.Annotations[annotationsID]
keywrapper := GetKeyWrapper(scheme)
@@ -136,10 +151,14 @@ func EncryptLayer(ec *config.EncryptConfig, encOrPlainLayerReader io.Reader, des
return nil, err
}
if b64Annotations != "" {
+ keysWrapped = true
newAnnotations[annotationsID] = b64Annotations
}
}
+ if !keysWrapped {
+ return nil, errors.New("no wrapped keys produced by encryption")
+ }
newAnnotations["org.opencontainers.image.enc.pubopts"] = base64.StdEncoding.EncodeToString(pubOptsData)
if len(newAnnotations) == 0 {
@@ -191,6 +210,7 @@ func DecryptLayer(dc *config.DecryptConfig, encLayerReader io.Reader, desc ocisp
func decryptLayerKeyOptsData(dc *config.DecryptConfig, desc ocispec.Descriptor) ([]byte, error) {
privKeyGiven := false
+ errs := ""
for annotationsID, scheme := range keyWrapperAnnotations {
b64Annotation := desc.Annotations[annotationsID]
if b64Annotation != "" {
@@ -203,10 +223,10 @@ func decryptLayerKeyOptsData(dc *config.DecryptConfig, desc ocispec.Descriptor)
if len(keywrapper.GetPrivateKeys(dc.Parameters)) > 0 {
privKeyGiven = true
}
-
optsData, err := preUnwrapKey(keywrapper, dc, b64Annotation)
if err != nil {
// try next keywrap.KeyWrapper
+ errs += fmt.Sprintf("%s\n", err)
continue
}
if optsData == nil {
@@ -219,7 +239,7 @@ func decryptLayerKeyOptsData(dc *config.DecryptConfig, desc ocispec.Descriptor)
if !privKeyGiven {
return nil, errors.New("missing private key needed for decryption")
}
- return nil, errors.Errorf("no suitable key unwrapper found or none of the private keys could be used for decryption")
+ return nil, errors.Errorf("no suitable key unwrapper found or none of the private keys could be used for decryption:\n%s", errs)
}
func getLayerPubOpts(desc ocispec.Descriptor) ([]byte, error) {
@@ -237,6 +257,7 @@ func preUnwrapKey(keywrapper keywrap.KeyWrapper, dc *config.DecryptConfig, b64An
if b64Annotations == "" {
return nil, nil
}
+ errs := ""
for _, b64Annotation := range strings.Split(b64Annotations, ",") {
annotation, err := base64.StdEncoding.DecodeString(b64Annotation)
if err != nil {
@@ -244,11 +265,12 @@ func preUnwrapKey(keywrapper keywrap.KeyWrapper, dc *config.DecryptConfig, b64An
}
optsData, err := keywrapper.UnwrapKey(dc, annotation)
if err != nil {
+ errs += fmt.Sprintf("- %s\n", err)
continue
}
return optsData, nil
}
- return nil, errors.New("no suitable key found for decrypting layer key")
+ return nil, errors.Errorf("no suitable key found for decrypting layer key:\n%s", errs)
}
// commonEncryptLayer is a function to encrypt the plain layer using a new random
diff --git a/vendor/github.com/containers/ocicrypt/go.mod b/vendor/github.com/containers/ocicrypt/go.mod
index 5e6bc2a75..06a77af95 100644
--- a/vendor/github.com/containers/ocicrypt/go.mod
+++ b/vendor/github.com/containers/ocicrypt/go.mod
@@ -3,13 +3,19 @@ module github.com/containers/ocicrypt
go 1.12
require (
- github.com/davecgh/go-spew v1.1.1 // indirect
- github.com/opencontainers/go-digest v1.0.0-rc1
+ github.com/golang/protobuf v1.4.3
+ github.com/google/go-cmp v0.5.2 // indirect
+ github.com/miekg/pkcs11 v1.0.3
+ github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.0.1
- github.com/pkg/errors v0.8.1
- github.com/stretchr/testify v1.3.0 // indirect
+ github.com/pkg/errors v0.9.1
+ github.com/sirupsen/logrus v1.7.0
+ github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980
+ github.com/stretchr/testify v1.3.0
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1
- golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4
- golang.org/x/sys v0.0.0-20190422165155-953cdadca894 // indirect
- gopkg.in/square/go-jose.v2 v2.3.1
+ golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de
+ golang.org/x/sys v0.0.0-20200817155316-9781c653f443 // indirect
+ google.golang.org/grpc v1.33.2
+ gopkg.in/square/go-jose.v2 v2.5.1
+ gopkg.in/yaml.v2 v2.3.0
)
diff --git a/vendor/github.com/containers/ocicrypt/go.sum b/vendor/github.com/containers/ocicrypt/go.sum
index 6b4e83d75..b014b76ee 100644
--- a/vendor/github.com/containers/ocicrypt/go.sum
+++ b/vendor/github.com/containers/ocicrypt/go.sum
@@ -1,31 +1,116 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
-github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
+github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
+github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
+github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
+github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
+github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
+github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
+github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
+github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
+github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
+github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/miekg/pkcs11 v1.0.3 h1:iMwmD7I5225wv84WxIG/bmxz9AXjWvTWIbM/TYHvWtw=
+github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
+github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
+github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
-github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
-github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
+github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
+github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980 h1:lIOOHPEbXzO3vnmx2gok1Tfs31Q8GQqKLc8vVqyQq/I=
+github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1 h1:A/5uWzF44DlIgdm/PQFwfMkW0JX+cIcQi/SwLAmZP5M=
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
-golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de h1:ikNHVSjEfnvz6sxdSPCaPt572qowuyMDMJLLm3Db3ig=
+golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
-golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200817155316-9781c653f443 h1:X18bCaipMcoJGm27Nv7zr4XYPKGUy92GtqboKC2Hxaw=
+golang.org/x/sys v0.0.0-20200817155316-9781c653f443/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-gopkg.in/square/go-jose.v2 v2.3.1 h1:SK5KegNXmKmqE342YYN2qPHEnUYeoMiXXl1poUlI+o4=
-gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
+google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
+google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o=
+google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
+google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
+google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
+google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
+google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
+google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
+google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w=
+gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
+gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
+gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/vendor/github.com/containers/ocicrypt/gpg.go b/vendor/github.com/containers/ocicrypt/gpg.go
index c89f3b0ea..c4d31e52d 100644
--- a/vendor/github.com/containers/ocicrypt/gpg.go
+++ b/vendor/github.com/containers/ocicrypt/gpg.go
@@ -180,13 +180,13 @@ func (gc *gpgv2Client) getKeyDetails(option string, keyid uint64) ([]byte, bool,
return keydata, err == nil, err
}
-// GetSecretKeyDetails retrives the secret key details of key with keyid.
+// GetSecretKeyDetails retrieves the secret key details of key with keyid.
// returns a byte array of the details and a bool if the key exists
func (gc *gpgv2Client) GetSecretKeyDetails(keyid uint64) ([]byte, bool, error) {
return gc.getKeyDetails("-K", keyid)
}
-// GetKeyDetails retrives the public key details of key with keyid.
+// GetKeyDetails retrieves the public key details of key with keyid.
// returns a byte array of the details and a bool if the key exists
func (gc *gpgv2Client) GetKeyDetails(keyid uint64) ([]byte, bool, error) {
return gc.getKeyDetails("-k", keyid)
@@ -240,13 +240,13 @@ func (gc *gpgv1Client) getKeyDetails(option string, keyid uint64) ([]byte, bool,
return keydata, err == nil, err
}
-// GetSecretKeyDetails retrives the secret key details of key with keyid.
+// GetSecretKeyDetails retrieves the secret key details of key with keyid.
// returns a byte array of the details and a bool if the key exists
func (gc *gpgv1Client) GetSecretKeyDetails(keyid uint64) ([]byte, bool, error) {
return gc.getKeyDetails("-K", keyid)
}
-// GetKeyDetails retrives the public key details of key with keyid.
+// GetKeyDetails retrieves the public key details of key with keyid.
// returns a byte array of the details and a bool if the key exists
func (gc *gpgv1Client) GetKeyDetails(keyid uint64) ([]byte, bool, error) {
return gc.getKeyDetails("-k", keyid)
diff --git a/vendor/github.com/containers/ocicrypt/helpers/parse_helpers.go b/vendor/github.com/containers/ocicrypt/helpers/parse_helpers.go
index 288296ea5..198c554aa 100644
--- a/vendor/github.com/containers/ocicrypt/helpers/parse_helpers.go
+++ b/vendor/github.com/containers/ocicrypt/helpers/parse_helpers.go
@@ -9,6 +9,8 @@ import (
"github.com/containers/ocicrypt"
encconfig "github.com/containers/ocicrypt/config"
+ "github.com/containers/ocicrypt/config/pkcs11config"
+ "github.com/containers/ocicrypt/crypto/pkcs11"
encutils "github.com/containers/ocicrypt/utils"
"github.com/pkg/errors"
@@ -16,17 +18,21 @@ import (
// processRecipientKeys sorts the array of recipients by type. Recipients may be either
// x509 certificates, public keys, or PGP public keys identified by email address or name
-func processRecipientKeys(recipients []string) ([][]byte, [][]byte, [][]byte, error) {
+func processRecipientKeys(recipients []string) ([][]byte, [][]byte, [][]byte, [][]byte, [][]byte, [][]byte, error) {
var (
gpgRecipients [][]byte
pubkeys [][]byte
x509s [][]byte
+ pkcs11Pubkeys [][]byte
+ pkcs11Yamls [][]byte
+ keyProviders [][]byte
)
+
for _, recipient := range recipients {
idx := strings.Index(recipient, ":")
if idx < 0 {
- return nil, nil, nil, errors.New("Invalid recipient format")
+ return nil, nil, nil, nil, nil, nil, errors.New("Invalid recipient format")
}
protocol := recipient[:idx]
@@ -39,35 +45,51 @@ func processRecipientKeys(recipients []string) ([][]byte, [][]byte, [][]byte, er
case "jwe":
tmp, err := ioutil.ReadFile(value)
if err != nil {
- return nil, nil, nil, errors.Wrap(err, "Unable to read file")
+ return nil, nil, nil, nil, nil, nil, errors.Wrap(err, "Unable to read file")
}
if !encutils.IsPublicKey(tmp) {
- return nil, nil, nil, errors.New("File provided is not a public key")
+ return nil, nil, nil, nil, nil, nil, errors.New("File provided is not a public key")
}
pubkeys = append(pubkeys, tmp)
case "pkcs7":
tmp, err := ioutil.ReadFile(value)
if err != nil {
- return nil, nil, nil, errors.Wrap(err, "Unable to read file")
+ return nil, nil, nil, nil, nil, nil, errors.Wrap(err, "Unable to read file")
}
if !encutils.IsCertificate(tmp) {
- return nil, nil, nil, errors.New("File provided is not an x509 cert")
+ return nil, nil, nil, nil, nil, nil, errors.New("File provided is not an x509 cert")
}
x509s = append(x509s, tmp)
+ case "pkcs11":
+ tmp, err := ioutil.ReadFile(value)
+ if err != nil {
+ return nil, nil, nil, nil, nil, nil, errors.Wrap(err, "Unable to read file")
+ }
+ if encutils.IsPkcs11PublicKey(tmp) {
+ pkcs11Yamls = append(pkcs11Yamls, tmp)
+ } else if encutils.IsPublicKey(tmp) {
+ pkcs11Pubkeys = append(pkcs11Pubkeys, tmp)
+ } else {
+ return nil, nil, nil, nil, nil, nil, errors.New("Provided file is not a public key")
+ }
+
+ case "provider":
+ keyProviders = append(keyProviders, []byte(value))
+
default:
- return nil, nil, nil, errors.New("Provided protocol not recognized")
+ return nil, nil, nil, nil, nil, nil, errors.New("Provided protocol not recognized")
}
}
- return gpgRecipients, pubkeys, x509s, nil
+ return gpgRecipients, pubkeys, x509s, pkcs11Pubkeys, pkcs11Yamls, keyProviders, nil
}
// processx509Certs processes x509 certificate files
func processx509Certs(keys []string) ([][]byte, error) {
var x509s [][]byte
for _, key := range keys {
- tmp, err := ioutil.ReadFile(key)
+ tmp, err := ioutil.ReadFile(strings.Split(key, ":")[0])
if err != nil {
return nil, errors.Wrap(err, "Unable to read file")
}
@@ -119,36 +141,47 @@ func processPwdString(pwdString string) ([]byte, error) {
// - <filename>:pass=<password>
// - <filename>:fd=<filedescriptor>
// - <filename>:<password>
-func processPrivateKeyFiles(keyFilesAndPwds []string) ([][]byte, [][]byte, [][]byte, [][]byte, error) {
+// - keyprovider:<...>
+func processPrivateKeyFiles(keyFilesAndPwds []string) ([][]byte, [][]byte, [][]byte, [][]byte, [][]byte, [][]byte, error) {
var (
gpgSecretKeyRingFiles [][]byte
gpgSecretKeyPasswords [][]byte
privkeys [][]byte
privkeysPasswords [][]byte
+ pkcs11Yamls [][]byte
+ keyProviders [][]byte
err error
)
// keys needed for decryption in case of adding a recipient
for _, keyfileAndPwd := range keyFilesAndPwds {
var password []byte
+ // treat "provider" protocol separately
+ if strings.HasPrefix(keyfileAndPwd, "provider:"){
+ keyProviders = append(keyProviders, []byte(keyfileAndPwd[len("provider:"):]))
+ continue
+ }
parts := strings.Split(keyfileAndPwd, ":")
if len(parts) == 2 {
password, err = processPwdString(parts[1])
if err != nil {
- return nil, nil, nil, nil, err
+ return nil, nil, nil, nil, nil, nil, err
}
}
keyfile := parts[0]
tmp, err := ioutil.ReadFile(keyfile)
if err != nil {
- return nil, nil, nil, nil, err
+ return nil, nil, nil, nil, nil, nil, err
}
isPrivKey, err := encutils.IsPrivateKey(tmp, password)
if encutils.IsPasswordError(err) {
- return nil, nil, nil, nil, err
+ return nil, nil, nil, nil, nil, nil, err
}
- if isPrivKey {
+
+ if encutils.IsPkcs11PrivateKey(tmp) {
+ pkcs11Yamls = append(pkcs11Yamls, tmp)
+ } else if isPrivKey {
privkeys = append(privkeys, tmp)
privkeysPasswords = append(privkeysPasswords, password)
} else if encutils.IsGPGPrivateKeyRing(tmp) {
@@ -160,29 +193,29 @@ func processPrivateKeyFiles(keyFilesAndPwds []string) ([][]byte, [][]byte, [][]b
continue
}
}
- return gpgSecretKeyRingFiles, gpgSecretKeyPasswords, privkeys, privkeysPasswords, nil
+ return gpgSecretKeyRingFiles, gpgSecretKeyPasswords, privkeys, privkeysPasswords, pkcs11Yamls, keyProviders, nil
}
// 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
+// information to perform decryption from command line options.
func CreateDecryptCryptoConfig(keys []string, decRecipients []string) (encconfig.CryptoConfig, error) {
ccs := []encconfig.CryptoConfig{}
// x509 cert is needed for PKCS7 decryption
- _, _, x509s, err := processRecipientKeys(decRecipients)
+ _, _, x509s, _, _, _, err := processRecipientKeys(decRecipients)
if err != nil {
return encconfig.CryptoConfig{}, err
}
- // x509 certs can also be passed in via keys
- x509FromKeys, err := processx509Certs(keys)
- if err != nil {
- return encconfig.CryptoConfig{}, err
+ if len(x509s) > 0 {
+ // x509 certs can also be passed in via keys
+ x509FromKeys, err := processx509Certs(keys)
+ if err != nil {
+ return encconfig.CryptoConfig{}, err
+ }
+ x509s = append(x509s, x509FromKeys...)
}
- x509s = append(x509s, x509FromKeys...)
-
- gpgSecretKeyRingFiles, gpgSecretKeyPasswords, privKeys, privKeysPasswords, err := processPrivateKeyFiles(keys)
+ gpgSecretKeyRingFiles, gpgSecretKeyPasswords, privKeys, privKeysPasswords, pkcs11Yamls, keyProviders, err := processPrivateKeyFiles(keys)
if err != nil {
return encconfig.CryptoConfig{}, err
}
@@ -199,7 +232,7 @@ func CreateDecryptCryptoConfig(keys []string, decRecipients []string) (encconfig
_, err = createGPGClient(context)
gpgInstalled := err == nil
if gpgInstalled {
- if len(gpgSecretKeyRingFiles) == 0 && len(privKeys) == 0 && descs != nil {
+ if len(gpgSecretKeyRingFiles) == 0 && len(privKeys) == 0 && len(pkcs11Yamls) == 0 && len(keyProviders) == 0 && descs != nil {
// Get pgp private keys from keyring only if no private key was passed
gpgPrivKeys, gpgPrivKeyPasswords, err := getGPGPrivateKeys(context, gpgSecretKeyRingFiles, descs, true)
if err != nil {
@@ -223,18 +256,38 @@ func CreateDecryptCryptoConfig(keys []string, decRecipients []string) (encconfig
}
*/
- x509sCc, err := encconfig.DecryptWithX509s(x509s)
- if err != nil {
- return encconfig.CryptoConfig{}, err
+ if len(x509s) > 0 {
+ x509sCc, err := encconfig.DecryptWithX509s(x509s)
+ if err != nil {
+ return encconfig.CryptoConfig{}, err
+ }
+ ccs = append(ccs, x509sCc)
}
- ccs = append(ccs, x509sCc)
-
- privKeysCc, err := encconfig.DecryptWithPrivKeys(privKeys, privKeysPasswords)
- if err != nil {
- return encconfig.CryptoConfig{}, err
+ if len(privKeys) > 0 {
+ privKeysCc, err := encconfig.DecryptWithPrivKeys(privKeys, privKeysPasswords)
+ if err != nil {
+ return encconfig.CryptoConfig{}, err
+ }
+ ccs = append(ccs, privKeysCc)
+ }
+ if len(pkcs11Yamls) > 0 {
+ p11conf, err := pkcs11config.GetUserPkcs11Config()
+ if err != nil {
+ return encconfig.CryptoConfig{}, err
+ }
+ pkcs11PrivKeysCc, err := encconfig.DecryptWithPkcs11Yaml(p11conf, pkcs11Yamls)
+ if err != nil {
+ return encconfig.CryptoConfig{}, err
+ }
+ ccs = append(ccs, pkcs11PrivKeysCc)
+ }
+ if len(keyProviders) > 0 {
+ keyProviderCc, err := encconfig.DecryptWithKeyProvider(keyProviders)
+ if err != nil {
+ return encconfig.CryptoConfig{}, err
+ }
+ ccs = append(ccs, keyProviderCc)
}
- ccs = append(ccs, privKeysCc)
-
return encconfig.CombineCryptoConfigs(ccs), nil
}
@@ -252,7 +305,7 @@ func CreateCryptoConfig(recipients []string, keys []string) (encconfig.CryptoCon
}
if len(recipients) > 0 {
- gpgRecipients, pubKeys, x509s, err := processRecipientKeys(recipients)
+ gpgRecipients, pubKeys, x509s, pkcs11Pubkeys, pkcs11Yamls, keyProvider, err := processRecipientKeys(recipients)
if err != nil {
return encconfig.CryptoConfig{}, err
}
@@ -275,17 +328,40 @@ func CreateCryptoConfig(recipients []string, keys []string) (encconfig.CryptoCon
}
// Create Encryption Crypto Config
- pkcs7Cc, err := encconfig.EncryptWithPkcs7(x509s)
- if err != nil {
- return encconfig.CryptoConfig{}, err
+ if len(x509s) > 0 {
+ pkcs7Cc, err := encconfig.EncryptWithPkcs7(x509s)
+ if err != nil {
+ return encconfig.CryptoConfig{}, err
+ }
+ encryptCcs = append(encryptCcs, pkcs7Cc)
+ }
+ if len(pubKeys) > 0 {
+ jweCc, err := encconfig.EncryptWithJwe(pubKeys)
+ if err != nil {
+ return encconfig.CryptoConfig{}, err
+ }
+ encryptCcs = append(encryptCcs, jweCc)
+ }
+ var p11conf *pkcs11.Pkcs11Config
+ if len(pkcs11Yamls) > 0 || len(pkcs11Pubkeys) > 0 {
+ p11conf, err = pkcs11config.GetUserPkcs11Config()
+ if err != nil {
+ return encconfig.CryptoConfig{}, err
+ }
+ pkcs11Cc, err := encconfig.EncryptWithPkcs11(p11conf, pkcs11Pubkeys, pkcs11Yamls)
+ if err != nil {
+ return encconfig.CryptoConfig{}, err
+ }
+ encryptCcs = append(encryptCcs, pkcs11Cc)
}
- encryptCcs = append(encryptCcs, pkcs7Cc)
- jweCc, err := encconfig.EncryptWithJwe(pubKeys)
- if err != nil {
- return encconfig.CryptoConfig{}, err
+ if len(keyProvider) > 0 {
+ keyProviderCc, err := encconfig.EncryptWithKeyProvider(keyProvider)
+ if err != nil {
+ return encconfig.CryptoConfig{}, err
+ }
+ encryptCcs = append(encryptCcs, keyProviderCc)
}
- encryptCcs = append(encryptCcs, jweCc)
ecc := encconfig.CombineCryptoConfigs(encryptCcs)
if decryptCc != nil {
ecc.EncryptConfig.AttachDecryptConfig(decryptCc.DecryptConfig)
diff --git a/vendor/github.com/containers/ocicrypt/keywrap/keyprovider/keyprovider.go b/vendor/github.com/containers/ocicrypt/keywrap/keyprovider/keyprovider.go
new file mode 100644
index 000000000..3b4c47ed4
--- /dev/null
+++ b/vendor/github.com/containers/ocicrypt/keywrap/keyprovider/keyprovider.go
@@ -0,0 +1,242 @@
+/*
+ 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 keyprovider
+
+import (
+ "context"
+ "encoding/json"
+ "github.com/containers/ocicrypt/config"
+ keyproviderconfig "github.com/containers/ocicrypt/config/keyprovider-config"
+ "github.com/containers/ocicrypt/keywrap"
+ "github.com/containers/ocicrypt/utils"
+ keyproviderpb "github.com/containers/ocicrypt/utils/keyprovider"
+ "github.com/pkg/errors"
+ log "github.com/sirupsen/logrus"
+ "google.golang.org/grpc"
+)
+
+type keyProviderKeyWrapper struct {
+ provider string
+ attrs keyproviderconfig.KeyProviderAttrs
+}
+
+func (kw *keyProviderKeyWrapper) GetAnnotationID() string {
+ return "org.opencontainers.image.enc.keys.provider." + kw.provider
+}
+
+// NewKeyWrapper returns a new key wrapping interface using keyprovider
+func NewKeyWrapper(p string, a keyproviderconfig.KeyProviderAttrs) keywrap.KeyWrapper {
+ return &keyProviderKeyWrapper{provider: p, attrs: a}
+}
+
+type KeyProviderKeyWrapProtocolOperation string
+
+var (
+ OpKeyWrap KeyProviderKeyWrapProtocolOperation = "keywrap"
+ OpKeyUnwrap KeyProviderKeyWrapProtocolOperation = "keyunwrap"
+)
+
+// KeyProviderKeyWrapProtocolInput defines the input to the key provider binary or grpc method.
+type KeyProviderKeyWrapProtocolInput struct {
+ // Operation is either "keywrap" or "keyunwrap"
+ Operation KeyProviderKeyWrapProtocolOperation `json:"op"`
+ // KeyWrapParams encodes the arguments to key wrap if operation is set to wrap
+ KeyWrapParams KeyWrapParams `json:"keywrapparams,omitempty"`
+ // KeyUnwrapParams encodes the arguments to key unwrap if operation is set to unwrap
+ KeyUnwrapParams KeyUnwrapParams `json:"keyunwrapparams,omitempty"`
+}
+
+// KeyProviderKeyWrapProtocolOutput defines the output of the key provider binary or grpc method.
+type KeyProviderKeyWrapProtocolOutput struct {
+ // KeyWrapResult encodes the results to key wrap if operation is to wrap
+ KeyWrapResults KeyWrapResults `json:"keywrapresults,omitempty"`
+ // KeyUnwrapResult encodes the result to key unwrap if operation is to unwrap
+ KeyUnwrapResults KeyUnwrapResults `json:"keyunwrapresults,omitempty"`
+}
+
+type KeyWrapParams struct {
+ Ec *config.EncryptConfig `json:"ec"`
+ OptsData []byte `json:"optsdata"`
+}
+
+type KeyUnwrapParams struct {
+ Dc *config.DecryptConfig `json:"dc"`
+ Annotation []byte `json:"annotation"`
+}
+
+type KeyUnwrapResults struct {
+ OptsData []byte `json:"optsdata"`
+}
+
+type KeyWrapResults struct {
+ Annotation []byte `json:"annotation"`
+}
+
+var runner utils.CommandExecuter
+
+func init() {
+ runner = utils.Runner{}
+}
+
+// WrapKeys calls appropriate binary executable/grpc server for wrapping the session key for recipients and gets encrypted optsData, which
+// describe the symmetric key used for encrypting the layer
+func (kw *keyProviderKeyWrapper) WrapKeys(ec *config.EncryptConfig, optsData []byte) ([]byte, error) {
+
+ input, err := json.Marshal(KeyProviderKeyWrapProtocolInput{
+ Operation: OpKeyWrap,
+ KeyWrapParams: KeyWrapParams{
+ Ec: ec,
+ OptsData: optsData,
+ },
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ if _, ok := ec.Parameters[kw.provider]; ok {
+ if kw.attrs.Command != nil {
+ protocolOuput, err := getProviderCommandOutput(input, kw.attrs.Command)
+ if err != nil {
+ return nil, errors.Wrap(err, "error while retrieving keyprovider protocol command output")
+ }
+ return protocolOuput.KeyWrapResults.Annotation, nil
+ } else if kw.attrs.Grpc != "" {
+ protocolOuput, err := getProviderGRPCOutput(input, kw.attrs.Grpc, OpKeyWrap)
+ if err != nil {
+ return nil, errors.Wrap(err, "error while retrieving keyprovider protocol grpc output")
+ }
+
+ return protocolOuput.KeyWrapResults.Annotation, nil
+ } else {
+ return nil, errors.New("Unsupported keyprovider invocation. Supported invocation methods are grpc and cmd")
+ }
+ }
+
+ return nil, nil
+}
+
+// UnwrapKey calls appropriate binary executable/grpc server for unwrapping the session key based on the protocol given in annotation for recipients and gets decrypted optsData,
+// which describe the symmetric key used for decrypting the layer
+func (kw *keyProviderKeyWrapper) UnwrapKey(dc *config.DecryptConfig, jsonString []byte) ([]byte, error) {
+ input, err := json.Marshal(KeyProviderKeyWrapProtocolInput{
+ Operation: OpKeyUnwrap,
+ KeyUnwrapParams: KeyUnwrapParams{
+ Dc: dc,
+ Annotation: jsonString,
+ },
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ if kw.attrs.Command != nil {
+ protocolOuput, err := getProviderCommandOutput(input, kw.attrs.Command)
+ if err != nil {
+ // If err is not nil, then ignore it and continue with rest of the given keyproviders
+ return nil, err
+ }
+
+ return protocolOuput.KeyUnwrapResults.OptsData, nil
+ } else if kw.attrs.Grpc != "" {
+ protocolOuput, err := getProviderGRPCOutput(input, kw.attrs.Grpc, OpKeyUnwrap)
+ if err != nil {
+ // If err is not nil, then ignore it and continue with rest of the given keyproviders
+ return nil, err
+ }
+
+ return protocolOuput.KeyUnwrapResults.OptsData, nil
+ } else {
+ return nil, errors.New("Unsupported keyprovider invocation. Supported invocation methods are grpc and cmd")
+ }
+}
+
+func getProviderGRPCOutput(input []byte, connString string, operation KeyProviderKeyWrapProtocolOperation) (*KeyProviderKeyWrapProtocolOutput, error) {
+ var protocolOuput KeyProviderKeyWrapProtocolOutput
+ var grpcOutput *keyproviderpb.KeyProviderKeyWrapProtocolOutput
+ cc, err := grpc.Dial(connString, grpc.WithInsecure())
+ if err != nil {
+ return nil, errors.Wrap(err, "error while dialing rpc server")
+ }
+ defer func() {
+ derr := cc.Close()
+ if derr != nil {
+ log.WithError(derr).Error("Error closing grpc socket")
+ }
+ }()
+
+ client := keyproviderpb.NewKeyProviderServiceClient(cc)
+ req := &keyproviderpb.KeyProviderKeyWrapProtocolInput{
+ KeyProviderKeyWrapProtocolInput: input,
+ }
+
+ if operation == OpKeyWrap {
+ grpcOutput, err = client.WrapKey(context.Background(), req)
+ if err != nil {
+ return nil, errors.Wrap(err, "Error from grpc method")
+ }
+ } else if operation == OpKeyUnwrap {
+ grpcOutput, err = client.UnWrapKey(context.Background(), req)
+ if err != nil {
+ return nil, errors.Wrap(err, "Error from grpc method")
+ }
+ } else {
+ return nil, errors.New("Unsupported operation")
+ }
+
+ respBytes := grpcOutput.GetKeyProviderKeyWrapProtocolOutput()
+ err = json.Unmarshal(respBytes, &protocolOuput)
+ if err != nil {
+ return nil, errors.Wrap(err, "Error while unmarshalling grpc method output")
+ }
+
+ return &protocolOuput, nil
+}
+
+func getProviderCommandOutput(input []byte, command *keyproviderconfig.Command) (*KeyProviderKeyWrapProtocolOutput, error) {
+ var protocolOuput KeyProviderKeyWrapProtocolOutput
+ // Convert interface to command structure
+ respBytes, err := runner.Exec(command.Path, command.Args, input)
+ if err != nil {
+ return nil, err
+ }
+ err = json.Unmarshal(respBytes, &protocolOuput)
+ if err != nil {
+ return nil, errors.Wrap(err, "Error while unmarshalling binary executable command output")
+ }
+ return &protocolOuput, nil
+}
+
+// Return false as it is not applicable to keyprovider protocol
+func (kw *keyProviderKeyWrapper) NoPossibleKeys(dcparameters map[string][][]byte) bool {
+ return false
+}
+
+// Return nil as it is not applicable to keyprovider protocol
+func (kw *keyProviderKeyWrapper) GetPrivateKeys(dcparameters map[string][][]byte) [][]byte {
+ return nil
+}
+
+// Return nil as it is not applicable to keyprovider protocol
+func (kw *keyProviderKeyWrapper) GetKeyIdsFromPacket(_ string) ([]uint64, error) {
+ return nil, nil
+}
+
+// Return nil as it is not applicable to keyprovider protocol
+func (kw *keyProviderKeyWrapper) GetRecipients(_ string) ([]string, error) {
+ return nil, nil
+}
diff --git a/vendor/github.com/containers/ocicrypt/keywrap/pkcs11/keywrapper_pkcs11.go b/vendor/github.com/containers/ocicrypt/keywrap/pkcs11/keywrapper_pkcs11.go
new file mode 100644
index 000000000..803b90865
--- /dev/null
+++ b/vendor/github.com/containers/ocicrypt/keywrap/pkcs11/keywrapper_pkcs11.go
@@ -0,0 +1,147 @@
+/*
+ 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 pkcs11
+
+import (
+ "github.com/containers/ocicrypt/config"
+ "github.com/containers/ocicrypt/crypto/pkcs11"
+ "github.com/containers/ocicrypt/keywrap"
+ "github.com/containers/ocicrypt/utils"
+
+ "github.com/pkg/errors"
+)
+
+type pkcs11KeyWrapper struct {
+}
+
+func (kw *pkcs11KeyWrapper) GetAnnotationID() string {
+ return "org.opencontainers.image.enc.keys.pkcs11"
+}
+
+// NewKeyWrapper returns a new key wrapping interface using pkcs11
+func NewKeyWrapper() keywrap.KeyWrapper {
+ return &pkcs11KeyWrapper{}
+}
+
+// WrapKeys wraps the session key for recpients and encrypts the optsData, which
+// describe the symmetric key used for encrypting the layer
+func (kw *pkcs11KeyWrapper) WrapKeys(ec *config.EncryptConfig, optsData []byte) ([]byte, error) {
+ pkcs11Recipients, err := addPubKeys(&ec.DecryptConfig, append(ec.Parameters["pkcs11-pubkeys"], ec.Parameters["pkcs11-yamls"]...))
+ if err != nil {
+ return nil, err
+ }
+ // no recipients is not an error...
+ if len(pkcs11Recipients) == 0 {
+ return nil, nil
+ }
+
+ jsonString, err := pkcs11.EncryptMultiple(pkcs11Recipients, optsData)
+ if err != nil {
+ return nil, errors.Wrapf(err, "PKCS11 EncryptMulitple failed")
+ }
+ return jsonString, nil
+}
+
+func (kw *pkcs11KeyWrapper) UnwrapKey(dc *config.DecryptConfig, jsonString []byte) ([]byte, error) {
+ var pkcs11PrivKeys []*pkcs11.Pkcs11KeyFileObject
+
+ privKeys := kw.GetPrivateKeys(dc.Parameters)
+ if len(privKeys) == 0 {
+ return nil, errors.New("No private keys found for PKCS11 decryption")
+ }
+
+ p11conf, err := p11confFromParameters(dc.Parameters)
+ if err != nil {
+ return nil, err
+ }
+
+ for _, privKey := range privKeys {
+ key, err := utils.ParsePrivateKey(privKey, nil, "PKCS11")
+ if err != nil {
+ return nil, err
+ }
+ switch pkcs11PrivKey := key.(type) {
+ case *pkcs11.Pkcs11KeyFileObject:
+ if p11conf != nil {
+ pkcs11PrivKey.Uri.SetModuleDirectories(p11conf.ModuleDirectories)
+ pkcs11PrivKey.Uri.SetAllowedModulePaths(p11conf.AllowedModulePaths)
+ }
+ pkcs11PrivKeys = append(pkcs11PrivKeys, pkcs11PrivKey)
+ default:
+ continue
+ }
+ }
+
+ plaintext, err := pkcs11.Decrypt(pkcs11PrivKeys, jsonString)
+ if err == nil {
+ return plaintext, nil
+ }
+
+ return nil, errors.Wrapf(err, "PKCS11: No suitable private key found for decryption")
+}
+
+func (kw *pkcs11KeyWrapper) NoPossibleKeys(dcparameters map[string][][]byte) bool {
+ return len(kw.GetPrivateKeys(dcparameters)) == 0
+}
+
+func (kw *pkcs11KeyWrapper) GetPrivateKeys(dcparameters map[string][][]byte) [][]byte {
+ return dcparameters["pkcs11-yamls"]
+}
+
+func (kw *pkcs11KeyWrapper) GetKeyIdsFromPacket(_ string) ([]uint64, error) {
+ return nil, nil
+}
+
+func (kw *pkcs11KeyWrapper) GetRecipients(_ string) ([]string, error) {
+ return []string{"[pkcs11]"}, nil
+}
+
+func addPubKeys(dc *config.DecryptConfig, pubKeys [][]byte) ([]interface{}, error) {
+ var pkcs11Keys []interface{}
+
+ if len(pubKeys) == 0 {
+ return pkcs11Keys, nil
+ }
+
+ p11conf, err := p11confFromParameters(dc.Parameters)
+ if err != nil {
+ return nil, err
+ }
+
+ for _, pubKey := range pubKeys {
+ key, err := utils.ParsePublicKey(pubKey, "PKCS11")
+ if err != nil {
+ return nil, err
+ }
+ switch pkcs11PubKey := key.(type) {
+ case *pkcs11.Pkcs11KeyFileObject:
+ if p11conf != nil {
+ pkcs11PubKey.Uri.SetModuleDirectories(p11conf.ModuleDirectories)
+ pkcs11PubKey.Uri.SetAllowedModulePaths(p11conf.AllowedModulePaths)
+ }
+ }
+ pkcs11Keys = append(pkcs11Keys, key)
+ }
+ return pkcs11Keys, nil
+}
+
+func p11confFromParameters(dcparameters map[string][][]byte) (*pkcs11.Pkcs11Config, error){
+ if _, ok := dcparameters["pkcs11-config"]; ok {
+ return pkcs11.ParsePkcs11ConfigFile(dcparameters["pkcs11-config"][0])
+ }
+ return nil, nil
+}
diff --git a/vendor/github.com/containers/ocicrypt/utils/ioutils.go b/vendor/github.com/containers/ocicrypt/utils/ioutils.go
index c360e0a33..078c34799 100644
--- a/vendor/github.com/containers/ocicrypt/utils/ioutils.go
+++ b/vendor/github.com/containers/ocicrypt/utils/ioutils.go
@@ -17,7 +17,10 @@
package utils
import (
+ "bytes"
"io"
+ "os/exec"
+ "github.com/pkg/errors"
)
// FillBuffer fills the given buffer with as many bytes from the reader as possible. It returns
@@ -29,3 +32,25 @@ func FillBuffer(reader io.Reader, buffer []byte) (int, error) {
}
return n, err
}
+
+// first argument is the command, like cat or echo,
+// the second is the list of args to pass to it
+type CommandExecuter interface {
+ Exec(string, []string, []byte) ([]byte, error)
+}
+
+type Runner struct{}
+
+// ExecuteCommand is used to execute a linux command line command and return the output of the command with an error if it exists.
+func (r Runner) Exec(cmdName string, args []string, input []byte) ([]byte, error) {
+ var out bytes.Buffer
+ stdInputBuffer := bytes.NewBuffer(input)
+ cmd := exec.Command(cmdName, args...)
+ cmd.Stdin = stdInputBuffer
+ cmd.Stdout = &out
+ err := cmd.Run()
+ if err != nil {
+ return nil, errors.Wrapf(err, "Error while running command: %s", cmdName)
+ }
+ return out.Bytes(), nil
+}
diff --git a/vendor/github.com/containers/ocicrypt/utils/keyprovider/keyprovider.pb.go b/vendor/github.com/containers/ocicrypt/utils/keyprovider/keyprovider.pb.go
new file mode 100644
index 000000000..dc477d3cf
--- /dev/null
+++ b/vendor/github.com/containers/ocicrypt/utils/keyprovider/keyprovider.pb.go
@@ -0,0 +1,243 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: keyprovider.proto
+
+package keyprovider
+
+import (
+ context "context"
+ fmt "fmt"
+ proto "github.com/golang/protobuf/proto"
+ grpc "google.golang.org/grpc"
+ codes "google.golang.org/grpc/codes"
+ status "google.golang.org/grpc/status"
+ math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
+
+type KeyProviderKeyWrapProtocolInput struct {
+ KeyProviderKeyWrapProtocolInput []byte `protobuf:"bytes,1,opt,name=KeyProviderKeyWrapProtocolInput,proto3" json:"KeyProviderKeyWrapProtocolInput,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *KeyProviderKeyWrapProtocolInput) Reset() { *m = KeyProviderKeyWrapProtocolInput{} }
+func (m *KeyProviderKeyWrapProtocolInput) String() string { return proto.CompactTextString(m) }
+func (*KeyProviderKeyWrapProtocolInput) ProtoMessage() {}
+func (*KeyProviderKeyWrapProtocolInput) Descriptor() ([]byte, []int) {
+ return fileDescriptor_da74c8e785ad390c, []int{0}
+}
+
+func (m *KeyProviderKeyWrapProtocolInput) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_KeyProviderKeyWrapProtocolInput.Unmarshal(m, b)
+}
+func (m *KeyProviderKeyWrapProtocolInput) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_KeyProviderKeyWrapProtocolInput.Marshal(b, m, deterministic)
+}
+func (m *KeyProviderKeyWrapProtocolInput) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_KeyProviderKeyWrapProtocolInput.Merge(m, src)
+}
+func (m *KeyProviderKeyWrapProtocolInput) XXX_Size() int {
+ return xxx_messageInfo_KeyProviderKeyWrapProtocolInput.Size(m)
+}
+func (m *KeyProviderKeyWrapProtocolInput) XXX_DiscardUnknown() {
+ xxx_messageInfo_KeyProviderKeyWrapProtocolInput.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_KeyProviderKeyWrapProtocolInput proto.InternalMessageInfo
+
+func (m *KeyProviderKeyWrapProtocolInput) GetKeyProviderKeyWrapProtocolInput() []byte {
+ if m != nil {
+ return m.KeyProviderKeyWrapProtocolInput
+ }
+ return nil
+}
+
+type KeyProviderKeyWrapProtocolOutput struct {
+ KeyProviderKeyWrapProtocolOutput []byte `protobuf:"bytes,1,opt,name=KeyProviderKeyWrapProtocolOutput,proto3" json:"KeyProviderKeyWrapProtocolOutput,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *KeyProviderKeyWrapProtocolOutput) Reset() { *m = KeyProviderKeyWrapProtocolOutput{} }
+func (m *KeyProviderKeyWrapProtocolOutput) String() string { return proto.CompactTextString(m) }
+func (*KeyProviderKeyWrapProtocolOutput) ProtoMessage() {}
+func (*KeyProviderKeyWrapProtocolOutput) Descriptor() ([]byte, []int) {
+ return fileDescriptor_da74c8e785ad390c, []int{1}
+}
+
+func (m *KeyProviderKeyWrapProtocolOutput) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_KeyProviderKeyWrapProtocolOutput.Unmarshal(m, b)
+}
+func (m *KeyProviderKeyWrapProtocolOutput) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_KeyProviderKeyWrapProtocolOutput.Marshal(b, m, deterministic)
+}
+func (m *KeyProviderKeyWrapProtocolOutput) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_KeyProviderKeyWrapProtocolOutput.Merge(m, src)
+}
+func (m *KeyProviderKeyWrapProtocolOutput) XXX_Size() int {
+ return xxx_messageInfo_KeyProviderKeyWrapProtocolOutput.Size(m)
+}
+func (m *KeyProviderKeyWrapProtocolOutput) XXX_DiscardUnknown() {
+ xxx_messageInfo_KeyProviderKeyWrapProtocolOutput.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_KeyProviderKeyWrapProtocolOutput proto.InternalMessageInfo
+
+func (m *KeyProviderKeyWrapProtocolOutput) GetKeyProviderKeyWrapProtocolOutput() []byte {
+ if m != nil {
+ return m.KeyProviderKeyWrapProtocolOutput
+ }
+ return nil
+}
+
+func init() {
+ proto.RegisterType((*KeyProviderKeyWrapProtocolInput)(nil), "keyprovider.keyProviderKeyWrapProtocolInput")
+ proto.RegisterType((*KeyProviderKeyWrapProtocolOutput)(nil), "keyprovider.keyProviderKeyWrapProtocolOutput")
+}
+
+func init() {
+ proto.RegisterFile("keyprovider.proto", fileDescriptor_da74c8e785ad390c)
+}
+
+var fileDescriptor_da74c8e785ad390c = []byte{
+ // 169 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x12, 0xcc, 0x4e, 0xad, 0x2c,
+ 0x28, 0xca, 0x2f, 0xcb, 0x4c, 0x49, 0x2d, 0xd2, 0x03, 0x32, 0x4a, 0xf2, 0x85, 0xb8, 0x91, 0x84,
+ 0x94, 0xb2, 0xb9, 0xe4, 0x81, 0xdc, 0x00, 0x28, 0xd7, 0x3b, 0xb5, 0x32, 0xbc, 0x28, 0xb1, 0x20,
+ 0x00, 0xa4, 0x2e, 0x39, 0x3f, 0xc7, 0x33, 0xaf, 0xa0, 0xb4, 0x44, 0xc8, 0x83, 0x4b, 0xde, 0x1b,
+ 0xbf, 0x12, 0x09, 0x46, 0x05, 0x46, 0x0d, 0x9e, 0x20, 0x42, 0xca, 0x94, 0xf2, 0xb8, 0x14, 0x70,
+ 0x5b, 0xe6, 0x5f, 0x5a, 0x02, 0xb2, 0xcd, 0x8b, 0x4b, 0xc1, 0x9b, 0x80, 0x1a, 0xa8, 0x75, 0x04,
+ 0xd5, 0x19, 0xbd, 0x62, 0xe4, 0x12, 0x42, 0x52, 0x14, 0x9c, 0x5a, 0x54, 0x96, 0x99, 0x9c, 0x2a,
+ 0x94, 0xc1, 0xc5, 0x0e, 0x52, 0x0c, 0x94, 0x11, 0xd2, 0xd1, 0x43, 0x0e, 0x1f, 0x02, 0x21, 0x21,
+ 0xa5, 0x4b, 0xa4, 0x6a, 0x88, 0xf5, 0x4a, 0x0c, 0x42, 0x59, 0x5c, 0x9c, 0xa1, 0x79, 0xf4, 0xb1,
+ 0xcb, 0x89, 0x37, 0x0a, 0x39, 0x62, 0x93, 0xd8, 0xc0, 0x91, 0x6d, 0x0c, 0x08, 0x00, 0x00, 0xff,
+ 0xff, 0x9a, 0x10, 0xcb, 0xf9, 0x01, 0x02, 0x00, 0x00,
+}
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConnInterface
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion6
+
+// KeyProviderServiceClient is the client API for KeyProviderService service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
+type KeyProviderServiceClient interface {
+ WrapKey(ctx context.Context, in *KeyProviderKeyWrapProtocolInput, opts ...grpc.CallOption) (*KeyProviderKeyWrapProtocolOutput, error)
+ UnWrapKey(ctx context.Context, in *KeyProviderKeyWrapProtocolInput, opts ...grpc.CallOption) (*KeyProviderKeyWrapProtocolOutput, error)
+}
+
+type keyProviderServiceClient struct {
+ cc grpc.ClientConnInterface
+}
+
+func NewKeyProviderServiceClient(cc grpc.ClientConnInterface) KeyProviderServiceClient {
+ return &keyProviderServiceClient{cc}
+}
+
+func (c *keyProviderServiceClient) WrapKey(ctx context.Context, in *KeyProviderKeyWrapProtocolInput, opts ...grpc.CallOption) (*KeyProviderKeyWrapProtocolOutput, error) {
+ out := new(KeyProviderKeyWrapProtocolOutput)
+ err := c.cc.Invoke(ctx, "/keyprovider.KeyProviderService/WrapKey", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *keyProviderServiceClient) UnWrapKey(ctx context.Context, in *KeyProviderKeyWrapProtocolInput, opts ...grpc.CallOption) (*KeyProviderKeyWrapProtocolOutput, error) {
+ out := new(KeyProviderKeyWrapProtocolOutput)
+ err := c.cc.Invoke(ctx, "/keyprovider.KeyProviderService/UnWrapKey", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+// KeyProviderServiceServer is the server API for KeyProviderService service.
+type KeyProviderServiceServer interface {
+ WrapKey(context.Context, *KeyProviderKeyWrapProtocolInput) (*KeyProviderKeyWrapProtocolOutput, error)
+ UnWrapKey(context.Context, *KeyProviderKeyWrapProtocolInput) (*KeyProviderKeyWrapProtocolOutput, error)
+}
+
+// UnimplementedKeyProviderServiceServer can be embedded to have forward compatible implementations.
+type UnimplementedKeyProviderServiceServer struct {
+}
+
+func (*UnimplementedKeyProviderServiceServer) WrapKey(ctx context.Context, req *KeyProviderKeyWrapProtocolInput) (*KeyProviderKeyWrapProtocolOutput, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method WrapKey not implemented")
+}
+func (*UnimplementedKeyProviderServiceServer) UnWrapKey(ctx context.Context, req *KeyProviderKeyWrapProtocolInput) (*KeyProviderKeyWrapProtocolOutput, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method UnWrapKey not implemented")
+}
+
+func RegisterKeyProviderServiceServer(s *grpc.Server, srv KeyProviderServiceServer) {
+ s.RegisterService(&_KeyProviderService_serviceDesc, srv)
+}
+
+func _KeyProviderService_WrapKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(KeyProviderKeyWrapProtocolInput)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(KeyProviderServiceServer).WrapKey(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/keyprovider.KeyProviderService/WrapKey",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(KeyProviderServiceServer).WrapKey(ctx, req.(*KeyProviderKeyWrapProtocolInput))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _KeyProviderService_UnWrapKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(KeyProviderKeyWrapProtocolInput)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(KeyProviderServiceServer).UnWrapKey(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/keyprovider.KeyProviderService/UnWrapKey",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(KeyProviderServiceServer).UnWrapKey(ctx, req.(*KeyProviderKeyWrapProtocolInput))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+var _KeyProviderService_serviceDesc = grpc.ServiceDesc{
+ ServiceName: "keyprovider.KeyProviderService",
+ HandlerType: (*KeyProviderServiceServer)(nil),
+ Methods: []grpc.MethodDesc{
+ {
+ MethodName: "WrapKey",
+ Handler: _KeyProviderService_WrapKey_Handler,
+ },
+ {
+ MethodName: "UnWrapKey",
+ Handler: _KeyProviderService_UnWrapKey_Handler,
+ },
+ },
+ Streams: []grpc.StreamDesc{},
+ Metadata: "keyprovider.proto",
+}
diff --git a/vendor/github.com/containers/ocicrypt/utils/keyprovider/keyprovider.proto b/vendor/github.com/containers/ocicrypt/utils/keyprovider/keyprovider.proto
new file mode 100644
index 000000000..a71f0a592
--- /dev/null
+++ b/vendor/github.com/containers/ocicrypt/utils/keyprovider/keyprovider.proto
@@ -0,0 +1,17 @@
+syntax = "proto3";
+
+package keyprovider;
+option go_package = "keyprovider";
+
+message keyProviderKeyWrapProtocolInput {
+ bytes KeyProviderKeyWrapProtocolInput = 1;
+}
+
+message keyProviderKeyWrapProtocolOutput {
+ bytes KeyProviderKeyWrapProtocolOutput = 1;
+}
+
+service KeyProviderService {
+ rpc WrapKey(keyProviderKeyWrapProtocolInput) returns (keyProviderKeyWrapProtocolOutput) {};
+ rpc UnWrapKey(keyProviderKeyWrapProtocolInput) returns (keyProviderKeyWrapProtocolOutput) {};
+} \ No newline at end of file
diff --git a/vendor/github.com/containers/ocicrypt/utils/utils.go b/vendor/github.com/containers/ocicrypt/utils/utils.go
index 14eea38c1..7bc2aa28d 100644
--- a/vendor/github.com/containers/ocicrypt/utils/utils.go
+++ b/vendor/github.com/containers/ocicrypt/utils/utils.go
@@ -24,6 +24,8 @@ import (
"fmt"
"strings"
+ "github.com/containers/ocicrypt/crypto/pkcs11"
+
"github.com/pkg/errors"
"golang.org/x/crypto/openpgp"
json "gopkg.in/square/go-jose.v2"
@@ -55,6 +57,18 @@ func parseJWKPublicKey(privKey []byte, prefix string) (interface{}, error) {
return &jwk, nil
}
+// parsePkcs11PrivateKeyYaml parses the input byte array as pkcs11 key file yaml format)
+func parsePkcs11PrivateKeyYaml(yaml []byte, prefix string) (*pkcs11.Pkcs11KeyFileObject, error) {
+ // if the URI does not have enough attributes, we will throw an error when decrypting
+ return pkcs11.ParsePkcs11KeyFile(yaml)
+}
+
+// parsePkcs11URIPublicKey parses the input byte array as a pkcs11 key file yaml
+func parsePkcs11PublicKeyYaml(yaml []byte, prefix string) (*pkcs11.Pkcs11KeyFileObject, error) {
+ // if the URI does not have enough attributes, we will throw an error when decrypting
+ return pkcs11.ParsePkcs11KeyFile(yaml)
+}
+
// IsPasswordError checks whether an error is related to a missing or wrong
// password
func IsPasswordError(err error) bool {
@@ -102,6 +116,9 @@ func ParsePrivateKey(privKey, privKeyPassword []byte, prefix string) (interface{
}
} else {
key, err = parseJWKPrivateKey(privKey, prefix)
+ if err != nil {
+ key, err = parsePkcs11PrivateKeyYaml(privKey, prefix)
+ }
}
}
return key, err
@@ -114,6 +131,11 @@ func IsPrivateKey(data []byte, password []byte) (bool, error) {
return err == nil, err
}
+// IsPkcs11PrivateKey returns true in case the given byte array represents a pkcs11 private key
+func IsPkcs11PrivateKey(data []byte) bool {
+ return pkcs11.IsPkcs11PrivateKey(data)
+}
+
// ParsePublicKey tries to parse a public key in DER format first and
// PEM format after, returning an error if the parsing failed
func ParsePublicKey(pubKey []byte, prefix string) (interface{}, error) {
@@ -127,6 +149,9 @@ func ParsePublicKey(pubKey []byte, prefix string) (interface{}, error) {
}
} else {
key, err = parseJWKPublicKey(pubKey, prefix)
+ if err != nil {
+ key, err = parsePkcs11PublicKeyYaml(pubKey, prefix)
+ }
}
}
return key, err
@@ -138,6 +163,11 @@ func IsPublicKey(data []byte) bool {
return err == nil
}
+// IsPkcs11PublicKey returns true in case the given byte array represents a pkcs11 public key
+func IsPkcs11PublicKey(data []byte) bool {
+ return pkcs11.IsPkcs11PublicKey(data)
+}
+
// ParseCertificate tries to parse a public key in DER format first and
// PEM format after, returning an error if the parsing failed
func ParseCertificate(certBytes []byte, prefix string) (*x509.Certificate, error) {