summaryrefslogtreecommitdiff
path: root/vendor/github.com
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com')
-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
-rw-r--r--vendor/github.com/miekg/pkcs11/.gitignore3
-rw-r--r--vendor/github.com/miekg/pkcs11/.travis.yml14
-rw-r--r--vendor/github.com/miekg/pkcs11/LICENSE27
-rw-r--r--vendor/github.com/miekg/pkcs11/Makefile.release57
-rw-r--r--vendor/github.com/miekg/pkcs11/README.md68
-rw-r--r--vendor/github.com/miekg/pkcs11/const.go736
-rw-r--r--vendor/github.com/miekg/pkcs11/error.go98
-rw-r--r--vendor/github.com/miekg/pkcs11/go.mod3
-rw-r--r--vendor/github.com/miekg/pkcs11/hsm.dbbin0 -> 10240 bytes
-rw-r--r--vendor/github.com/miekg/pkcs11/params.go190
-rw-r--r--vendor/github.com/miekg/pkcs11/pkcs11.go1606
-rw-r--r--vendor/github.com/miekg/pkcs11/pkcs11.h265
-rw-r--r--vendor/github.com/miekg/pkcs11/pkcs11f.h939
-rw-r--r--vendor/github.com/miekg/pkcs11/pkcs11go.h33
-rw-r--r--vendor/github.com/miekg/pkcs11/pkcs11t.h2047
-rw-r--r--vendor/github.com/miekg/pkcs11/release.go17
-rw-r--r--vendor/github.com/miekg/pkcs11/softhsm.conf1
-rw-r--r--vendor/github.com/miekg/pkcs11/softhsm2.conf4
-rw-r--r--vendor/github.com/miekg/pkcs11/types.go303
-rw-r--r--vendor/github.com/miekg/pkcs11/vendor.go127
-rw-r--r--vendor/github.com/stefanberger/go-pkcs11uri/.gitignore2
-rw-r--r--vendor/github.com/stefanberger/go-pkcs11uri/.travis.yml25
-rw-r--r--vendor/github.com/stefanberger/go-pkcs11uri/LICENSE177
-rw-r--r--vendor/github.com/stefanberger/go-pkcs11uri/Makefile28
-rw-r--r--vendor/github.com/stefanberger/go-pkcs11uri/README.md102
-rw-r--r--vendor/github.com/stefanberger/go-pkcs11uri/pkcs11uri.go453
47 files changed, 9390 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) {
diff --git a/vendor/github.com/miekg/pkcs11/.gitignore b/vendor/github.com/miekg/pkcs11/.gitignore
new file mode 100644
index 000000000..5fde17f99
--- /dev/null
+++ b/vendor/github.com/miekg/pkcs11/.gitignore
@@ -0,0 +1,3 @@
+tags
+test_db/*/generation
+test_db/*/*.lock
diff --git a/vendor/github.com/miekg/pkcs11/.travis.yml b/vendor/github.com/miekg/pkcs11/.travis.yml
new file mode 100644
index 000000000..687044d83
--- /dev/null
+++ b/vendor/github.com/miekg/pkcs11/.travis.yml
@@ -0,0 +1,14 @@
+language: go
+sudo: required
+dist: trusty
+
+go:
+ - 1.9
+ - tip
+
+script:
+ - go test -v ./...
+
+before_script:
+ - sudo apt-get update
+ - sudo apt-get -y install libsofthsm
diff --git a/vendor/github.com/miekg/pkcs11/LICENSE b/vendor/github.com/miekg/pkcs11/LICENSE
new file mode 100644
index 000000000..ce25d13ab
--- /dev/null
+++ b/vendor/github.com/miekg/pkcs11/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2013 Miek Gieben. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Miek Gieben nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/miekg/pkcs11/Makefile.release b/vendor/github.com/miekg/pkcs11/Makefile.release
new file mode 100644
index 000000000..4f58165f9
--- /dev/null
+++ b/vendor/github.com/miekg/pkcs11/Makefile.release
@@ -0,0 +1,57 @@
+# Makefile for releasing.
+#
+# The release is controlled from version.go. The version found there is
+# used to tag the git repo, we're not building any artifects so there is nothing
+# to upload to github.
+#
+# * Up the version in version.go
+# * Run: make -f Makefile.release release
+# * will *commit* your change with 'Release $VERSION'
+# * push to github
+#
+
+define GO
+//+build ignore
+
+package main
+
+import (
+ "fmt"
+
+ "github.com/miekg/pkcs11"
+)
+
+func main() {
+ fmt.Println(pkcs11.Release.String())
+}
+endef
+
+$(file > version_release.go,$(GO))
+VERSION:=$(shell go run -tags release version_release.go)
+TAG="v$(VERSION)"
+
+all:
+ rm -f version_release.go
+ @echo Use the \'release\' target to start a release $(VERSION)
+
+.PHONY: run
+run:
+ rm -f version_release.go
+ @echo $(VERSION)
+
+.PHONY: release
+release: commit push
+ @echo Released $(VERSION)
+
+.PHONY: commit
+commit:
+ rm -f version_release.go
+ @echo Committing release $(VERSION)
+ git commit -am"Release $(VERSION)"
+ git tag $(TAG)
+
+.PHONY: push
+push:
+ @echo Pushing release $(VERSION) to master
+ git push --tags
+ git push
diff --git a/vendor/github.com/miekg/pkcs11/README.md b/vendor/github.com/miekg/pkcs11/README.md
new file mode 100644
index 000000000..0a5c1b7b6
--- /dev/null
+++ b/vendor/github.com/miekg/pkcs11/README.md
@@ -0,0 +1,68 @@
+# PKCS#11 [![Build Status](https://travis-ci.org/miekg/pkcs11.png?branch=master)](https://travis-ci.org/miekg/pkcs11) [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](http://godoc.org/github.com/miekg/pkcs11)
+
+This is a Go implementation of the PKCS#11 API. It wraps the library closely, but uses Go idiom were
+it makes sense. It has been tested with SoftHSM.
+
+## SoftHSM
+
+ * Make it use a custom configuration file `export SOFTHSM_CONF=$PWD/softhsm.conf`
+
+ * Then use `softhsm` to init it
+
+ ~~~
+ softhsm --init-token --slot 0 --label test --pin 1234
+ ~~~
+
+ * Then use `libsofthsm.so` as the pkcs11 module:
+
+ ~~~ go
+ p := pkcs11.New("/usr/lib/softhsm/libsofthsm.so")
+ ~~~
+
+## Examples
+
+A skeleton program would look somewhat like this (yes, pkcs#11 is verbose):
+
+~~~ go
+p := pkcs11.New("/usr/lib/softhsm/libsofthsm.so")
+err := p.Initialize()
+if err != nil {
+ panic(err)
+}
+
+defer p.Destroy()
+defer p.Finalize()
+
+slots, err := p.GetSlotList(true)
+if err != nil {
+ panic(err)
+}
+
+session, err := p.OpenSession(slots[0], pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION)
+if err != nil {
+ panic(err)
+}
+defer p.CloseSession(session)
+
+err = p.Login(session, pkcs11.CKU_USER, "1234")
+if err != nil {
+ panic(err)
+}
+defer p.Logout(session)
+
+p.DigestInit(session, []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_SHA_1, nil)})
+hash, err := p.Digest(session, []byte("this is a string"))
+if err != nil {
+ panic(err)
+}
+
+for _, d := range hash {
+ fmt.Printf("%x", d)
+}
+fmt.Println()
+~~~
+
+Further examples are included in the tests.
+
+To expose PKCS#11 keys using the [crypto.Signer interface](https://golang.org/pkg/crypto/#Signer),
+please see [github.com/thalesignite/crypto11](https://github.com/thalesignite/crypto11).
diff --git a/vendor/github.com/miekg/pkcs11/const.go b/vendor/github.com/miekg/pkcs11/const.go
new file mode 100644
index 000000000..408856146
--- /dev/null
+++ b/vendor/github.com/miekg/pkcs11/const.go
@@ -0,0 +1,736 @@
+// Copyright 2013 Miek Gieben. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkcs11
+
+const (
+ CKU_SO uint = 0
+ CKU_USER uint = 1
+ CKU_CONTEXT_SPECIFIC uint = 2
+)
+
+const (
+ CKO_DATA uint = 0x00000000
+ CKO_CERTIFICATE uint = 0x00000001
+ CKO_PUBLIC_KEY uint = 0x00000002
+ CKO_PRIVATE_KEY uint = 0x00000003
+ CKO_SECRET_KEY uint = 0x00000004
+ CKO_HW_FEATURE uint = 0x00000005
+ CKO_DOMAIN_PARAMETERS uint = 0x00000006
+ CKO_MECHANISM uint = 0x00000007
+ CKO_OTP_KEY uint = 0x00000008
+ CKO_VENDOR_DEFINED uint = 0x80000000
+)
+
+const (
+ CKG_MGF1_SHA1 uint = 0x00000001
+ CKG_MGF1_SHA224 uint = 0x00000005
+ CKG_MGF1_SHA256 uint = 0x00000002
+ CKG_MGF1_SHA384 uint = 0x00000003
+ CKG_MGF1_SHA512 uint = 0x00000004
+ CKG_MGF1_SHA3_224 uint = 0x00000006
+ CKG_MGF1_SHA3_256 uint = 0x00000007
+ CKG_MGF1_SHA3_384 uint = 0x00000008
+ CKG_MGF1_SHA3_512 uint = 0x00000009
+)
+
+const (
+ CKZ_DATA_SPECIFIED uint = 0x00000001
+)
+
+// Generated with: awk '/#define CK[AFKMRC]/{ print $2 " = " $3 }' pkcs11t.h | sed -e 's/UL$//g' -e 's/UL)$/)/g'
+
+// All the flag (CKF_), attribute (CKA_), error code (CKR_), key type (CKK_), certificate type (CKC_) and
+// mechanism (CKM_) constants as defined in PKCS#11.
+const (
+ CKF_TOKEN_PRESENT = 0x00000001
+ CKF_REMOVABLE_DEVICE = 0x00000002
+ CKF_HW_SLOT = 0x00000004
+ CKF_RNG = 0x00000001
+ CKF_WRITE_PROTECTED = 0x00000002
+ CKF_LOGIN_REQUIRED = 0x00000004
+ CKF_USER_PIN_INITIALIZED = 0x00000008
+ CKF_RESTORE_KEY_NOT_NEEDED = 0x00000020
+ CKF_CLOCK_ON_TOKEN = 0x00000040
+ CKF_PROTECTED_AUTHENTICATION_PATH = 0x00000100
+ CKF_DUAL_CRYPTO_OPERATIONS = 0x00000200
+ CKF_TOKEN_INITIALIZED = 0x00000400
+ CKF_SECONDARY_AUTHENTICATION = 0x00000800
+ CKF_USER_PIN_COUNT_LOW = 0x00010000
+ CKF_USER_PIN_FINAL_TRY = 0x00020000
+ CKF_USER_PIN_LOCKED = 0x00040000
+ CKF_USER_PIN_TO_BE_CHANGED = 0x00080000
+ CKF_SO_PIN_COUNT_LOW = 0x00100000
+ CKF_SO_PIN_FINAL_TRY = 0x00200000
+ CKF_SO_PIN_LOCKED = 0x00400000
+ CKF_SO_PIN_TO_BE_CHANGED = 0x00800000
+ CKF_ERROR_STATE = 0x01000000
+ CKF_RW_SESSION = 0x00000002
+ CKF_SERIAL_SESSION = 0x00000004
+ CKK_RSA = 0x00000000
+ CKK_DSA = 0x00000001
+ CKK_DH = 0x00000002
+ CKK_ECDSA = 0x00000003
+ CKK_EC = 0x00000003
+ CKK_X9_42_DH = 0x00000004
+ CKK_KEA = 0x00000005
+ CKK_GENERIC_SECRET = 0x00000010
+ CKK_RC2 = 0x00000011
+ CKK_RC4 = 0x00000012
+ CKK_DES = 0x00000013
+ CKK_DES2 = 0x00000014
+ CKK_DES3 = 0x00000015
+ CKK_CAST = 0x00000016
+ CKK_CAST3 = 0x00000017
+ CKK_CAST5 = 0x00000018
+ CKK_CAST128 = 0x00000018
+ CKK_RC5 = 0x00000019
+ CKK_IDEA = 0x0000001A
+ CKK_SKIPJACK = 0x0000001B
+ CKK_BATON = 0x0000001C
+ CKK_JUNIPER = 0x0000001D
+ CKK_CDMF = 0x0000001E
+ CKK_AES = 0x0000001F
+ CKK_BLOWFISH = 0x00000020
+ CKK_TWOFISH = 0x00000021
+ CKK_SECURID = 0x00000022
+ CKK_HOTP = 0x00000023
+ CKK_ACTI = 0x00000024
+ CKK_CAMELLIA = 0x00000025
+ CKK_ARIA = 0x00000026
+ CKK_SHA512_224_HMAC = 0x00000027
+ CKK_SHA512_256_HMAC = 0x00000028
+ CKK_SHA512_T_HMAC = 0x00000029
+ CKK_SHA_1_HMAC = 0x00000028
+ CKK_SHA224_HMAC = 0x0000002E
+ CKK_SHA256_HMAC = 0x0000002B
+ CKK_SHA384_HMAC = 0x0000002C
+ CKK_SHA512_HMAC = 0x0000002D
+ CKK_SEED = 0x0000002F
+ CKK_GOSTR3410 = 0x00000030
+ CKK_GOSTR3411 = 0x00000031
+ CKK_GOST28147 = 0x00000032
+ CKK_SHA3_224_HMAC = 0x00000033
+ CKK_SHA3_256_HMAC = 0x00000034
+ CKK_SHA3_384_HMAC = 0x00000035
+ CKK_SHA3_512_HMAC = 0x00000036
+ CKK_VENDOR_DEFINED = 0x80000000
+ CKC_X_509 = 0x00000000
+ CKC_X_509_ATTR_CERT = 0x00000001
+ CKC_WTLS = 0x00000002
+ CKC_VENDOR_DEFINED = 0x80000000
+ CKF_ARRAY_ATTRIBUTE = 0x40000000
+ CKA_CLASS = 0x00000000
+ CKA_TOKEN = 0x00000001
+ CKA_PRIVATE = 0x00000002
+ CKA_LABEL = 0x00000003
+ CKA_APPLICATION = 0x00000010
+ CKA_VALUE = 0x00000011
+ CKA_OBJECT_ID = 0x00000012
+ CKA_CERTIFICATE_TYPE = 0x00000080
+ CKA_ISSUER = 0x00000081
+ CKA_SERIAL_NUMBER = 0x00000082
+ CKA_AC_ISSUER = 0x00000083
+ CKA_OWNER = 0x00000084
+ CKA_ATTR_TYPES = 0x00000085
+ CKA_TRUSTED = 0x00000086
+ CKA_CERTIFICATE_CATEGORY = 0x00000087
+ CKA_JAVA_MIDP_SECURITY_DOMAIN = 0x00000088
+ CKA_URL = 0x00000089
+ CKA_HASH_OF_SUBJECT_PUBLIC_KEY = 0x0000008A
+ CKA_HASH_OF_ISSUER_PUBLIC_KEY = 0x0000008B
+ CKA_NAME_HASH_ALGORITHM = 0x0000008C
+ CKA_CHECK_VALUE = 0x00000090
+ CKA_KEY_TYPE = 0x00000100
+ CKA_SUBJECT = 0x00000101
+ CKA_ID = 0x00000102
+ CKA_SENSITIVE = 0x00000103
+ CKA_ENCRYPT = 0x00000104
+ CKA_DECRYPT = 0x00000105
+ CKA_WRAP = 0x00000106
+ CKA_UNWRAP = 0x00000107
+ CKA_SIGN = 0x00000108
+ CKA_SIGN_RECOVER = 0x00000109
+ CKA_VERIFY = 0x0000010A
+ CKA_VERIFY_RECOVER = 0x0000010B
+ CKA_DERIVE = 0x0000010C
+ CKA_START_DATE = 0x00000110
+ CKA_END_DATE = 0x00000111
+ CKA_MODULUS = 0x00000120
+ CKA_MODULUS_BITS = 0x00000121
+ CKA_PUBLIC_EXPONENT = 0x00000122
+ CKA_PRIVATE_EXPONENT = 0x00000123
+ CKA_PRIME_1 = 0x00000124
+ CKA_PRIME_2 = 0x00000125
+ CKA_EXPONENT_1 = 0x00000126
+ CKA_EXPONENT_2 = 0x00000127
+ CKA_COEFFICIENT = 0x00000128
+ CKA_PUBLIC_KEY_INFO = 0x00000129
+ CKA_PRIME = 0x00000130
+ CKA_SUBPRIME = 0x00000131
+ CKA_BASE = 0x00000132
+ CKA_PRIME_BITS = 0x00000133
+ CKA_SUBPRIME_BITS = 0x00000134
+ CKA_SUB_PRIME_BITS = CKA_SUBPRIME_BITS
+ CKA_VALUE_BITS = 0x00000160
+ CKA_VALUE_LEN = 0x00000161
+ CKA_EXTRACTABLE = 0x00000162
+ CKA_LOCAL = 0x00000163
+ CKA_NEVER_EXTRACTABLE = 0x00000164
+ CKA_ALWAYS_SENSITIVE = 0x00000165
+ CKA_KEY_GEN_MECHANISM = 0x00000166
+ CKA_MODIFIABLE = 0x00000170
+ CKA_COPYABLE = 0x00000171
+ CKA_DESTROYABLE = 0x00000172
+ CKA_ECDSA_PARAMS = 0x00000180
+ CKA_EC_PARAMS = 0x00000180
+ CKA_EC_POINT = 0x00000181
+ CKA_SECONDARY_AUTH = 0x00000200
+ CKA_AUTH_PIN_FLAGS = 0x00000201
+ CKA_ALWAYS_AUTHENTICATE = 0x00000202
+ CKA_WRAP_WITH_TRUSTED = 0x00000210
+ CKA_WRAP_TEMPLATE = CKF_ARRAY_ATTRIBUTE | 0x00000211
+ CKA_UNWRAP_TEMPLATE = CKF_ARRAY_ATTRIBUTE | 0x00000212
+ CKA_OTP_FORMAT = 0x00000220
+ CKA_OTP_LENGTH = 0x00000221
+ CKA_OTP_TIME_INTERVAL = 0x00000222
+ CKA_OTP_USER_FRIENDLY_MODE = 0x00000223
+ CKA_OTP_CHALLENGE_REQUIREMENT = 0x00000224
+ CKA_OTP_TIME_REQUIREMENT = 0x00000225
+ CKA_OTP_COUNTER_REQUIREMENT = 0x00000226
+ CKA_OTP_PIN_REQUIREMENT = 0x00000227
+ CKA_OTP_COUNTER = 0x0000022E
+ CKA_OTP_TIME = 0x0000022F
+ CKA_OTP_USER_IDENTIFIER = 0x0000022A
+ CKA_OTP_SERVICE_IDENTIFIER = 0x0000022B
+ CKA_OTP_SERVICE_LOGO = 0x0000022C
+ CKA_OTP_SERVICE_LOGO_TYPE = 0x0000022D
+ CKA_GOSTR3410_PARAMS = 0x00000250
+ CKA_GOSTR3411_PARAMS = 0x00000251
+ CKA_GOST28147_PARAMS = 0x00000252
+ CKA_HW_FEATURE_TYPE = 0x00000300
+ CKA_RESET_ON_INIT = 0x00000301
+ CKA_HAS_RESET = 0x00000302
+ CKA_PIXEL_X = 0x00000400
+ CKA_PIXEL_Y = 0x00000401
+ CKA_RESOLUTION = 0x00000402
+ CKA_CHAR_ROWS = 0x00000403
+ CKA_CHAR_COLUMNS = 0x00000404
+ CKA_COLOR = 0x00000405
+ CKA_BITS_PER_PIXEL = 0x00000406
+ CKA_CHAR_SETS = 0x00000480
+ CKA_ENCODING_METHODS = 0x00000481
+ CKA_MIME_TYPES = 0x00000482
+ CKA_MECHANISM_TYPE = 0x00000500
+ CKA_REQUIRED_CMS_ATTRIBUTES = 0x00000501
+ CKA_DEFAULT_CMS_ATTRIBUTES = 0x00000502
+ CKA_SUPPORTED_CMS_ATTRIBUTES = 0x00000503
+ CKA_ALLOWED_MECHANISMS = CKF_ARRAY_ATTRIBUTE | 0x00000600
+ CKA_VENDOR_DEFINED = 0x80000000
+ CKM_RSA_PKCS_KEY_PAIR_GEN = 0x00000000
+ CKM_RSA_PKCS = 0x00000001
+ CKM_RSA_9796 = 0x00000002
+ CKM_RSA_X_509 = 0x00000003
+ CKM_MD2_RSA_PKCS = 0x00000004
+ CKM_MD5_RSA_PKCS = 0x00000005
+ CKM_SHA1_RSA_PKCS = 0x00000006
+ CKM_RIPEMD128_RSA_PKCS = 0x00000007
+ CKM_RIPEMD160_RSA_PKCS = 0x00000008
+ CKM_RSA_PKCS_OAEP = 0x00000009
+ CKM_RSA_X9_31_KEY_PAIR_GEN = 0x0000000A
+ CKM_RSA_X9_31 = 0x0000000B
+ CKM_SHA1_RSA_X9_31 = 0x0000000C
+ CKM_RSA_PKCS_PSS = 0x0000000D
+ CKM_SHA1_RSA_PKCS_PSS = 0x0000000E
+ CKM_DSA_KEY_PAIR_GEN = 0x00000010
+ CKM_DSA = 0x00000011
+ CKM_DSA_SHA1 = 0x00000012
+ CKM_DSA_FIPS_G_GEN = 0x00000013
+ CKM_DSA_SHA224 = 0x00000014
+ CKM_DSA_SHA256 = 0x00000015
+ CKM_DSA_SHA384 = 0x00000016
+ CKM_DSA_SHA512 = 0x00000017
+ CKM_DSA_SHA3_224 = 0x00000018
+ CKM_DSA_SHA3_256 = 0x00000019
+ CKM_DSA_SHA3_384 = 0x0000001A
+ CKM_DSA_SHA3_512 = 0x0000001B
+ CKM_DH_PKCS_KEY_PAIR_GEN = 0x00000020
+ CKM_DH_PKCS_DERIVE = 0x00000021
+ CKM_X9_42_DH_KEY_PAIR_GEN = 0x00000030
+ CKM_X9_42_DH_DERIVE = 0x00000031
+ CKM_X9_42_DH_HYBRID_DERIVE = 0x00000032
+ CKM_X9_42_MQV_DERIVE = 0x00000033
+ CKM_SHA256_RSA_PKCS = 0x00000040
+ CKM_SHA384_RSA_PKCS = 0x00000041
+ CKM_SHA512_RSA_PKCS = 0x00000042
+ CKM_SHA256_RSA_PKCS_PSS = 0x00000043
+ CKM_SHA384_RSA_PKCS_PSS = 0x00000044
+ CKM_SHA512_RSA_PKCS_PSS = 0x00000045
+ CKM_SHA224_RSA_PKCS = 0x00000046
+ CKM_SHA224_RSA_PKCS_PSS = 0x00000047
+ CKM_SHA512_224 = 0x00000048
+ CKM_SHA512_224_HMAC = 0x00000049
+ CKM_SHA512_224_HMAC_GENERAL = 0x0000004A
+ CKM_SHA512_224_KEY_DERIVATION = 0x0000004B
+ CKM_SHA512_256 = 0x0000004C
+ CKM_SHA512_256_HMAC = 0x0000004D
+ CKM_SHA512_256_HMAC_GENERAL = 0x0000004E
+ CKM_SHA512_256_KEY_DERIVATION = 0x0000004F
+ CKM_SHA512_T = 0x00000050
+ CKM_SHA512_T_HMAC = 0x00000051
+ CKM_SHA512_T_HMAC_GENERAL = 0x00000052
+ CKM_SHA512_T_KEY_DERIVATION = 0x00000053
+ CKM_SHA3_256_RSA_PKCS = 0x00000060
+ CKM_SHA3_384_RSA_PKCS = 0x00000061
+ CKM_SHA3_512_RSA_PKCS = 0x00000062
+ CKM_SHA3_256_RSA_PKCS_PSS = 0x00000063
+ CKM_SHA3_384_RSA_PKCS_PSS = 0x00000064
+ CKM_SHA3_512_RSA_PKCS_PSS = 0x00000065
+ CKM_SHA3_224_RSA_PKCS = 0x00000066
+ CKM_SHA3_224_RSA_PKCS_PSS = 0x00000067
+ CKM_RC2_KEY_GEN = 0x00000100
+ CKM_RC2_ECB = 0x00000101
+ CKM_RC2_CBC = 0x00000102
+ CKM_RC2_MAC = 0x00000103
+ CKM_RC2_MAC_GENERAL = 0x00000104
+ CKM_RC2_CBC_PAD = 0x00000105
+ CKM_RC4_KEY_GEN = 0x00000110
+ CKM_RC4 = 0x00000111
+ CKM_DES_KEY_GEN = 0x00000120
+ CKM_DES_ECB = 0x00000121
+ CKM_DES_CBC = 0x00000122
+ CKM_DES_MAC = 0x00000123
+ CKM_DES_MAC_GENERAL = 0x00000124
+ CKM_DES_CBC_PAD = 0x00000125
+ CKM_DES2_KEY_GEN = 0x00000130
+ CKM_DES3_KEY_GEN = 0x00000131
+ CKM_DES3_ECB = 0x00000132
+ CKM_DES3_CBC = 0x00000133
+ CKM_DES3_MAC = 0x00000134
+ CKM_DES3_MAC_GENERAL = 0x00000135
+ CKM_DES3_CBC_PAD = 0x00000136
+ CKM_DES3_CMAC_GENERAL = 0x00000137
+ CKM_DES3_CMAC = 0x00000138
+ CKM_CDMF_KEY_GEN = 0x00000140
+ CKM_CDMF_ECB = 0x00000141
+ CKM_CDMF_CBC = 0x00000142
+ CKM_CDMF_MAC = 0x00000143
+ CKM_CDMF_MAC_GENERAL = 0x00000144
+ CKM_CDMF_CBC_PAD = 0x00000145
+ CKM_DES_OFB64 = 0x00000150
+ CKM_DES_OFB8 = 0x00000151
+ CKM_DES_CFB64 = 0x00000152
+ CKM_DES_CFB8 = 0x00000153
+ CKM_MD2 = 0x00000200
+ CKM_MD2_HMAC = 0x00000201
+ CKM_MD2_HMAC_GENERAL = 0x00000202
+ CKM_MD5 = 0x00000210
+ CKM_MD5_HMAC = 0x00000211
+ CKM_MD5_HMAC_GENERAL = 0x00000212
+ CKM_SHA_1 = 0x00000220
+ CKM_SHA_1_HMAC = 0x00000221
+ CKM_SHA_1_HMAC_GENERAL = 0x00000222
+ CKM_RIPEMD128 = 0x00000230
+ CKM_RIPEMD128_HMAC = 0x00000231
+ CKM_RIPEMD128_HMAC_GENERAL = 0x00000232
+ CKM_RIPEMD160 = 0x00000240
+ CKM_RIPEMD160_HMAC = 0x00000241
+ CKM_RIPEMD160_HMAC_GENERAL = 0x00000242
+ CKM_SHA256 = 0x00000250
+ CKM_SHA256_HMAC = 0x00000251
+ CKM_SHA256_HMAC_GENERAL = 0x00000252
+ CKM_SHA224 = 0x00000255
+ CKM_SHA224_HMAC = 0x00000256
+ CKM_SHA224_HMAC_GENERAL = 0x00000257
+ CKM_SHA384 = 0x00000260
+ CKM_SHA384_HMAC = 0x00000261
+ CKM_SHA384_HMAC_GENERAL = 0x00000262
+ CKM_SHA512 = 0x00000270
+ CKM_SHA512_HMAC = 0x00000271
+ CKM_SHA512_HMAC_GENERAL = 0x00000272
+ CKM_SECURID_KEY_GEN = 0x00000280
+ CKM_SECURID = 0x00000282
+ CKM_HOTP_KEY_GEN = 0x00000290
+ CKM_HOTP = 0x00000291
+ CKM_ACTI = 0x000002A0
+ CKM_ACTI_KEY_GEN = 0x000002A1
+ CKM_SHA3_256 = 0x000002B0
+ CKM_SHA3_256_HMAC = 0x000002B1
+ CKM_SHA3_256_HMAC_GENERAL = 0x000002B2
+ CKM_SHA3_256_KEY_GEN = 0x000002B3
+ CKM_SHA3_224 = 0x000002B5
+ CKM_SHA3_224_HMAC = 0x000002B6
+ CKM_SHA3_224_HMAC_GENERAL = 0x000002B7
+ CKM_SHA3_224_KEY_GEN = 0x000002B8
+ CKM_SHA3_384 = 0x000002C0
+ CKM_SHA3_384_HMAC = 0x000002C1
+ CKM_SHA3_384_HMAC_GENERAL = 0x000002C2
+ CKM_SHA3_384_KEY_GEN = 0x000002C3
+ CKM_SHA3_512 = 0x000002D0
+ CKM_SHA3_512_HMAC = 0x000002D1
+ CKM_SHA3_512_HMAC_GENERAL = 0x000002D2
+ CKM_SHA3_512_KEY_GEN = 0x000002D3
+ CKM_CAST_KEY_GEN = 0x00000300
+ CKM_CAST_ECB = 0x00000301
+ CKM_CAST_CBC = 0x00000302
+ CKM_CAST_MAC = 0x00000303
+ CKM_CAST_MAC_GENERAL = 0x00000304
+ CKM_CAST_CBC_PAD = 0x00000305
+ CKM_CAST3_KEY_GEN = 0x00000310
+ CKM_CAST3_ECB = 0x00000311
+ CKM_CAST3_CBC = 0x00000312
+ CKM_CAST3_MAC = 0x00000313
+ CKM_CAST3_MAC_GENERAL = 0x00000314
+ CKM_CAST3_CBC_PAD = 0x00000315
+ CKM_CAST5_KEY_GEN = 0x00000320
+ CKM_CAST128_KEY_GEN = 0x00000320
+ CKM_CAST5_ECB = 0x00000321
+ CKM_CAST128_ECB = 0x00000321
+ CKM_CAST5_CBC = 0x00000322
+ CKM_CAST128_CBC = 0x00000322
+ CKM_CAST5_MAC = 0x00000323
+ CKM_CAST128_MAC = 0x00000323
+ CKM_CAST5_MAC_GENERAL = 0x00000324
+ CKM_CAST128_MAC_GENERAL = 0x00000324
+ CKM_CAST5_CBC_PAD = 0x00000325
+ CKM_CAST128_CBC_PAD = 0x00000325
+ CKM_RC5_KEY_GEN = 0x00000330
+ CKM_RC5_ECB = 0x00000331
+ CKM_RC5_CBC = 0x00000332
+ CKM_RC5_MAC = 0x00000333
+ CKM_RC5_MAC_GENERAL = 0x00000334
+ CKM_RC5_CBC_PAD = 0x00000335
+ CKM_IDEA_KEY_GEN = 0x00000340
+ CKM_IDEA_ECB = 0x00000341
+ CKM_IDEA_CBC = 0x00000342
+ CKM_IDEA_MAC = 0x00000343
+ CKM_IDEA_MAC_GENERAL = 0x00000344
+ CKM_IDEA_CBC_PAD = 0x00000345
+ CKM_GENERIC_SECRET_KEY_GEN = 0x00000350
+ CKM_CONCATENATE_BASE_AND_KEY = 0x00000360
+ CKM_CONCATENATE_BASE_AND_DATA = 0x00000362
+ CKM_CONCATENATE_DATA_AND_BASE = 0x00000363
+ CKM_XOR_BASE_AND_DATA = 0x00000364
+ CKM_EXTRACT_KEY_FROM_KEY = 0x00000365
+ CKM_SSL3_PRE_MASTER_KEY_GEN = 0x00000370
+ CKM_SSL3_MASTER_KEY_DERIVE = 0x00000371
+ CKM_SSL3_KEY_AND_MAC_DERIVE = 0x00000372
+ CKM_SSL3_MASTER_KEY_DERIVE_DH = 0x00000373
+ CKM_TLS_PRE_MASTER_KEY_GEN = 0x00000374
+ CKM_TLS_MASTER_KEY_DERIVE = 0x00000375
+ CKM_TLS_KEY_AND_MAC_DERIVE = 0x00000376
+ CKM_TLS_MASTER_KEY_DERIVE_DH = 0x00000377
+ CKM_TLS_PRF = 0x00000378
+ CKM_SSL3_MD5_MAC = 0x00000380
+ CKM_SSL3_SHA1_MAC = 0x00000381
+ CKM_MD5_KEY_DERIVATION = 0x00000390
+ CKM_MD2_KEY_DERIVATION = 0x00000391
+ CKM_SHA1_KEY_DERIVATION = 0x00000392
+ CKM_SHA256_KEY_DERIVATION = 0x00000393
+ CKM_SHA384_KEY_DERIVATION = 0x00000394
+ CKM_SHA512_KEY_DERIVATION = 0x00000395
+ CKM_SHA224_KEY_DERIVATION = 0x00000396
+ CKM_SHA3_256_KEY_DERIVE = 0x00000397
+ CKM_SHA3_224_KEY_DERIVE = 0x00000398
+ CKM_SHA3_384_KEY_DERIVE = 0x00000399
+ CKM_SHA3_512_KEY_DERIVE = 0x0000039A
+ CKM_SHAKE_128_KEY_DERIVE = 0x0000039B
+ CKM_SHAKE_256_KEY_DERIVE = 0x0000039C
+ CKM_PBE_MD2_DES_CBC = 0x000003A0
+ CKM_PBE_MD5_DES_CBC = 0x000003A1
+ CKM_PBE_MD5_CAST_CBC = 0x000003A2
+ CKM_PBE_MD5_CAST3_CBC = 0x000003A3
+ CKM_PBE_MD5_CAST5_CBC = 0x000003A4
+ CKM_PBE_MD5_CAST128_CBC = 0x000003A4
+ CKM_PBE_SHA1_CAST5_CBC = 0x000003A5
+ CKM_PBE_SHA1_CAST128_CBC = 0x000003A5
+ CKM_PBE_SHA1_RC4_128 = 0x000003A6
+ CKM_PBE_SHA1_RC4_40 = 0x000003A7
+ CKM_PBE_SHA1_DES3_EDE_CBC = 0x000003A8
+ CKM_PBE_SHA1_DES2_EDE_CBC = 0x000003A9
+ CKM_PBE_SHA1_RC2_128_CBC = 0x000003AA
+ CKM_PBE_SHA1_RC2_40_CBC = 0x000003AB
+ CKM_PKCS5_PBKD2 = 0x000003B0
+ CKM_PBA_SHA1_WITH_SHA1_HMAC = 0x000003C0
+ CKM_WTLS_PRE_MASTER_KEY_GEN = 0x000003D0
+ CKM_WTLS_MASTER_KEY_DERIVE = 0x000003D1
+ CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC = 0x000003D2
+ CKM_WTLS_PRF = 0x000003D3
+ CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE = 0x000003D4
+ CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE = 0x000003D5
+ CKM_TLS10_MAC_SERVER = 0x000003D6
+ CKM_TLS10_MAC_CLIENT = 0x000003D7
+ CKM_TLS12_MAC = 0x000003D8
+ CKM_TLS12_KDF = 0x000003D9
+ CKM_TLS12_MASTER_KEY_DERIVE = 0x000003E0
+ CKM_TLS12_KEY_AND_MAC_DERIVE = 0x000003E1
+ CKM_TLS12_MASTER_KEY_DERIVE_DH = 0x000003E2
+ CKM_TLS12_KEY_SAFE_DERIVE = 0x000003E3
+ CKM_TLS_MAC = 0x000003E4
+ CKM_TLS_KDF = 0x000003E5
+ CKM_KEY_WRAP_LYNKS = 0x00000400
+ CKM_KEY_WRAP_SET_OAEP = 0x00000401
+ CKM_CMS_SIG = 0x00000500
+ CKM_KIP_DERIVE = 0x00000510
+ CKM_KIP_WRAP = 0x00000511
+ CKM_KIP_MAC = 0x00000512
+ CKM_CAMELLIA_KEY_GEN = 0x00000550
+ CKM_CAMELLIA_ECB = 0x00000551
+ CKM_CAMELLIA_CBC = 0x00000552
+ CKM_CAMELLIA_MAC = 0x00000553
+ CKM_CAMELLIA_MAC_GENERAL = 0x00000554
+ CKM_CAMELLIA_CBC_PAD = 0x00000555
+ CKM_CAMELLIA_ECB_ENCRYPT_DATA = 0x00000556
+ CKM_CAMELLIA_CBC_ENCRYPT_DATA = 0x00000557
+ CKM_CAMELLIA_CTR = 0x00000558
+ CKM_ARIA_KEY_GEN = 0x00000560
+ CKM_ARIA_ECB = 0x00000561
+ CKM_ARIA_CBC = 0x00000562
+ CKM_ARIA_MAC = 0x00000563
+ CKM_ARIA_MAC_GENERAL = 0x00000564
+ CKM_ARIA_CBC_PAD = 0x00000565
+ CKM_ARIA_ECB_ENCRYPT_DATA = 0x00000566
+ CKM_ARIA_CBC_ENCRYPT_DATA = 0x00000567
+ CKM_SEED_KEY_GEN = 0x00000650
+ CKM_SEED_ECB = 0x00000651
+ CKM_SEED_CBC = 0x00000652
+ CKM_SEED_MAC = 0x00000653
+ CKM_SEED_MAC_GENERAL = 0x00000654
+ CKM_SEED_CBC_PAD = 0x00000655
+ CKM_SEED_ECB_ENCRYPT_DATA = 0x00000656
+ CKM_SEED_CBC_ENCRYPT_DATA = 0x00000657
+ CKM_SKIPJACK_KEY_GEN = 0x00001000
+ CKM_SKIPJACK_ECB64 = 0x00001001
+ CKM_SKIPJACK_CBC64 = 0x00001002
+ CKM_SKIPJACK_OFB64 = 0x00001003
+ CKM_SKIPJACK_CFB64 = 0x00001004
+ CKM_SKIPJACK_CFB32 = 0x00001005
+ CKM_SKIPJACK_CFB16 = 0x00001006
+ CKM_SKIPJACK_CFB8 = 0x00001007
+ CKM_SKIPJACK_WRAP = 0x00001008
+ CKM_SKIPJACK_PRIVATE_WRAP = 0x00001009
+ CKM_SKIPJACK_RELAYX = 0x0000100a
+ CKM_KEA_KEY_PAIR_GEN = 0x00001010
+ CKM_KEA_KEY_DERIVE = 0x00001011
+ CKM_KEA_DERIVE = 0x00001012
+ CKM_FORTEZZA_TIMESTAMP = 0x00001020
+ CKM_BATON_KEY_GEN = 0x00001030
+ CKM_BATON_ECB128 = 0x00001031
+ CKM_BATON_ECB96 = 0x00001032
+ CKM_BATON_CBC128 = 0x00001033
+ CKM_BATON_COUNTER = 0x00001034
+ CKM_BATON_SHUFFLE = 0x00001035
+ CKM_BATON_WRAP = 0x00001036
+ CKM_ECDSA_KEY_PAIR_GEN = 0x00001040
+ CKM_EC_KEY_PAIR_GEN = 0x00001040
+ CKM_ECDSA = 0x00001041
+ CKM_ECDSA_SHA1 = 0x00001042
+ CKM_ECDSA_SHA224 = 0x00001043
+ CKM_ECDSA_SHA256 = 0x00001044
+ CKM_ECDSA_SHA384 = 0x00001045
+ CKM_ECDSA_SHA512 = 0x00001046
+ CKM_ECDH1_DERIVE = 0x00001050
+ CKM_ECDH1_COFACTOR_DERIVE = 0x00001051
+ CKM_ECMQV_DERIVE = 0x00001052
+ CKM_ECDH_AES_KEY_WRAP = 0x00001053
+ CKM_RSA_AES_KEY_WRAP = 0x00001054
+ CKM_JUNIPER_KEY_GEN = 0x00001060
+ CKM_JUNIPER_ECB128 = 0x00001061
+ CKM_JUNIPER_CBC128 = 0x00001062
+ CKM_JUNIPER_COUNTER = 0x00001063
+ CKM_JUNIPER_SHUFFLE = 0x00001064
+ CKM_JUNIPER_WRAP = 0x00001065
+ CKM_FASTHASH = 0x00001070
+ CKM_AES_KEY_GEN = 0x00001080
+ CKM_AES_ECB = 0x00001081
+ CKM_AES_CBC = 0x00001082
+ CKM_AES_MAC = 0x00001083
+ CKM_AES_MAC_GENERAL = 0x00001084
+ CKM_AES_CBC_PAD = 0x00001085
+ CKM_AES_CTR = 0x00001086
+ CKM_AES_GCM = 0x00001087
+ CKM_AES_CCM = 0x00001088
+ CKM_AES_CMAC_GENERAL = 0x00001089
+ CKM_AES_CMAC = 0x0000108A
+ CKM_AES_CTS = 0x0000108B
+ CKM_AES_XCBC_MAC = 0x0000108C
+ CKM_AES_XCBC_MAC_96 = 0x0000108D
+ CKM_AES_GMAC = 0x0000108E
+ CKM_BLOWFISH_KEY_GEN = 0x00001090
+ CKM_BLOWFISH_CBC = 0x00001091
+ CKM_TWOFISH_KEY_GEN = 0x00001092
+ CKM_TWOFISH_CBC = 0x00001093
+ CKM_BLOWFISH_CBC_PAD = 0x00001094
+ CKM_TWOFISH_CBC_PAD = 0x00001095
+ CKM_DES_ECB_ENCRYPT_DATA = 0x00001100
+ CKM_DES_CBC_ENCRYPT_DATA = 0x00001101
+ CKM_DES3_ECB_ENCRYPT_DATA = 0x00001102
+ CKM_DES3_CBC_ENCRYPT_DATA = 0x00001103
+ CKM_AES_ECB_ENCRYPT_DATA = 0x00001104
+ CKM_AES_CBC_ENCRYPT_DATA = 0x00001105
+ CKM_GOSTR3410_KEY_PAIR_GEN = 0x00001200
+ CKM_GOSTR3410 = 0x00001201
+ CKM_GOSTR3410_WITH_GOSTR3411 = 0x00001202
+ CKM_GOSTR3410_KEY_WRAP = 0x00001203
+ CKM_GOSTR3410_DERIVE = 0x00001204
+ CKM_GOSTR3411 = 0x00001210
+ CKM_GOSTR3411_HMAC = 0x00001211
+ CKM_GOST28147_KEY_GEN = 0x00001220
+ CKM_GOST28147_ECB = 0x00001221
+ CKM_GOST28147 = 0x00001222
+ CKM_GOST28147_MAC = 0x00001223
+ CKM_GOST28147_KEY_WRAP = 0x00001224
+ CKM_DSA_PARAMETER_GEN = 0x00002000
+ CKM_DH_PKCS_PARAMETER_GEN = 0x00002001
+ CKM_X9_42_DH_PARAMETER_GEN = 0x00002002
+ CKM_DSA_PROBABLISTIC_PARAMETER_GEN = 0x00002003
+ CKM_DSA_SHAWE_TAYLOR_PARAMETER_GEN = 0x00002004
+ CKM_AES_OFB = 0x00002104
+ CKM_AES_CFB64 = 0x00002105
+ CKM_AES_CFB8 = 0x00002106
+ CKM_AES_CFB128 = 0x00002107
+ CKM_AES_CFB1 = 0x00002108
+ CKM_AES_KEY_WRAP = 0x00002109
+ CKM_AES_KEY_WRAP_PAD = 0x0000210A
+ CKM_RSA_PKCS_TPM_1_1 = 0x00004001
+ CKM_RSA_PKCS_OAEP_TPM_1_1 = 0x00004002
+ CKM_VENDOR_DEFINED = 0x80000000
+ CKF_HW = 0x00000001
+ CKF_ENCRYPT = 0x00000100
+ CKF_DECRYPT = 0x00000200
+ CKF_DIGEST = 0x00000400
+ CKF_SIGN = 0x00000800
+ CKF_SIGN_RECOVER = 0x00001000
+ CKF_VERIFY = 0x00002000
+ CKF_VERIFY_RECOVER = 0x00004000
+ CKF_GENERATE = 0x00008000
+ CKF_GENERATE_KEY_PAIR = 0x00010000
+ CKF_WRAP = 0x00020000
+ CKF_UNWRAP = 0x00040000
+ CKF_DERIVE = 0x00080000
+ CKF_EC_F_P = 0x00100000
+ CKF_EC_F_2M = 0x00200000
+ CKF_EC_ECPARAMETERS = 0x00400000
+ CKF_EC_NAMEDCURVE = 0x00800000
+ CKF_EC_UNCOMPRESS = 0x01000000
+ CKF_EC_COMPRESS = 0x02000000
+ CKF_EXTENSION = 0x80000000
+ CKR_OK = 0x00000000
+ CKR_CANCEL = 0x00000001
+ CKR_HOST_MEMORY = 0x00000002
+ CKR_SLOT_ID_INVALID = 0x00000003
+ CKR_GENERAL_ERROR = 0x00000005
+ CKR_FUNCTION_FAILED = 0x00000006
+ CKR_ARGUMENTS_BAD = 0x00000007
+ CKR_NO_EVENT = 0x00000008
+ CKR_NEED_TO_CREATE_THREADS = 0x00000009
+ CKR_CANT_LOCK = 0x0000000A
+ CKR_ATTRIBUTE_READ_ONLY = 0x00000010
+ CKR_ATTRIBUTE_SENSITIVE = 0x00000011
+ CKR_ATTRIBUTE_TYPE_INVALID = 0x00000012
+ CKR_ATTRIBUTE_VALUE_INVALID = 0x00000013
+ CKR_ACTION_PROHIBITED = 0x0000001B
+ CKR_DATA_INVALID = 0x00000020
+ CKR_DATA_LEN_RANGE = 0x00000021
+ CKR_DEVICE_ERROR = 0x00000030
+ CKR_DEVICE_MEMORY = 0x00000031
+ CKR_DEVICE_REMOVED = 0x00000032
+ CKR_ENCRYPTED_DATA_INVALID = 0x00000040
+ CKR_ENCRYPTED_DATA_LEN_RANGE = 0x00000041
+ CKR_FUNCTION_CANCELED = 0x00000050
+ CKR_FUNCTION_NOT_PARALLEL = 0x00000051
+ CKR_FUNCTION_NOT_SUPPORTED = 0x00000054
+ CKR_KEY_HANDLE_INVALID = 0x00000060
+ CKR_KEY_SIZE_RANGE = 0x00000062
+ CKR_KEY_TYPE_INCONSISTENT = 0x00000063
+ CKR_KEY_NOT_NEEDED = 0x00000064
+ CKR_KEY_CHANGED = 0x00000065
+ CKR_KEY_NEEDED = 0x00000066
+ CKR_KEY_INDIGESTIBLE = 0x00000067
+ CKR_KEY_FUNCTION_NOT_PERMITTED = 0x00000068
+ CKR_KEY_NOT_WRAPPABLE = 0x00000069
+ CKR_KEY_UNEXTRACTABLE = 0x0000006A
+ CKR_MECHANISM_INVALID = 0x00000070
+ CKR_MECHANISM_PARAM_INVALID = 0x00000071
+ CKR_OBJECT_HANDLE_INVALID = 0x00000082
+ CKR_OPERATION_ACTIVE = 0x00000090
+ CKR_OPERATION_NOT_INITIALIZED = 0x00000091
+ CKR_PIN_INCORRECT = 0x000000A0
+ CKR_PIN_INVALID = 0x000000A1
+ CKR_PIN_LEN_RANGE = 0x000000A2
+ CKR_PIN_EXPIRED = 0x000000A3
+ CKR_PIN_LOCKED = 0x000000A4
+ CKR_SESSION_CLOSED = 0x000000B0
+ CKR_SESSION_COUNT = 0x000000B1
+ CKR_SESSION_HANDLE_INVALID = 0x000000B3
+ CKR_SESSION_PARALLEL_NOT_SUPPORTED = 0x000000B4
+ CKR_SESSION_READ_ONLY = 0x000000B5
+ CKR_SESSION_EXISTS = 0x000000B6
+ CKR_SESSION_READ_ONLY_EXISTS = 0x000000B7
+ CKR_SESSION_READ_WRITE_SO_EXISTS = 0x000000B8
+ CKR_SIGNATURE_INVALID = 0x000000C0
+ CKR_SIGNATURE_LEN_RANGE = 0x000000C1
+ CKR_TEMPLATE_INCOMPLETE = 0x000000D0
+ CKR_TEMPLATE_INCONSISTENT = 0x000000D1
+ CKR_TOKEN_NOT_PRESENT = 0x000000E0
+ CKR_TOKEN_NOT_RECOGNIZED = 0x000000E1
+ CKR_TOKEN_WRITE_PROTECTED = 0x000000E2
+ CKR_UNWRAPPING_KEY_HANDLE_INVALID = 0x000000F0
+ CKR_UNWRAPPING_KEY_SIZE_RANGE = 0x000000F1
+ CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT = 0x000000F2
+ CKR_USER_ALREADY_LOGGED_IN = 0x00000100
+ CKR_USER_NOT_LOGGED_IN = 0x00000101
+ CKR_USER_PIN_NOT_INITIALIZED = 0x00000102
+ CKR_USER_TYPE_INVALID = 0x00000103
+ CKR_USER_ANOTHER_ALREADY_LOGGED_IN = 0x00000104
+ CKR_USER_TOO_MANY_TYPES = 0x00000105
+ CKR_WRAPPED_KEY_INVALID = 0x00000110
+ CKR_WRAPPED_KEY_LEN_RANGE = 0x00000112
+ CKR_WRAPPING_KEY_HANDLE_INVALID = 0x00000113
+ CKR_WRAPPING_KEY_SIZE_RANGE = 0x00000114
+ CKR_WRAPPING_KEY_TYPE_INCONSISTENT = 0x00000115
+ CKR_RANDOM_SEED_NOT_SUPPORTED = 0x00000120
+ CKR_RANDOM_NO_RNG = 0x00000121
+ CKR_DOMAIN_PARAMS_INVALID = 0x00000130
+ CKR_CURVE_NOT_SUPPORTED = 0x00000140
+ CKR_BUFFER_TOO_SMALL = 0x00000150
+ CKR_SAVED_STATE_INVALID = 0x00000160
+ CKR_INFORMATION_SENSITIVE = 0x00000170
+ CKR_STATE_UNSAVEABLE = 0x00000180
+ CKR_CRYPTOKI_NOT_INITIALIZED = 0x00000190
+ CKR_CRYPTOKI_ALREADY_INITIALIZED = 0x00000191
+ CKR_MUTEX_BAD = 0x000001A0
+ CKR_MUTEX_NOT_LOCKED = 0x000001A1
+ CKR_NEW_PIN_MODE = 0x000001B0
+ CKR_NEXT_OTP = 0x000001B1
+ CKR_EXCEEDED_MAX_ITERATIONS = 0x000001C0
+ CKR_FIPS_SELF_TEST_FAILED = 0x000001C1
+ CKR_LIBRARY_LOAD_FAILED = 0x000001C2
+ CKR_PIN_TOO_WEAK = 0x000001C3
+ CKR_PUBLIC_KEY_INVALID = 0x000001C4
+ CKR_FUNCTION_REJECTED = 0x00000200
+ CKR_VENDOR_DEFINED = 0x80000000
+ CKF_LIBRARY_CANT_CREATE_OS_THREADS = 0x00000001
+ CKF_OS_LOCKING_OK = 0x00000002
+ CKF_DONT_BLOCK = 1
+ CKF_NEXT_OTP = 0x00000001
+ CKF_EXCLUDE_TIME = 0x00000002
+ CKF_EXCLUDE_COUNTER = 0x00000004
+ CKF_EXCLUDE_CHALLENGE = 0x00000008
+ CKF_EXCLUDE_PIN = 0x00000010
+ CKF_USER_FRIENDLY_OTP = 0x00000020
+ CKD_NULL = 0x00000001
+ CKD_SHA1_KDF = 0x00000002
+)
+
+// Special return values defined in PKCS#11 v2.40 section 3.2.
+const (
+ // CK_EFFECTIVELY_INFINITE may be returned in the CK_TOKEN_INFO fields ulMaxSessionCount and ulMaxRwSessionCount.
+ // It indicates there is no practical limit on the number of sessions.
+ CK_EFFECTIVELY_INFINITE = 0
+
+ // CK_UNAVAILABLE_INFORMATION may be returned for several fields within CK_TOKEN_INFO. It indicates
+ // the token is unable or unwilling to provide the requested information.
+ CK_UNAVAILABLE_INFORMATION = ^uint(0)
+)
diff --git a/vendor/github.com/miekg/pkcs11/error.go b/vendor/github.com/miekg/pkcs11/error.go
new file mode 100644
index 000000000..7df0e93a6
--- /dev/null
+++ b/vendor/github.com/miekg/pkcs11/error.go
@@ -0,0 +1,98 @@
+// Copyright 2013 Miek Gieben. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkcs11
+
+// awk '/#define CKR_/{ print $3":\""$2"\"," }' pkcs11t.h
+
+var strerror = map[uint]string{
+ 0x00000000: "CKR_OK",
+ 0x00000001: "CKR_CANCEL",
+ 0x00000002: "CKR_HOST_MEMORY",
+ 0x00000003: "CKR_SLOT_ID_INVALID",
+ 0x00000005: "CKR_GENERAL_ERROR",
+ 0x00000006: "CKR_FUNCTION_FAILED",
+ 0x00000007: "CKR_ARGUMENTS_BAD",
+ 0x00000008: "CKR_NO_EVENT",
+ 0x00000009: "CKR_NEED_TO_CREATE_THREADS",
+ 0x0000000A: "CKR_CANT_LOCK",
+ 0x00000010: "CKR_ATTRIBUTE_READ_ONLY",
+ 0x00000011: "CKR_ATTRIBUTE_SENSITIVE",
+ 0x00000012: "CKR_ATTRIBUTE_TYPE_INVALID",
+ 0x00000013: "CKR_ATTRIBUTE_VALUE_INVALID",
+ 0x00000020: "CKR_DATA_INVALID",
+ 0x00000021: "CKR_DATA_LEN_RANGE",
+ 0x00000030: "CKR_DEVICE_ERROR",
+ 0x00000031: "CKR_DEVICE_MEMORY",
+ 0x00000032: "CKR_DEVICE_REMOVED",
+ 0x00000040: "CKR_ENCRYPTED_DATA_INVALID",
+ 0x00000041: "CKR_ENCRYPTED_DATA_LEN_RANGE",
+ 0x00000050: "CKR_FUNCTION_CANCELED",
+ 0x00000051: "CKR_FUNCTION_NOT_PARALLEL",
+ 0x00000054: "CKR_FUNCTION_NOT_SUPPORTED",
+ 0x00000060: "CKR_KEY_HANDLE_INVALID",
+ 0x00000062: "CKR_KEY_SIZE_RANGE",
+ 0x00000063: "CKR_KEY_TYPE_INCONSISTENT",
+ 0x00000064: "CKR_KEY_NOT_NEEDED",
+ 0x00000065: "CKR_KEY_CHANGED",
+ 0x00000066: "CKR_KEY_NEEDED",
+ 0x00000067: "CKR_KEY_INDIGESTIBLE",
+ 0x00000068: "CKR_KEY_FUNCTION_NOT_PERMITTED",
+ 0x00000069: "CKR_KEY_NOT_WRAPPABLE",
+ 0x0000006A: "CKR_KEY_UNEXTRACTABLE",
+ 0x00000070: "CKR_MECHANISM_INVALID",
+ 0x00000071: "CKR_MECHANISM_PARAM_INVALID",
+ 0x00000082: "CKR_OBJECT_HANDLE_INVALID",
+ 0x00000090: "CKR_OPERATION_ACTIVE",
+ 0x00000091: "CKR_OPERATION_NOT_INITIALIZED",
+ 0x000000A0: "CKR_PIN_INCORRECT",
+ 0x000000A1: "CKR_PIN_INVALID",
+ 0x000000A2: "CKR_PIN_LEN_RANGE",
+ 0x000000A3: "CKR_PIN_EXPIRED",
+ 0x000000A4: "CKR_PIN_LOCKED",
+ 0x000000B0: "CKR_SESSION_CLOSED",
+ 0x000000B1: "CKR_SESSION_COUNT",
+ 0x000000B3: "CKR_SESSION_HANDLE_INVALID",
+ 0x000000B4: "CKR_SESSION_PARALLEL_NOT_SUPPORTED",
+ 0x000000B5: "CKR_SESSION_READ_ONLY",
+ 0x000000B6: "CKR_SESSION_EXISTS",
+ 0x000000B7: "CKR_SESSION_READ_ONLY_EXISTS",
+ 0x000000B8: "CKR_SESSION_READ_WRITE_SO_EXISTS",
+ 0x000000C0: "CKR_SIGNATURE_INVALID",
+ 0x000000C1: "CKR_SIGNATURE_LEN_RANGE",
+ 0x000000D0: "CKR_TEMPLATE_INCOMPLETE",
+ 0x000000D1: "CKR_TEMPLATE_INCONSISTENT",
+ 0x000000E0: "CKR_TOKEN_NOT_PRESENT",
+ 0x000000E1: "CKR_TOKEN_NOT_RECOGNIZED",
+ 0x000000E2: "CKR_TOKEN_WRITE_PROTECTED",
+ 0x000000F0: "CKR_UNWRAPPING_KEY_HANDLE_INVALID",
+ 0x000000F1: "CKR_UNWRAPPING_KEY_SIZE_RANGE",
+ 0x000000F2: "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT",
+ 0x00000100: "CKR_USER_ALREADY_LOGGED_IN",
+ 0x00000101: "CKR_USER_NOT_LOGGED_IN",
+ 0x00000102: "CKR_USER_PIN_NOT_INITIALIZED",
+ 0x00000103: "CKR_USER_TYPE_INVALID",
+ 0x00000104: "CKR_USER_ANOTHER_ALREADY_LOGGED_IN",
+ 0x00000105: "CKR_USER_TOO_MANY_TYPES",
+ 0x00000110: "CKR_WRAPPED_KEY_INVALID",
+ 0x00000112: "CKR_WRAPPED_KEY_LEN_RANGE",
+ 0x00000113: "CKR_WRAPPING_KEY_HANDLE_INVALID",
+ 0x00000114: "CKR_WRAPPING_KEY_SIZE_RANGE",
+ 0x00000115: "CKR_WRAPPING_KEY_TYPE_INCONSISTENT",
+ 0x00000120: "CKR_RANDOM_SEED_NOT_SUPPORTED",
+ 0x00000121: "CKR_RANDOM_NO_RNG",
+ 0x00000130: "CKR_DOMAIN_PARAMS_INVALID",
+ 0x00000150: "CKR_BUFFER_TOO_SMALL",
+ 0x00000160: "CKR_SAVED_STATE_INVALID",
+ 0x00000170: "CKR_INFORMATION_SENSITIVE",
+ 0x00000180: "CKR_STATE_UNSAVEABLE",
+ 0x00000190: "CKR_CRYPTOKI_NOT_INITIALIZED",
+ 0x00000191: "CKR_CRYPTOKI_ALREADY_INITIALIZED",
+ 0x000001A0: "CKR_MUTEX_BAD",
+ 0x000001A1: "CKR_MUTEX_NOT_LOCKED",
+ 0x000001B0: "CKR_NEW_PIN_MODE",
+ 0x000001B1: "CKR_NEXT_OTP",
+ 0x00000200: "CKR_FUNCTION_REJECTED",
+ 0x80000000: "CKR_VENDOR_DEFINED",
+}
diff --git a/vendor/github.com/miekg/pkcs11/go.mod b/vendor/github.com/miekg/pkcs11/go.mod
new file mode 100644
index 000000000..704296fc9
--- /dev/null
+++ b/vendor/github.com/miekg/pkcs11/go.mod
@@ -0,0 +1,3 @@
+module github.com/miekg/pkcs11
+
+go 1.12
diff --git a/vendor/github.com/miekg/pkcs11/hsm.db b/vendor/github.com/miekg/pkcs11/hsm.db
new file mode 100644
index 000000000..eb3f10dad
--- /dev/null
+++ b/vendor/github.com/miekg/pkcs11/hsm.db
Binary files differ
diff --git a/vendor/github.com/miekg/pkcs11/params.go b/vendor/github.com/miekg/pkcs11/params.go
new file mode 100644
index 000000000..6d9ce96ae
--- /dev/null
+++ b/vendor/github.com/miekg/pkcs11/params.go
@@ -0,0 +1,190 @@
+// Copyright 2013 Miek Gieben. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkcs11
+
+/*
+#include <stdlib.h>
+#include <string.h>
+#include "pkcs11go.h"
+
+static inline void putOAEPParams(CK_RSA_PKCS_OAEP_PARAMS_PTR params, CK_VOID_PTR pSourceData, CK_ULONG ulSourceDataLen)
+{
+ params->pSourceData = pSourceData;
+ params->ulSourceDataLen = ulSourceDataLen;
+}
+
+static inline void putECDH1SharedParams(CK_ECDH1_DERIVE_PARAMS_PTR params, CK_VOID_PTR pSharedData, CK_ULONG ulSharedDataLen)
+{
+ params->pSharedData = pSharedData;
+ params->ulSharedDataLen = ulSharedDataLen;
+}
+
+static inline void putECDH1PublicParams(CK_ECDH1_DERIVE_PARAMS_PTR params, CK_VOID_PTR pPublicData, CK_ULONG ulPublicDataLen)
+{
+ params->pPublicData = pPublicData;
+ params->ulPublicDataLen = ulPublicDataLen;
+}
+*/
+import "C"
+import "unsafe"
+
+// GCMParams represents the parameters for the AES-GCM mechanism.
+type GCMParams struct {
+ arena
+ params *C.CK_GCM_PARAMS
+ iv []byte
+ aad []byte
+ tagSize int
+}
+
+// NewGCMParams returns a pointer to AES-GCM parameters that can be used with the CKM_AES_GCM mechanism.
+// The Free() method must be called after the operation is complete.
+//
+// Note that some HSMs, like CloudHSM, will ignore the IV you pass in and write their
+// own. As a result, to support all libraries, memory is not freed
+// automatically, so that after the EncryptInit/Encrypt operation the HSM's IV
+// can be read back out. It is up to the caller to ensure that Free() is called
+// on the GCMParams object at an appropriate time, which is after
+//
+// Encrypt/Decrypt. As an example:
+//
+// gcmParams := pkcs11.NewGCMParams(make([]byte, 12), nil, 128)
+// p.ctx.EncryptInit(session, []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_AES_GCM, gcmParams)},
+// aesObjHandle)
+// ct, _ := p.ctx.Encrypt(session, pt)
+// iv := gcmParams.IV()
+// gcmParams.Free()
+//
+func NewGCMParams(iv, aad []byte, tagSize int) *GCMParams {
+ return &GCMParams{
+ iv: iv,
+ aad: aad,
+ tagSize: tagSize,
+ }
+}
+
+func cGCMParams(p *GCMParams) []byte {
+ params := C.CK_GCM_PARAMS{
+ ulTagBits: C.CK_ULONG(p.tagSize),
+ }
+ var arena arena
+ if len(p.iv) > 0 {
+ iv, ivLen := arena.Allocate(p.iv)
+ params.pIv = C.CK_BYTE_PTR(iv)
+ params.ulIvLen = ivLen
+ params.ulIvBits = ivLen * 8
+ }
+ if len(p.aad) > 0 {
+ aad, aadLen := arena.Allocate(p.aad)
+ params.pAAD = C.CK_BYTE_PTR(aad)
+ params.ulAADLen = aadLen
+ }
+ p.Free()
+ p.arena = arena
+ p.params = &params
+ return C.GoBytes(unsafe.Pointer(&params), C.int(unsafe.Sizeof(params)))
+}
+
+// IV returns a copy of the actual IV used for the operation.
+//
+// Some HSMs may ignore the user-specified IV and write their own at the end of
+// the encryption operation; this method allows you to retrieve it.
+func (p *GCMParams) IV() []byte {
+ if p == nil || p.params == nil {
+ return nil
+ }
+ newIv := C.GoBytes(unsafe.Pointer(p.params.pIv), C.int(p.params.ulIvLen))
+ iv := make([]byte, len(newIv))
+ copy(iv, newIv)
+ return iv
+}
+
+// Free deallocates the memory reserved for the HSM to write back the actual IV.
+//
+// This must be called after the entire operation is complete, i.e. after
+// Encrypt or EncryptFinal. It is safe to call Free multiple times.
+func (p *GCMParams) Free() {
+ if p == nil || p.arena == nil {
+ return
+ }
+ p.arena.Free()
+ p.params = nil
+ p.arena = nil
+}
+
+// NewPSSParams creates a CK_RSA_PKCS_PSS_PARAMS structure and returns it as a byte array for use with the CKM_RSA_PKCS_PSS mechanism.
+func NewPSSParams(hashAlg, mgf, saltLength uint) []byte {
+ p := C.CK_RSA_PKCS_PSS_PARAMS{
+ hashAlg: C.CK_MECHANISM_TYPE(hashAlg),
+ mgf: C.CK_RSA_PKCS_MGF_TYPE(mgf),
+ sLen: C.CK_ULONG(saltLength),
+ }
+ return C.GoBytes(unsafe.Pointer(&p), C.int(unsafe.Sizeof(p)))
+}
+
+// OAEPParams can be passed to NewMechanism to implement CKM_RSA_PKCS_OAEP.
+type OAEPParams struct {
+ HashAlg uint
+ MGF uint
+ SourceType uint
+ SourceData []byte
+}
+
+// NewOAEPParams creates a CK_RSA_PKCS_OAEP_PARAMS structure suitable for use with the CKM_RSA_PKCS_OAEP mechanism.
+func NewOAEPParams(hashAlg, mgf, sourceType uint, sourceData []byte) *OAEPParams {
+ return &OAEPParams{
+ HashAlg: hashAlg,
+ MGF: mgf,
+ SourceType: sourceType,
+ SourceData: sourceData,
+ }
+}
+
+func cOAEPParams(p *OAEPParams, arena arena) ([]byte, arena) {
+ params := C.CK_RSA_PKCS_OAEP_PARAMS{
+ hashAlg: C.CK_MECHANISM_TYPE(p.HashAlg),
+ mgf: C.CK_RSA_PKCS_MGF_TYPE(p.MGF),
+ source: C.CK_RSA_PKCS_OAEP_SOURCE_TYPE(p.SourceType),
+ }
+ if len(p.SourceData) != 0 {
+ buf, len := arena.Allocate(p.SourceData)
+ // field is unaligned on windows so this has to call into C
+ C.putOAEPParams(&params, buf, len)
+ }
+ return C.GoBytes(unsafe.Pointer(&params), C.int(unsafe.Sizeof(params))), arena
+}
+
+// ECDH1DeriveParams can be passed to NewMechanism to implement CK_ECDH1_DERIVE_PARAMS.
+type ECDH1DeriveParams struct {
+ KDF uint
+ SharedData []byte
+ PublicKeyData []byte
+}
+
+// NewECDH1DeriveParams creates a CK_ECDH1_DERIVE_PARAMS structure suitable for use with the CKM_ECDH1_DERIVE mechanism.
+func NewECDH1DeriveParams(kdf uint, sharedData []byte, publicKeyData []byte) *ECDH1DeriveParams {
+ return &ECDH1DeriveParams{
+ KDF: kdf,
+ SharedData: sharedData,
+ PublicKeyData: publicKeyData,
+ }
+}
+
+func cECDH1DeriveParams(p *ECDH1DeriveParams, arena arena) ([]byte, arena) {
+ params := C.CK_ECDH1_DERIVE_PARAMS{
+ kdf: C.CK_EC_KDF_TYPE(p.KDF),
+ }
+
+ // SharedData MUST be null if key derivation function (KDF) is CKD_NULL
+ if len(p.SharedData) != 0 {
+ sharedData, sharedDataLen := arena.Allocate(p.SharedData)
+ C.putECDH1SharedParams(&params, sharedData, sharedDataLen)
+ }
+
+ publicKeyData, publicKeyDataLen := arena.Allocate(p.PublicKeyData)
+ C.putECDH1PublicParams(&params, publicKeyData, publicKeyDataLen)
+
+ return C.GoBytes(unsafe.Pointer(&params), C.int(unsafe.Sizeof(params))), arena
+}
diff --git a/vendor/github.com/miekg/pkcs11/pkcs11.go b/vendor/github.com/miekg/pkcs11/pkcs11.go
new file mode 100644
index 000000000..e21d23b73
--- /dev/null
+++ b/vendor/github.com/miekg/pkcs11/pkcs11.go
@@ -0,0 +1,1606 @@
+// Copyright 2013 Miek Gieben. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package pkcs11 is a wrapper around the PKCS#11 cryptographic library.
+package pkcs11
+
+// It is *assumed*, that:
+//
+// * Go's uint size == PKCS11's CK_ULONG size
+// * CK_ULONG never overflows an Go int
+
+/*
+#cgo windows CFLAGS: -DPACKED_STRUCTURES
+#cgo linux LDFLAGS: -ldl
+#cgo darwin LDFLAGS: -ldl
+#cgo openbsd LDFLAGS: -ldl
+#cgo freebsd LDFLAGS: -ldl
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "pkcs11go.h"
+
+#ifdef _WIN32
+#include <windows.h>
+
+struct ctx {
+ HMODULE handle;
+ CK_FUNCTION_LIST_PTR sym;
+};
+
+// New initializes a ctx and fills the symbol table.
+struct ctx *New(const char *module)
+{
+ CK_C_GetFunctionList list;
+ struct ctx *c = calloc(1, sizeof(struct ctx));
+ c->handle = LoadLibrary(module);
+ if (c->handle == NULL) {
+ free(c);
+ return NULL;
+ }
+ list = (CK_C_GetFunctionList) GetProcAddress(c->handle, "C_GetFunctionList");
+ if (list == NULL) {
+ free(c);
+ return NULL;
+ }
+ list(&c->sym);
+ return c;
+}
+
+// Destroy cleans up a ctx.
+void Destroy(struct ctx *c)
+{
+ if (!c) {
+ return;
+ }
+ free(c);
+}
+#else
+#include <dlfcn.h>
+
+struct ctx {
+ void *handle;
+ CK_FUNCTION_LIST_PTR sym;
+};
+
+// New initializes a ctx and fills the symbol table.
+struct ctx *New(const char *module)
+{
+ CK_C_GetFunctionList list;
+ struct ctx *c = calloc(1, sizeof(struct ctx));
+ c->handle = dlopen(module, RTLD_LAZY);
+ if (c->handle == NULL) {
+ free(c);
+ return NULL;
+ }
+ list = (CK_C_GetFunctionList) dlsym(c->handle, "C_GetFunctionList");
+ if (list == NULL) {
+ free(c);
+ return NULL;
+ }
+ list(&c->sym);
+ return c;
+}
+
+// Destroy cleans up a ctx.
+void Destroy(struct ctx *c)
+{
+ if (!c) {
+ return;
+ }
+ if (c->handle == NULL) {
+ return;
+ }
+ if (dlclose(c->handle) < 0) {
+ return;
+ }
+ free(c);
+}
+#endif
+
+CK_RV Initialize(struct ctx * c)
+{
+ CK_C_INITIALIZE_ARGS args;
+ memset(&args, 0, sizeof(args));
+ args.flags = CKF_OS_LOCKING_OK;
+ return c->sym->C_Initialize(&args);
+}
+
+CK_RV Finalize(struct ctx * c)
+{
+ return c->sym->C_Finalize(NULL);
+}
+
+CK_RV GetInfo(struct ctx * c, ckInfoPtr info)
+{
+ CK_INFO p;
+ CK_RV e = c->sym->C_GetInfo(&p);
+ if (e != CKR_OK) {
+ return e;
+ }
+ info->cryptokiVersion = p.cryptokiVersion;
+ memcpy(info->manufacturerID, p.manufacturerID, sizeof(p.manufacturerID));
+ info->flags = p.flags;
+ memcpy(info->libraryDescription, p.libraryDescription, sizeof(p.libraryDescription));
+ info->libraryVersion = p.libraryVersion;
+ return e;
+}
+
+CK_RV GetSlotList(struct ctx * c, CK_BBOOL tokenPresent,
+ CK_ULONG_PTR * slotList, CK_ULONG_PTR ulCount)
+{
+ CK_RV e = c->sym->C_GetSlotList(tokenPresent, NULL, ulCount);
+ if (e != CKR_OK) {
+ return e;
+ }
+ *slotList = calloc(*ulCount, sizeof(CK_SLOT_ID));
+ e = c->sym->C_GetSlotList(tokenPresent, *slotList, ulCount);
+ return e;
+}
+
+CK_RV GetSlotInfo(struct ctx * c, CK_ULONG slotID, CK_SLOT_INFO_PTR info)
+{
+ CK_RV e = c->sym->C_GetSlotInfo((CK_SLOT_ID) slotID, info);
+ return e;
+}
+
+CK_RV GetTokenInfo(struct ctx * c, CK_ULONG slotID, CK_TOKEN_INFO_PTR info)
+{
+ CK_RV e = c->sym->C_GetTokenInfo((CK_SLOT_ID) slotID, info);
+ return e;
+}
+
+CK_RV GetMechanismList(struct ctx * c, CK_ULONG slotID,
+ CK_ULONG_PTR * mech, CK_ULONG_PTR mechlen)
+{
+ CK_RV e =
+ c->sym->C_GetMechanismList((CK_SLOT_ID) slotID, NULL, mechlen);
+ // Gemaltos PKCS11 implementation returns CKR_BUFFER_TOO_SMALL on a NULL ptr instad of CKR_OK as the spec states.
+ if (e != CKR_OK && e != CKR_BUFFER_TOO_SMALL) {
+ return e;
+ }
+ *mech = calloc(*mechlen, sizeof(CK_MECHANISM_TYPE));
+ e = c->sym->C_GetMechanismList((CK_SLOT_ID) slotID,
+ (CK_MECHANISM_TYPE_PTR) * mech, mechlen);
+ return e;
+}
+
+CK_RV GetMechanismInfo(struct ctx * c, CK_ULONG slotID, CK_MECHANISM_TYPE mech,
+ CK_MECHANISM_INFO_PTR info)
+{
+ CK_RV e = c->sym->C_GetMechanismInfo((CK_SLOT_ID) slotID, mech, info);
+ return e;
+}
+
+CK_RV InitToken(struct ctx * c, CK_ULONG slotID, char *pin, CK_ULONG pinlen,
+ char *label)
+{
+ CK_RV e =
+ c->sym->C_InitToken((CK_SLOT_ID) slotID, (CK_UTF8CHAR_PTR) pin,
+ pinlen, (CK_UTF8CHAR_PTR) label);
+ return e;
+}
+
+CK_RV InitPIN(struct ctx * c, CK_SESSION_HANDLE sh, char *pin, CK_ULONG pinlen)
+{
+ CK_RV e = c->sym->C_InitPIN(sh, (CK_UTF8CHAR_PTR) pin, pinlen);
+ return e;
+}
+
+CK_RV SetPIN(struct ctx * c, CK_SESSION_HANDLE sh, char *oldpin,
+ CK_ULONG oldpinlen, char *newpin, CK_ULONG newpinlen)
+{
+ CK_RV e = c->sym->C_SetPIN(sh, (CK_UTF8CHAR_PTR) oldpin, oldpinlen,
+ (CK_UTF8CHAR_PTR) newpin, newpinlen);
+ return e;
+}
+
+CK_RV OpenSession(struct ctx * c, CK_ULONG slotID, CK_ULONG flags,
+ CK_SESSION_HANDLE_PTR session)
+{
+ CK_RV e =
+ c->sym->C_OpenSession((CK_SLOT_ID) slotID, (CK_FLAGS) flags, NULL,
+ NULL, session);
+ return e;
+}
+
+CK_RV CloseSession(struct ctx * c, CK_SESSION_HANDLE session)
+{
+ CK_RV e = c->sym->C_CloseSession(session);
+ return e;
+}
+
+CK_RV CloseAllSessions(struct ctx * c, CK_ULONG slotID)
+{
+ CK_RV e = c->sym->C_CloseAllSessions(slotID);
+ return e;
+}
+
+CK_RV GetSessionInfo(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_SESSION_INFO_PTR info)
+{
+ CK_RV e = c->sym->C_GetSessionInfo(session, info);
+ return e;
+}
+
+CK_RV GetOperationState(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_BYTE_PTR * state, CK_ULONG_PTR statelen)
+{
+ CK_RV rv = c->sym->C_GetOperationState(session, NULL, statelen);
+ if (rv != CKR_OK) {
+ return rv;
+ }
+ *state = calloc(*statelen, sizeof(CK_BYTE));
+ if (*state == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+ rv = c->sym->C_GetOperationState(session, *state, statelen);
+ return rv;
+}
+
+CK_RV SetOperationState(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_BYTE_PTR state, CK_ULONG statelen,
+ CK_OBJECT_HANDLE encryptkey, CK_OBJECT_HANDLE authkey)
+{
+ return c->sym->C_SetOperationState(session, state, statelen, encryptkey,
+ authkey);
+}
+
+CK_RV Login(struct ctx *c, CK_SESSION_HANDLE session, CK_USER_TYPE userType,
+ char *pin, CK_ULONG pinLen)
+{
+ if (pinLen == 0) {
+ pin = NULL;
+ }
+ CK_RV e =
+ c->sym->C_Login(session, userType, (CK_UTF8CHAR_PTR) pin, pinLen);
+ return e;
+}
+
+CK_RV Logout(struct ctx * c, CK_SESSION_HANDLE session)
+{
+ CK_RV e = c->sym->C_Logout(session);
+ return e;
+}
+
+CK_RV CreateObject(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_ATTRIBUTE_PTR temp, CK_ULONG tempCount,
+ CK_OBJECT_HANDLE_PTR obj)
+{
+ return c->sym->C_CreateObject(session, temp, tempCount, obj);
+}
+
+CK_RV CopyObject(struct ctx * c, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE o,
+ CK_ATTRIBUTE_PTR temp, CK_ULONG tempCount,
+ CK_OBJECT_HANDLE_PTR obj)
+{
+ return c->sym->C_CopyObject(session, o, temp, tempCount, obj);
+}
+
+CK_RV DestroyObject(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object)
+{
+ CK_RV e = c->sym->C_DestroyObject(session, object);
+ return e;
+}
+
+CK_RV GetObjectSize(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object, CK_ULONG_PTR size)
+{
+ CK_RV e = c->sym->C_GetObjectSize(session, object, size);
+ return e;
+}
+
+CK_RV GetAttributeValue(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object, CK_ATTRIBUTE_PTR temp,
+ CK_ULONG templen)
+{
+ // Call for the first time, check the returned ulValue in the attributes, then
+ // allocate enough space and try again.
+ CK_RV e = c->sym->C_GetAttributeValue(session, object, temp, templen);
+ if (e != CKR_OK) {
+ return e;
+ }
+ CK_ULONG i;
+ for (i = 0; i < templen; i++) {
+ if ((CK_LONG) temp[i].ulValueLen == -1) {
+ // either access denied or no such object
+ continue;
+ }
+ temp[i].pValue = calloc(temp[i].ulValueLen, sizeof(CK_BYTE));
+ }
+ return c->sym->C_GetAttributeValue(session, object, temp, templen);
+}
+
+CK_RV SetAttributeValue(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object, CK_ATTRIBUTE_PTR temp,
+ CK_ULONG templen)
+{
+ return c->sym->C_SetAttributeValue(session, object, temp, templen);
+}
+
+CK_RV FindObjectsInit(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_ATTRIBUTE_PTR temp, CK_ULONG tempCount)
+{
+ return c->sym->C_FindObjectsInit(session, temp, tempCount);
+}
+
+CK_RV FindObjects(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE_PTR * obj, CK_ULONG max,
+ CK_ULONG_PTR objCount)
+{
+ *obj = calloc(max, sizeof(CK_OBJECT_HANDLE));
+ CK_RV e = c->sym->C_FindObjects(session, *obj, max, objCount);
+ return e;
+}
+
+CK_RV FindObjectsFinal(struct ctx * c, CK_SESSION_HANDLE session)
+{
+ CK_RV e = c->sym->C_FindObjectsFinal(session);
+ return e;
+}
+
+CK_RV EncryptInit(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key)
+{
+ return c->sym->C_EncryptInit(session, mechanism, key);
+}
+
+CK_RV Encrypt(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR message,
+ CK_ULONG mlen, CK_BYTE_PTR * enc, CK_ULONG_PTR enclen)
+{
+ CK_RV rv = c->sym->C_Encrypt(session, message, mlen, NULL, enclen);
+ if (rv != CKR_OK) {
+ return rv;
+ }
+ *enc = calloc(*enclen, sizeof(CK_BYTE));
+ if (*enc == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+ rv = c->sym->C_Encrypt(session, message, mlen, *enc, enclen);
+ return rv;
+}
+
+CK_RV EncryptUpdate(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_BYTE_PTR plain, CK_ULONG plainlen, CK_BYTE_PTR * cipher,
+ CK_ULONG_PTR cipherlen)
+{
+ CK_RV rv =
+ c->sym->C_EncryptUpdate(session, plain, plainlen, NULL, cipherlen);
+ if (rv != CKR_OK) {
+ return rv;
+ }
+ *cipher = calloc(*cipherlen, sizeof(CK_BYTE));
+ if (*cipher == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+ rv = c->sym->C_EncryptUpdate(session, plain, plainlen, *cipher,
+ cipherlen);
+ return rv;
+}
+
+CK_RV EncryptFinal(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_BYTE_PTR * cipher, CK_ULONG_PTR cipherlen)
+{
+ CK_RV rv = c->sym->C_EncryptFinal(session, NULL, cipherlen);
+ if (rv != CKR_OK) {
+ return rv;
+ }
+ *cipher = calloc(*cipherlen, sizeof(CK_BYTE));
+ if (*cipher == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+ rv = c->sym->C_EncryptFinal(session, *cipher, cipherlen);
+ return rv;
+}
+
+CK_RV DecryptInit(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key)
+{
+ return c->sym->C_DecryptInit(session, mechanism, key);
+}
+
+CK_RV Decrypt(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR cipher,
+ CK_ULONG clen, CK_BYTE_PTR * plain, CK_ULONG_PTR plainlen)
+{
+ CK_RV e = c->sym->C_Decrypt(session, cipher, clen, NULL, plainlen);
+ if (e != CKR_OK) {
+ return e;
+ }
+ *plain = calloc(*plainlen, sizeof(CK_BYTE));
+ if (*plain == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+ e = c->sym->C_Decrypt(session, cipher, clen, *plain, plainlen);
+ return e;
+}
+
+CK_RV DecryptUpdate(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_BYTE_PTR cipher, CK_ULONG cipherlen, CK_BYTE_PTR * part,
+ CK_ULONG_PTR partlen)
+{
+ CK_RV rv =
+ c->sym->C_DecryptUpdate(session, cipher, cipherlen, NULL, partlen);
+ if (rv != CKR_OK) {
+ return rv;
+ }
+ *part = calloc(*partlen, sizeof(CK_BYTE));
+ if (*part == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+ rv = c->sym->C_DecryptUpdate(session, cipher, cipherlen, *part,
+ partlen);
+ return rv;
+}
+
+CK_RV DecryptFinal(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_BYTE_PTR * plain, CK_ULONG_PTR plainlen)
+{
+ CK_RV rv = c->sym->C_DecryptFinal(session, NULL, plainlen);
+ if (rv != CKR_OK) {
+ return rv;
+ }
+ *plain = calloc(*plainlen, sizeof(CK_BYTE));
+ if (*plain == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+ rv = c->sym->C_DecryptFinal(session, *plain, plainlen);
+ return rv;
+}
+
+CK_RV DigestInit(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism)
+{
+ return c->sym->C_DigestInit(session, mechanism);
+}
+
+CK_RV Digest(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR message,
+ CK_ULONG mlen, CK_BYTE_PTR * hash, CK_ULONG_PTR hashlen)
+{
+ CK_RV rv = c->sym->C_Digest(session, message, mlen, NULL, hashlen);
+ if (rv != CKR_OK) {
+ return rv;
+ }
+ *hash = calloc(*hashlen, sizeof(CK_BYTE));
+ if (*hash == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+ rv = c->sym->C_Digest(session, message, mlen, *hash, hashlen);
+ return rv;
+}
+
+CK_RV DigestUpdate(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_BYTE_PTR message, CK_ULONG mlen)
+{
+ CK_RV rv = c->sym->C_DigestUpdate(session, message, mlen);
+ return rv;
+}
+
+CK_RV DigestKey(struct ctx * c, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key)
+{
+ CK_RV rv = c->sym->C_DigestKey(session, key);
+ return rv;
+}
+
+CK_RV DigestFinal(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR * hash,
+ CK_ULONG_PTR hashlen)
+{
+ CK_RV rv = c->sym->C_DigestFinal(session, NULL, hashlen);
+ if (rv != CKR_OK) {
+ return rv;
+ }
+ *hash = calloc(*hashlen, sizeof(CK_BYTE));
+ if (*hash == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+ rv = c->sym->C_DigestFinal(session, *hash, hashlen);
+ return rv;
+}
+
+CK_RV SignInit(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key)
+{
+ return c->sym->C_SignInit(session, mechanism, key);
+}
+
+CK_RV Sign(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR message,
+ CK_ULONG mlen, CK_BYTE_PTR * sig, CK_ULONG_PTR siglen)
+{
+ CK_RV rv = c->sym->C_Sign(session, message, mlen, NULL, siglen);
+ if (rv != CKR_OK) {
+ return rv;
+ }
+ *sig = calloc(*siglen, sizeof(CK_BYTE));
+ if (*sig == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+ rv = c->sym->C_Sign(session, message, mlen, *sig, siglen);
+ return rv;
+}
+
+CK_RV SignUpdate(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_BYTE_PTR message, CK_ULONG mlen)
+{
+ CK_RV rv = c->sym->C_SignUpdate(session, message, mlen);
+ return rv;
+}
+
+CK_RV SignFinal(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR * sig,
+ CK_ULONG_PTR siglen)
+{
+ CK_RV rv = c->sym->C_SignFinal(session, NULL, siglen);
+ if (rv != CKR_OK) {
+ return rv;
+ }
+ *sig = calloc(*siglen, sizeof(CK_BYTE));
+ if (*sig == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+ rv = c->sym->C_SignFinal(session, *sig, siglen);
+ return rv;
+}
+
+CK_RV SignRecoverInit(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key)
+{
+ return c->sym->C_SignRecoverInit(session, mechanism, key);
+}
+
+CK_RV SignRecover(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR data,
+ CK_ULONG datalen, CK_BYTE_PTR * sig, CK_ULONG_PTR siglen)
+{
+ CK_RV rv = c->sym->C_SignRecover(session, data, datalen, NULL, siglen);
+ if (rv != CKR_OK) {
+ return rv;
+ }
+ *sig = calloc(*siglen, sizeof(CK_BYTE));
+ if (*sig == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+ rv = c->sym->C_SignRecover(session, data, datalen, *sig, siglen);
+ return rv;
+}
+
+CK_RV VerifyInit(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key)
+{
+ return c->sym->C_VerifyInit(session, mechanism, key);
+}
+
+CK_RV Verify(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR message,
+ CK_ULONG mesglen, CK_BYTE_PTR sig, CK_ULONG siglen)
+{
+ CK_RV rv = c->sym->C_Verify(session, message, mesglen, sig, siglen);
+ return rv;
+}
+
+CK_RV VerifyUpdate(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_BYTE_PTR part, CK_ULONG partlen)
+{
+ CK_RV rv = c->sym->C_VerifyUpdate(session, part, partlen);
+ return rv;
+}
+
+CK_RV VerifyFinal(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR sig,
+ CK_ULONG siglen)
+{
+ CK_RV rv = c->sym->C_VerifyFinal(session, sig, siglen);
+ return rv;
+}
+
+CK_RV VerifyRecoverInit(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key)
+{
+ return c->sym->C_VerifyRecoverInit(session, mechanism, key);
+}
+
+CK_RV VerifyRecover(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR sig,
+ CK_ULONG siglen, CK_BYTE_PTR * data, CK_ULONG_PTR datalen)
+{
+ CK_RV rv = c->sym->C_VerifyRecover(session, sig, siglen, NULL, datalen);
+ if (rv != CKR_OK) {
+ return rv;
+ }
+ *data = calloc(*datalen, sizeof(CK_BYTE));
+ if (*data == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+ rv = c->sym->C_VerifyRecover(session, sig, siglen, *data, datalen);
+ return rv;
+}
+
+CK_RV DigestEncryptUpdate(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_BYTE_PTR part, CK_ULONG partlen, CK_BYTE_PTR * enc,
+ CK_ULONG_PTR enclen)
+{
+ CK_RV rv =
+ c->sym->C_DigestEncryptUpdate(session, part, partlen, NULL, enclen);
+ if (rv != CKR_OK) {
+ return rv;
+ }
+ *enc = calloc(*enclen, sizeof(CK_BYTE));
+ if (*enc == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+ rv = c->sym->C_DigestEncryptUpdate(session, part, partlen, *enc,
+ enclen);
+ return rv;
+}
+
+CK_RV DecryptDigestUpdate(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_BYTE_PTR cipher, CK_ULONG cipherlen,
+ CK_BYTE_PTR * part, CK_ULONG_PTR partlen)
+{
+ CK_RV rv =
+ c->sym->C_DecryptDigestUpdate(session, cipher, cipherlen, NULL,
+ partlen);
+ if (rv != CKR_OK) {
+ return rv;
+ }
+ *part = calloc(*partlen, sizeof(CK_BYTE));
+ if (*part == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+ rv = c->sym->C_DecryptDigestUpdate(session, cipher, cipherlen, *part,
+ partlen);
+ return rv;
+}
+
+CK_RV SignEncryptUpdate(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_BYTE_PTR part, CK_ULONG partlen, CK_BYTE_PTR * enc,
+ CK_ULONG_PTR enclen)
+{
+ CK_RV rv =
+ c->sym->C_SignEncryptUpdate(session, part, partlen, NULL, enclen);
+ if (rv != CKR_OK) {
+ return rv;
+ }
+ *enc = calloc(*enclen, sizeof(CK_BYTE));
+ if (*enc == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+ rv = c->sym->C_SignEncryptUpdate(session, part, partlen, *enc, enclen);
+ return rv;
+}
+
+CK_RV DecryptVerifyUpdate(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_BYTE_PTR cipher, CK_ULONG cipherlen,
+ CK_BYTE_PTR * part, CK_ULONG_PTR partlen)
+{
+ CK_RV rv =
+ c->sym->C_DecryptVerifyUpdate(session, cipher, cipherlen, NULL,
+ partlen);
+ if (rv != CKR_OK) {
+ return rv;
+ }
+ *part = calloc(*partlen, sizeof(CK_BYTE));
+ if (*part == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+ rv = c->sym->C_DecryptVerifyUpdate(session, cipher, cipherlen, *part,
+ partlen);
+ return rv;
+}
+
+CK_RV GenerateKey(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism, CK_ATTRIBUTE_PTR temp,
+ CK_ULONG tempCount, CK_OBJECT_HANDLE_PTR key)
+{
+ return c->sym->C_GenerateKey(session, mechanism, temp, tempCount, key);
+}
+
+CK_RV GenerateKeyPair(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism, CK_ATTRIBUTE_PTR pub,
+ CK_ULONG pubCount, CK_ATTRIBUTE_PTR priv,
+ CK_ULONG privCount, CK_OBJECT_HANDLE_PTR pubkey,
+ CK_OBJECT_HANDLE_PTR privkey)
+{
+ return c->sym->C_GenerateKeyPair(session, mechanism, pub, pubCount,
+ priv, privCount, pubkey, privkey);
+}
+
+CK_RV WrapKey(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE wrappingkey,
+ CK_OBJECT_HANDLE key, CK_BYTE_PTR * wrapped,
+ CK_ULONG_PTR wrappedlen)
+{
+ CK_RV rv = c->sym->C_WrapKey(session, mechanism, wrappingkey, key, NULL,
+ wrappedlen);
+ if (rv != CKR_OK) {
+ return rv;
+ }
+ *wrapped = calloc(*wrappedlen, sizeof(CK_BYTE));
+ if (*wrapped == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+ rv = c->sym->C_WrapKey(session, mechanism, wrappingkey, key, *wrapped,
+ wrappedlen);
+ return rv;
+}
+
+CK_RV DeriveKey(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE basekey,
+ CK_ATTRIBUTE_PTR a, CK_ULONG alen, CK_OBJECT_HANDLE_PTR key)
+{
+ return c->sym->C_DeriveKey(session, mechanism, basekey, a, alen, key);
+}
+
+CK_RV UnwrapKey(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE unwrappingkey,
+ CK_BYTE_PTR wrappedkey, CK_ULONG wrappedkeylen,
+ CK_ATTRIBUTE_PTR a, CK_ULONG alen, CK_OBJECT_HANDLE_PTR key)
+{
+ return c->sym->C_UnwrapKey(session, mechanism, unwrappingkey, wrappedkey,
+ wrappedkeylen, a, alen, key);
+}
+
+CK_RV SeedRandom(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR seed,
+ CK_ULONG seedlen)
+{
+ CK_RV e = c->sym->C_SeedRandom(session, seed, seedlen);
+ return e;
+}
+
+CK_RV GenerateRandom(struct ctx * c, CK_SESSION_HANDLE session,
+ CK_BYTE_PTR * rand, CK_ULONG length)
+{
+ *rand = calloc(length, sizeof(CK_BYTE));
+ if (*rand == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+ CK_RV e = c->sym->C_GenerateRandom(session, *rand, length);
+ return e;
+}
+
+CK_RV WaitForSlotEvent(struct ctx * c, CK_FLAGS flags, CK_ULONG_PTR slot)
+{
+ CK_RV e =
+ c->sym->C_WaitForSlotEvent(flags, (CK_SLOT_ID_PTR) slot, NULL);
+ return e;
+}
+
+static inline CK_VOID_PTR getAttributePval(CK_ATTRIBUTE_PTR a)
+{
+ return a->pValue;
+}
+
+*/
+import "C"
+import "strings"
+
+import "unsafe"
+
+// Ctx contains the current pkcs11 context.
+type Ctx struct {
+ ctx *C.struct_ctx
+}
+
+// New creates a new context and initializes the module/library for use.
+func New(module string) *Ctx {
+ c := new(Ctx)
+ mod := C.CString(module)
+ defer C.free(unsafe.Pointer(mod))
+ c.ctx = C.New(mod)
+ if c.ctx == nil {
+ return nil
+ }
+ return c
+}
+
+// Destroy unloads the module/library and frees any remaining memory.
+func (c *Ctx) Destroy() {
+ if c == nil || c.ctx == nil {
+ return
+ }
+ C.Destroy(c.ctx)
+ c.ctx = nil
+}
+
+// Initialize initializes the Cryptoki library.
+func (c *Ctx) Initialize() error {
+ e := C.Initialize(c.ctx)
+ return toError(e)
+}
+
+// Finalize indicates that an application is done with the Cryptoki library.
+func (c *Ctx) Finalize() error {
+ if c.ctx == nil {
+ return toError(CKR_CRYPTOKI_NOT_INITIALIZED)
+ }
+ e := C.Finalize(c.ctx)
+ return toError(e)
+}
+
+// GetInfo returns general information about Cryptoki.
+func (c *Ctx) GetInfo() (Info, error) {
+ var p C.ckInfo
+ e := C.GetInfo(c.ctx, &p)
+ i := Info{
+ CryptokiVersion: toVersion(p.cryptokiVersion),
+ ManufacturerID: strings.TrimRight(string(C.GoBytes(unsafe.Pointer(&p.manufacturerID[0]), 32)), " "),
+ Flags: uint(p.flags),
+ LibraryDescription: strings.TrimRight(string(C.GoBytes(unsafe.Pointer(&p.libraryDescription[0]), 32)), " "),
+ LibraryVersion: toVersion(p.libraryVersion),
+ }
+ return i, toError(e)
+}
+
+// GetSlotList obtains a list of slots in the system.
+func (c *Ctx) GetSlotList(tokenPresent bool) ([]uint, error) {
+ var (
+ slotList C.CK_ULONG_PTR
+ ulCount C.CK_ULONG
+ )
+ e := C.GetSlotList(c.ctx, cBBool(tokenPresent), &slotList, &ulCount)
+ if toError(e) != nil {
+ return nil, toError(e)
+ }
+ l := toList(slotList, ulCount)
+ return l, nil
+}
+
+// GetSlotInfo obtains information about a particular slot in the system.
+func (c *Ctx) GetSlotInfo(slotID uint) (SlotInfo, error) {
+ var csi C.CK_SLOT_INFO
+ e := C.GetSlotInfo(c.ctx, C.CK_ULONG(slotID), &csi)
+ s := SlotInfo{
+ SlotDescription: strings.TrimRight(string(C.GoBytes(unsafe.Pointer(&csi.slotDescription[0]), 64)), " "),
+ ManufacturerID: strings.TrimRight(string(C.GoBytes(unsafe.Pointer(&csi.manufacturerID[0]), 32)), " "),
+ Flags: uint(csi.flags),
+ HardwareVersion: toVersion(csi.hardwareVersion),
+ FirmwareVersion: toVersion(csi.firmwareVersion),
+ }
+ return s, toError(e)
+}
+
+// GetTokenInfo obtains information about a particular token
+// in the system.
+func (c *Ctx) GetTokenInfo(slotID uint) (TokenInfo, error) {
+ var cti C.CK_TOKEN_INFO
+ e := C.GetTokenInfo(c.ctx, C.CK_ULONG(slotID), &cti)
+ s := TokenInfo{
+ Label: strings.TrimRight(string(C.GoBytes(unsafe.Pointer(&cti.label[0]), 32)), " "),
+ ManufacturerID: strings.TrimRight(string(C.GoBytes(unsafe.Pointer(&cti.manufacturerID[0]), 32)), " "),
+ Model: strings.TrimRight(string(C.GoBytes(unsafe.Pointer(&cti.model[0]), 16)), " "),
+ SerialNumber: strings.TrimRight(string(C.GoBytes(unsafe.Pointer(&cti.serialNumber[0]), 16)), " "),
+ Flags: uint(cti.flags),
+ MaxSessionCount: uint(cti.ulMaxSessionCount),
+ SessionCount: uint(cti.ulSessionCount),
+ MaxRwSessionCount: uint(cti.ulMaxRwSessionCount),
+ RwSessionCount: uint(cti.ulRwSessionCount),
+ MaxPinLen: uint(cti.ulMaxPinLen),
+ MinPinLen: uint(cti.ulMinPinLen),
+ TotalPublicMemory: uint(cti.ulTotalPublicMemory),
+ FreePublicMemory: uint(cti.ulFreePublicMemory),
+ TotalPrivateMemory: uint(cti.ulTotalPrivateMemory),
+ FreePrivateMemory: uint(cti.ulFreePrivateMemory),
+ HardwareVersion: toVersion(cti.hardwareVersion),
+ FirmwareVersion: toVersion(cti.firmwareVersion),
+ UTCTime: strings.TrimRight(string(C.GoBytes(unsafe.Pointer(&cti.utcTime[0]), 16)), " "),
+ }
+ return s, toError(e)
+}
+
+// GetMechanismList obtains a list of mechanism types supported by a token.
+func (c *Ctx) GetMechanismList(slotID uint) ([]*Mechanism, error) {
+ var (
+ mech C.CK_ULONG_PTR // in pkcs#11 we're all CK_ULONGs \o/
+ mechlen C.CK_ULONG
+ )
+ e := C.GetMechanismList(c.ctx, C.CK_ULONG(slotID), &mech, &mechlen)
+ if toError(e) != nil {
+ return nil, toError(e)
+ }
+ // Although the function returns only type, cast them back into real
+ // attributes as this is used in other functions.
+ m := make([]*Mechanism, int(mechlen))
+ for i, typ := range toList(mech, mechlen) {
+ m[i] = NewMechanism(typ, nil)
+ }
+ return m, nil
+}
+
+// GetMechanismInfo obtains information about a particular
+// mechanism possibly supported by a token.
+func (c *Ctx) GetMechanismInfo(slotID uint, m []*Mechanism) (MechanismInfo, error) {
+ var cm C.CK_MECHANISM_INFO
+ e := C.GetMechanismInfo(c.ctx, C.CK_ULONG(slotID), C.CK_MECHANISM_TYPE(m[0].Mechanism),
+ C.CK_MECHANISM_INFO_PTR(&cm))
+ mi := MechanismInfo{
+ MinKeySize: uint(cm.ulMinKeySize),
+ MaxKeySize: uint(cm.ulMaxKeySize),
+ Flags: uint(cm.flags),
+ }
+ return mi, toError(e)
+}
+
+// InitToken initializes a token. The label must be 32 characters
+// long, it is blank padded if it is not. If it is longer it is capped
+// to 32 characters.
+func (c *Ctx) InitToken(slotID uint, pin string, label string) error {
+ p := C.CString(pin)
+ defer C.free(unsafe.Pointer(p))
+ ll := len(label)
+ for ll < 32 {
+ label += " "
+ ll++
+ }
+ l := C.CString(label[:32])
+ defer C.free(unsafe.Pointer(l))
+ e := C.InitToken(c.ctx, C.CK_ULONG(slotID), p, C.CK_ULONG(len(pin)), l)
+ return toError(e)
+}
+
+// InitPIN initializes the normal user's PIN.
+func (c *Ctx) InitPIN(sh SessionHandle, pin string) error {
+ p := C.CString(pin)
+ defer C.free(unsafe.Pointer(p))
+ e := C.InitPIN(c.ctx, C.CK_SESSION_HANDLE(sh), p, C.CK_ULONG(len(pin)))
+ return toError(e)
+}
+
+// SetPIN modifies the PIN of the user who is logged in.
+func (c *Ctx) SetPIN(sh SessionHandle, oldpin string, newpin string) error {
+ old := C.CString(oldpin)
+ defer C.free(unsafe.Pointer(old))
+ new := C.CString(newpin)
+ defer C.free(unsafe.Pointer(new))
+ e := C.SetPIN(c.ctx, C.CK_SESSION_HANDLE(sh), old, C.CK_ULONG(len(oldpin)), new, C.CK_ULONG(len(newpin)))
+ return toError(e)
+}
+
+// OpenSession opens a session between an application and a token.
+func (c *Ctx) OpenSession(slotID uint, flags uint) (SessionHandle, error) {
+ var s C.CK_SESSION_HANDLE
+ e := C.OpenSession(c.ctx, C.CK_ULONG(slotID), C.CK_ULONG(flags), C.CK_SESSION_HANDLE_PTR(&s))
+ return SessionHandle(s), toError(e)
+}
+
+// CloseSession closes a session between an application and a token.
+func (c *Ctx) CloseSession(sh SessionHandle) error {
+ if c.ctx == nil {
+ return toError(CKR_CRYPTOKI_NOT_INITIALIZED)
+ }
+ e := C.CloseSession(c.ctx, C.CK_SESSION_HANDLE(sh))
+ return toError(e)
+}
+
+// CloseAllSessions closes all sessions with a token.
+func (c *Ctx) CloseAllSessions(slotID uint) error {
+ if c.ctx == nil {
+ return toError(CKR_CRYPTOKI_NOT_INITIALIZED)
+ }
+ e := C.CloseAllSessions(c.ctx, C.CK_ULONG(slotID))
+ return toError(e)
+}
+
+// GetSessionInfo obtains information about the session.
+func (c *Ctx) GetSessionInfo(sh SessionHandle) (SessionInfo, error) {
+ var csi C.CK_SESSION_INFO
+ e := C.GetSessionInfo(c.ctx, C.CK_SESSION_HANDLE(sh), &csi)
+ s := SessionInfo{SlotID: uint(csi.slotID),
+ State: uint(csi.state),
+ Flags: uint(csi.flags),
+ DeviceError: uint(csi.ulDeviceError),
+ }
+ return s, toError(e)
+}
+
+// GetOperationState obtains the state of the cryptographic operation in a session.
+func (c *Ctx) GetOperationState(sh SessionHandle) ([]byte, error) {
+ var (
+ state C.CK_BYTE_PTR
+ statelen C.CK_ULONG
+ )
+ e := C.GetOperationState(c.ctx, C.CK_SESSION_HANDLE(sh), &state, &statelen)
+ defer C.free(unsafe.Pointer(state))
+ if toError(e) != nil {
+ return nil, toError(e)
+ }
+ b := C.GoBytes(unsafe.Pointer(state), C.int(statelen))
+ return b, nil
+}
+
+// SetOperationState restores the state of the cryptographic operation in a session.
+func (c *Ctx) SetOperationState(sh SessionHandle, state []byte, encryptKey, authKey ObjectHandle) error {
+ e := C.SetOperationState(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&state[0])),
+ C.CK_ULONG(len(state)), C.CK_OBJECT_HANDLE(encryptKey), C.CK_OBJECT_HANDLE(authKey))
+ return toError(e)
+}
+
+// Login logs a user into a token.
+func (c *Ctx) Login(sh SessionHandle, userType uint, pin string) error {
+ p := C.CString(pin)
+ defer C.free(unsafe.Pointer(p))
+ e := C.Login(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_USER_TYPE(userType), p, C.CK_ULONG(len(pin)))
+ return toError(e)
+}
+
+// Logout logs a user out from a token.
+func (c *Ctx) Logout(sh SessionHandle) error {
+ if c.ctx == nil {
+ return toError(CKR_CRYPTOKI_NOT_INITIALIZED)
+ }
+ e := C.Logout(c.ctx, C.CK_SESSION_HANDLE(sh))
+ return toError(e)
+}
+
+// CreateObject creates a new object.
+func (c *Ctx) CreateObject(sh SessionHandle, temp []*Attribute) (ObjectHandle, error) {
+ var obj C.CK_OBJECT_HANDLE
+ arena, t, tcount := cAttributeList(temp)
+ defer arena.Free()
+ e := C.CreateObject(c.ctx, C.CK_SESSION_HANDLE(sh), t, tcount, C.CK_OBJECT_HANDLE_PTR(&obj))
+ e1 := toError(e)
+ if e1 == nil {
+ return ObjectHandle(obj), nil
+ }
+ return 0, e1
+}
+
+// CopyObject copies an object, creating a new object for the copy.
+func (c *Ctx) CopyObject(sh SessionHandle, o ObjectHandle, temp []*Attribute) (ObjectHandle, error) {
+ var obj C.CK_OBJECT_HANDLE
+ arena, t, tcount := cAttributeList(temp)
+ defer arena.Free()
+
+ e := C.CopyObject(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_OBJECT_HANDLE(o), t, tcount, C.CK_OBJECT_HANDLE_PTR(&obj))
+ e1 := toError(e)
+ if e1 == nil {
+ return ObjectHandle(obj), nil
+ }
+ return 0, e1
+}
+
+// DestroyObject destroys an object.
+func (c *Ctx) DestroyObject(sh SessionHandle, oh ObjectHandle) error {
+ e := C.DestroyObject(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_OBJECT_HANDLE(oh))
+ return toError(e)
+}
+
+// GetObjectSize gets the size of an object in bytes.
+func (c *Ctx) GetObjectSize(sh SessionHandle, oh ObjectHandle) (uint, error) {
+ var size C.CK_ULONG
+ e := C.GetObjectSize(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_OBJECT_HANDLE(oh), &size)
+ return uint(size), toError(e)
+}
+
+// GetAttributeValue obtains the value of one or more object attributes.
+func (c *Ctx) GetAttributeValue(sh SessionHandle, o ObjectHandle, a []*Attribute) ([]*Attribute, error) {
+ // copy the attribute list and make all the values nil, so that
+ // the C function can (allocate) fill them in
+ pa := make([]C.CK_ATTRIBUTE, len(a))
+ for i := 0; i < len(a); i++ {
+ pa[i]._type = C.CK_ATTRIBUTE_TYPE(a[i].Type)
+ }
+ e := C.GetAttributeValue(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_OBJECT_HANDLE(o), &pa[0], C.CK_ULONG(len(a)))
+ if err := toError(e); err != nil {
+ return nil, err
+ }
+ a1 := make([]*Attribute, len(a))
+ for i, c := range pa {
+ x := new(Attribute)
+ x.Type = uint(c._type)
+ if int(c.ulValueLen) != -1 {
+ buf := unsafe.Pointer(C.getAttributePval(&c))
+ x.Value = C.GoBytes(buf, C.int(c.ulValueLen))
+ C.free(buf)
+ }
+ a1[i] = x
+ }
+ return a1, nil
+}
+
+// SetAttributeValue modifies the value of one or more object attributes
+func (c *Ctx) SetAttributeValue(sh SessionHandle, o ObjectHandle, a []*Attribute) error {
+ arena, pa, palen := cAttributeList(a)
+ defer arena.Free()
+ e := C.SetAttributeValue(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_OBJECT_HANDLE(o), pa, palen)
+ return toError(e)
+}
+
+// FindObjectsInit initializes a search for token and session
+// objects that match a template.
+func (c *Ctx) FindObjectsInit(sh SessionHandle, temp []*Attribute) error {
+ arena, t, tcount := cAttributeList(temp)
+ defer arena.Free()
+ e := C.FindObjectsInit(c.ctx, C.CK_SESSION_HANDLE(sh), t, tcount)
+ return toError(e)
+}
+
+// FindObjects continues a search for token and session
+// objects that match a template, obtaining additional object
+// handles. Calling the function repeatedly may yield additional results until
+// an empty slice is returned.
+//
+// The returned boolean value is deprecated and should be ignored.
+func (c *Ctx) FindObjects(sh SessionHandle, max int) ([]ObjectHandle, bool, error) {
+ var (
+ objectList C.CK_OBJECT_HANDLE_PTR
+ ulCount C.CK_ULONG
+ )
+ e := C.FindObjects(c.ctx, C.CK_SESSION_HANDLE(sh), &objectList, C.CK_ULONG(max), &ulCount)
+ if toError(e) != nil {
+ return nil, false, toError(e)
+ }
+ l := toList(C.CK_ULONG_PTR(unsafe.Pointer(objectList)), ulCount)
+ // Make again a new list of the correct type.
+ // This is copying data, but this is not an often used function.
+ o := make([]ObjectHandle, len(l))
+ for i, v := range l {
+ o[i] = ObjectHandle(v)
+ }
+ return o, ulCount > C.CK_ULONG(max), nil
+}
+
+// FindObjectsFinal finishes a search for token and session objects.
+func (c *Ctx) FindObjectsFinal(sh SessionHandle) error {
+ e := C.FindObjectsFinal(c.ctx, C.CK_SESSION_HANDLE(sh))
+ return toError(e)
+}
+
+// EncryptInit initializes an encryption operation.
+func (c *Ctx) EncryptInit(sh SessionHandle, m []*Mechanism, o ObjectHandle) error {
+ arena, mech := cMechanism(m)
+ defer arena.Free()
+ e := C.EncryptInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(o))
+ return toError(e)
+}
+
+// Encrypt encrypts single-part data.
+func (c *Ctx) Encrypt(sh SessionHandle, message []byte) ([]byte, error) {
+ var (
+ enc C.CK_BYTE_PTR
+ enclen C.CK_ULONG
+ )
+ e := C.Encrypt(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(message), C.CK_ULONG(len(message)), &enc, &enclen)
+ if toError(e) != nil {
+ return nil, toError(e)
+ }
+ s := C.GoBytes(unsafe.Pointer(enc), C.int(enclen))
+ C.free(unsafe.Pointer(enc))
+ return s, nil
+}
+
+// EncryptUpdate continues a multiple-part encryption operation.
+func (c *Ctx) EncryptUpdate(sh SessionHandle, plain []byte) ([]byte, error) {
+ var (
+ part C.CK_BYTE_PTR
+ partlen C.CK_ULONG
+ )
+ e := C.EncryptUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(plain), C.CK_ULONG(len(plain)), &part, &partlen)
+ if toError(e) != nil {
+ return nil, toError(e)
+ }
+ h := C.GoBytes(unsafe.Pointer(part), C.int(partlen))
+ C.free(unsafe.Pointer(part))
+ return h, nil
+}
+
+// EncryptFinal finishes a multiple-part encryption operation.
+func (c *Ctx) EncryptFinal(sh SessionHandle) ([]byte, error) {
+ var (
+ enc C.CK_BYTE_PTR
+ enclen C.CK_ULONG
+ )
+ e := C.EncryptFinal(c.ctx, C.CK_SESSION_HANDLE(sh), &enc, &enclen)
+ if toError(e) != nil {
+ return nil, toError(e)
+ }
+ h := C.GoBytes(unsafe.Pointer(enc), C.int(enclen))
+ C.free(unsafe.Pointer(enc))
+ return h, nil
+}
+
+// DecryptInit initializes a decryption operation.
+func (c *Ctx) DecryptInit(sh SessionHandle, m []*Mechanism, o ObjectHandle) error {
+ arena, mech := cMechanism(m)
+ defer arena.Free()
+ e := C.DecryptInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(o))
+ return toError(e)
+}
+
+// Decrypt decrypts encrypted data in a single part.
+func (c *Ctx) Decrypt(sh SessionHandle, cipher []byte) ([]byte, error) {
+ var (
+ plain C.CK_BYTE_PTR
+ plainlen C.CK_ULONG
+ )
+ e := C.Decrypt(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(cipher), C.CK_ULONG(len(cipher)), &plain, &plainlen)
+ if toError(e) != nil {
+ return nil, toError(e)
+ }
+ s := C.GoBytes(unsafe.Pointer(plain), C.int(plainlen))
+ C.free(unsafe.Pointer(plain))
+ return s, nil
+}
+
+// DecryptUpdate continues a multiple-part decryption operation.
+func (c *Ctx) DecryptUpdate(sh SessionHandle, cipher []byte) ([]byte, error) {
+ var (
+ part C.CK_BYTE_PTR
+ partlen C.CK_ULONG
+ )
+ e := C.DecryptUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(cipher), C.CK_ULONG(len(cipher)), &part, &partlen)
+ if toError(e) != nil {
+ return nil, toError(e)
+ }
+ h := C.GoBytes(unsafe.Pointer(part), C.int(partlen))
+ C.free(unsafe.Pointer(part))
+ return h, nil
+}
+
+// DecryptFinal finishes a multiple-part decryption operation.
+func (c *Ctx) DecryptFinal(sh SessionHandle) ([]byte, error) {
+ var (
+ plain C.CK_BYTE_PTR
+ plainlen C.CK_ULONG
+ )
+ e := C.DecryptFinal(c.ctx, C.CK_SESSION_HANDLE(sh), &plain, &plainlen)
+ if toError(e) != nil {
+ return nil, toError(e)
+ }
+ h := C.GoBytes(unsafe.Pointer(plain), C.int(plainlen))
+ C.free(unsafe.Pointer(plain))
+ return h, nil
+}
+
+// DigestInit initializes a message-digesting operation.
+func (c *Ctx) DigestInit(sh SessionHandle, m []*Mechanism) error {
+ arena, mech := cMechanism(m)
+ defer arena.Free()
+ e := C.DigestInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech)
+ return toError(e)
+}
+
+// Digest digests message in a single part.
+func (c *Ctx) Digest(sh SessionHandle, message []byte) ([]byte, error) {
+ var (
+ hash C.CK_BYTE_PTR
+ hashlen C.CK_ULONG
+ )
+ e := C.Digest(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(message), C.CK_ULONG(len(message)), &hash, &hashlen)
+ if toError(e) != nil {
+ return nil, toError(e)
+ }
+ h := C.GoBytes(unsafe.Pointer(hash), C.int(hashlen))
+ C.free(unsafe.Pointer(hash))
+ return h, nil
+}
+
+// DigestUpdate continues a multiple-part message-digesting operation.
+func (c *Ctx) DigestUpdate(sh SessionHandle, message []byte) error {
+ e := C.DigestUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(message), C.CK_ULONG(len(message)))
+ if toError(e) != nil {
+ return toError(e)
+ }
+ return nil
+}
+
+// DigestKey continues a multi-part message-digesting
+// operation, by digesting the value of a secret key as part of
+// the data already digested.
+func (c *Ctx) DigestKey(sh SessionHandle, key ObjectHandle) error {
+ e := C.DigestKey(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_OBJECT_HANDLE(key))
+ if toError(e) != nil {
+ return toError(e)
+ }
+ return nil
+}
+
+// DigestFinal finishes a multiple-part message-digesting operation.
+func (c *Ctx) DigestFinal(sh SessionHandle) ([]byte, error) {
+ var (
+ hash C.CK_BYTE_PTR
+ hashlen C.CK_ULONG
+ )
+ e := C.DigestFinal(c.ctx, C.CK_SESSION_HANDLE(sh), &hash, &hashlen)
+ if toError(e) != nil {
+ return nil, toError(e)
+ }
+ h := C.GoBytes(unsafe.Pointer(hash), C.int(hashlen))
+ C.free(unsafe.Pointer(hash))
+ return h, nil
+}
+
+// SignInit initializes a signature (private key encryption)
+// operation, where the signature is (will be) an appendix to
+// the data, and plaintext cannot be recovered from the signature.
+func (c *Ctx) SignInit(sh SessionHandle, m []*Mechanism, o ObjectHandle) error {
+ arena, mech := cMechanism(m)
+ defer arena.Free()
+ e := C.SignInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(o))
+ return toError(e)
+}
+
+// Sign signs (encrypts with private key) data in a single part, where the signature
+// is (will be) an appendix to the data, and plaintext cannot be recovered from the signature.
+func (c *Ctx) Sign(sh SessionHandle, message []byte) ([]byte, error) {
+ var (
+ sig C.CK_BYTE_PTR
+ siglen C.CK_ULONG
+ )
+ e := C.Sign(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(message), C.CK_ULONG(len(message)), &sig, &siglen)
+ if toError(e) != nil {
+ return nil, toError(e)
+ }
+ s := C.GoBytes(unsafe.Pointer(sig), C.int(siglen))
+ C.free(unsafe.Pointer(sig))
+ return s, nil
+}
+
+// SignUpdate continues a multiple-part signature operation,
+// where the signature is (will be) an appendix to the data,
+// and plaintext cannot be recovered from the signature.
+func (c *Ctx) SignUpdate(sh SessionHandle, message []byte) error {
+ e := C.SignUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(message), C.CK_ULONG(len(message)))
+ return toError(e)
+}
+
+// SignFinal finishes a multiple-part signature operation returning the signature.
+func (c *Ctx) SignFinal(sh SessionHandle) ([]byte, error) {
+ var (
+ sig C.CK_BYTE_PTR
+ siglen C.CK_ULONG
+ )
+ e := C.SignFinal(c.ctx, C.CK_SESSION_HANDLE(sh), &sig, &siglen)
+ if toError(e) != nil {
+ return nil, toError(e)
+ }
+ h := C.GoBytes(unsafe.Pointer(sig), C.int(siglen))
+ C.free(unsafe.Pointer(sig))
+ return h, nil
+}
+
+// SignRecoverInit initializes a signature operation, where the data can be recovered from the signature.
+func (c *Ctx) SignRecoverInit(sh SessionHandle, m []*Mechanism, key ObjectHandle) error {
+ arena, mech := cMechanism(m)
+ defer arena.Free()
+ e := C.SignRecoverInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(key))
+ return toError(e)
+}
+
+// SignRecover signs data in a single operation, where the data can be recovered from the signature.
+func (c *Ctx) SignRecover(sh SessionHandle, data []byte) ([]byte, error) {
+ var (
+ sig C.CK_BYTE_PTR
+ siglen C.CK_ULONG
+ )
+ e := C.SignRecover(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(data), C.CK_ULONG(len(data)), &sig, &siglen)
+ if toError(e) != nil {
+ return nil, toError(e)
+ }
+ h := C.GoBytes(unsafe.Pointer(sig), C.int(siglen))
+ C.free(unsafe.Pointer(sig))
+ return h, nil
+}
+
+// VerifyInit initializes a verification operation, where the
+// signature is an appendix to the data, and plaintext cannot
+// be recovered from the signature (e.g. DSA).
+func (c *Ctx) VerifyInit(sh SessionHandle, m []*Mechanism, key ObjectHandle) error {
+ arena, mech := cMechanism(m)
+ defer arena.Free()
+ e := C.VerifyInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(key))
+ return toError(e)
+}
+
+// Verify verifies a signature in a single-part operation,
+// where the signature is an appendix to the data, and plaintext
+// cannot be recovered from the signature.
+func (c *Ctx) Verify(sh SessionHandle, data []byte, signature []byte) error {
+ e := C.Verify(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(data), C.CK_ULONG(len(data)), cMessage(signature), C.CK_ULONG(len(signature)))
+ return toError(e)
+}
+
+// VerifyUpdate continues a multiple-part verification
+// operation, where the signature is an appendix to the data,
+// and plaintext cannot be recovered from the signature.
+func (c *Ctx) VerifyUpdate(sh SessionHandle, part []byte) error {
+ e := C.VerifyUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(part), C.CK_ULONG(len(part)))
+ return toError(e)
+}
+
+// VerifyFinal finishes a multiple-part verification
+// operation, checking the signature.
+func (c *Ctx) VerifyFinal(sh SessionHandle, signature []byte) error {
+ e := C.VerifyFinal(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(signature), C.CK_ULONG(len(signature)))
+ return toError(e)
+}
+
+// VerifyRecoverInit initializes a signature verification
+// operation, where the data is recovered from the signature.
+func (c *Ctx) VerifyRecoverInit(sh SessionHandle, m []*Mechanism, key ObjectHandle) error {
+ arena, mech := cMechanism(m)
+ defer arena.Free()
+ e := C.VerifyRecoverInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(key))
+ return toError(e)
+}
+
+// VerifyRecover verifies a signature in a single-part
+// operation, where the data is recovered from the signature.
+func (c *Ctx) VerifyRecover(sh SessionHandle, signature []byte) ([]byte, error) {
+ var (
+ data C.CK_BYTE_PTR
+ datalen C.CK_ULONG
+ )
+ e := C.DecryptVerifyUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(signature), C.CK_ULONG(len(signature)), &data, &datalen)
+ if toError(e) != nil {
+ return nil, toError(e)
+ }
+ h := C.GoBytes(unsafe.Pointer(data), C.int(datalen))
+ C.free(unsafe.Pointer(data))
+ return h, nil
+}
+
+// DigestEncryptUpdate continues a multiple-part digesting and encryption operation.
+func (c *Ctx) DigestEncryptUpdate(sh SessionHandle, part []byte) ([]byte, error) {
+ var (
+ enc C.CK_BYTE_PTR
+ enclen C.CK_ULONG
+ )
+ e := C.DigestEncryptUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(part), C.CK_ULONG(len(part)), &enc, &enclen)
+ if toError(e) != nil {
+ return nil, toError(e)
+ }
+ h := C.GoBytes(unsafe.Pointer(enc), C.int(enclen))
+ C.free(unsafe.Pointer(enc))
+ return h, nil
+}
+
+// DecryptDigestUpdate continues a multiple-part decryption and digesting operation.
+func (c *Ctx) DecryptDigestUpdate(sh SessionHandle, cipher []byte) ([]byte, error) {
+ var (
+ part C.CK_BYTE_PTR
+ partlen C.CK_ULONG
+ )
+ e := C.DecryptDigestUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(cipher), C.CK_ULONG(len(cipher)), &part, &partlen)
+ if toError(e) != nil {
+ return nil, toError(e)
+ }
+ h := C.GoBytes(unsafe.Pointer(part), C.int(partlen))
+ C.free(unsafe.Pointer(part))
+ return h, nil
+}
+
+// SignEncryptUpdate continues a multiple-part signing and encryption operation.
+func (c *Ctx) SignEncryptUpdate(sh SessionHandle, part []byte) ([]byte, error) {
+ var (
+ enc C.CK_BYTE_PTR
+ enclen C.CK_ULONG
+ )
+ e := C.SignEncryptUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(part), C.CK_ULONG(len(part)), &enc, &enclen)
+ if toError(e) != nil {
+ return nil, toError(e)
+ }
+ h := C.GoBytes(unsafe.Pointer(enc), C.int(enclen))
+ C.free(unsafe.Pointer(enc))
+ return h, nil
+}
+
+// DecryptVerifyUpdate continues a multiple-part decryption and verify operation.
+func (c *Ctx) DecryptVerifyUpdate(sh SessionHandle, cipher []byte) ([]byte, error) {
+ var (
+ part C.CK_BYTE_PTR
+ partlen C.CK_ULONG
+ )
+ e := C.DecryptVerifyUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(cipher), C.CK_ULONG(len(cipher)), &part, &partlen)
+ if toError(e) != nil {
+ return nil, toError(e)
+ }
+ h := C.GoBytes(unsafe.Pointer(part), C.int(partlen))
+ C.free(unsafe.Pointer(part))
+ return h, nil
+}
+
+// GenerateKey generates a secret key, creating a new key object.
+func (c *Ctx) GenerateKey(sh SessionHandle, m []*Mechanism, temp []*Attribute) (ObjectHandle, error) {
+ var key C.CK_OBJECT_HANDLE
+ attrarena, t, tcount := cAttributeList(temp)
+ defer attrarena.Free()
+ mecharena, mech := cMechanism(m)
+ defer mecharena.Free()
+ e := C.GenerateKey(c.ctx, C.CK_SESSION_HANDLE(sh), mech, t, tcount, C.CK_OBJECT_HANDLE_PTR(&key))
+ e1 := toError(e)
+ if e1 == nil {
+ return ObjectHandle(key), nil
+ }
+ return 0, e1
+}
+
+// GenerateKeyPair generates a public-key/private-key pair creating new key objects.
+func (c *Ctx) GenerateKeyPair(sh SessionHandle, m []*Mechanism, public, private []*Attribute) (ObjectHandle, ObjectHandle, error) {
+ var (
+ pubkey C.CK_OBJECT_HANDLE
+ privkey C.CK_OBJECT_HANDLE
+ )
+ pubarena, pub, pubcount := cAttributeList(public)
+ defer pubarena.Free()
+ privarena, priv, privcount := cAttributeList(private)
+ defer privarena.Free()
+ mecharena, mech := cMechanism(m)
+ defer mecharena.Free()
+ e := C.GenerateKeyPair(c.ctx, C.CK_SESSION_HANDLE(sh), mech, pub, pubcount, priv, privcount, C.CK_OBJECT_HANDLE_PTR(&pubkey), C.CK_OBJECT_HANDLE_PTR(&privkey))
+ e1 := toError(e)
+ if e1 == nil {
+ return ObjectHandle(pubkey), ObjectHandle(privkey), nil
+ }
+ return 0, 0, e1
+}
+
+// WrapKey wraps (i.e., encrypts) a key.
+func (c *Ctx) WrapKey(sh SessionHandle, m []*Mechanism, wrappingkey, key ObjectHandle) ([]byte, error) {
+ var (
+ wrappedkey C.CK_BYTE_PTR
+ wrappedkeylen C.CK_ULONG
+ )
+ arena, mech := cMechanism(m)
+ defer arena.Free()
+ e := C.WrapKey(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(wrappingkey), C.CK_OBJECT_HANDLE(key), &wrappedkey, &wrappedkeylen)
+ if toError(e) != nil {
+ return nil, toError(e)
+ }
+ h := C.GoBytes(unsafe.Pointer(wrappedkey), C.int(wrappedkeylen))
+ C.free(unsafe.Pointer(wrappedkey))
+ return h, nil
+}
+
+// UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object.
+func (c *Ctx) UnwrapKey(sh SessionHandle, m []*Mechanism, unwrappingkey ObjectHandle, wrappedkey []byte, a []*Attribute) (ObjectHandle, error) {
+ var key C.CK_OBJECT_HANDLE
+ attrarena, ac, aclen := cAttributeList(a)
+ defer attrarena.Free()
+ mecharena, mech := cMechanism(m)
+ defer mecharena.Free()
+ e := C.UnwrapKey(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(unwrappingkey), C.CK_BYTE_PTR(unsafe.Pointer(&wrappedkey[0])), C.CK_ULONG(len(wrappedkey)), ac, aclen, &key)
+ return ObjectHandle(key), toError(e)
+}
+
+// DeriveKey derives a key from a base key, creating a new key object.
+func (c *Ctx) DeriveKey(sh SessionHandle, m []*Mechanism, basekey ObjectHandle, a []*Attribute) (ObjectHandle, error) {
+ var key C.CK_OBJECT_HANDLE
+ attrarena, ac, aclen := cAttributeList(a)
+ defer attrarena.Free()
+ mecharena, mech := cMechanism(m)
+ defer mecharena.Free()
+ e := C.DeriveKey(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(basekey), ac, aclen, &key)
+ return ObjectHandle(key), toError(e)
+}
+
+// SeedRandom mixes additional seed material into the token's
+// random number generator.
+func (c *Ctx) SeedRandom(sh SessionHandle, seed []byte) error {
+ e := C.SeedRandom(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&seed[0])), C.CK_ULONG(len(seed)))
+ return toError(e)
+}
+
+// GenerateRandom generates random data.
+func (c *Ctx) GenerateRandom(sh SessionHandle, length int) ([]byte, error) {
+ var rand C.CK_BYTE_PTR
+ e := C.GenerateRandom(c.ctx, C.CK_SESSION_HANDLE(sh), &rand, C.CK_ULONG(length))
+ if toError(e) != nil {
+ return nil, toError(e)
+ }
+ h := C.GoBytes(unsafe.Pointer(rand), C.int(length))
+ C.free(unsafe.Pointer(rand))
+ return h, nil
+}
+
+// WaitForSlotEvent returns a channel which returns a slot event
+// (token insertion, removal, etc.) when it occurs.
+func (c *Ctx) WaitForSlotEvent(flags uint) chan SlotEvent {
+ sl := make(chan SlotEvent, 1) // hold one element
+ go c.waitForSlotEventHelper(flags, sl)
+ return sl
+}
+
+func (c *Ctx) waitForSlotEventHelper(f uint, sl chan SlotEvent) {
+ var slotID C.CK_ULONG
+ C.WaitForSlotEvent(c.ctx, C.CK_FLAGS(f), &slotID)
+ sl <- SlotEvent{uint(slotID)}
+ close(sl) // TODO(miek): Sending and then closing ...?
+}
diff --git a/vendor/github.com/miekg/pkcs11/pkcs11.h b/vendor/github.com/miekg/pkcs11/pkcs11.h
new file mode 100644
index 000000000..0d78dd711
--- /dev/null
+++ b/vendor/github.com/miekg/pkcs11/pkcs11.h
@@ -0,0 +1,265 @@
+/* Copyright (c) OASIS Open 2016. All Rights Reserved./
+ * /Distributed under the terms of the OASIS IPR Policy,
+ * [http://www.oasis-open.org/policies-guidelines/ipr], AS-IS, WITHOUT ANY
+ * IMPLIED OR EXPRESS WARRANTY; there is no warranty of MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE or NONINFRINGEMENT of the rights of others.
+ */
+
+/* Latest version of the specification:
+ * http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/pkcs11-base-v2.40.html
+ */
+
+#ifndef _PKCS11_H_
+#define _PKCS11_H_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Before including this file (pkcs11.h) (or pkcs11t.h by
+ * itself), 5 platform-specific macros must be defined. These
+ * macros are described below, and typical definitions for them
+ * are also given. Be advised that these definitions can depend
+ * on both the platform and the compiler used (and possibly also
+ * on whether a Cryptoki library is linked statically or
+ * dynamically).
+ *
+ * In addition to defining these 5 macros, the packing convention
+ * for Cryptoki structures should be set. The Cryptoki
+ * convention on packing is that structures should be 1-byte
+ * aligned.
+ *
+ * If you're using Microsoft Developer Studio 5.0 to produce
+ * Win32 stuff, this might be done by using the following
+ * preprocessor directive before including pkcs11.h or pkcs11t.h:
+ *
+ * #pragma pack(push, cryptoki, 1)
+ *
+ * and using the following preprocessor directive after including
+ * pkcs11.h or pkcs11t.h:
+ *
+ * #pragma pack(pop, cryptoki)
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to produce Win16 stuff, this might be done by using
+ * the following preprocessor directive before including
+ * pkcs11.h or pkcs11t.h:
+ *
+ * #pragma pack(1)
+ *
+ * In a UNIX environment, you're on your own for this. You might
+ * not need to do (or be able to do!) anything.
+ *
+ *
+ * Now for the macros:
+ *
+ *
+ * 1. CK_PTR: The indirection string for making a pointer to an
+ * object. It can be used like this:
+ *
+ * typedef CK_BYTE CK_PTR CK_BYTE_PTR;
+ *
+ * If you're using Microsoft Developer Studio 5.0 to produce
+ * Win32 stuff, it might be defined by:
+ *
+ * #define CK_PTR *
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to produce Win16 stuff, it might be defined by:
+ *
+ * #define CK_PTR far *
+ *
+ * In a typical UNIX environment, it might be defined by:
+ *
+ * #define CK_PTR *
+ *
+ *
+ * 2. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
+ * an importable Cryptoki library function declaration out of a
+ * return type and a function name. It should be used in the
+ * following fashion:
+ *
+ * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
+ * CK_VOID_PTR pReserved
+ * );
+ *
+ * If you're using Microsoft Developer Studio 5.0 to declare a
+ * function in a Win32 Cryptoki .dll, it might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION(returnType, name) \
+ * returnType __declspec(dllimport) name
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to declare a function in a Win16 Cryptoki .dll, it
+ * might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION(returnType, name) \
+ * returnType __export _far _pascal name
+ *
+ * In a UNIX environment, it might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION(returnType, name) \
+ * returnType name
+ *
+ *
+ * 3. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
+ * which makes a Cryptoki API function pointer declaration or
+ * function pointer type declaration out of a return type and a
+ * function name. It should be used in the following fashion:
+ *
+ * // Define funcPtr to be a pointer to a Cryptoki API function
+ * // taking arguments args and returning CK_RV.
+ * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
+ *
+ * or
+ *
+ * // Define funcPtrType to be the type of a pointer to a
+ * // Cryptoki API function taking arguments args and returning
+ * // CK_RV, and then define funcPtr to be a variable of type
+ * // funcPtrType.
+ * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
+ * funcPtrType funcPtr;
+ *
+ * If you're using Microsoft Developer Studio 5.0 to access
+ * functions in a Win32 Cryptoki .dll, in might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
+ * returnType __declspec(dllimport) (* name)
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to access functions in a Win16 Cryptoki .dll, it might
+ * be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
+ * returnType __export _far _pascal (* name)
+ *
+ * In a UNIX environment, it might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
+ * returnType (* name)
+ *
+ *
+ * 4. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
+ * a function pointer type for an application callback out of
+ * a return type for the callback and a name for the callback.
+ * It should be used in the following fashion:
+ *
+ * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
+ *
+ * to declare a function pointer, myCallback, to a callback
+ * which takes arguments args and returns a CK_RV. It can also
+ * be used like this:
+ *
+ * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
+ * myCallbackType myCallback;
+ *
+ * If you're using Microsoft Developer Studio 5.0 to do Win32
+ * Cryptoki development, it might be defined by:
+ *
+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
+ * returnType (* name)
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to do Win16 development, it might be defined by:
+ *
+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
+ * returnType _far _pascal (* name)
+ *
+ * In a UNIX environment, it might be defined by:
+ *
+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
+ * returnType (* name)
+ *
+ *
+ * 5. NULL_PTR: This macro is the value of a NULL pointer.
+ *
+ * In any ANSI/ISO C environment (and in many others as well),
+ * this should best be defined by
+ *
+ * #ifndef NULL_PTR
+ * #define NULL_PTR 0
+ * #endif
+ */
+
+
+/* All the various Cryptoki types and #define'd values are in the
+ * file pkcs11t.h.
+ */
+#include "pkcs11t.h"
+
+#define __PASTE(x,y) x##y
+
+
+/* ==============================================================
+ * Define the "extern" form of all the entry points.
+ * ==============================================================
+ */
+
+#define CK_NEED_ARG_LIST 1
+#define CK_PKCS11_FUNCTION_INFO(name) \
+ extern CK_DECLARE_FUNCTION(CK_RV, name)
+
+/* pkcs11f.h has all the information about the Cryptoki
+ * function prototypes.
+ */
+#include "pkcs11f.h"
+
+#undef CK_NEED_ARG_LIST
+#undef CK_PKCS11_FUNCTION_INFO
+
+
+/* ==============================================================
+ * Define the typedef form of all the entry points. That is, for
+ * each Cryptoki function C_XXX, define a type CK_C_XXX which is
+ * a pointer to that kind of function.
+ * ==============================================================
+ */
+
+#define CK_NEED_ARG_LIST 1
+#define CK_PKCS11_FUNCTION_INFO(name) \
+ typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
+
+/* pkcs11f.h has all the information about the Cryptoki
+ * function prototypes.
+ */
+#include "pkcs11f.h"
+
+#undef CK_NEED_ARG_LIST
+#undef CK_PKCS11_FUNCTION_INFO
+
+
+/* ==============================================================
+ * Define structed vector of entry points. A CK_FUNCTION_LIST
+ * contains a CK_VERSION indicating a library's Cryptoki version
+ * and then a whole slew of function pointers to the routines in
+ * the library. This type was declared, but not defined, in
+ * pkcs11t.h.
+ * ==============================================================
+ */
+
+#define CK_PKCS11_FUNCTION_INFO(name) \
+ __PASTE(CK_,name) name;
+
+struct CK_FUNCTION_LIST {
+
+ CK_VERSION version; /* Cryptoki version */
+
+/* Pile all the function pointers into the CK_FUNCTION_LIST. */
+/* pkcs11f.h has all the information about the Cryptoki
+ * function prototypes.
+ */
+#include "pkcs11f.h"
+
+};
+
+#undef CK_PKCS11_FUNCTION_INFO
+
+
+#undef __PASTE
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PKCS11_H_ */
+
diff --git a/vendor/github.com/miekg/pkcs11/pkcs11f.h b/vendor/github.com/miekg/pkcs11/pkcs11f.h
new file mode 100644
index 000000000..ed90affc5
--- /dev/null
+++ b/vendor/github.com/miekg/pkcs11/pkcs11f.h
@@ -0,0 +1,939 @@
+/* Copyright (c) OASIS Open 2016. All Rights Reserved./
+ * /Distributed under the terms of the OASIS IPR Policy,
+ * [http://www.oasis-open.org/policies-guidelines/ipr], AS-IS, WITHOUT ANY
+ * IMPLIED OR EXPRESS WARRANTY; there is no warranty of MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE or NONINFRINGEMENT of the rights of others.
+ */
+
+/* Latest version of the specification:
+ * http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/pkcs11-base-v2.40.html
+ */
+
+/* This header file contains pretty much everything about all the
+ * Cryptoki function prototypes. Because this information is
+ * used for more than just declaring function prototypes, the
+ * order of the functions appearing herein is important, and
+ * should not be altered.
+ */
+
+/* General-purpose */
+
+/* C_Initialize initializes the Cryptoki library. */
+CK_PKCS11_FUNCTION_INFO(C_Initialize)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets
+ * cast to CK_C_INITIALIZE_ARGS_PTR
+ * and dereferenced
+ */
+);
+#endif
+
+
+/* C_Finalize indicates that an application is done with the
+ * Cryptoki library.
+ */
+CK_PKCS11_FUNCTION_INFO(C_Finalize)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */
+);
+#endif
+
+
+/* C_GetInfo returns general information about Cryptoki. */
+CK_PKCS11_FUNCTION_INFO(C_GetInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_INFO_PTR pInfo /* location that receives information */
+);
+#endif
+
+
+/* C_GetFunctionList returns the function list. */
+CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives pointer to
+ * function list
+ */
+);
+#endif
+
+
+
+/* Slot and token management */
+
+/* C_GetSlotList obtains a list of slots in the system. */
+CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_BBOOL tokenPresent, /* only slots with tokens */
+ CK_SLOT_ID_PTR pSlotList, /* receives array of slot IDs */
+ CK_ULONG_PTR pulCount /* receives number of slots */
+);
+#endif
+
+
+/* C_GetSlotInfo obtains information about a particular slot in
+ * the system.
+ */
+CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* the ID of the slot */
+ CK_SLOT_INFO_PTR pInfo /* receives the slot information */
+);
+#endif
+
+
+/* C_GetTokenInfo obtains information about a particular token
+ * in the system.
+ */
+CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* ID of the token's slot */
+ CK_TOKEN_INFO_PTR pInfo /* receives the token information */
+);
+#endif
+
+
+/* C_GetMechanismList obtains a list of mechanism types
+ * supported by a token.
+ */
+CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* ID of token's slot */
+ CK_MECHANISM_TYPE_PTR pMechanismList, /* gets mech. array */
+ CK_ULONG_PTR pulCount /* gets # of mechs. */
+);
+#endif
+
+
+/* C_GetMechanismInfo obtains information about a particular
+ * mechanism possibly supported by a token.
+ */
+CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* ID of the token's slot */
+ CK_MECHANISM_TYPE type, /* type of mechanism */
+ CK_MECHANISM_INFO_PTR pInfo /* receives mechanism info */
+);
+#endif
+
+
+/* C_InitToken initializes a token. */
+CK_PKCS11_FUNCTION_INFO(C_InitToken)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* ID of the token's slot */
+ CK_UTF8CHAR_PTR pPin, /* the SO's initial PIN */
+ CK_ULONG ulPinLen, /* length in bytes of the PIN */
+ CK_UTF8CHAR_PTR pLabel /* 32-byte token label (blank padded) */
+);
+#endif
+
+
+/* C_InitPIN initializes the normal user's PIN. */
+CK_PKCS11_FUNCTION_INFO(C_InitPIN)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_UTF8CHAR_PTR pPin, /* the normal user's PIN */
+ CK_ULONG ulPinLen /* length in bytes of the PIN */
+);
+#endif
+
+
+/* C_SetPIN modifies the PIN of the user who is logged in. */
+CK_PKCS11_FUNCTION_INFO(C_SetPIN)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_UTF8CHAR_PTR pOldPin, /* the old PIN */
+ CK_ULONG ulOldLen, /* length of the old PIN */
+ CK_UTF8CHAR_PTR pNewPin, /* the new PIN */
+ CK_ULONG ulNewLen /* length of the new PIN */
+);
+#endif
+
+
+
+/* Session management */
+
+/* C_OpenSession opens a session between an application and a
+ * token.
+ */
+CK_PKCS11_FUNCTION_INFO(C_OpenSession)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* the slot's ID */
+ CK_FLAGS flags, /* from CK_SESSION_INFO */
+ CK_VOID_PTR pApplication, /* passed to callback */
+ CK_NOTIFY Notify, /* callback function */
+ CK_SESSION_HANDLE_PTR phSession /* gets session handle */
+);
+#endif
+
+
+/* C_CloseSession closes a session between an application and a
+ * token.
+ */
+CK_PKCS11_FUNCTION_INFO(C_CloseSession)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+
+/* C_CloseAllSessions closes all sessions with a token. */
+CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID /* the token's slot */
+);
+#endif
+
+
+/* C_GetSessionInfo obtains information about the session. */
+CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_SESSION_INFO_PTR pInfo /* receives session info */
+);
+#endif
+
+
+/* C_GetOperationState obtains the state of the cryptographic operation
+ * in a session.
+ */
+CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pOperationState, /* gets state */
+ CK_ULONG_PTR pulOperationStateLen /* gets state length */
+);
+#endif
+
+
+/* C_SetOperationState restores the state of the cryptographic
+ * operation in a session.
+ */
+CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pOperationState, /* holds state */
+ CK_ULONG ulOperationStateLen, /* holds state length */
+ CK_OBJECT_HANDLE hEncryptionKey, /* en/decryption key */
+ CK_OBJECT_HANDLE hAuthenticationKey /* sign/verify key */
+);
+#endif
+
+
+/* C_Login logs a user into a token. */
+CK_PKCS11_FUNCTION_INFO(C_Login)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_USER_TYPE userType, /* the user type */
+ CK_UTF8CHAR_PTR pPin, /* the user's PIN */
+ CK_ULONG ulPinLen /* the length of the PIN */
+);
+#endif
+
+
+/* C_Logout logs a user out from a token. */
+CK_PKCS11_FUNCTION_INFO(C_Logout)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+
+
+/* Object management */
+
+/* C_CreateObject creates a new object. */
+CK_PKCS11_FUNCTION_INFO(C_CreateObject)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* the object's template */
+ CK_ULONG ulCount, /* attributes in template */
+ CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */
+);
+#endif
+
+
+/* C_CopyObject copies an object, creating a new object for the
+ * copy.
+ */
+CK_PKCS11_FUNCTION_INFO(C_CopyObject)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject, /* the object's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* template for new object */
+ CK_ULONG ulCount, /* attributes in template */
+ CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */
+);
+#endif
+
+
+/* C_DestroyObject destroys an object. */
+CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject /* the object's handle */
+);
+#endif
+
+
+/* C_GetObjectSize gets the size of an object in bytes. */
+CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject, /* the object's handle */
+ CK_ULONG_PTR pulSize /* receives size of object */
+);
+#endif
+
+
+/* C_GetAttributeValue obtains the value of one or more object
+ * attributes.
+ */
+CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject, /* the object's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs; gets vals */
+ CK_ULONG ulCount /* attributes in template */
+);
+#endif
+
+
+/* C_SetAttributeValue modifies the value of one or more object
+ * attributes.
+ */
+CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject, /* the object's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs and values */
+ CK_ULONG ulCount /* attributes in template */
+);
+#endif
+
+
+/* C_FindObjectsInit initializes a search for token and session
+ * objects that match a template.
+ */
+CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */
+ CK_ULONG ulCount /* attrs in search template */
+);
+#endif
+
+
+/* C_FindObjects continues a search for token and session
+ * objects that match a template, obtaining additional object
+ * handles.
+ */
+CK_PKCS11_FUNCTION_INFO(C_FindObjects)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_OBJECT_HANDLE_PTR phObject, /* gets obj. handles */
+ CK_ULONG ulMaxObjectCount, /* max handles to get */
+ CK_ULONG_PTR pulObjectCount /* actual # returned */
+);
+#endif
+
+
+/* C_FindObjectsFinal finishes a search for token and session
+ * objects.
+ */
+CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+
+
+/* Encryption and decryption */
+
+/* C_EncryptInit initializes an encryption operation. */
+CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of encryption key */
+);
+#endif
+
+
+/* C_Encrypt encrypts single-part data. */
+CK_PKCS11_FUNCTION_INFO(C_Encrypt)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pData, /* the plaintext data */
+ CK_ULONG ulDataLen, /* bytes of plaintext */
+ CK_BYTE_PTR pEncryptedData, /* gets ciphertext */
+ CK_ULONG_PTR pulEncryptedDataLen /* gets c-text size */
+);
+#endif
+
+
+/* C_EncryptUpdate continues a multiple-part encryption
+ * operation.
+ */
+CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pPart, /* the plaintext data */
+ CK_ULONG ulPartLen, /* plaintext data len */
+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text size */
+);
+#endif
+
+
+/* C_EncryptFinal finishes a multiple-part encryption
+ * operation.
+ */
+CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session handle */
+ CK_BYTE_PTR pLastEncryptedPart, /* last c-text */
+ CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */
+);
+#endif
+
+
+/* C_DecryptInit initializes a decryption operation. */
+CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of decryption key */
+);
+#endif
+
+
+/* C_Decrypt decrypts encrypted data in a single part. */
+CK_PKCS11_FUNCTION_INFO(C_Decrypt)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pEncryptedData, /* ciphertext */
+ CK_ULONG ulEncryptedDataLen, /* ciphertext length */
+ CK_BYTE_PTR pData, /* gets plaintext */
+ CK_ULONG_PTR pulDataLen /* gets p-text size */
+);
+#endif
+
+
+/* C_DecryptUpdate continues a multiple-part decryption
+ * operation.
+ */
+CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pEncryptedPart, /* encrypted data */
+ CK_ULONG ulEncryptedPartLen, /* input length */
+ CK_BYTE_PTR pPart, /* gets plaintext */
+ CK_ULONG_PTR pulPartLen /* p-text size */
+);
+#endif
+
+
+/* C_DecryptFinal finishes a multiple-part decryption
+ * operation.
+ */
+CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pLastPart, /* gets plaintext */
+ CK_ULONG_PTR pulLastPartLen /* p-text size */
+);
+#endif
+
+
+
+/* Message digesting */
+
+/* C_DigestInit initializes a message-digesting operation. */
+CK_PKCS11_FUNCTION_INFO(C_DigestInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism /* the digesting mechanism */
+);
+#endif
+
+
+/* C_Digest digests data in a single part. */
+CK_PKCS11_FUNCTION_INFO(C_Digest)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pData, /* data to be digested */
+ CK_ULONG ulDataLen, /* bytes of data to digest */
+ CK_BYTE_PTR pDigest, /* gets the message digest */
+ CK_ULONG_PTR pulDigestLen /* gets digest length */
+);
+#endif
+
+
+/* C_DigestUpdate continues a multiple-part message-digesting
+ * operation.
+ */
+CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pPart, /* data to be digested */
+ CK_ULONG ulPartLen /* bytes of data to be digested */
+);
+#endif
+
+
+/* C_DigestKey continues a multi-part message-digesting
+ * operation, by digesting the value of a secret key as part of
+ * the data already digested.
+ */
+CK_PKCS11_FUNCTION_INFO(C_DigestKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hKey /* secret key to digest */
+);
+#endif
+
+
+/* C_DigestFinal finishes a multiple-part message-digesting
+ * operation.
+ */
+CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pDigest, /* gets the message digest */
+ CK_ULONG_PTR pulDigestLen /* gets byte count of digest */
+);
+#endif
+
+
+
+/* Signing and MACing */
+
+/* C_SignInit initializes a signature (private key encryption)
+ * operation, where the signature is (will be) an appendix to
+ * the data, and plaintext cannot be recovered from the
+ * signature.
+ */
+CK_PKCS11_FUNCTION_INFO(C_SignInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of signature key */
+);
+#endif
+
+
+/* C_Sign signs (encrypts with private key) data in a single
+ * part, where the signature is (will be) an appendix to the
+ * data, and plaintext cannot be recovered from the signature.
+ */
+CK_PKCS11_FUNCTION_INFO(C_Sign)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pData, /* the data to sign */
+ CK_ULONG ulDataLen, /* count of bytes to sign */
+ CK_BYTE_PTR pSignature, /* gets the signature */
+ CK_ULONG_PTR pulSignatureLen /* gets signature length */
+);
+#endif
+
+
+/* C_SignUpdate continues a multiple-part signature operation,
+ * where the signature is (will be) an appendix to the data,
+ * and plaintext cannot be recovered from the signature.
+ */
+CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pPart, /* the data to sign */
+ CK_ULONG ulPartLen /* count of bytes to sign */
+);
+#endif
+
+
+/* C_SignFinal finishes a multiple-part signature operation,
+ * returning the signature.
+ */
+CK_PKCS11_FUNCTION_INFO(C_SignFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pSignature, /* gets the signature */
+ CK_ULONG_PTR pulSignatureLen /* gets signature length */
+);
+#endif
+
+
+/* C_SignRecoverInit initializes a signature operation, where
+ * the data can be recovered from the signature.
+ */
+CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of the signature key */
+);
+#endif
+
+
+/* C_SignRecover signs data in a single operation, where the
+ * data can be recovered from the signature.
+ */
+CK_PKCS11_FUNCTION_INFO(C_SignRecover)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pData, /* the data to sign */
+ CK_ULONG ulDataLen, /* count of bytes to sign */
+ CK_BYTE_PTR pSignature, /* gets the signature */
+ CK_ULONG_PTR pulSignatureLen /* gets signature length */
+);
+#endif
+
+
+
+/* Verifying signatures and MACs */
+
+/* C_VerifyInit initializes a verification operation, where the
+ * signature is an appendix to the data, and plaintext cannot
+ * cannot be recovered from the signature (e.g. DSA).
+ */
+CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
+ CK_OBJECT_HANDLE hKey /* verification key */
+);
+#endif
+
+
+/* C_Verify verifies a signature in a single-part operation,
+ * where the signature is an appendix to the data, and plaintext
+ * cannot be recovered from the signature.
+ */
+CK_PKCS11_FUNCTION_INFO(C_Verify)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pData, /* signed data */
+ CK_ULONG ulDataLen, /* length of signed data */
+ CK_BYTE_PTR pSignature, /* signature */
+ CK_ULONG ulSignatureLen /* signature length*/
+);
+#endif
+
+
+/* C_VerifyUpdate continues a multiple-part verification
+ * operation, where the signature is an appendix to the data,
+ * and plaintext cannot be recovered from the signature.
+ */
+CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pPart, /* signed data */
+ CK_ULONG ulPartLen /* length of signed data */
+);
+#endif
+
+
+/* C_VerifyFinal finishes a multiple-part verification
+ * operation, checking the signature.
+ */
+CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pSignature, /* signature to verify */
+ CK_ULONG ulSignatureLen /* signature length */
+);
+#endif
+
+
+/* C_VerifyRecoverInit initializes a signature verification
+ * operation, where the data is recovered from the signature.
+ */
+CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
+ CK_OBJECT_HANDLE hKey /* verification key */
+);
+#endif
+
+
+/* C_VerifyRecover verifies a signature in a single-part
+ * operation, where the data is recovered from the signature.
+ */
+CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pSignature, /* signature to verify */
+ CK_ULONG ulSignatureLen, /* signature length */
+ CK_BYTE_PTR pData, /* gets signed data */
+ CK_ULONG_PTR pulDataLen /* gets signed data len */
+);
+#endif
+
+
+
+/* Dual-function cryptographic operations */
+
+/* C_DigestEncryptUpdate continues a multiple-part digesting
+ * and encryption operation.
+ */
+CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pPart, /* the plaintext data */
+ CK_ULONG ulPartLen, /* plaintext length */
+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
+);
+#endif
+
+
+/* C_DecryptDigestUpdate continues a multiple-part decryption and
+ * digesting operation.
+ */
+CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pEncryptedPart, /* ciphertext */
+ CK_ULONG ulEncryptedPartLen, /* ciphertext length */
+ CK_BYTE_PTR pPart, /* gets plaintext */
+ CK_ULONG_PTR pulPartLen /* gets plaintext len */
+);
+#endif
+
+
+/* C_SignEncryptUpdate continues a multiple-part signing and
+ * encryption operation.
+ */
+CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pPart, /* the plaintext data */
+ CK_ULONG ulPartLen, /* plaintext length */
+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
+);
+#endif
+
+
+/* C_DecryptVerifyUpdate continues a multiple-part decryption and
+ * verify operation.
+ */
+CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pEncryptedPart, /* ciphertext */
+ CK_ULONG ulEncryptedPartLen, /* ciphertext length */
+ CK_BYTE_PTR pPart, /* gets plaintext */
+ CK_ULONG_PTR pulPartLen /* gets p-text length */
+);
+#endif
+
+
+
+/* Key management */
+
+/* C_GenerateKey generates a secret key, creating a new key
+ * object.
+ */
+CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* key generation mech. */
+ CK_ATTRIBUTE_PTR pTemplate, /* template for new key */
+ CK_ULONG ulCount, /* # of attrs in template */
+ CK_OBJECT_HANDLE_PTR phKey /* gets handle of new key */
+);
+#endif
+
+
+/* C_GenerateKeyPair generates a public-key/private-key pair,
+ * creating new key objects.
+ */
+CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session handle */
+ CK_MECHANISM_PTR pMechanism, /* key-gen mech. */
+ CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* template for pub. key */
+ CK_ULONG ulPublicKeyAttributeCount, /* # pub. attrs. */
+ CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* template for priv. key */
+ CK_ULONG ulPrivateKeyAttributeCount, /* # priv. attrs. */
+ CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub. key handle */
+ CK_OBJECT_HANDLE_PTR phPrivateKey /* gets priv. key handle */
+);
+#endif
+
+
+/* C_WrapKey wraps (i.e., encrypts) a key. */
+CK_PKCS11_FUNCTION_INFO(C_WrapKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */
+ CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */
+ CK_OBJECT_HANDLE hKey, /* key to be wrapped */
+ CK_BYTE_PTR pWrappedKey, /* gets wrapped key */
+ CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */
+);
+#endif
+
+
+/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
+ * key object.
+ */
+CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */
+ CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */
+ CK_BYTE_PTR pWrappedKey, /* the wrapped key */
+ CK_ULONG ulWrappedKeyLen, /* wrapped key len */
+ CK_ATTRIBUTE_PTR pTemplate, /* new key template */
+ CK_ULONG ulAttributeCount, /* template length */
+ CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
+);
+#endif
+
+
+/* C_DeriveKey derives a key from a base key, creating a new key
+ * object.
+ */
+CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */
+ CK_OBJECT_HANDLE hBaseKey, /* base key */
+ CK_ATTRIBUTE_PTR pTemplate, /* new key template */
+ CK_ULONG ulAttributeCount, /* template length */
+ CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
+);
+#endif
+
+
+
+/* Random number generation */
+
+/* C_SeedRandom mixes additional seed material into the token's
+ * random number generator.
+ */
+CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pSeed, /* the seed material */
+ CK_ULONG ulSeedLen /* length of seed material */
+);
+#endif
+
+
+/* C_GenerateRandom generates random data. */
+CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR RandomData, /* receives the random data */
+ CK_ULONG ulRandomLen /* # of bytes to generate */
+);
+#endif
+
+
+
+/* Parallel function management */
+
+/* C_GetFunctionStatus is a legacy function; it obtains an
+ * updated status of a function running in parallel with an
+ * application.
+ */
+CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+
+/* C_CancelFunction is a legacy function; it cancels a function
+ * running in parallel.
+ */
+CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+
+/* C_WaitForSlotEvent waits for a slot event (token insertion,
+ * removal, etc.) to occur.
+ */
+CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_FLAGS flags, /* blocking/nonblocking flag */
+ CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */
+ CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */
+);
+#endif
+
diff --git a/vendor/github.com/miekg/pkcs11/pkcs11go.h b/vendor/github.com/miekg/pkcs11/pkcs11go.h
new file mode 100644
index 000000000..1b98bad21
--- /dev/null
+++ b/vendor/github.com/miekg/pkcs11/pkcs11go.h
@@ -0,0 +1,33 @@
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+//
+
+#define CK_PTR *
+#ifndef NULL_PTR
+#define NULL_PTR 0
+#endif
+#define CK_DEFINE_FUNCTION(returnType, name) returnType name
+#define CK_DECLARE_FUNCTION(returnType, name) returnType name
+#define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name)
+#define CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)
+
+#include <unistd.h>
+#ifdef PACKED_STRUCTURES
+# pragma pack(push, 1)
+# include "pkcs11.h"
+# pragma pack(pop)
+#else
+# include "pkcs11.h"
+#endif
+
+// Copy of CK_INFO but with default alignment (not packed). Go hides unaligned
+// struct fields so copying to an aligned struct is necessary to read CK_INFO
+// from Go on Windows where packing is required.
+typedef struct ckInfo {
+ CK_VERSION cryptokiVersion;
+ CK_UTF8CHAR manufacturerID[32];
+ CK_FLAGS flags;
+ CK_UTF8CHAR libraryDescription[32];
+ CK_VERSION libraryVersion;
+} ckInfo, *ckInfoPtr;
diff --git a/vendor/github.com/miekg/pkcs11/pkcs11t.h b/vendor/github.com/miekg/pkcs11/pkcs11t.h
new file mode 100644
index 000000000..321c3075a
--- /dev/null
+++ b/vendor/github.com/miekg/pkcs11/pkcs11t.h
@@ -0,0 +1,2047 @@
+/* Copyright (c) OASIS Open 2016. All Rights Reserved./
+ * /Distributed under the terms of the OASIS IPR Policy,
+ * [http://www.oasis-open.org/policies-guidelines/ipr], AS-IS, WITHOUT ANY
+ * IMPLIED OR EXPRESS WARRANTY; there is no warranty of MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE or NONINFRINGEMENT of the rights of others.
+ */
+
+/* Latest version of the specification:
+ * http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/pkcs11-base-v2.40.html
+ */
+
+/* See top of pkcs11.h for information about the macros that
+ * must be defined and the structure-packing conventions that
+ * must be set before including this file.
+ */
+
+#ifndef _PKCS11T_H_
+#define _PKCS11T_H_ 1
+
+#define CRYPTOKI_VERSION_MAJOR 2
+#define CRYPTOKI_VERSION_MINOR 40
+#define CRYPTOKI_VERSION_AMENDMENT 0
+
+#define CK_TRUE 1
+#define CK_FALSE 0
+
+#ifndef CK_DISABLE_TRUE_FALSE
+#ifndef FALSE
+#define FALSE CK_FALSE
+#endif
+#ifndef TRUE
+#define TRUE CK_TRUE
+#endif
+#endif
+
+/* an unsigned 8-bit value */
+typedef unsigned char CK_BYTE;
+
+/* an unsigned 8-bit character */
+typedef CK_BYTE CK_CHAR;
+
+/* an 8-bit UTF-8 character */
+typedef CK_BYTE CK_UTF8CHAR;
+
+/* a BYTE-sized Boolean flag */
+typedef CK_BYTE CK_BBOOL;
+
+/* an unsigned value, at least 32 bits long */
+typedef unsigned long int CK_ULONG;
+
+/* a signed value, the same size as a CK_ULONG */
+typedef long int CK_LONG;
+
+/* at least 32 bits; each bit is a Boolean flag */
+typedef CK_ULONG CK_FLAGS;
+
+
+/* some special values for certain CK_ULONG variables */
+#define CK_UNAVAILABLE_INFORMATION (~0UL)
+#define CK_EFFECTIVELY_INFINITE 0UL
+
+
+typedef CK_BYTE CK_PTR CK_BYTE_PTR;
+typedef CK_CHAR CK_PTR CK_CHAR_PTR;
+typedef CK_UTF8CHAR CK_PTR CK_UTF8CHAR_PTR;
+typedef CK_ULONG CK_PTR CK_ULONG_PTR;
+typedef void CK_PTR CK_VOID_PTR;
+
+/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */
+typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR;
+
+
+/* The following value is always invalid if used as a session
+ * handle or object handle
+ */
+#define CK_INVALID_HANDLE 0UL
+
+
+typedef struct CK_VERSION {
+ CK_BYTE major; /* integer portion of version number */
+ CK_BYTE minor; /* 1/100ths portion of version number */
+} CK_VERSION;
+
+typedef CK_VERSION CK_PTR CK_VERSION_PTR;
+
+
+typedef struct CK_INFO {
+ CK_VERSION cryptokiVersion; /* Cryptoki interface ver */
+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */
+ CK_FLAGS flags; /* must be zero */
+ CK_UTF8CHAR libraryDescription[32]; /* blank padded */
+ CK_VERSION libraryVersion; /* version of library */
+} CK_INFO;
+
+typedef CK_INFO CK_PTR CK_INFO_PTR;
+
+
+/* CK_NOTIFICATION enumerates the types of notifications that
+ * Cryptoki provides to an application
+ */
+typedef CK_ULONG CK_NOTIFICATION;
+#define CKN_SURRENDER 0UL
+#define CKN_OTP_CHANGED 1UL
+
+typedef CK_ULONG CK_SLOT_ID;
+
+typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
+
+
+/* CK_SLOT_INFO provides information about a slot */
+typedef struct CK_SLOT_INFO {
+ CK_UTF8CHAR slotDescription[64]; /* blank padded */
+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */
+ CK_FLAGS flags;
+
+ CK_VERSION hardwareVersion; /* version of hardware */
+ CK_VERSION firmwareVersion; /* version of firmware */
+} CK_SLOT_INFO;
+
+/* flags: bit flags that provide capabilities of the slot
+ * Bit Flag Mask Meaning
+ */
+#define CKF_TOKEN_PRESENT 0x00000001UL /* a token is there */
+#define CKF_REMOVABLE_DEVICE 0x00000002UL /* removable devices*/
+#define CKF_HW_SLOT 0x00000004UL /* hardware slot */
+
+typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
+
+
+/* CK_TOKEN_INFO provides information about a token */
+typedef struct CK_TOKEN_INFO {
+ CK_UTF8CHAR label[32]; /* blank padded */
+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */
+ CK_UTF8CHAR model[16]; /* blank padded */
+ CK_CHAR serialNumber[16]; /* blank padded */
+ CK_FLAGS flags; /* see below */
+
+ CK_ULONG ulMaxSessionCount; /* max open sessions */
+ CK_ULONG ulSessionCount; /* sess. now open */
+ CK_ULONG ulMaxRwSessionCount; /* max R/W sessions */
+ CK_ULONG ulRwSessionCount; /* R/W sess. now open */
+ CK_ULONG ulMaxPinLen; /* in bytes */
+ CK_ULONG ulMinPinLen; /* in bytes */
+ CK_ULONG ulTotalPublicMemory; /* in bytes */
+ CK_ULONG ulFreePublicMemory; /* in bytes */
+ CK_ULONG ulTotalPrivateMemory; /* in bytes */
+ CK_ULONG ulFreePrivateMemory; /* in bytes */
+ CK_VERSION hardwareVersion; /* version of hardware */
+ CK_VERSION firmwareVersion; /* version of firmware */
+ CK_CHAR utcTime[16]; /* time */
+} CK_TOKEN_INFO;
+
+/* The flags parameter is defined as follows:
+ * Bit Flag Mask Meaning
+ */
+#define CKF_RNG 0x00000001UL /* has random # generator */
+#define CKF_WRITE_PROTECTED 0x00000002UL /* token is write-protected */
+#define CKF_LOGIN_REQUIRED 0x00000004UL /* user must login */
+#define CKF_USER_PIN_INITIALIZED 0x00000008UL /* normal user's PIN is set */
+
+/* CKF_RESTORE_KEY_NOT_NEEDED. If it is set,
+ * that means that *every* time the state of cryptographic
+ * operations of a session is successfully saved, all keys
+ * needed to continue those operations are stored in the state
+ */
+#define CKF_RESTORE_KEY_NOT_NEEDED 0x00000020UL
+
+/* CKF_CLOCK_ON_TOKEN. If it is set, that means
+ * that the token has some sort of clock. The time on that
+ * clock is returned in the token info structure
+ */
+#define CKF_CLOCK_ON_TOKEN 0x00000040UL
+
+/* CKF_PROTECTED_AUTHENTICATION_PATH. If it is
+ * set, that means that there is some way for the user to login
+ * without sending a PIN through the Cryptoki library itself
+ */
+#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100UL
+
+/* CKF_DUAL_CRYPTO_OPERATIONS. If it is true,
+ * that means that a single session with the token can perform
+ * dual simultaneous cryptographic operations (digest and
+ * encrypt; decrypt and digest; sign and encrypt; and decrypt
+ * and sign)
+ */
+#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200UL
+
+/* CKF_TOKEN_INITIALIZED. If it is true, the
+ * token has been initialized using C_InitializeToken or an
+ * equivalent mechanism outside the scope of PKCS #11.
+ * Calling C_InitializeToken when this flag is set will cause
+ * the token to be reinitialized.
+ */
+#define CKF_TOKEN_INITIALIZED 0x00000400UL
+
+/* CKF_SECONDARY_AUTHENTICATION. If it is
+ * true, the token supports secondary authentication for
+ * private key objects.
+ */
+#define CKF_SECONDARY_AUTHENTICATION 0x00000800UL
+
+/* CKF_USER_PIN_COUNT_LOW. If it is true, an
+ * incorrect user login PIN has been entered at least once
+ * since the last successful authentication.
+ */
+#define CKF_USER_PIN_COUNT_LOW 0x00010000UL
+
+/* CKF_USER_PIN_FINAL_TRY. If it is true,
+ * supplying an incorrect user PIN will it to become locked.
+ */
+#define CKF_USER_PIN_FINAL_TRY 0x00020000UL
+
+/* CKF_USER_PIN_LOCKED. If it is true, the
+ * user PIN has been locked. User login to the token is not
+ * possible.
+ */
+#define CKF_USER_PIN_LOCKED 0x00040000UL
+
+/* CKF_USER_PIN_TO_BE_CHANGED. If it is true,
+ * the user PIN value is the default value set by token
+ * initialization or manufacturing, or the PIN has been
+ * expired by the card.
+ */
+#define CKF_USER_PIN_TO_BE_CHANGED 0x00080000UL
+
+/* CKF_SO_PIN_COUNT_LOW. If it is true, an
+ * incorrect SO login PIN has been entered at least once since
+ * the last successful authentication.
+ */
+#define CKF_SO_PIN_COUNT_LOW 0x00100000UL
+
+/* CKF_SO_PIN_FINAL_TRY. If it is true,
+ * supplying an incorrect SO PIN will it to become locked.
+ */
+#define CKF_SO_PIN_FINAL_TRY 0x00200000UL
+
+/* CKF_SO_PIN_LOCKED. If it is true, the SO
+ * PIN has been locked. SO login to the token is not possible.
+ */
+#define CKF_SO_PIN_LOCKED 0x00400000UL
+
+/* CKF_SO_PIN_TO_BE_CHANGED. If it is true,
+ * the SO PIN value is the default value set by token
+ * initialization or manufacturing, or the PIN has been
+ * expired by the card.
+ */
+#define CKF_SO_PIN_TO_BE_CHANGED 0x00800000UL
+
+#define CKF_ERROR_STATE 0x01000000UL
+
+typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
+
+
+/* CK_SESSION_HANDLE is a Cryptoki-assigned value that
+ * identifies a session
+ */
+typedef CK_ULONG CK_SESSION_HANDLE;
+
+typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
+
+
+/* CK_USER_TYPE enumerates the types of Cryptoki users */
+typedef CK_ULONG CK_USER_TYPE;
+/* Security Officer */
+#define CKU_SO 0UL
+/* Normal user */
+#define CKU_USER 1UL
+/* Context specific */
+#define CKU_CONTEXT_SPECIFIC 2UL
+
+/* CK_STATE enumerates the session states */
+typedef CK_ULONG CK_STATE;
+#define CKS_RO_PUBLIC_SESSION 0UL
+#define CKS_RO_USER_FUNCTIONS 1UL
+#define CKS_RW_PUBLIC_SESSION 2UL
+#define CKS_RW_USER_FUNCTIONS 3UL
+#define CKS_RW_SO_FUNCTIONS 4UL
+
+/* CK_SESSION_INFO provides information about a session */
+typedef struct CK_SESSION_INFO {
+ CK_SLOT_ID slotID;
+ CK_STATE state;
+ CK_FLAGS flags; /* see below */
+ CK_ULONG ulDeviceError; /* device-dependent error code */
+} CK_SESSION_INFO;
+
+/* The flags are defined in the following table:
+ * Bit Flag Mask Meaning
+ */
+#define CKF_RW_SESSION 0x00000002UL /* session is r/w */
+#define CKF_SERIAL_SESSION 0x00000004UL /* no parallel */
+
+typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR;
+
+
+/* CK_OBJECT_HANDLE is a token-specific identifier for an
+ * object
+ */
+typedef CK_ULONG CK_OBJECT_HANDLE;
+
+typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
+
+
+/* CK_OBJECT_CLASS is a value that identifies the classes (or
+ * types) of objects that Cryptoki recognizes. It is defined
+ * as follows:
+ */
+typedef CK_ULONG CK_OBJECT_CLASS;
+
+/* The following classes of objects are defined: */
+#define CKO_DATA 0x00000000UL
+#define CKO_CERTIFICATE 0x00000001UL
+#define CKO_PUBLIC_KEY 0x00000002UL
+#define CKO_PRIVATE_KEY 0x00000003UL
+#define CKO_SECRET_KEY 0x00000004UL
+#define CKO_HW_FEATURE 0x00000005UL
+#define CKO_DOMAIN_PARAMETERS 0x00000006UL
+#define CKO_MECHANISM 0x00000007UL
+#define CKO_OTP_KEY 0x00000008UL
+
+#define CKO_VENDOR_DEFINED 0x80000000UL
+
+typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
+
+/* CK_HW_FEATURE_TYPE is a value that identifies the hardware feature type
+ * of an object with CK_OBJECT_CLASS equal to CKO_HW_FEATURE.
+ */
+typedef CK_ULONG CK_HW_FEATURE_TYPE;
+
+/* The following hardware feature types are defined */
+#define CKH_MONOTONIC_COUNTER 0x00000001UL
+#define CKH_CLOCK 0x00000002UL
+#define CKH_USER_INTERFACE 0x00000003UL
+#define CKH_VENDOR_DEFINED 0x80000000UL
+
+/* CK_KEY_TYPE is a value that identifies a key type */
+typedef CK_ULONG CK_KEY_TYPE;
+
+/* the following key types are defined: */
+#define CKK_RSA 0x00000000UL
+#define CKK_DSA 0x00000001UL
+#define CKK_DH 0x00000002UL
+#define CKK_ECDSA 0x00000003UL /* Deprecated */
+#define CKK_EC 0x00000003UL
+#define CKK_X9_42_DH 0x00000004UL
+#define CKK_KEA 0x00000005UL
+#define CKK_GENERIC_SECRET 0x00000010UL
+#define CKK_RC2 0x00000011UL
+#define CKK_RC4 0x00000012UL
+#define CKK_DES 0x00000013UL
+#define CKK_DES2 0x00000014UL
+#define CKK_DES3 0x00000015UL
+#define CKK_CAST 0x00000016UL
+#define CKK_CAST3 0x00000017UL
+#define CKK_CAST5 0x00000018UL /* Deprecated */
+#define CKK_CAST128 0x00000018UL
+#define CKK_RC5 0x00000019UL
+#define CKK_IDEA 0x0000001AUL
+#define CKK_SKIPJACK 0x0000001BUL
+#define CKK_BATON 0x0000001CUL
+#define CKK_JUNIPER 0x0000001DUL
+#define CKK_CDMF 0x0000001EUL
+#define CKK_AES 0x0000001FUL
+#define CKK_BLOWFISH 0x00000020UL
+#define CKK_TWOFISH 0x00000021UL
+#define CKK_SECURID 0x00000022UL
+#define CKK_HOTP 0x00000023UL
+#define CKK_ACTI 0x00000024UL
+#define CKK_CAMELLIA 0x00000025UL
+#define CKK_ARIA 0x00000026UL
+
+#define CKK_MD5_HMAC 0x00000027UL
+#define CKK_SHA_1_HMAC 0x00000028UL
+#define CKK_RIPEMD128_HMAC 0x00000029UL
+#define CKK_RIPEMD160_HMAC 0x0000002AUL
+#define CKK_SHA256_HMAC 0x0000002BUL
+#define CKK_SHA384_HMAC 0x0000002CUL
+#define CKK_SHA512_HMAC 0x0000002DUL
+#define CKK_SHA224_HMAC 0x0000002EUL
+
+#define CKK_SEED 0x0000002FUL
+#define CKK_GOSTR3410 0x00000030UL
+#define CKK_GOSTR3411 0x00000031UL
+#define CKK_GOST28147 0x00000032UL
+
+#define CKK_SHA3_224_HMAC 0x00000033UL
+#define CKK_SHA3_256_HMAC 0x00000034UL
+#define CKK_SHA3_384_HMAC 0x00000035UL
+#define CKK_SHA3_512_HMAC 0x00000036UL
+
+
+
+#define CKK_VENDOR_DEFINED 0x80000000UL
+
+
+/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
+ * type
+ */
+typedef CK_ULONG CK_CERTIFICATE_TYPE;
+
+#define CK_CERTIFICATE_CATEGORY_UNSPECIFIED 0UL
+#define CK_CERTIFICATE_CATEGORY_TOKEN_USER 1UL
+#define CK_CERTIFICATE_CATEGORY_AUTHORITY 2UL
+#define CK_CERTIFICATE_CATEGORY_OTHER_ENTITY 3UL
+
+#define CK_SECURITY_DOMAIN_UNSPECIFIED 0UL
+#define CK_SECURITY_DOMAIN_MANUFACTURER 1UL
+#define CK_SECURITY_DOMAIN_OPERATOR 2UL
+#define CK_SECURITY_DOMAIN_THIRD_PARTY 3UL
+
+
+/* The following certificate types are defined: */
+#define CKC_X_509 0x00000000UL
+#define CKC_X_509_ATTR_CERT 0x00000001UL
+#define CKC_WTLS 0x00000002UL
+#define CKC_VENDOR_DEFINED 0x80000000UL
+
+
+/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute
+ * type
+ */
+typedef CK_ULONG CK_ATTRIBUTE_TYPE;
+
+/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which
+ * consists of an array of values.
+ */
+#define CKF_ARRAY_ATTRIBUTE 0x40000000UL
+
+/* The following OTP-related defines relate to the CKA_OTP_FORMAT attribute */
+#define CK_OTP_FORMAT_DECIMAL 0UL
+#define CK_OTP_FORMAT_HEXADECIMAL 1UL
+#define CK_OTP_FORMAT_ALPHANUMERIC 2UL
+#define CK_OTP_FORMAT_BINARY 3UL
+
+/* The following OTP-related defines relate to the CKA_OTP_..._REQUIREMENT
+ * attributes
+ */
+#define CK_OTP_PARAM_IGNORED 0UL
+#define CK_OTP_PARAM_OPTIONAL 1UL
+#define CK_OTP_PARAM_MANDATORY 2UL
+
+/* The following attribute types are defined: */
+#define CKA_CLASS 0x00000000UL
+#define CKA_TOKEN 0x00000001UL
+#define CKA_PRIVATE 0x00000002UL
+#define CKA_LABEL 0x00000003UL
+#define CKA_APPLICATION 0x00000010UL
+#define CKA_VALUE 0x00000011UL
+#define CKA_OBJECT_ID 0x00000012UL
+#define CKA_CERTIFICATE_TYPE 0x00000080UL
+#define CKA_ISSUER 0x00000081UL
+#define CKA_SERIAL_NUMBER 0x00000082UL
+#define CKA_AC_ISSUER 0x00000083UL
+#define CKA_OWNER 0x00000084UL
+#define CKA_ATTR_TYPES 0x00000085UL
+#define CKA_TRUSTED 0x00000086UL
+#define CKA_CERTIFICATE_CATEGORY 0x00000087UL
+#define CKA_JAVA_MIDP_SECURITY_DOMAIN 0x00000088UL
+#define CKA_URL 0x00000089UL
+#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY 0x0000008AUL
+#define CKA_HASH_OF_ISSUER_PUBLIC_KEY 0x0000008BUL
+#define CKA_NAME_HASH_ALGORITHM 0x0000008CUL
+#define CKA_CHECK_VALUE 0x00000090UL
+
+#define CKA_KEY_TYPE 0x00000100UL
+#define CKA_SUBJECT 0x00000101UL
+#define CKA_ID 0x00000102UL
+#define CKA_SENSITIVE 0x00000103UL
+#define CKA_ENCRYPT 0x00000104UL
+#define CKA_DECRYPT 0x00000105UL
+#define CKA_WRAP 0x00000106UL
+#define CKA_UNWRAP 0x00000107UL
+#define CKA_SIGN 0x00000108UL
+#define CKA_SIGN_RECOVER 0x00000109UL
+#define CKA_VERIFY 0x0000010AUL
+#define CKA_VERIFY_RECOVER 0x0000010BUL
+#define CKA_DERIVE 0x0000010CUL
+#define CKA_START_DATE 0x00000110UL
+#define CKA_END_DATE 0x00000111UL
+#define CKA_MODULUS 0x00000120UL
+#define CKA_MODULUS_BITS 0x00000121UL
+#define CKA_PUBLIC_EXPONENT 0x00000122UL
+#define CKA_PRIVATE_EXPONENT 0x00000123UL
+#define CKA_PRIME_1 0x00000124UL
+#define CKA_PRIME_2 0x00000125UL
+#define CKA_EXPONENT_1 0x00000126UL
+#define CKA_EXPONENT_2 0x00000127UL
+#define CKA_COEFFICIENT 0x00000128UL
+#define CKA_PUBLIC_KEY_INFO 0x00000129UL
+#define CKA_PRIME 0x00000130UL
+#define CKA_SUBPRIME 0x00000131UL
+#define CKA_BASE 0x00000132UL
+
+#define CKA_PRIME_BITS 0x00000133UL
+#define CKA_SUBPRIME_BITS 0x00000134UL
+#define CKA_SUB_PRIME_BITS CKA_SUBPRIME_BITS
+
+#define CKA_VALUE_BITS 0x00000160UL
+#define CKA_VALUE_LEN 0x00000161UL
+#define CKA_EXTRACTABLE 0x00000162UL
+#define CKA_LOCAL 0x00000163UL
+#define CKA_NEVER_EXTRACTABLE 0x00000164UL
+#define CKA_ALWAYS_SENSITIVE 0x00000165UL
+#define CKA_KEY_GEN_MECHANISM 0x00000166UL
+
+#define CKA_MODIFIABLE 0x00000170UL
+#define CKA_COPYABLE 0x00000171UL
+
+#define CKA_DESTROYABLE 0x00000172UL
+
+#define CKA_ECDSA_PARAMS 0x00000180UL /* Deprecated */
+#define CKA_EC_PARAMS 0x00000180UL
+
+#define CKA_EC_POINT 0x00000181UL
+
+#define CKA_SECONDARY_AUTH 0x00000200UL /* Deprecated */
+#define CKA_AUTH_PIN_FLAGS 0x00000201UL /* Deprecated */
+
+#define CKA_ALWAYS_AUTHENTICATE 0x00000202UL
+
+#define CKA_WRAP_WITH_TRUSTED 0x00000210UL
+#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000211UL)
+#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000212UL)
+#define CKA_DERIVE_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000213UL)
+
+#define CKA_OTP_FORMAT 0x00000220UL
+#define CKA_OTP_LENGTH 0x00000221UL
+#define CKA_OTP_TIME_INTERVAL 0x00000222UL
+#define CKA_OTP_USER_FRIENDLY_MODE 0x00000223UL
+#define CKA_OTP_CHALLENGE_REQUIREMENT 0x00000224UL
+#define CKA_OTP_TIME_REQUIREMENT 0x00000225UL
+#define CKA_OTP_COUNTER_REQUIREMENT 0x00000226UL
+#define CKA_OTP_PIN_REQUIREMENT 0x00000227UL
+#define CKA_OTP_COUNTER 0x0000022EUL
+#define CKA_OTP_TIME 0x0000022FUL
+#define CKA_OTP_USER_IDENTIFIER 0x0000022AUL
+#define CKA_OTP_SERVICE_IDENTIFIER 0x0000022BUL
+#define CKA_OTP_SERVICE_LOGO 0x0000022CUL
+#define CKA_OTP_SERVICE_LOGO_TYPE 0x0000022DUL
+
+#define CKA_GOSTR3410_PARAMS 0x00000250UL
+#define CKA_GOSTR3411_PARAMS 0x00000251UL
+#define CKA_GOST28147_PARAMS 0x00000252UL
+
+#define CKA_HW_FEATURE_TYPE 0x00000300UL
+#define CKA_RESET_ON_INIT 0x00000301UL
+#define CKA_HAS_RESET 0x00000302UL
+
+#define CKA_PIXEL_X 0x00000400UL
+#define CKA_PIXEL_Y 0x00000401UL
+#define CKA_RESOLUTION 0x00000402UL
+#define CKA_CHAR_ROWS 0x00000403UL
+#define CKA_CHAR_COLUMNS 0x00000404UL
+#define CKA_COLOR 0x00000405UL
+#define CKA_BITS_PER_PIXEL 0x00000406UL
+#define CKA_CHAR_SETS 0x00000480UL
+#define CKA_ENCODING_METHODS 0x00000481UL
+#define CKA_MIME_TYPES 0x00000482UL
+#define CKA_MECHANISM_TYPE 0x00000500UL
+#define CKA_REQUIRED_CMS_ATTRIBUTES 0x00000501UL
+#define CKA_DEFAULT_CMS_ATTRIBUTES 0x00000502UL
+#define CKA_SUPPORTED_CMS_ATTRIBUTES 0x00000503UL
+#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE|0x00000600UL)
+
+#define CKA_VENDOR_DEFINED 0x80000000UL
+
+/* CK_ATTRIBUTE is a structure that includes the type, length
+ * and value of an attribute
+ */
+typedef struct CK_ATTRIBUTE {
+ CK_ATTRIBUTE_TYPE type;
+ CK_VOID_PTR pValue;
+ CK_ULONG ulValueLen; /* in bytes */
+} CK_ATTRIBUTE;
+
+typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;
+
+/* CK_DATE is a structure that defines a date */
+typedef struct CK_DATE{
+ CK_CHAR year[4]; /* the year ("1900" - "9999") */
+ CK_CHAR month[2]; /* the month ("01" - "12") */
+ CK_CHAR day[2]; /* the day ("01" - "31") */
+} CK_DATE;
+
+
+/* CK_MECHANISM_TYPE is a value that identifies a mechanism
+ * type
+ */
+typedef CK_ULONG CK_MECHANISM_TYPE;
+
+/* the following mechanism types are defined: */
+#define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000UL
+#define CKM_RSA_PKCS 0x00000001UL
+#define CKM_RSA_9796 0x00000002UL
+#define CKM_RSA_X_509 0x00000003UL
+
+#define CKM_MD2_RSA_PKCS 0x00000004UL
+#define CKM_MD5_RSA_PKCS 0x00000005UL
+#define CKM_SHA1_RSA_PKCS 0x00000006UL
+
+#define CKM_RIPEMD128_RSA_PKCS 0x00000007UL
+#define CKM_RIPEMD160_RSA_PKCS 0x00000008UL
+#define CKM_RSA_PKCS_OAEP 0x00000009UL
+
+#define CKM_RSA_X9_31_KEY_PAIR_GEN 0x0000000AUL
+#define CKM_RSA_X9_31 0x0000000BUL
+#define CKM_SHA1_RSA_X9_31 0x0000000CUL
+#define CKM_RSA_PKCS_PSS 0x0000000DUL
+#define CKM_SHA1_RSA_PKCS_PSS 0x0000000EUL
+
+#define CKM_DSA_KEY_PAIR_GEN 0x00000010UL
+#define CKM_DSA 0x00000011UL
+#define CKM_DSA_SHA1 0x00000012UL
+#define CKM_DSA_SHA224 0x00000013UL
+#define CKM_DSA_SHA256 0x00000014UL
+#define CKM_DSA_SHA384 0x00000015UL
+#define CKM_DSA_SHA512 0x00000016UL
+#define CKM_DSA_SHA3_224 0x00000018UL
+#define CKM_DSA_SHA3_256 0x00000019UL
+#define CKM_DSA_SHA3_384 0x0000001AUL
+#define CKM_DSA_SHA3_512 0x0000001BUL
+
+#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020UL
+#define CKM_DH_PKCS_DERIVE 0x00000021UL
+
+#define CKM_X9_42_DH_KEY_PAIR_GEN 0x00000030UL
+#define CKM_X9_42_DH_DERIVE 0x00000031UL
+#define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032UL
+#define CKM_X9_42_MQV_DERIVE 0x00000033UL
+
+#define CKM_SHA256_RSA_PKCS 0x00000040UL
+#define CKM_SHA384_RSA_PKCS 0x00000041UL
+#define CKM_SHA512_RSA_PKCS 0x00000042UL
+#define CKM_SHA256_RSA_PKCS_PSS 0x00000043UL
+#define CKM_SHA384_RSA_PKCS_PSS 0x00000044UL
+#define CKM_SHA512_RSA_PKCS_PSS 0x00000045UL
+
+#define CKM_SHA224_RSA_PKCS 0x00000046UL
+#define CKM_SHA224_RSA_PKCS_PSS 0x00000047UL
+
+#define CKM_SHA512_224 0x00000048UL
+#define CKM_SHA512_224_HMAC 0x00000049UL
+#define CKM_SHA512_224_HMAC_GENERAL 0x0000004AUL
+#define CKM_SHA512_224_KEY_DERIVATION 0x0000004BUL
+#define CKM_SHA512_256 0x0000004CUL
+#define CKM_SHA512_256_HMAC 0x0000004DUL
+#define CKM_SHA512_256_HMAC_GENERAL 0x0000004EUL
+#define CKM_SHA512_256_KEY_DERIVATION 0x0000004FUL
+
+#define CKM_SHA512_T 0x00000050UL
+#define CKM_SHA512_T_HMAC 0x00000051UL
+#define CKM_SHA512_T_HMAC_GENERAL 0x00000052UL
+#define CKM_SHA512_T_KEY_DERIVATION 0x00000053UL
+
+#define CKM_SHA3_256_RSA_PKCS 0x00000060UL
+#define CKM_SHA3_384_RSA_PKCS 0x00000061UL
+#define CKM_SHA3_512_RSA_PKCS 0x00000062UL
+#define CKM_SHA3_256_RSA_PKCS_PSS 0x00000063UL
+#define CKM_SHA3_384_RSA_PKCS_PSS 0x00000064UL
+#define CKM_SHA3_512_RSA_PKCS_PSS 0x00000065UL
+#define CKM_SHA3_224_RSA_PKCS 0x00000066UL
+#define CKM_SHA3_224_RSA_PKCS_PSS 0x00000067UL
+
+#define CKM_RC2_KEY_GEN 0x00000100UL
+#define CKM_RC2_ECB 0x00000101UL
+#define CKM_RC2_CBC 0x00000102UL
+#define CKM_RC2_MAC 0x00000103UL
+
+#define CKM_RC2_MAC_GENERAL 0x00000104UL
+#define CKM_RC2_CBC_PAD 0x00000105UL
+
+#define CKM_RC4_KEY_GEN 0x00000110UL
+#define CKM_RC4 0x00000111UL
+#define CKM_DES_KEY_GEN 0x00000120UL
+#define CKM_DES_ECB 0x00000121UL
+#define CKM_DES_CBC 0x00000122UL
+#define CKM_DES_MAC 0x00000123UL
+
+#define CKM_DES_MAC_GENERAL 0x00000124UL
+#define CKM_DES_CBC_PAD 0x00000125UL
+
+#define CKM_DES2_KEY_GEN 0x00000130UL
+#define CKM_DES3_KEY_GEN 0x00000131UL
+#define CKM_DES3_ECB 0x00000132UL
+#define CKM_DES3_CBC 0x00000133UL
+#define CKM_DES3_MAC 0x00000134UL
+
+#define CKM_DES3_MAC_GENERAL 0x00000135UL
+#define CKM_DES3_CBC_PAD 0x00000136UL
+#define CKM_DES3_CMAC_GENERAL 0x00000137UL
+#define CKM_DES3_CMAC 0x00000138UL
+#define CKM_CDMF_KEY_GEN 0x00000140UL
+#define CKM_CDMF_ECB 0x00000141UL
+#define CKM_CDMF_CBC 0x00000142UL
+#define CKM_CDMF_MAC 0x00000143UL
+#define CKM_CDMF_MAC_GENERAL 0x00000144UL
+#define CKM_CDMF_CBC_PAD 0x00000145UL
+
+#define CKM_DES_OFB64 0x00000150UL
+#define CKM_DES_OFB8 0x00000151UL
+#define CKM_DES_CFB64 0x00000152UL
+#define CKM_DES_CFB8 0x00000153UL
+
+#define CKM_MD2 0x00000200UL
+
+#define CKM_MD2_HMAC 0x00000201UL
+#define CKM_MD2_HMAC_GENERAL 0x00000202UL
+
+#define CKM_MD5 0x00000210UL
+
+#define CKM_MD5_HMAC 0x00000211UL
+#define CKM_MD5_HMAC_GENERAL 0x00000212UL
+
+#define CKM_SHA_1 0x00000220UL
+
+#define CKM_SHA_1_HMAC 0x00000221UL
+#define CKM_SHA_1_HMAC_GENERAL 0x00000222UL
+
+#define CKM_RIPEMD128 0x00000230UL
+#define CKM_RIPEMD128_HMAC 0x00000231UL
+#define CKM_RIPEMD128_HMAC_GENERAL 0x00000232UL
+#define CKM_RIPEMD160 0x00000240UL
+#define CKM_RIPEMD160_HMAC 0x00000241UL
+#define CKM_RIPEMD160_HMAC_GENERAL 0x00000242UL
+
+#define CKM_SHA256 0x00000250UL
+#define CKM_SHA256_HMAC 0x00000251UL
+#define CKM_SHA256_HMAC_GENERAL 0x00000252UL
+#define CKM_SHA224 0x00000255UL
+#define CKM_SHA224_HMAC 0x00000256UL
+#define CKM_SHA224_HMAC_GENERAL 0x00000257UL
+#define CKM_SHA384 0x00000260UL
+#define CKM_SHA384_HMAC 0x00000261UL
+#define CKM_SHA384_HMAC_GENERAL 0x00000262UL
+#define CKM_SHA512 0x00000270UL
+#define CKM_SHA512_HMAC 0x00000271UL
+#define CKM_SHA512_HMAC_GENERAL 0x00000272UL
+#define CKM_SECURID_KEY_GEN 0x00000280UL
+#define CKM_SECURID 0x00000282UL
+#define CKM_HOTP_KEY_GEN 0x00000290UL
+#define CKM_HOTP 0x00000291UL
+#define CKM_ACTI 0x000002A0UL
+#define CKM_ACTI_KEY_GEN 0x000002A1UL
+
+#define CKM_SHA3_256 0x000002B0UL
+#define CKM_SHA3_256_HMAC 0x000002B1UL
+#define CKM_SHA3_256_HMAC_GENERAL 0x000002B2UL
+#define CKM_SHA3_256_KEY_GEN 0x000002B3UL
+#define CKM_SHA3_224 0x000002B5UL
+#define CKM_SHA3_224_HMAC 0x000002B6UL
+#define CKM_SHA3_224_HMAC_GENERAL 0x000002B7UL
+#define CKM_SHA3_224_KEY_GEN 0x000002B8UL
+#define CKM_SHA3_384 0x000002C0UL
+#define CKM_SHA3_384_HMAC 0x000002C1UL
+#define CKM_SHA3_384_HMAC_GENERAL 0x000002C2UL
+#define CKM_SHA3_384_KEY_GEN 0x000002C3UL
+#define CKM_SHA3_512 0x000002D0UL
+#define CKM_SHA3_512_HMAC 0x000002D1UL
+#define CKM_SHA3_512_HMAC_GENERAL 0x000002D2UL
+#define CKM_SHA3_512_KEY_GEN 0x000002D3UL
+
+#define CKM_CAST_KEY_GEN 0x00000300UL
+#define CKM_CAST_ECB 0x00000301UL
+#define CKM_CAST_CBC 0x00000302UL
+#define CKM_CAST_MAC 0x00000303UL
+#define CKM_CAST_MAC_GENERAL 0x00000304UL
+#define CKM_CAST_CBC_PAD 0x00000305UL
+#define CKM_CAST3_KEY_GEN 0x00000310UL
+#define CKM_CAST3_ECB 0x00000311UL
+#define CKM_CAST3_CBC 0x00000312UL
+#define CKM_CAST3_MAC 0x00000313UL
+#define CKM_CAST3_MAC_GENERAL 0x00000314UL
+#define CKM_CAST3_CBC_PAD 0x00000315UL
+/* Note that CAST128 and CAST5 are the same algorithm */
+#define CKM_CAST5_KEY_GEN 0x00000320UL
+#define CKM_CAST128_KEY_GEN 0x00000320UL
+#define CKM_CAST5_ECB 0x00000321UL
+#define CKM_CAST128_ECB 0x00000321UL
+#define CKM_CAST5_CBC 0x00000322UL /* Deprecated */
+#define CKM_CAST128_CBC 0x00000322UL
+#define CKM_CAST5_MAC 0x00000323UL /* Deprecated */
+#define CKM_CAST128_MAC 0x00000323UL
+#define CKM_CAST5_MAC_GENERAL 0x00000324UL /* Deprecated */
+#define CKM_CAST128_MAC_GENERAL 0x00000324UL
+#define CKM_CAST5_CBC_PAD 0x00000325UL /* Deprecated */
+#define CKM_CAST128_CBC_PAD 0x00000325UL
+#define CKM_RC5_KEY_GEN 0x00000330UL
+#define CKM_RC5_ECB 0x00000331UL
+#define CKM_RC5_CBC 0x00000332UL
+#define CKM_RC5_MAC 0x00000333UL
+#define CKM_RC5_MAC_GENERAL 0x00000334UL
+#define CKM_RC5_CBC_PAD 0x00000335UL
+#define CKM_IDEA_KEY_GEN 0x00000340UL
+#define CKM_IDEA_ECB 0x00000341UL
+#define CKM_IDEA_CBC 0x00000342UL
+#define CKM_IDEA_MAC 0x00000343UL
+#define CKM_IDEA_MAC_GENERAL 0x00000344UL
+#define CKM_IDEA_CBC_PAD 0x00000345UL
+#define CKM_GENERIC_SECRET_KEY_GEN 0x00000350UL
+#define CKM_CONCATENATE_BASE_AND_KEY 0x00000360UL
+#define CKM_CONCATENATE_BASE_AND_DATA 0x00000362UL
+#define CKM_CONCATENATE_DATA_AND_BASE 0x00000363UL
+#define CKM_XOR_BASE_AND_DATA 0x00000364UL
+#define CKM_EXTRACT_KEY_FROM_KEY 0x00000365UL
+#define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370UL
+#define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371UL
+#define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372UL
+
+#define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x00000373UL
+#define CKM_TLS_PRE_MASTER_KEY_GEN 0x00000374UL
+#define CKM_TLS_MASTER_KEY_DERIVE 0x00000375UL
+#define CKM_TLS_KEY_AND_MAC_DERIVE 0x00000376UL
+#define CKM_TLS_MASTER_KEY_DERIVE_DH 0x00000377UL
+
+#define CKM_TLS_PRF 0x00000378UL
+
+#define CKM_SSL3_MD5_MAC 0x00000380UL
+#define CKM_SSL3_SHA1_MAC 0x00000381UL
+#define CKM_MD5_KEY_DERIVATION 0x00000390UL
+#define CKM_MD2_KEY_DERIVATION 0x00000391UL
+#define CKM_SHA1_KEY_DERIVATION 0x00000392UL
+
+#define CKM_SHA256_KEY_DERIVATION 0x00000393UL
+#define CKM_SHA384_KEY_DERIVATION 0x00000394UL
+#define CKM_SHA512_KEY_DERIVATION 0x00000395UL
+#define CKM_SHA224_KEY_DERIVATION 0x00000396UL
+#define CKM_SHA3_256_KEY_DERIVE 0x00000397UL
+#define CKM_SHA3_224_KEY_DERIVE 0x00000398UL
+#define CKM_SHA3_384_KEY_DERIVE 0x00000399UL
+#define CKM_SHA3_512_KEY_DERIVE 0x0000039AUL
+#define CKM_SHAKE_128_KEY_DERIVE 0x0000039BUL
+#define CKM_SHAKE_256_KEY_DERIVE 0x0000039CUL
+
+#define CKM_PBE_MD2_DES_CBC 0x000003A0UL
+#define CKM_PBE_MD5_DES_CBC 0x000003A1UL
+#define CKM_PBE_MD5_CAST_CBC 0x000003A2UL
+#define CKM_PBE_MD5_CAST3_CBC 0x000003A3UL
+#define CKM_PBE_MD5_CAST5_CBC 0x000003A4UL /* Deprecated */
+#define CKM_PBE_MD5_CAST128_CBC 0x000003A4UL
+#define CKM_PBE_SHA1_CAST5_CBC 0x000003A5UL /* Deprecated */
+#define CKM_PBE_SHA1_CAST128_CBC 0x000003A5UL
+#define CKM_PBE_SHA1_RC4_128 0x000003A6UL
+#define CKM_PBE_SHA1_RC4_40 0x000003A7UL
+#define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8UL
+#define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9UL
+#define CKM_PBE_SHA1_RC2_128_CBC 0x000003AAUL
+#define CKM_PBE_SHA1_RC2_40_CBC 0x000003ABUL
+
+#define CKM_PKCS5_PBKD2 0x000003B0UL
+
+#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0UL
+
+#define CKM_WTLS_PRE_MASTER_KEY_GEN 0x000003D0UL
+#define CKM_WTLS_MASTER_KEY_DERIVE 0x000003D1UL
+#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC 0x000003D2UL
+#define CKM_WTLS_PRF 0x000003D3UL
+#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE 0x000003D4UL
+#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE 0x000003D5UL
+
+#define CKM_TLS10_MAC_SERVER 0x000003D6UL
+#define CKM_TLS10_MAC_CLIENT 0x000003D7UL
+#define CKM_TLS12_MAC 0x000003D8UL
+#define CKM_TLS12_KDF 0x000003D9UL
+#define CKM_TLS12_MASTER_KEY_DERIVE 0x000003E0UL
+#define CKM_TLS12_KEY_AND_MAC_DERIVE 0x000003E1UL
+#define CKM_TLS12_MASTER_KEY_DERIVE_DH 0x000003E2UL
+#define CKM_TLS12_KEY_SAFE_DERIVE 0x000003E3UL
+#define CKM_TLS_MAC 0x000003E4UL
+#define CKM_TLS_KDF 0x000003E5UL
+
+#define CKM_KEY_WRAP_LYNKS 0x00000400UL
+#define CKM_KEY_WRAP_SET_OAEP 0x00000401UL
+
+#define CKM_CMS_SIG 0x00000500UL
+#define CKM_KIP_DERIVE 0x00000510UL
+#define CKM_KIP_WRAP 0x00000511UL
+#define CKM_KIP_MAC 0x00000512UL
+
+#define CKM_CAMELLIA_KEY_GEN 0x00000550UL
+#define CKM_CAMELLIA_ECB 0x00000551UL
+#define CKM_CAMELLIA_CBC 0x00000552UL
+#define CKM_CAMELLIA_MAC 0x00000553UL
+#define CKM_CAMELLIA_MAC_GENERAL 0x00000554UL
+#define CKM_CAMELLIA_CBC_PAD 0x00000555UL
+#define CKM_CAMELLIA_ECB_ENCRYPT_DATA 0x00000556UL
+#define CKM_CAMELLIA_CBC_ENCRYPT_DATA 0x00000557UL
+#define CKM_CAMELLIA_CTR 0x00000558UL
+
+#define CKM_ARIA_KEY_GEN 0x00000560UL
+#define CKM_ARIA_ECB 0x00000561UL
+#define CKM_ARIA_CBC 0x00000562UL
+#define CKM_ARIA_MAC 0x00000563UL
+#define CKM_ARIA_MAC_GENERAL 0x00000564UL
+#define CKM_ARIA_CBC_PAD 0x00000565UL
+#define CKM_ARIA_ECB_ENCRYPT_DATA 0x00000566UL
+#define CKM_ARIA_CBC_ENCRYPT_DATA 0x00000567UL
+
+#define CKM_SEED_KEY_GEN 0x00000650UL
+#define CKM_SEED_ECB 0x00000651UL
+#define CKM_SEED_CBC 0x00000652UL
+#define CKM_SEED_MAC 0x00000653UL
+#define CKM_SEED_MAC_GENERAL 0x00000654UL
+#define CKM_SEED_CBC_PAD 0x00000655UL
+#define CKM_SEED_ECB_ENCRYPT_DATA 0x00000656UL
+#define CKM_SEED_CBC_ENCRYPT_DATA 0x00000657UL
+
+#define CKM_SKIPJACK_KEY_GEN 0x00001000UL
+#define CKM_SKIPJACK_ECB64 0x00001001UL
+#define CKM_SKIPJACK_CBC64 0x00001002UL
+#define CKM_SKIPJACK_OFB64 0x00001003UL
+#define CKM_SKIPJACK_CFB64 0x00001004UL
+#define CKM_SKIPJACK_CFB32 0x00001005UL
+#define CKM_SKIPJACK_CFB16 0x00001006UL
+#define CKM_SKIPJACK_CFB8 0x00001007UL
+#define CKM_SKIPJACK_WRAP 0x00001008UL
+#define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009UL
+#define CKM_SKIPJACK_RELAYX 0x0000100aUL
+#define CKM_KEA_KEY_PAIR_GEN 0x00001010UL
+#define CKM_KEA_KEY_DERIVE 0x00001011UL
+#define CKM_KEA_DERIVE 0x00001012UL
+#define CKM_FORTEZZA_TIMESTAMP 0x00001020UL
+#define CKM_BATON_KEY_GEN 0x00001030UL
+#define CKM_BATON_ECB128 0x00001031UL
+#define CKM_BATON_ECB96 0x00001032UL
+#define CKM_BATON_CBC128 0x00001033UL
+#define CKM_BATON_COUNTER 0x00001034UL
+#define CKM_BATON_SHUFFLE 0x00001035UL
+#define CKM_BATON_WRAP 0x00001036UL
+
+#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040UL /* Deprecated */
+#define CKM_EC_KEY_PAIR_GEN 0x00001040UL
+
+#define CKM_ECDSA 0x00001041UL
+#define CKM_ECDSA_SHA1 0x00001042UL
+#define CKM_ECDSA_SHA224 0x00001043UL
+#define CKM_ECDSA_SHA256 0x00001044UL
+#define CKM_ECDSA_SHA384 0x00001045UL
+#define CKM_ECDSA_SHA512 0x00001046UL
+
+#define CKM_ECDH1_DERIVE 0x00001050UL
+#define CKM_ECDH1_COFACTOR_DERIVE 0x00001051UL
+#define CKM_ECMQV_DERIVE 0x00001052UL
+
+#define CKM_ECDH_AES_KEY_WRAP 0x00001053UL
+#define CKM_RSA_AES_KEY_WRAP 0x00001054UL
+
+#define CKM_JUNIPER_KEY_GEN 0x00001060UL
+#define CKM_JUNIPER_ECB128 0x00001061UL
+#define CKM_JUNIPER_CBC128 0x00001062UL
+#define CKM_JUNIPER_COUNTER 0x00001063UL
+#define CKM_JUNIPER_SHUFFLE 0x00001064UL
+#define CKM_JUNIPER_WRAP 0x00001065UL
+#define CKM_FASTHASH 0x00001070UL
+
+#define CKM_AES_KEY_GEN 0x00001080UL
+#define CKM_AES_ECB 0x00001081UL
+#define CKM_AES_CBC 0x00001082UL
+#define CKM_AES_MAC 0x00001083UL
+#define CKM_AES_MAC_GENERAL 0x00001084UL
+#define CKM_AES_CBC_PAD 0x00001085UL
+#define CKM_AES_CTR 0x00001086UL
+#define CKM_AES_GCM 0x00001087UL
+#define CKM_AES_CCM 0x00001088UL
+#define CKM_AES_CTS 0x00001089UL
+#define CKM_AES_CMAC 0x0000108AUL
+#define CKM_AES_CMAC_GENERAL 0x0000108BUL
+
+#define CKM_AES_XCBC_MAC 0x0000108CUL
+#define CKM_AES_XCBC_MAC_96 0x0000108DUL
+#define CKM_AES_GMAC 0x0000108EUL
+
+#define CKM_BLOWFISH_KEY_GEN 0x00001090UL
+#define CKM_BLOWFISH_CBC 0x00001091UL
+#define CKM_TWOFISH_KEY_GEN 0x00001092UL
+#define CKM_TWOFISH_CBC 0x00001093UL
+#define CKM_BLOWFISH_CBC_PAD 0x00001094UL
+#define CKM_TWOFISH_CBC_PAD 0x00001095UL
+
+#define CKM_DES_ECB_ENCRYPT_DATA 0x00001100UL
+#define CKM_DES_CBC_ENCRYPT_DATA 0x00001101UL
+#define CKM_DES3_ECB_ENCRYPT_DATA 0x00001102UL
+#define CKM_DES3_CBC_ENCRYPT_DATA 0x00001103UL
+#define CKM_AES_ECB_ENCRYPT_DATA 0x00001104UL
+#define CKM_AES_CBC_ENCRYPT_DATA 0x00001105UL
+
+#define CKM_GOSTR3410_KEY_PAIR_GEN 0x00001200UL
+#define CKM_GOSTR3410 0x00001201UL
+#define CKM_GOSTR3410_WITH_GOSTR3411 0x00001202UL
+#define CKM_GOSTR3410_KEY_WRAP 0x00001203UL
+#define CKM_GOSTR3410_DERIVE 0x00001204UL
+#define CKM_GOSTR3411 0x00001210UL
+#define CKM_GOSTR3411_HMAC 0x00001211UL
+#define CKM_GOST28147_KEY_GEN 0x00001220UL
+#define CKM_GOST28147_ECB 0x00001221UL
+#define CKM_GOST28147 0x00001222UL
+#define CKM_GOST28147_MAC 0x00001223UL
+#define CKM_GOST28147_KEY_WRAP 0x00001224UL
+
+#define CKM_DSA_PARAMETER_GEN 0x00002000UL
+#define CKM_DH_PKCS_PARAMETER_GEN 0x00002001UL
+#define CKM_X9_42_DH_PARAMETER_GEN 0x00002002UL
+#define CKM_DSA_PROBABLISTIC_PARAMETER_GEN 0x00002003UL
+#define CKM_DSA_SHAWE_TAYLOR_PARAMETER_GEN 0x00002004UL
+
+#define CKM_AES_OFB 0x00002104UL
+#define CKM_AES_CFB64 0x00002105UL
+#define CKM_AES_CFB8 0x00002106UL
+#define CKM_AES_CFB128 0x00002107UL
+
+#define CKM_AES_CFB1 0x00002108UL
+#define CKM_AES_KEY_WRAP 0x00002109UL /* WAS: 0x00001090 */
+#define CKM_AES_KEY_WRAP_PAD 0x0000210AUL /* WAS: 0x00001091 */
+
+#define CKM_RSA_PKCS_TPM_1_1 0x00004001UL
+#define CKM_RSA_PKCS_OAEP_TPM_1_1 0x00004002UL
+
+#define CKM_VENDOR_DEFINED 0x80000000UL
+
+typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
+
+
+/* CK_MECHANISM is a structure that specifies a particular
+ * mechanism
+ */
+typedef struct CK_MECHANISM {
+ CK_MECHANISM_TYPE mechanism;
+ CK_VOID_PTR pParameter;
+ CK_ULONG ulParameterLen; /* in bytes */
+} CK_MECHANISM;
+
+typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR;
+
+
+/* CK_MECHANISM_INFO provides information about a particular
+ * mechanism
+ */
+typedef struct CK_MECHANISM_INFO {
+ CK_ULONG ulMinKeySize;
+ CK_ULONG ulMaxKeySize;
+ CK_FLAGS flags;
+} CK_MECHANISM_INFO;
+
+/* The flags are defined as follows:
+ * Bit Flag Mask Meaning */
+#define CKF_HW 0x00000001UL /* performed by HW */
+
+/* Specify whether or not a mechanism can be used for a particular task */
+#define CKF_ENCRYPT 0x00000100UL
+#define CKF_DECRYPT 0x00000200UL
+#define CKF_DIGEST 0x00000400UL
+#define CKF_SIGN 0x00000800UL
+#define CKF_SIGN_RECOVER 0x00001000UL
+#define CKF_VERIFY 0x00002000UL
+#define CKF_VERIFY_RECOVER 0x00004000UL
+#define CKF_GENERATE 0x00008000UL
+#define CKF_GENERATE_KEY_PAIR 0x00010000UL
+#define CKF_WRAP 0x00020000UL
+#define CKF_UNWRAP 0x00040000UL
+#define CKF_DERIVE 0x00080000UL
+
+/* Describe a token's EC capabilities not available in mechanism
+ * information.
+ */
+#define CKF_EC_F_P 0x00100000UL
+#define CKF_EC_F_2M 0x00200000UL
+#define CKF_EC_ECPARAMETERS 0x00400000UL
+#define CKF_EC_NAMEDCURVE 0x00800000UL
+#define CKF_EC_UNCOMPRESS 0x01000000UL
+#define CKF_EC_COMPRESS 0x02000000UL
+
+#define CKF_EXTENSION 0x80000000UL
+
+typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
+
+/* CK_RV is a value that identifies the return value of a
+ * Cryptoki function
+ */
+typedef CK_ULONG CK_RV;
+
+#define CKR_OK 0x00000000UL
+#define CKR_CANCEL 0x00000001UL
+#define CKR_HOST_MEMORY 0x00000002UL
+#define CKR_SLOT_ID_INVALID 0x00000003UL
+
+#define CKR_GENERAL_ERROR 0x00000005UL
+#define CKR_FUNCTION_FAILED 0x00000006UL
+
+#define CKR_ARGUMENTS_BAD 0x00000007UL
+#define CKR_NO_EVENT 0x00000008UL
+#define CKR_NEED_TO_CREATE_THREADS 0x00000009UL
+#define CKR_CANT_LOCK 0x0000000AUL
+
+#define CKR_ATTRIBUTE_READ_ONLY 0x00000010UL
+#define CKR_ATTRIBUTE_SENSITIVE 0x00000011UL
+#define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012UL
+#define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013UL
+
+#define CKR_ACTION_PROHIBITED 0x0000001BUL
+
+#define CKR_DATA_INVALID 0x00000020UL
+#define CKR_DATA_LEN_RANGE 0x00000021UL
+#define CKR_DEVICE_ERROR 0x00000030UL
+#define CKR_DEVICE_MEMORY 0x00000031UL
+#define CKR_DEVICE_REMOVED 0x00000032UL
+#define CKR_ENCRYPTED_DATA_INVALID 0x00000040UL
+#define CKR_ENCRYPTED_DATA_LEN_RANGE 0x00000041UL
+#define CKR_FUNCTION_CANCELED 0x00000050UL
+#define CKR_FUNCTION_NOT_PARALLEL 0x00000051UL
+
+#define CKR_FUNCTION_NOT_SUPPORTED 0x00000054UL
+
+#define CKR_KEY_HANDLE_INVALID 0x00000060UL
+
+#define CKR_KEY_SIZE_RANGE 0x00000062UL
+#define CKR_KEY_TYPE_INCONSISTENT 0x00000063UL
+
+#define CKR_KEY_NOT_NEEDED 0x00000064UL
+#define CKR_KEY_CHANGED 0x00000065UL
+#define CKR_KEY_NEEDED 0x00000066UL
+#define CKR_KEY_INDIGESTIBLE 0x00000067UL
+#define CKR_KEY_FUNCTION_NOT_PERMITTED 0x00000068UL
+#define CKR_KEY_NOT_WRAPPABLE 0x00000069UL
+#define CKR_KEY_UNEXTRACTABLE 0x0000006AUL
+
+#define CKR_MECHANISM_INVALID 0x00000070UL
+#define CKR_MECHANISM_PARAM_INVALID 0x00000071UL
+
+#define CKR_OBJECT_HANDLE_INVALID 0x00000082UL
+#define CKR_OPERATION_ACTIVE 0x00000090UL
+#define CKR_OPERATION_NOT_INITIALIZED 0x00000091UL
+#define CKR_PIN_INCORRECT 0x000000A0UL
+#define CKR_PIN_INVALID 0x000000A1UL
+#define CKR_PIN_LEN_RANGE 0x000000A2UL
+
+#define CKR_PIN_EXPIRED 0x000000A3UL
+#define CKR_PIN_LOCKED 0x000000A4UL
+
+#define CKR_SESSION_CLOSED 0x000000B0UL
+#define CKR_SESSION_COUNT 0x000000B1UL
+#define CKR_SESSION_HANDLE_INVALID 0x000000B3UL
+#define CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x000000B4UL
+#define CKR_SESSION_READ_ONLY 0x000000B5UL
+#define CKR_SESSION_EXISTS 0x000000B6UL
+
+#define CKR_SESSION_READ_ONLY_EXISTS 0x000000B7UL
+#define CKR_SESSION_READ_WRITE_SO_EXISTS 0x000000B8UL
+
+#define CKR_SIGNATURE_INVALID 0x000000C0UL
+#define CKR_SIGNATURE_LEN_RANGE 0x000000C1UL
+#define CKR_TEMPLATE_INCOMPLETE 0x000000D0UL
+#define CKR_TEMPLATE_INCONSISTENT 0x000000D1UL
+#define CKR_TOKEN_NOT_PRESENT 0x000000E0UL
+#define CKR_TOKEN_NOT_RECOGNIZED 0x000000E1UL
+#define CKR_TOKEN_WRITE_PROTECTED 0x000000E2UL
+#define CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x000000F0UL
+#define CKR_UNWRAPPING_KEY_SIZE_RANGE 0x000000F1UL
+#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x000000F2UL
+#define CKR_USER_ALREADY_LOGGED_IN 0x00000100UL
+#define CKR_USER_NOT_LOGGED_IN 0x00000101UL
+#define CKR_USER_PIN_NOT_INITIALIZED 0x00000102UL
+#define CKR_USER_TYPE_INVALID 0x00000103UL
+
+#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x00000104UL
+#define CKR_USER_TOO_MANY_TYPES 0x00000105UL
+
+#define CKR_WRAPPED_KEY_INVALID 0x00000110UL
+#define CKR_WRAPPED_KEY_LEN_RANGE 0x00000112UL
+#define CKR_WRAPPING_KEY_HANDLE_INVALID 0x00000113UL
+#define CKR_WRAPPING_KEY_SIZE_RANGE 0x00000114UL
+#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115UL
+#define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120UL
+
+#define CKR_RANDOM_NO_RNG 0x00000121UL
+
+#define CKR_DOMAIN_PARAMS_INVALID 0x00000130UL
+
+#define CKR_CURVE_NOT_SUPPORTED 0x00000140UL
+
+#define CKR_BUFFER_TOO_SMALL 0x00000150UL
+#define CKR_SAVED_STATE_INVALID 0x00000160UL
+#define CKR_INFORMATION_SENSITIVE 0x00000170UL
+#define CKR_STATE_UNSAVEABLE 0x00000180UL
+
+#define CKR_CRYPTOKI_NOT_INITIALIZED 0x00000190UL
+#define CKR_CRYPTOKI_ALREADY_INITIALIZED 0x00000191UL
+#define CKR_MUTEX_BAD 0x000001A0UL
+#define CKR_MUTEX_NOT_LOCKED 0x000001A1UL
+
+#define CKR_NEW_PIN_MODE 0x000001B0UL
+#define CKR_NEXT_OTP 0x000001B1UL
+
+#define CKR_EXCEEDED_MAX_ITERATIONS 0x000001B5UL
+#define CKR_FIPS_SELF_TEST_FAILED 0x000001B6UL
+#define CKR_LIBRARY_LOAD_FAILED 0x000001B7UL
+#define CKR_PIN_TOO_WEAK 0x000001B8UL
+#define CKR_PUBLIC_KEY_INVALID 0x000001B9UL
+
+#define CKR_FUNCTION_REJECTED 0x00000200UL
+
+#define CKR_VENDOR_DEFINED 0x80000000UL
+
+
+/* CK_NOTIFY is an application callback that processes events */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_NOTIFICATION event,
+ CK_VOID_PTR pApplication /* passed to C_OpenSession */
+);
+
+
+/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec
+ * version and pointers of appropriate types to all the
+ * Cryptoki functions
+ */
+typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST;
+
+typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR;
+
+typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR;
+
+
+/* CK_CREATEMUTEX is an application callback for creating a
+ * mutex object
+ */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)(
+ CK_VOID_PTR_PTR ppMutex /* location to receive ptr to mutex */
+);
+
+
+/* CK_DESTROYMUTEX is an application callback for destroying a
+ * mutex object
+ */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)(
+ CK_VOID_PTR pMutex /* pointer to mutex */
+);
+
+
+/* CK_LOCKMUTEX is an application callback for locking a mutex */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)(
+ CK_VOID_PTR pMutex /* pointer to mutex */
+);
+
+
+/* CK_UNLOCKMUTEX is an application callback for unlocking a
+ * mutex
+ */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)(
+ CK_VOID_PTR pMutex /* pointer to mutex */
+);
+
+
+/* CK_C_INITIALIZE_ARGS provides the optional arguments to
+ * C_Initialize
+ */
+typedef struct CK_C_INITIALIZE_ARGS {
+ CK_CREATEMUTEX CreateMutex;
+ CK_DESTROYMUTEX DestroyMutex;
+ CK_LOCKMUTEX LockMutex;
+ CK_UNLOCKMUTEX UnlockMutex;
+ CK_FLAGS flags;
+ CK_VOID_PTR pReserved;
+} CK_C_INITIALIZE_ARGS;
+
+/* flags: bit flags that provide capabilities of the slot
+ * Bit Flag Mask Meaning
+ */
+#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001UL
+#define CKF_OS_LOCKING_OK 0x00000002UL
+
+typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
+
+
+/* additional flags for parameters to functions */
+
+/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
+#define CKF_DONT_BLOCK 1
+
+/* CK_RSA_PKCS_MGF_TYPE is used to indicate the Message
+ * Generation Function (MGF) applied to a message block when
+ * formatting a message block for the PKCS #1 OAEP encryption
+ * scheme.
+ */
+typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE;
+
+typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR;
+
+/* The following MGFs are defined */
+#define CKG_MGF1_SHA1 0x00000001UL
+#define CKG_MGF1_SHA256 0x00000002UL
+#define CKG_MGF1_SHA384 0x00000003UL
+#define CKG_MGF1_SHA512 0x00000004UL
+#define CKG_MGF1_SHA224 0x00000005UL
+
+/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is used to indicate the source
+ * of the encoding parameter when formatting a message block
+ * for the PKCS #1 OAEP encryption scheme.
+ */
+typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE;
+
+typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR;
+
+/* The following encoding parameter sources are defined */
+#define CKZ_DATA_SPECIFIED 0x00000001UL
+
+/* CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
+ * CKM_RSA_PKCS_OAEP mechanism.
+ */
+typedef struct CK_RSA_PKCS_OAEP_PARAMS {
+ CK_MECHANISM_TYPE hashAlg;
+ CK_RSA_PKCS_MGF_TYPE mgf;
+ CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
+ CK_VOID_PTR pSourceData;
+ CK_ULONG ulSourceDataLen;
+} CK_RSA_PKCS_OAEP_PARAMS;
+
+typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR;
+
+/* CK_RSA_PKCS_PSS_PARAMS provides the parameters to the
+ * CKM_RSA_PKCS_PSS mechanism(s).
+ */
+typedef struct CK_RSA_PKCS_PSS_PARAMS {
+ CK_MECHANISM_TYPE hashAlg;
+ CK_RSA_PKCS_MGF_TYPE mgf;
+ CK_ULONG sLen;
+} CK_RSA_PKCS_PSS_PARAMS;
+
+typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR;
+
+typedef CK_ULONG CK_EC_KDF_TYPE;
+
+/* The following EC Key Derivation Functions are defined */
+#define CKD_NULL 0x00000001UL
+#define CKD_SHA1_KDF 0x00000002UL
+
+/* The following X9.42 DH key derivation functions are defined */
+#define CKD_SHA1_KDF_ASN1 0x00000003UL
+#define CKD_SHA1_KDF_CONCATENATE 0x00000004UL
+#define CKD_SHA224_KDF 0x00000005UL
+#define CKD_SHA256_KDF 0x00000006UL
+#define CKD_SHA384_KDF 0x00000007UL
+#define CKD_SHA512_KDF 0x00000008UL
+#define CKD_CPDIVERSIFY_KDF 0x00000009UL
+#define CKD_SHA3_224_KDF 0x0000000AUL
+#define CKD_SHA3_256_KDF 0x0000000BUL
+#define CKD_SHA3_384_KDF 0x0000000CUL
+#define CKD_SHA3_512_KDF 0x0000000DUL
+
+/* CK_ECDH1_DERIVE_PARAMS provides the parameters to the
+ * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms,
+ * where each party contributes one key pair.
+ */
+typedef struct CK_ECDH1_DERIVE_PARAMS {
+ CK_EC_KDF_TYPE kdf;
+ CK_ULONG ulSharedDataLen;
+ CK_BYTE_PTR pSharedData;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+} CK_ECDH1_DERIVE_PARAMS;
+
+typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR;
+
+/*
+ * CK_ECDH2_DERIVE_PARAMS provides the parameters to the
+ * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs.
+ */
+typedef struct CK_ECDH2_DERIVE_PARAMS {
+ CK_EC_KDF_TYPE kdf;
+ CK_ULONG ulSharedDataLen;
+ CK_BYTE_PTR pSharedData;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+ CK_ULONG ulPrivateDataLen;
+ CK_OBJECT_HANDLE hPrivateData;
+ CK_ULONG ulPublicDataLen2;
+ CK_BYTE_PTR pPublicData2;
+} CK_ECDH2_DERIVE_PARAMS;
+
+typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR;
+
+typedef struct CK_ECMQV_DERIVE_PARAMS {
+ CK_EC_KDF_TYPE kdf;
+ CK_ULONG ulSharedDataLen;
+ CK_BYTE_PTR pSharedData;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+ CK_ULONG ulPrivateDataLen;
+ CK_OBJECT_HANDLE hPrivateData;
+ CK_ULONG ulPublicDataLen2;
+ CK_BYTE_PTR pPublicData2;
+ CK_OBJECT_HANDLE publicKey;
+} CK_ECMQV_DERIVE_PARAMS;
+
+typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR;
+
+/* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the
+ * CKM_X9_42_DH_PARAMETER_GEN mechanisms
+ */
+typedef CK_ULONG CK_X9_42_DH_KDF_TYPE;
+typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR;
+
+/* CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the
+ * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party
+ * contributes one key pair
+ */
+typedef struct CK_X9_42_DH1_DERIVE_PARAMS {
+ CK_X9_42_DH_KDF_TYPE kdf;
+ CK_ULONG ulOtherInfoLen;
+ CK_BYTE_PTR pOtherInfo;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+} CK_X9_42_DH1_DERIVE_PARAMS;
+
+typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR;
+
+/* CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the
+ * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation
+ * mechanisms, where each party contributes two key pairs
+ */
+typedef struct CK_X9_42_DH2_DERIVE_PARAMS {
+ CK_X9_42_DH_KDF_TYPE kdf;
+ CK_ULONG ulOtherInfoLen;
+ CK_BYTE_PTR pOtherInfo;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+ CK_ULONG ulPrivateDataLen;
+ CK_OBJECT_HANDLE hPrivateData;
+ CK_ULONG ulPublicDataLen2;
+ CK_BYTE_PTR pPublicData2;
+} CK_X9_42_DH2_DERIVE_PARAMS;
+
+typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR;
+
+typedef struct CK_X9_42_MQV_DERIVE_PARAMS {
+ CK_X9_42_DH_KDF_TYPE kdf;
+ CK_ULONG ulOtherInfoLen;
+ CK_BYTE_PTR pOtherInfo;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+ CK_ULONG ulPrivateDataLen;
+ CK_OBJECT_HANDLE hPrivateData;
+ CK_ULONG ulPublicDataLen2;
+ CK_BYTE_PTR pPublicData2;
+ CK_OBJECT_HANDLE publicKey;
+} CK_X9_42_MQV_DERIVE_PARAMS;
+
+typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR;
+
+/* CK_KEA_DERIVE_PARAMS provides the parameters to the
+ * CKM_KEA_DERIVE mechanism
+ */
+typedef struct CK_KEA_DERIVE_PARAMS {
+ CK_BBOOL isSender;
+ CK_ULONG ulRandomLen;
+ CK_BYTE_PTR pRandomA;
+ CK_BYTE_PTR pRandomB;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+} CK_KEA_DERIVE_PARAMS;
+
+typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
+
+
+/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
+ * CKM_RC2_MAC mechanisms. An instance of CK_RC2_PARAMS just
+ * holds the effective keysize
+ */
+typedef CK_ULONG CK_RC2_PARAMS;
+
+typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
+
+
+/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
+ * mechanism
+ */
+typedef struct CK_RC2_CBC_PARAMS {
+ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
+ CK_BYTE iv[8]; /* IV for CBC mode */
+} CK_RC2_CBC_PARAMS;
+
+typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
+
+
+/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
+ * CKM_RC2_MAC_GENERAL mechanism
+ */
+typedef struct CK_RC2_MAC_GENERAL_PARAMS {
+ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
+ CK_ULONG ulMacLength; /* Length of MAC in bytes */
+} CK_RC2_MAC_GENERAL_PARAMS;
+
+typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
+ CK_RC2_MAC_GENERAL_PARAMS_PTR;
+
+
+/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
+ * CKM_RC5_MAC mechanisms
+ */
+typedef struct CK_RC5_PARAMS {
+ CK_ULONG ulWordsize; /* wordsize in bits */
+ CK_ULONG ulRounds; /* number of rounds */
+} CK_RC5_PARAMS;
+
+typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
+
+
+/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
+ * mechanism
+ */
+typedef struct CK_RC5_CBC_PARAMS {
+ CK_ULONG ulWordsize; /* wordsize in bits */
+ CK_ULONG ulRounds; /* number of rounds */
+ CK_BYTE_PTR pIv; /* pointer to IV */
+ CK_ULONG ulIvLen; /* length of IV in bytes */
+} CK_RC5_CBC_PARAMS;
+
+typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
+
+
+/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
+ * CKM_RC5_MAC_GENERAL mechanism
+ */
+typedef struct CK_RC5_MAC_GENERAL_PARAMS {
+ CK_ULONG ulWordsize; /* wordsize in bits */
+ CK_ULONG ulRounds; /* number of rounds */
+ CK_ULONG ulMacLength; /* Length of MAC in bytes */
+} CK_RC5_MAC_GENERAL_PARAMS;
+
+typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
+ CK_RC5_MAC_GENERAL_PARAMS_PTR;
+
+/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
+ * ciphers' MAC_GENERAL mechanisms. Its value is the length of
+ * the MAC
+ */
+typedef CK_ULONG CK_MAC_GENERAL_PARAMS;
+
+typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
+
+typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS {
+ CK_BYTE iv[8];
+ CK_BYTE_PTR pData;
+ CK_ULONG length;
+} CK_DES_CBC_ENCRYPT_DATA_PARAMS;
+
+typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR;
+
+typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS {
+ CK_BYTE iv[16];
+ CK_BYTE_PTR pData;
+ CK_ULONG length;
+} CK_AES_CBC_ENCRYPT_DATA_PARAMS;
+
+typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR;
+
+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
+ * CKM_SKIPJACK_PRIVATE_WRAP mechanism
+ */
+typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
+ CK_ULONG ulPasswordLen;
+ CK_BYTE_PTR pPassword;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+ CK_ULONG ulPAndGLen;
+ CK_ULONG ulQLen;
+ CK_ULONG ulRandomLen;
+ CK_BYTE_PTR pRandomA;
+ CK_BYTE_PTR pPrimeP;
+ CK_BYTE_PTR pBaseG;
+ CK_BYTE_PTR pSubprimeQ;
+} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
+
+typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
+ CK_SKIPJACK_PRIVATE_WRAP_PARAMS_PTR;
+
+
+/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
+ * CKM_SKIPJACK_RELAYX mechanism
+ */
+typedef struct CK_SKIPJACK_RELAYX_PARAMS {
+ CK_ULONG ulOldWrappedXLen;
+ CK_BYTE_PTR pOldWrappedX;
+ CK_ULONG ulOldPasswordLen;
+ CK_BYTE_PTR pOldPassword;
+ CK_ULONG ulOldPublicDataLen;
+ CK_BYTE_PTR pOldPublicData;
+ CK_ULONG ulOldRandomLen;
+ CK_BYTE_PTR pOldRandomA;
+ CK_ULONG ulNewPasswordLen;
+ CK_BYTE_PTR pNewPassword;
+ CK_ULONG ulNewPublicDataLen;
+ CK_BYTE_PTR pNewPublicData;
+ CK_ULONG ulNewRandomLen;
+ CK_BYTE_PTR pNewRandomA;
+} CK_SKIPJACK_RELAYX_PARAMS;
+
+typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
+ CK_SKIPJACK_RELAYX_PARAMS_PTR;
+
+
+typedef struct CK_PBE_PARAMS {
+ CK_BYTE_PTR pInitVector;
+ CK_UTF8CHAR_PTR pPassword;
+ CK_ULONG ulPasswordLen;
+ CK_BYTE_PTR pSalt;
+ CK_ULONG ulSaltLen;
+ CK_ULONG ulIteration;
+} CK_PBE_PARAMS;
+
+typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
+
+
+/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
+ * CKM_KEY_WRAP_SET_OAEP mechanism
+ */
+typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
+ CK_BYTE bBC; /* block contents byte */
+ CK_BYTE_PTR pX; /* extra data */
+ CK_ULONG ulXLen; /* length of extra data in bytes */
+} CK_KEY_WRAP_SET_OAEP_PARAMS;
+
+typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
+
+typedef struct CK_SSL3_RANDOM_DATA {
+ CK_BYTE_PTR pClientRandom;
+ CK_ULONG ulClientRandomLen;
+ CK_BYTE_PTR pServerRandom;
+ CK_ULONG ulServerRandomLen;
+} CK_SSL3_RANDOM_DATA;
+
+
+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
+ CK_SSL3_RANDOM_DATA RandomInfo;
+ CK_VERSION_PTR pVersion;
+} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
+
+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
+ CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
+
+typedef struct CK_SSL3_KEY_MAT_OUT {
+ CK_OBJECT_HANDLE hClientMacSecret;
+ CK_OBJECT_HANDLE hServerMacSecret;
+ CK_OBJECT_HANDLE hClientKey;
+ CK_OBJECT_HANDLE hServerKey;
+ CK_BYTE_PTR pIVClient;
+ CK_BYTE_PTR pIVServer;
+} CK_SSL3_KEY_MAT_OUT;
+
+typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
+
+
+typedef struct CK_SSL3_KEY_MAT_PARAMS {
+ CK_ULONG ulMacSizeInBits;
+ CK_ULONG ulKeySizeInBits;
+ CK_ULONG ulIVSizeInBits;
+ CK_BBOOL bIsExport;
+ CK_SSL3_RANDOM_DATA RandomInfo;
+ CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
+} CK_SSL3_KEY_MAT_PARAMS;
+
+typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
+
+typedef struct CK_TLS_PRF_PARAMS {
+ CK_BYTE_PTR pSeed;
+ CK_ULONG ulSeedLen;
+ CK_BYTE_PTR pLabel;
+ CK_ULONG ulLabelLen;
+ CK_BYTE_PTR pOutput;
+ CK_ULONG_PTR pulOutputLen;
+} CK_TLS_PRF_PARAMS;
+
+typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR;
+
+typedef struct CK_WTLS_RANDOM_DATA {
+ CK_BYTE_PTR pClientRandom;
+ CK_ULONG ulClientRandomLen;
+ CK_BYTE_PTR pServerRandom;
+ CK_ULONG ulServerRandomLen;
+} CK_WTLS_RANDOM_DATA;
+
+typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR;
+
+typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS {
+ CK_MECHANISM_TYPE DigestMechanism;
+ CK_WTLS_RANDOM_DATA RandomInfo;
+ CK_BYTE_PTR pVersion;
+} CK_WTLS_MASTER_KEY_DERIVE_PARAMS;
+
+typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \
+ CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR;
+
+typedef struct CK_WTLS_PRF_PARAMS {
+ CK_MECHANISM_TYPE DigestMechanism;
+ CK_BYTE_PTR pSeed;
+ CK_ULONG ulSeedLen;
+ CK_BYTE_PTR pLabel;
+ CK_ULONG ulLabelLen;
+ CK_BYTE_PTR pOutput;
+ CK_ULONG_PTR pulOutputLen;
+} CK_WTLS_PRF_PARAMS;
+
+typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR;
+
+typedef struct CK_WTLS_KEY_MAT_OUT {
+ CK_OBJECT_HANDLE hMacSecret;
+ CK_OBJECT_HANDLE hKey;
+ CK_BYTE_PTR pIV;
+} CK_WTLS_KEY_MAT_OUT;
+
+typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR;
+
+typedef struct CK_WTLS_KEY_MAT_PARAMS {
+ CK_MECHANISM_TYPE DigestMechanism;
+ CK_ULONG ulMacSizeInBits;
+ CK_ULONG ulKeySizeInBits;
+ CK_ULONG ulIVSizeInBits;
+ CK_ULONG ulSequenceNumber;
+ CK_BBOOL bIsExport;
+ CK_WTLS_RANDOM_DATA RandomInfo;
+ CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
+} CK_WTLS_KEY_MAT_PARAMS;
+
+typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR;
+
+typedef struct CK_CMS_SIG_PARAMS {
+ CK_OBJECT_HANDLE certificateHandle;
+ CK_MECHANISM_PTR pSigningMechanism;
+ CK_MECHANISM_PTR pDigestMechanism;
+ CK_UTF8CHAR_PTR pContentType;
+ CK_BYTE_PTR pRequestedAttributes;
+ CK_ULONG ulRequestedAttributesLen;
+ CK_BYTE_PTR pRequiredAttributes;
+ CK_ULONG ulRequiredAttributesLen;
+} CK_CMS_SIG_PARAMS;
+
+typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR;
+
+typedef struct CK_KEY_DERIVATION_STRING_DATA {
+ CK_BYTE_PTR pData;
+ CK_ULONG ulLen;
+} CK_KEY_DERIVATION_STRING_DATA;
+
+typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
+ CK_KEY_DERIVATION_STRING_DATA_PTR;
+
+
+/* The CK_EXTRACT_PARAMS is used for the
+ * CKM_EXTRACT_KEY_FROM_KEY mechanism. It specifies which bit
+ * of the base key should be used as the first bit of the
+ * derived key
+ */
+typedef CK_ULONG CK_EXTRACT_PARAMS;
+
+typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
+
+/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
+ * indicate the Pseudo-Random Function (PRF) used to generate
+ * key bits using PKCS #5 PBKDF2.
+ */
+typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
+
+typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR \
+ CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR;
+
+#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001UL
+#define CKP_PKCS5_PBKD2_HMAC_GOSTR3411 0x00000002UL
+#define CKP_PKCS5_PBKD2_HMAC_SHA224 0x00000003UL
+#define CKP_PKCS5_PBKD2_HMAC_SHA256 0x00000004UL
+#define CKP_PKCS5_PBKD2_HMAC_SHA384 0x00000005UL
+#define CKP_PKCS5_PBKD2_HMAC_SHA512 0x00000006UL
+#define CKP_PKCS5_PBKD2_HMAC_SHA512_224 0x00000007UL
+#define CKP_PKCS5_PBKD2_HMAC_SHA512_256 0x00000008UL
+
+/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the
+ * source of the salt value when deriving a key using PKCS #5
+ * PBKDF2.
+ */
+typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
+
+typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR \
+ CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR;
+
+/* The following salt value sources are defined in PKCS #5 v2.0. */
+#define CKZ_SALT_SPECIFIED 0x00000001UL
+
+/* CK_PKCS5_PBKD2_PARAMS is a structure that provides the
+ * parameters to the CKM_PKCS5_PBKD2 mechanism.
+ */
+typedef struct CK_PKCS5_PBKD2_PARAMS {
+ CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource;
+ CK_VOID_PTR pSaltSourceData;
+ CK_ULONG ulSaltSourceDataLen;
+ CK_ULONG iterations;
+ CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
+ CK_VOID_PTR pPrfData;
+ CK_ULONG ulPrfDataLen;
+ CK_UTF8CHAR_PTR pPassword;
+ CK_ULONG_PTR ulPasswordLen;
+} CK_PKCS5_PBKD2_PARAMS;
+
+typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
+
+/* CK_PKCS5_PBKD2_PARAMS2 is a corrected version of the CK_PKCS5_PBKD2_PARAMS
+ * structure that provides the parameters to the CKM_PKCS5_PBKD2 mechanism
+ * noting that the ulPasswordLen field is a CK_ULONG and not a CK_ULONG_PTR.
+ */
+typedef struct CK_PKCS5_PBKD2_PARAMS2 {
+ CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource;
+ CK_VOID_PTR pSaltSourceData;
+ CK_ULONG ulSaltSourceDataLen;
+ CK_ULONG iterations;
+ CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
+ CK_VOID_PTR pPrfData;
+ CK_ULONG ulPrfDataLen;
+ CK_UTF8CHAR_PTR pPassword;
+ CK_ULONG ulPasswordLen;
+} CK_PKCS5_PBKD2_PARAMS2;
+
+typedef CK_PKCS5_PBKD2_PARAMS2 CK_PTR CK_PKCS5_PBKD2_PARAMS2_PTR;
+
+typedef CK_ULONG CK_OTP_PARAM_TYPE;
+typedef CK_OTP_PARAM_TYPE CK_PARAM_TYPE; /* backward compatibility */
+
+typedef struct CK_OTP_PARAM {
+ CK_OTP_PARAM_TYPE type;
+ CK_VOID_PTR pValue;
+ CK_ULONG ulValueLen;
+} CK_OTP_PARAM;
+
+typedef CK_OTP_PARAM CK_PTR CK_OTP_PARAM_PTR;
+
+typedef struct CK_OTP_PARAMS {
+ CK_OTP_PARAM_PTR pParams;
+ CK_ULONG ulCount;
+} CK_OTP_PARAMS;
+
+typedef CK_OTP_PARAMS CK_PTR CK_OTP_PARAMS_PTR;
+
+typedef struct CK_OTP_SIGNATURE_INFO {
+ CK_OTP_PARAM_PTR pParams;
+ CK_ULONG ulCount;
+} CK_OTP_SIGNATURE_INFO;
+
+typedef CK_OTP_SIGNATURE_INFO CK_PTR CK_OTP_SIGNATURE_INFO_PTR;
+
+#define CK_OTP_VALUE 0UL
+#define CK_OTP_PIN 1UL
+#define CK_OTP_CHALLENGE 2UL
+#define CK_OTP_TIME 3UL
+#define CK_OTP_COUNTER 4UL
+#define CK_OTP_FLAGS 5UL
+#define CK_OTP_OUTPUT_LENGTH 6UL
+#define CK_OTP_OUTPUT_FORMAT 7UL
+
+#define CKF_NEXT_OTP 0x00000001UL
+#define CKF_EXCLUDE_TIME 0x00000002UL
+#define CKF_EXCLUDE_COUNTER 0x00000004UL
+#define CKF_EXCLUDE_CHALLENGE 0x00000008UL
+#define CKF_EXCLUDE_PIN 0x00000010UL
+#define CKF_USER_FRIENDLY_OTP 0x00000020UL
+
+typedef struct CK_KIP_PARAMS {
+ CK_MECHANISM_PTR pMechanism;
+ CK_OBJECT_HANDLE hKey;
+ CK_BYTE_PTR pSeed;
+ CK_ULONG ulSeedLen;
+} CK_KIP_PARAMS;
+
+typedef CK_KIP_PARAMS CK_PTR CK_KIP_PARAMS_PTR;
+
+typedef struct CK_AES_CTR_PARAMS {
+ CK_ULONG ulCounterBits;
+ CK_BYTE cb[16];
+} CK_AES_CTR_PARAMS;
+
+typedef CK_AES_CTR_PARAMS CK_PTR CK_AES_CTR_PARAMS_PTR;
+
+typedef struct CK_GCM_PARAMS {
+ CK_BYTE_PTR pIv;
+ CK_ULONG ulIvLen;
+ CK_ULONG ulIvBits;
+ CK_BYTE_PTR pAAD;
+ CK_ULONG ulAADLen;
+ CK_ULONG ulTagBits;
+} CK_GCM_PARAMS;
+
+typedef CK_GCM_PARAMS CK_PTR CK_GCM_PARAMS_PTR;
+
+typedef struct CK_CCM_PARAMS {
+ CK_ULONG ulDataLen;
+ CK_BYTE_PTR pNonce;
+ CK_ULONG ulNonceLen;
+ CK_BYTE_PTR pAAD;
+ CK_ULONG ulAADLen;
+ CK_ULONG ulMACLen;
+} CK_CCM_PARAMS;
+
+typedef CK_CCM_PARAMS CK_PTR CK_CCM_PARAMS_PTR;
+
+/* Deprecated. Use CK_GCM_PARAMS */
+typedef struct CK_AES_GCM_PARAMS {
+ CK_BYTE_PTR pIv;
+ CK_ULONG ulIvLen;
+ CK_ULONG ulIvBits;
+ CK_BYTE_PTR pAAD;
+ CK_ULONG ulAADLen;
+ CK_ULONG ulTagBits;
+} CK_AES_GCM_PARAMS;
+
+typedef CK_AES_GCM_PARAMS CK_PTR CK_AES_GCM_PARAMS_PTR;
+
+/* Deprecated. Use CK_CCM_PARAMS */
+typedef struct CK_AES_CCM_PARAMS {
+ CK_ULONG ulDataLen;
+ CK_BYTE_PTR pNonce;
+ CK_ULONG ulNonceLen;
+ CK_BYTE_PTR pAAD;
+ CK_ULONG ulAADLen;
+ CK_ULONG ulMACLen;
+} CK_AES_CCM_PARAMS;
+
+typedef CK_AES_CCM_PARAMS CK_PTR CK_AES_CCM_PARAMS_PTR;
+
+typedef struct CK_CAMELLIA_CTR_PARAMS {
+ CK_ULONG ulCounterBits;
+ CK_BYTE cb[16];
+} CK_CAMELLIA_CTR_PARAMS;
+
+typedef CK_CAMELLIA_CTR_PARAMS CK_PTR CK_CAMELLIA_CTR_PARAMS_PTR;
+
+typedef struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS {
+ CK_BYTE iv[16];
+ CK_BYTE_PTR pData;
+ CK_ULONG length;
+} CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS;
+
+typedef CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR \
+ CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
+
+typedef struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS {
+ CK_BYTE iv[16];
+ CK_BYTE_PTR pData;
+ CK_ULONG length;
+} CK_ARIA_CBC_ENCRYPT_DATA_PARAMS;
+
+typedef CK_ARIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR \
+ CK_ARIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
+
+typedef struct CK_DSA_PARAMETER_GEN_PARAM {
+ CK_MECHANISM_TYPE hash;
+ CK_BYTE_PTR pSeed;
+ CK_ULONG ulSeedLen;
+ CK_ULONG ulIndex;
+} CK_DSA_PARAMETER_GEN_PARAM;
+
+typedef CK_DSA_PARAMETER_GEN_PARAM CK_PTR CK_DSA_PARAMETER_GEN_PARAM_PTR;
+
+typedef struct CK_ECDH_AES_KEY_WRAP_PARAMS {
+ CK_ULONG ulAESKeyBits;
+ CK_EC_KDF_TYPE kdf;
+ CK_ULONG ulSharedDataLen;
+ CK_BYTE_PTR pSharedData;
+} CK_ECDH_AES_KEY_WRAP_PARAMS;
+
+typedef CK_ECDH_AES_KEY_WRAP_PARAMS CK_PTR CK_ECDH_AES_KEY_WRAP_PARAMS_PTR;
+
+typedef CK_ULONG CK_JAVA_MIDP_SECURITY_DOMAIN;
+
+typedef CK_ULONG CK_CERTIFICATE_CATEGORY;
+
+typedef struct CK_RSA_AES_KEY_WRAP_PARAMS {
+ CK_ULONG ulAESKeyBits;
+ CK_RSA_PKCS_OAEP_PARAMS_PTR pOAEPParams;
+} CK_RSA_AES_KEY_WRAP_PARAMS;
+
+typedef CK_RSA_AES_KEY_WRAP_PARAMS CK_PTR CK_RSA_AES_KEY_WRAP_PARAMS_PTR;
+
+typedef struct CK_TLS12_MASTER_KEY_DERIVE_PARAMS {
+ CK_SSL3_RANDOM_DATA RandomInfo;
+ CK_VERSION_PTR pVersion;
+ CK_MECHANISM_TYPE prfHashMechanism;
+} CK_TLS12_MASTER_KEY_DERIVE_PARAMS;
+
+typedef CK_TLS12_MASTER_KEY_DERIVE_PARAMS CK_PTR \
+ CK_TLS12_MASTER_KEY_DERIVE_PARAMS_PTR;
+
+typedef struct CK_TLS12_KEY_MAT_PARAMS {
+ CK_ULONG ulMacSizeInBits;
+ CK_ULONG ulKeySizeInBits;
+ CK_ULONG ulIVSizeInBits;
+ CK_BBOOL bIsExport;
+ CK_SSL3_RANDOM_DATA RandomInfo;
+ CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
+ CK_MECHANISM_TYPE prfHashMechanism;
+} CK_TLS12_KEY_MAT_PARAMS;
+
+typedef CK_TLS12_KEY_MAT_PARAMS CK_PTR CK_TLS12_KEY_MAT_PARAMS_PTR;
+
+typedef struct CK_TLS_KDF_PARAMS {
+ CK_MECHANISM_TYPE prfMechanism;
+ CK_BYTE_PTR pLabel;
+ CK_ULONG ulLabelLength;
+ CK_SSL3_RANDOM_DATA RandomInfo;
+ CK_BYTE_PTR pContextData;
+ CK_ULONG ulContextDataLength;
+} CK_TLS_KDF_PARAMS;
+
+typedef CK_TLS_KDF_PARAMS CK_PTR CK_TLS_KDF_PARAMS_PTR;
+
+typedef struct CK_TLS_MAC_PARAMS {
+ CK_MECHANISM_TYPE prfHashMechanism;
+ CK_ULONG ulMacLength;
+ CK_ULONG ulServerOrClient;
+} CK_TLS_MAC_PARAMS;
+
+typedef CK_TLS_MAC_PARAMS CK_PTR CK_TLS_MAC_PARAMS_PTR;
+
+typedef struct CK_GOSTR3410_DERIVE_PARAMS {
+ CK_EC_KDF_TYPE kdf;
+ CK_BYTE_PTR pPublicData;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pUKM;
+ CK_ULONG ulUKMLen;
+} CK_GOSTR3410_DERIVE_PARAMS;
+
+typedef CK_GOSTR3410_DERIVE_PARAMS CK_PTR CK_GOSTR3410_DERIVE_PARAMS_PTR;
+
+typedef struct CK_GOSTR3410_KEY_WRAP_PARAMS {
+ CK_BYTE_PTR pWrapOID;
+ CK_ULONG ulWrapOIDLen;
+ CK_BYTE_PTR pUKM;
+ CK_ULONG ulUKMLen;
+ CK_OBJECT_HANDLE hKey;
+} CK_GOSTR3410_KEY_WRAP_PARAMS;
+
+typedef CK_GOSTR3410_KEY_WRAP_PARAMS CK_PTR CK_GOSTR3410_KEY_WRAP_PARAMS_PTR;
+
+typedef struct CK_SEED_CBC_ENCRYPT_DATA_PARAMS {
+ CK_BYTE iv[16];
+ CK_BYTE_PTR pData;
+ CK_ULONG length;
+} CK_SEED_CBC_ENCRYPT_DATA_PARAMS;
+
+typedef CK_SEED_CBC_ENCRYPT_DATA_PARAMS CK_PTR \
+ CK_SEED_CBC_ENCRYPT_DATA_PARAMS_PTR;
+
+#endif /* _PKCS11T_H_ */
+
diff --git a/vendor/github.com/miekg/pkcs11/release.go b/vendor/github.com/miekg/pkcs11/release.go
new file mode 100644
index 000000000..4380f374d
--- /dev/null
+++ b/vendor/github.com/miekg/pkcs11/release.go
@@ -0,0 +1,17 @@
+// +build release
+
+package pkcs11
+
+import "fmt"
+
+// Release is current version of the pkcs11 library.
+var Release = R{1, 0, 3}
+
+// R holds the version of this library.
+type R struct {
+ Major, Minor, Patch int
+}
+
+func (r R) String() string {
+ return fmt.Sprintf("%d.%d.%d", r.Major, r.Minor, r.Patch)
+}
diff --git a/vendor/github.com/miekg/pkcs11/softhsm.conf b/vendor/github.com/miekg/pkcs11/softhsm.conf
new file mode 100644
index 000000000..f95862b10
--- /dev/null
+++ b/vendor/github.com/miekg/pkcs11/softhsm.conf
@@ -0,0 +1 @@
+0:hsm.db
diff --git a/vendor/github.com/miekg/pkcs11/softhsm2.conf b/vendor/github.com/miekg/pkcs11/softhsm2.conf
new file mode 100644
index 000000000..876990cdd
--- /dev/null
+++ b/vendor/github.com/miekg/pkcs11/softhsm2.conf
@@ -0,0 +1,4 @@
+log.level = INFO
+objectstore.backend = file
+directories.tokendir = test_data
+slots.removable = false
diff --git a/vendor/github.com/miekg/pkcs11/types.go b/vendor/github.com/miekg/pkcs11/types.go
new file mode 100644
index 000000000..970db9061
--- /dev/null
+++ b/vendor/github.com/miekg/pkcs11/types.go
@@ -0,0 +1,303 @@
+// Copyright 2013 Miek Gieben. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkcs11
+
+/*
+#include <stdlib.h>
+#include <string.h>
+#include "pkcs11go.h"
+
+CK_ULONG Index(CK_ULONG_PTR array, CK_ULONG i)
+{
+ return array[i];
+}
+
+static inline void putAttributePval(CK_ATTRIBUTE_PTR a, CK_VOID_PTR pValue)
+{
+ a->pValue = pValue;
+}
+
+static inline void putMechanismParam(CK_MECHANISM_PTR m, CK_VOID_PTR pParameter)
+{
+ m->pParameter = pParameter;
+}
+*/
+import "C"
+
+import (
+ "fmt"
+ "time"
+ "unsafe"
+)
+
+type arena []unsafe.Pointer
+
+func (a *arena) Allocate(obj []byte) (C.CK_VOID_PTR, C.CK_ULONG) {
+ cobj := C.calloc(C.size_t(len(obj)), 1)
+ *a = append(*a, cobj)
+ C.memmove(cobj, unsafe.Pointer(&obj[0]), C.size_t(len(obj)))
+ return C.CK_VOID_PTR(cobj), C.CK_ULONG(len(obj))
+}
+
+func (a arena) Free() {
+ for _, p := range a {
+ C.free(p)
+ }
+}
+
+// toList converts from a C style array to a []uint.
+func toList(clist C.CK_ULONG_PTR, size C.CK_ULONG) []uint {
+ l := make([]uint, int(size))
+ for i := 0; i < len(l); i++ {
+ l[i] = uint(C.Index(clist, C.CK_ULONG(i)))
+ }
+ defer C.free(unsafe.Pointer(clist))
+ return l
+}
+
+// cBBool converts a bool to a CK_BBOOL.
+func cBBool(x bool) C.CK_BBOOL {
+ if x {
+ return C.CK_BBOOL(C.CK_TRUE)
+ }
+ return C.CK_BBOOL(C.CK_FALSE)
+}
+
+func uintToBytes(x uint64) []byte {
+ ul := C.CK_ULONG(x)
+ return C.GoBytes(unsafe.Pointer(&ul), C.int(unsafe.Sizeof(ul)))
+}
+
+// Error represents an PKCS#11 error.
+type Error uint
+
+func (e Error) Error() string {
+ return fmt.Sprintf("pkcs11: 0x%X: %s", uint(e), strerror[uint(e)])
+}
+
+func toError(e C.CK_RV) error {
+ if e == C.CKR_OK {
+ return nil
+ }
+ return Error(e)
+}
+
+// SessionHandle is a Cryptoki-assigned value that identifies a session.
+type SessionHandle uint
+
+// ObjectHandle is a token-specific identifier for an object.
+type ObjectHandle uint
+
+// Version represents any version information from the library.
+type Version struct {
+ Major byte
+ Minor byte
+}
+
+func toVersion(version C.CK_VERSION) Version {
+ return Version{byte(version.major), byte(version.minor)}
+}
+
+// SlotEvent holds the SlotID which for which an slot event (token insertion,
+// removal, etc.) occurred.
+type SlotEvent struct {
+ SlotID uint
+}
+
+// Info provides information about the library and hardware used.
+type Info struct {
+ CryptokiVersion Version
+ ManufacturerID string
+ Flags uint
+ LibraryDescription string
+ LibraryVersion Version
+}
+
+// SlotInfo provides information about a slot.
+type SlotInfo struct {
+ SlotDescription string // 64 bytes.
+ ManufacturerID string // 32 bytes.
+ Flags uint
+ HardwareVersion Version
+ FirmwareVersion Version
+}
+
+// TokenInfo provides information about a token.
+type TokenInfo struct {
+ Label string
+ ManufacturerID string
+ Model string
+ SerialNumber string
+ Flags uint
+ MaxSessionCount uint
+ SessionCount uint
+ MaxRwSessionCount uint
+ RwSessionCount uint
+ MaxPinLen uint
+ MinPinLen uint
+ TotalPublicMemory uint
+ FreePublicMemory uint
+ TotalPrivateMemory uint
+ FreePrivateMemory uint
+ HardwareVersion Version
+ FirmwareVersion Version
+ UTCTime string
+}
+
+// SessionInfo provides information about a session.
+type SessionInfo struct {
+ SlotID uint
+ State uint
+ Flags uint
+ DeviceError uint
+}
+
+// Attribute holds an attribute type/value combination.
+type Attribute struct {
+ Type uint
+ Value []byte
+}
+
+// NewAttribute allocates a Attribute and returns a pointer to it.
+// Note that this is merely a convenience function, as values returned
+// from the HSM are not converted back to Go values, those are just raw
+// byte slices.
+func NewAttribute(typ uint, x interface{}) *Attribute {
+ // This function nicely transforms *to* an attribute, but there is
+ // no corresponding function that transform back *from* an attribute,
+ // which in PKCS#11 is just an byte array.
+ a := new(Attribute)
+ a.Type = typ
+ if x == nil {
+ return a
+ }
+ switch v := x.(type) {
+ case bool:
+ if v {
+ a.Value = []byte{1}
+ } else {
+ a.Value = []byte{0}
+ }
+ case int:
+ a.Value = uintToBytes(uint64(v))
+ case uint:
+ a.Value = uintToBytes(uint64(v))
+ case string:
+ a.Value = []byte(v)
+ case []byte:
+ a.Value = v
+ case time.Time: // for CKA_DATE
+ a.Value = cDate(v)
+ default:
+ panic("pkcs11: unhandled attribute type")
+ }
+ return a
+}
+
+// cAttribute returns the start address and the length of an attribute list.
+func cAttributeList(a []*Attribute) (arena, C.CK_ATTRIBUTE_PTR, C.CK_ULONG) {
+ var arena arena
+ if len(a) == 0 {
+ return nil, nil, 0
+ }
+ pa := make([]C.CK_ATTRIBUTE, len(a))
+ for i, attr := range a {
+ pa[i]._type = C.CK_ATTRIBUTE_TYPE(attr.Type)
+ if len(attr.Value) != 0 {
+ buf, len := arena.Allocate(attr.Value)
+ // field is unaligned on windows so this has to call into C
+ C.putAttributePval(&pa[i], buf)
+ pa[i].ulValueLen = len
+ }
+ }
+ return arena, &pa[0], C.CK_ULONG(len(a))
+}
+
+func cDate(t time.Time) []byte {
+ b := make([]byte, 8)
+ year, month, day := t.Date()
+ y := fmt.Sprintf("%4d", year)
+ m := fmt.Sprintf("%02d", month)
+ d1 := fmt.Sprintf("%02d", day)
+ b[0], b[1], b[2], b[3] = y[0], y[1], y[2], y[3]
+ b[4], b[5] = m[0], m[1]
+ b[6], b[7] = d1[0], d1[1]
+ return b
+}
+
+// Mechanism holds an mechanism type/value combination.
+type Mechanism struct {
+ Mechanism uint
+ Parameter []byte
+ generator interface{}
+}
+
+// NewMechanism returns a pointer to an initialized Mechanism.
+func NewMechanism(mech uint, x interface{}) *Mechanism {
+ m := new(Mechanism)
+ m.Mechanism = mech
+ if x == nil {
+ return m
+ }
+
+ switch p := x.(type) {
+ case *GCMParams, *OAEPParams, *ECDH1DeriveParams:
+ // contains pointers; defer serialization until cMechanism
+ m.generator = p
+ case []byte:
+ m.Parameter = p
+ default:
+ panic("parameter must be one of type: []byte, *GCMParams, *OAEPParams, *ECDH1DeriveParams")
+ }
+
+ return m
+}
+
+func cMechanism(mechList []*Mechanism) (arena, *C.CK_MECHANISM) {
+ if len(mechList) != 1 {
+ panic("expected exactly one mechanism")
+ }
+ mech := mechList[0]
+ cmech := &C.CK_MECHANISM{mechanism: C.CK_MECHANISM_TYPE(mech.Mechanism)}
+ // params that contain pointers are allocated here
+ param := mech.Parameter
+ var arena arena
+ switch p := mech.generator.(type) {
+ case *GCMParams:
+ // uses its own arena because it has to outlive this function call (yuck)
+ param = cGCMParams(p)
+ case *OAEPParams:
+ param, arena = cOAEPParams(p, arena)
+ case *ECDH1DeriveParams:
+ param, arena = cECDH1DeriveParams(p, arena)
+ }
+ if len(param) != 0 {
+ buf, len := arena.Allocate(param)
+ // field is unaligned on windows so this has to call into C
+ C.putMechanismParam(cmech, buf)
+ cmech.ulParameterLen = len
+ }
+ return arena, cmech
+}
+
+// MechanismInfo provides information about a particular mechanism.
+type MechanismInfo struct {
+ MinKeySize uint
+ MaxKeySize uint
+ Flags uint
+}
+
+// stubData is a persistent nonempty byte array used by cMessage.
+var stubData = []byte{0}
+
+// cMessage returns the pointer/length pair corresponding to data.
+func cMessage(data []byte) (dataPtr C.CK_BYTE_PTR) {
+ l := len(data)
+ if l == 0 {
+ // &data[0] is forbidden in this case, so use a nontrivial array instead.
+ data = stubData
+ }
+ return C.CK_BYTE_PTR(unsafe.Pointer(&data[0]))
+}
diff --git a/vendor/github.com/miekg/pkcs11/vendor.go b/vendor/github.com/miekg/pkcs11/vendor.go
new file mode 100644
index 000000000..83188e500
--- /dev/null
+++ b/vendor/github.com/miekg/pkcs11/vendor.go
@@ -0,0 +1,127 @@
+package pkcs11
+
+// Vendor specific range for Ncipher network HSM.
+const (
+ NFCK_VENDOR_NCIPHER = 0xde436972
+ CKA_NCIPHER = NFCK_VENDOR_NCIPHER
+ CKM_NCIPHER = NFCK_VENDOR_NCIPHER
+ CKK_NCIPHER = NFCK_VENDOR_NCIPHER
+)
+
+// Vendor specific mechanisms for HMAC on Ncipher HSMs where Ncipher does not allow use of generic_secret keys.
+const (
+ CKM_NC_SHA_1_HMAC_KEY_GEN = CKM_NCIPHER + 0x3 /* no params */
+ CKM_NC_MD5_HMAC_KEY_GEN = CKM_NCIPHER + 0x6 /* no params */
+ CKM_NC_SHA224_HMAC_KEY_GEN = CKM_NCIPHER + 0x24 /* no params */
+ CKM_NC_SHA256_HMAC_KEY_GEN = CKM_NCIPHER + 0x25 /* no params */
+ CKM_NC_SHA384_HMAC_KEY_GEN = CKM_NCIPHER + 0x26 /* no params */
+ CKM_NC_SHA512_HMAC_KEY_GEN = CKM_NCIPHER + 0x27 /* no params */
+)
+
+// Vendor specific range for Mozilla NSS.
+const (
+ NSSCK_VENDOR_NSS = 0x4E534350
+ CKO_NSS = CKO_VENDOR_DEFINED | NSSCK_VENDOR_NSS
+ CKK_NSS = CKK_VENDOR_DEFINED | NSSCK_VENDOR_NSS
+ CKC_NSS = CKC_VENDOR_DEFINED | NSSCK_VENDOR_NSS
+ CKA_NSS = CKA_VENDOR_DEFINED | NSSCK_VENDOR_NSS
+ CKA_TRUST = CKA_NSS + 0x2000
+ CKM_NSS = CKM_VENDOR_DEFINED | NSSCK_VENDOR_NSS
+ CKR_NSS = CKM_VENDOR_DEFINED | NSSCK_VENDOR_NSS
+ CKT_VENDOR_DEFINED = 0x80000000
+ CKT_NSS = CKT_VENDOR_DEFINED | NSSCK_VENDOR_NSS
+)
+
+// Vendor specific values for Mozilla NSS.
+const (
+ CKO_NSS_CRL = CKO_NSS + 1
+ CKO_NSS_SMIME = CKO_NSS + 2
+ CKO_NSS_TRUST = CKO_NSS + 3
+ CKO_NSS_BUILTIN_ROOT_LIST = CKO_NSS + 4
+ CKO_NSS_NEWSLOT = CKO_NSS + 5
+ CKO_NSS_DELSLOT = CKO_NSS + 6
+ CKK_NSS_PKCS8 = CKK_NSS + 1
+ CKK_NSS_JPAKE_ROUND1 = CKK_NSS + 2
+ CKK_NSS_JPAKE_ROUND2 = CKK_NSS + 3
+ CKK_NSS_CHACHA20 = CKK_NSS + 4
+ CKA_NSS_URL = CKA_NSS + 1
+ CKA_NSS_EMAIL = CKA_NSS + 2
+ CKA_NSS_SMIME_INFO = CKA_NSS + 3
+ CKA_NSS_SMIME_TIMESTAMP = CKA_NSS + 4
+ CKA_NSS_PKCS8_SALT = CKA_NSS + 5
+ CKA_NSS_PASSWORD_CHECK = CKA_NSS + 6
+ CKA_NSS_EXPIRES = CKA_NSS + 7
+ CKA_NSS_KRL = CKA_NSS + 8
+ CKA_NSS_PQG_COUNTER = CKA_NSS + 20
+ CKA_NSS_PQG_SEED = CKA_NSS + 21
+ CKA_NSS_PQG_H = CKA_NSS + 22
+ CKA_NSS_PQG_SEED_BITS = CKA_NSS + 23
+ CKA_NSS_MODULE_SPEC = CKA_NSS + 24
+ CKA_NSS_OVERRIDE_EXTENSIONS = CKA_NSS + 25
+ CKA_NSS_JPAKE_SIGNERID = CKA_NSS + 26
+ CKA_NSS_JPAKE_PEERID = CKA_NSS + 27
+ CKA_NSS_JPAKE_GX1 = CKA_NSS + 28
+ CKA_NSS_JPAKE_GX2 = CKA_NSS + 29
+ CKA_NSS_JPAKE_GX3 = CKA_NSS + 30
+ CKA_NSS_JPAKE_GX4 = CKA_NSS + 31
+ CKA_NSS_JPAKE_X2 = CKA_NSS + 32
+ CKA_NSS_JPAKE_X2S = CKA_NSS + 33
+ CKA_NSS_MOZILLA_CA_POLICY = CKA_NSS + 34
+ CKA_TRUST_DIGITAL_SIGNATURE = CKA_TRUST + 1
+ CKA_TRUST_NON_REPUDIATION = CKA_TRUST + 2
+ CKA_TRUST_KEY_ENCIPHERMENT = CKA_TRUST + 3
+ CKA_TRUST_DATA_ENCIPHERMENT = CKA_TRUST + 4
+ CKA_TRUST_KEY_AGREEMENT = CKA_TRUST + 5
+ CKA_TRUST_KEY_CERT_SIGN = CKA_TRUST + 6
+ CKA_TRUST_CRL_SIGN = CKA_TRUST + 7
+ CKA_TRUST_SERVER_AUTH = CKA_TRUST + 8
+ CKA_TRUST_CLIENT_AUTH = CKA_TRUST + 9
+ CKA_TRUST_CODE_SIGNING = CKA_TRUST + 10
+ CKA_TRUST_EMAIL_PROTECTION = CKA_TRUST + 11
+ CKA_TRUST_IPSEC_END_SYSTEM = CKA_TRUST + 12
+ CKA_TRUST_IPSEC_TUNNEL = CKA_TRUST + 13
+ CKA_TRUST_IPSEC_USER = CKA_TRUST + 14
+ CKA_TRUST_TIME_STAMPING = CKA_TRUST + 15
+ CKA_TRUST_STEP_UP_APPROVED = CKA_TRUST + 16
+ CKA_CERT_SHA1_HASH = CKA_TRUST + 100
+ CKA_CERT_MD5_HASH = CKA_TRUST + 101
+ CKM_NSS_AES_KEY_WRAP = CKM_NSS + 1
+ CKM_NSS_AES_KEY_WRAP_PAD = CKM_NSS + 2
+ CKM_NSS_HKDF_SHA1 = CKM_NSS + 3
+ CKM_NSS_HKDF_SHA256 = CKM_NSS + 4
+ CKM_NSS_HKDF_SHA384 = CKM_NSS + 5
+ CKM_NSS_HKDF_SHA512 = CKM_NSS + 6
+ CKM_NSS_JPAKE_ROUND1_SHA1 = CKM_NSS + 7
+ CKM_NSS_JPAKE_ROUND1_SHA256 = CKM_NSS + 8
+ CKM_NSS_JPAKE_ROUND1_SHA384 = CKM_NSS + 9
+ CKM_NSS_JPAKE_ROUND1_SHA512 = CKM_NSS + 10
+ CKM_NSS_JPAKE_ROUND2_SHA1 = CKM_NSS + 11
+ CKM_NSS_JPAKE_ROUND2_SHA256 = CKM_NSS + 12
+ CKM_NSS_JPAKE_ROUND2_SHA384 = CKM_NSS + 13
+ CKM_NSS_JPAKE_ROUND2_SHA512 = CKM_NSS + 14
+ CKM_NSS_JPAKE_FINAL_SHA1 = CKM_NSS + 15
+ CKM_NSS_JPAKE_FINAL_SHA256 = CKM_NSS + 16
+ CKM_NSS_JPAKE_FINAL_SHA384 = CKM_NSS + 17
+ CKM_NSS_JPAKE_FINAL_SHA512 = CKM_NSS + 18
+ CKM_NSS_HMAC_CONSTANT_TIME = CKM_NSS + 19
+ CKM_NSS_SSL3_MAC_CONSTANT_TIME = CKM_NSS + 20
+ CKM_NSS_TLS_PRF_GENERAL_SHA256 = CKM_NSS + 21
+ CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256 = CKM_NSS + 22
+ CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256 = CKM_NSS + 23
+ CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256 = CKM_NSS + 24
+ CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE = CKM_NSS + 25
+ CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH = CKM_NSS + 26
+ CKM_NSS_CHACHA20_KEY_GEN = CKM_NSS + 27
+ CKM_NSS_CHACHA20_POLY1305 = CKM_NSS + 28
+ CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN = CKM_NSS + 29
+ CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN = CKM_NSS + 30
+ CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN = CKM_NSS + 31
+ CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN = CKM_NSS + 32
+ CKR_NSS_CERTDB_FAILED = CKR_NSS + 1
+ CKR_NSS_KEYDB_FAILED = CKR_NSS + 2
+ CKT_NSS_TRUSTED = CKT_NSS + 1
+ CKT_NSS_TRUSTED_DELEGATOR = CKT_NSS + 2
+ CKT_NSS_MUST_VERIFY_TRUST = CKT_NSS + 3
+ CKT_NSS_NOT_TRUSTED = CKT_NSS + 10
+ CKT_NSS_TRUST_UNKNOWN = CKT_NSS + 5
+)
diff --git a/vendor/github.com/stefanberger/go-pkcs11uri/.gitignore b/vendor/github.com/stefanberger/go-pkcs11uri/.gitignore
new file mode 100644
index 000000000..1823f5d48
--- /dev/null
+++ b/vendor/github.com/stefanberger/go-pkcs11uri/.gitignore
@@ -0,0 +1,2 @@
+*~
+pkcs11uri
diff --git a/vendor/github.com/stefanberger/go-pkcs11uri/.travis.yml b/vendor/github.com/stefanberger/go-pkcs11uri/.travis.yml
new file mode 100644
index 000000000..f5f274f96
--- /dev/null
+++ b/vendor/github.com/stefanberger/go-pkcs11uri/.travis.yml
@@ -0,0 +1,25 @@
+dist: bionic
+language: go
+
+os:
+- linux
+
+go:
+ - "1.13.x"
+
+matrix:
+ include:
+ - os: linux
+
+addons:
+ apt:
+ packages:
+ - softhsm2
+
+install:
+ - curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.30.0
+
+script:
+ - make
+ - make check
+ - make test
diff --git a/vendor/github.com/stefanberger/go-pkcs11uri/LICENSE b/vendor/github.com/stefanberger/go-pkcs11uri/LICENSE
new file mode 100644
index 000000000..49cc83d2e
--- /dev/null
+++ b/vendor/github.com/stefanberger/go-pkcs11uri/LICENSE
@@ -0,0 +1,177 @@
+
+ Apache License
+ Version 2.0, January 2004
+ https://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
diff --git a/vendor/github.com/stefanberger/go-pkcs11uri/Makefile b/vendor/github.com/stefanberger/go-pkcs11uri/Makefile
new file mode 100644
index 000000000..1a1051524
--- /dev/null
+++ b/vendor/github.com/stefanberger/go-pkcs11uri/Makefile
@@ -0,0 +1,28 @@
+# Copyright IBM Corporation, 2020
+
+# 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.
+
+.PHONY: check build test
+
+all: build
+
+FORCE:
+
+check:
+ golangci-lint run
+
+build:
+ go build ./...
+
+test:
+ go test ./... -test.v
diff --git a/vendor/github.com/stefanberger/go-pkcs11uri/README.md b/vendor/github.com/stefanberger/go-pkcs11uri/README.md
new file mode 100644
index 000000000..c1fc6e911
--- /dev/null
+++ b/vendor/github.com/stefanberger/go-pkcs11uri/README.md
@@ -0,0 +1,102 @@
+# go-pkcs11uri
+
+Welcome to the go-pkcs11uri library. The implementation follows [RFC 7512](https://tools.ietf.org/html/rfc7512) and this [errata](https://www.rfc-editor.org/errata/rfc7512).
+
+# Exampe usage:
+
+The following example builds on this library [here](https://github.com/miekg/pkcs11) and are using softhsm2 on Fedora.
+
+## Example
+
+This example program extending the one found [here](https://github.com/miekg/pkcs11/blob/master/README.md#examples):
+
+```
+package main
+
+import (
+ "fmt"
+ "os"
+ "strconv"
+
+ "github.com/miekg/pkcs11"
+ pkcs11uri "github.com/stefanberger/go-pkcs11uri"
+)
+
+func main() {
+ if len(os.Args) < 2 {
+ panic("Missing pkcs11 URI argument")
+ }
+ uristr := os.Args[1]
+
+ uri, err := pkcs11uri.New()
+ if err != nil {
+ panic(err)
+ }
+ err = uri.Parse(uristr)
+ if err != nil {
+ panic(err)
+ }
+
+ module, err := uri.GetModule()
+ if err != nil {
+ panic(err)
+ }
+
+ slot, ok := uri.GetPathAttribute("slot-id", false)
+ if !ok {
+ panic("No slot-id in pkcs11 URI")
+ }
+ slotid, err := strconv.Atoi(slot)
+ if err != nil {
+ panic(err)
+ }
+
+ pin, err := uri.GetPIN()
+ if err != nil {
+ panic(err)
+ }
+
+ p := pkcs11.New(module)
+ err = p.Initialize()
+ if err != nil {
+ panic(err)
+ }
+
+ defer p.Destroy()
+ defer p.Finalize()
+
+ session, err := p.OpenSession(uint(slotid), pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION)
+ if err != nil {
+ panic(err)
+ }
+ defer p.CloseSession(session)
+
+ err = p.Login(session, pkcs11.CKU_USER, pin)
+ if err != nil {
+ panic(err)
+ }
+ defer p.Logout(session)
+
+ p.DigestInit(session, []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_SHA_1, nil)})
+ hash, err := p.Digest(session, []byte("this is a string"))
+ if err != nil {
+ panic(err)
+ }
+
+ for _, d := range hash {
+ fmt.Printf("%x", d)
+ }
+ fmt.Println()
+}
+```
+
+## Exampe Usage
+
+```
+$ sudo softhsm2-util --init-token --slot 1 --label test --pin 1234 --so-pin 1234
+The token has been initialized and is reassigned to slot 2053753261
+$ go build ./...
+$ sudo ./pkcs11-example 'pkcs11:slot-id=2053753261?module-path=/usr/lib64/pkcs11/libsofthsm2.so&pin-value=1234'
+517592df8fec3ad146a79a9af153db2a4d784ec5
+```
+
diff --git a/vendor/github.com/stefanberger/go-pkcs11uri/pkcs11uri.go b/vendor/github.com/stefanberger/go-pkcs11uri/pkcs11uri.go
new file mode 100644
index 000000000..39b06548e
--- /dev/null
+++ b/vendor/github.com/stefanberger/go-pkcs11uri/pkcs11uri.go
@@ -0,0 +1,453 @@
+/*
+ (c) Copyright IBM Corporation, 2020
+
+ 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 pkcs11uri
+
+import (
+ "errors"
+ "fmt"
+ "io/ioutil"
+ "net/url"
+ "os"
+ "path/filepath"
+ "regexp"
+ "strconv"
+ "strings"
+)
+
+// Pkcs11URI holds a pkcs11 URI object
+type Pkcs11URI struct {
+ // path and query attributes may have custom attributes that either
+ // have to be in the query or in the path part, so we use two maps
+ pathAttributes map[string]string
+ queryAttributes map[string]string
+ // directories to search for pkcs11 modules
+ moduleDirectories []string
+ // file paths of allowed pkcs11 modules
+ allowedModulePaths []string
+ // whether any module is allowed to be loaded
+ allowAnyModule bool
+ // A map of environment variables needed by the pkcs11 module using this URI.
+ // This map is not needed by this implementation but is there for convenience.
+ env map[string]string
+}
+
+// upper character hex digits needed for pct-encoding
+const hex = "0123456789ABCDEF"
+
+// escapeAll pct-escapes all characters in the string
+func escapeAll(s string) string {
+ res := make([]byte, len(s)*3)
+ j := 0
+ for i := 0; i < len(s); i++ {
+ c := s[i]
+ res[j] = '%'
+ res[j+1] = hex[c>>4]
+ res[j+2] = hex[c&0xf]
+ j += 3
+ }
+ return string(res)
+}
+
+// escape pct-escapes the path and query part of the pkcs11 URI following the different rules of the
+// path and query part as decribed in RFC 7512 sec. 2.3
+func escape(s string, isPath bool) string {
+ res := make([]byte, len(s)*3)
+ j := 0
+ for i := 0; i < len(s); i++ {
+ c := s[i]
+ // unreserved per RFC 3986 sec. 2.3
+ if (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') {
+ res[j] = c
+ } else if isPath && c == '&' {
+ res[j] = c
+ } else if !isPath && (c == '/' || c == '?' || c == '|') {
+ res[j] = c
+ } else {
+ switch c {
+ case '-', '.', '_', '~': // unreserved per RFC 3986 sec. 2.3
+ res[j] = c
+ case ':', '[', ']', '@', '!', '$', '\'', '(', ')', '*', '+', ',', '=':
+ res[j] = c
+ default:
+ res[j] = '%'
+ res[j+1] = hex[c>>4]
+ res[j+2] = hex[c&0xf]
+ j += 2
+ }
+ }
+ j++
+ }
+ return string(res[:j])
+}
+
+// New creates a new Pkcs11URI object
+func New() *Pkcs11URI {
+ return &Pkcs11URI{
+ pathAttributes: make(map[string]string),
+ queryAttributes: make(map[string]string),
+ env: make(map[string]string),
+ }
+}
+
+func (uri *Pkcs11URI) setAttribute(attrMap map[string]string, name, value string) error {
+ v, err := url.PathUnescape(value)
+ if err != nil {
+ return err
+ }
+ attrMap[name] = v
+ return nil
+}
+
+// GetPathAttribute returns the value of a path attribute in unescaped form or
+// pct-encoded form
+func (uri *Pkcs11URI) GetPathAttribute(name string, pctencode bool) (string, bool) {
+ v, ok := uri.pathAttributes[name]
+ if ok && pctencode {
+ v = escape(v, true)
+ }
+ return v, ok
+}
+
+// SetPathAttribute sets the value for a path attribute; this function may return an error
+// if the given value cannot be pct-unescaped
+func (uri *Pkcs11URI) SetPathAttribute(name, value string) error {
+ return uri.setAttribute(uri.pathAttributes, name, value)
+}
+
+// AddPathAttribute adds a path attribute; it returns an error if an attribute with the same
+// name already existed or if the given value cannot be pct-unescaped
+func (uri *Pkcs11URI) AddPathAttribute(name, value string) error {
+ if _, ok := uri.pathAttributes[name]; ok {
+ return errors.New("duplicate path attribute")
+ }
+ return uri.SetPathAttribute(name, value)
+}
+
+// RemovePathAttribute removes a path attribute
+func (uri *Pkcs11URI) RemovePathAttribute(name string) {
+ delete(uri.pathAttributes, name)
+}
+
+// AddEnv adds an environment variable for the pkcs11 module
+func (uri *Pkcs11URI) AddEnv(name, value string) {
+ uri.env[name] = value
+}
+
+// SetEnvMap sets the environment variables for the pkcs11 module
+func (uri *Pkcs11URI) SetEnvMap(env map[string]string) {
+ uri.env = env
+}
+
+// GetEnvMap returns the map of environment variables
+func (uri *Pkcs11URI) GetEnvMap() map[string]string {
+ return uri.env
+}
+
+// GetQueryAttribute returns the value of a query attribute in unescaped or
+// pct-encoded form
+func (uri *Pkcs11URI) GetQueryAttribute(name string, pctencode bool) (string, bool) {
+ v, ok := uri.queryAttributes[name]
+ if ok && pctencode {
+ v = escape(v, false)
+ }
+ return v, ok
+}
+
+// SetQueryAttribute sets the value for a query attribute; this function may return an error
+// if the given value cannot pct-unescaped
+func (uri *Pkcs11URI) SetQueryAttribute(name, value string) error {
+ return uri.setAttribute(uri.queryAttributes, name, value)
+}
+
+// AddQueryAttribute adds a query attribute; it returns an error if an attribute with the same
+// name already existed or if the given value cannot be pct-unescaped
+func (uri *Pkcs11URI) AddQueryAttribute(name, value string) error {
+ if _, ok := uri.queryAttributes[name]; ok {
+ return errors.New("duplicate query attribute")
+ }
+ return uri.SetQueryAttribute(name, value)
+}
+
+// RemoveQueryAttribute removes a path attribute
+func (uri *Pkcs11URI) RemoveQueryAttribute(name string) {
+ delete(uri.queryAttributes, name)
+}
+
+// Validate validates a Pkcs11URI object's attributes following RFC 7512 rules and proper formatting of
+// their values
+func (uri *Pkcs11URI) Validate() error {
+ /* RFC 7512: 2.3 */
+ /* slot-id should be DIGIT, but we go for number */
+ if v, ok := uri.pathAttributes["slot-id"]; ok {
+ if _, err := strconv.Atoi(v); err != nil {
+ return fmt.Errorf("slot-id must be a number: %s", v)
+ }
+ }
+
+ /* library-version should 1*DIGIT [ "." 1 *DIGIT ]; allow NUMBERS for DIGIT */
+ if v, ok := uri.pathAttributes["library-version"]; ok {
+ m, err := regexp.Match("^[0-9]+(\\.[0-9]+)?$", []byte(v))
+ if err != nil || !m {
+ return fmt.Errorf("Invalid format for library-version '%s'", v)
+ }
+ }
+
+ if v, ok := uri.pathAttributes["type"]; ok {
+ m, err := regexp.Match("^(public|private|cert|secret-key}data)?$", []byte(v))
+ if err != nil || !m {
+ return fmt.Errorf("Invalid type '%s'", v)
+ }
+ }
+
+ /* RFC 7512: 2.4 */
+ _, ok1 := uri.queryAttributes["pin-source"]
+ _, ok2 := uri.queryAttributes["pin-value"]
+ if ok1 && ok2 {
+ return errors.New("URI must not contain pin-source and pin-value")
+ }
+
+ if v, ok := uri.queryAttributes["module-path"]; ok {
+ if !filepath.IsAbs(v) {
+ return fmt.Errorf("path %s of module-name attribute must be absolute", v)
+ }
+ }
+
+ return nil
+}
+
+// HasPIN allows the user to check whether a PIN has been provided either by the pin-value or the pin-source
+// attributes. It should be called before GetPIN(), which may still fail getting the PIN from a file for example.
+func (uri *Pkcs11URI) HasPIN() bool {
+ _, ok := uri.queryAttributes["pin-value"]
+ if ok {
+ return true
+ }
+ _, ok = uri.queryAttributes["pin-source"]
+ return ok
+}
+
+// GetPIN gets the PIN from either the pin-value or pin-source attribute; a user may want to call HasPIN()
+// before calling this function to determine whether a PIN has been provided at all so that an error code
+// returned by this function indicates that the PIN value could not be retrieved.
+func (uri *Pkcs11URI) GetPIN() (string, error) {
+ if v, ok := uri.queryAttributes["pin-value"]; ok {
+ return v, nil
+ }
+ if v, ok := uri.queryAttributes["pin-source"]; ok {
+ pinuri, err := url.ParseRequestURI(v)
+ if err != nil {
+ return "", fmt.Errorf("Could not parse pin-source: %s ", err)
+ }
+ switch pinuri.Scheme {
+ case "", "file":
+ if !filepath.IsAbs(pinuri.Path) {
+ return "", fmt.Errorf("PIN URI path '%s' is not absolute", pinuri.Path)
+ }
+ pin, err := ioutil.ReadFile(pinuri.Path)
+ if err != nil {
+ return "", fmt.Errorf("Could not open PIN file: %s", err)
+ }
+ return string(pin), nil
+ default:
+ return "", fmt.Errorf("PIN URI scheme %s is not supported", pinuri.Scheme)
+ }
+ }
+ return "", fmt.Errorf("Neither pin-source nor pin-value are available")
+}
+
+// Parse parses a pkcs11: URI string
+func (uri *Pkcs11URI) Parse(uristring string) error {
+ if !strings.HasPrefix(uristring, "pkcs11:") {
+ return errors.New("Malformed pkcs11 URI: missing pcks11: prefix")
+ }
+
+ parts := strings.SplitN(uristring[7:], "?", 2)
+
+ uri.pathAttributes = make(map[string]string)
+ uri.queryAttributes = make(map[string]string)
+
+ if len(parts[0]) > 0 {
+ /* parse path part */
+ for _, part := range strings.Split(parts[0], ";") {
+ p := strings.SplitN(part, "=", 2)
+ if len(p) != 2 {
+ return errors.New("Malformed pkcs11 URI: malformed path attribute")
+ }
+ if err := uri.AddPathAttribute(p[0], p[1]); err != nil {
+ return fmt.Errorf("Malformed pkcs11 URI: %s", err)
+ }
+ }
+ }
+
+ if len(parts) == 2 {
+ /* parse query part */
+ for _, part := range strings.Split(parts[1], "&") {
+ p := strings.SplitN(part, "=", 2)
+ if len(p) != 2 {
+ return errors.New("Malformed pkcs11 URI: malformed query attribute")
+ }
+ if err := uri.AddQueryAttribute(p[0], p[1]); err != nil {
+ return fmt.Errorf("Malformed pkcs11 URI: %s", err)
+ }
+ }
+ }
+ return uri.Validate()
+}
+
+// formatAttribute formats attributes and escapes their values as needed
+func formatAttributes(attrMap map[string]string, ispath bool) string {
+ res := ""
+ for key, value := range attrMap {
+ switch key {
+ case "id":
+ /* id is always pct-encoded */
+ value = escapeAll(value)
+ default:
+ if ispath {
+ value = escape(value, true)
+ } else {
+ value = escape(value, false)
+ }
+ }
+ if len(res) > 0 {
+ if ispath {
+ res += ";"
+ } else {
+ res += "&"
+ }
+ }
+ res += key + "=" + value
+ }
+ return res
+}
+
+// Format formats a Pkcs11URI to it string representaion
+func (uri *Pkcs11URI) Format() (string, error) {
+ if err := uri.Validate(); err != nil {
+ return "", err
+ }
+ result := "pkcs11:" + formatAttributes(uri.pathAttributes, true)
+ if len(uri.queryAttributes) > 0 {
+ result += "?" + formatAttributes(uri.queryAttributes, false)
+ }
+ return result, nil
+}
+
+// SetModuleDirectories sets the search directories for pkcs11 modules
+func (uri *Pkcs11URI) SetModuleDirectories(moduleDirectories []string) {
+ uri.moduleDirectories = moduleDirectories
+}
+
+// GetModuleDirectories gets the search directories for pkcs11 modules
+func (uri *Pkcs11URI) GetModuleDirectories() []string {
+ return uri.moduleDirectories
+}
+
+// SetAllowedModulePaths sets allowed module paths to restrict access to modules.
+// Directory entries must end with a '/', all other ones are assumed to be file entries.
+// Allowed modules are filtered by string matching.
+func (uri *Pkcs11URI) SetAllowedModulePaths(allowedModulePaths []string) {
+ uri.allowedModulePaths = allowedModulePaths
+}
+
+// SetAllowAnyModule allows any module to be loaded; by default this is not allowed
+func (uri *Pkcs11URI) SetAllowAnyModule(allowAnyModule bool) {
+ uri.allowAnyModule = allowAnyModule
+}
+
+func (uri *Pkcs11URI) isAllowedPath(path string, allowedPaths []string) bool {
+ if uri.allowAnyModule {
+ return true
+ }
+ for _, allowedPath := range allowedPaths {
+ if allowedPath == path {
+ // exact filename match
+ return true
+ }
+ if allowedPath[len(allowedPath)-1] == '/' && strings.HasPrefix(path, allowedPath) {
+ // allowedPath no subdirectory is allowed
+ idx := strings.IndexRune(path[len(allowedPath):], os.PathSeparator)
+ if idx < 0 {
+ return true
+ }
+ }
+ }
+ return false
+}
+
+// GetModule returns the module to use or an error in case no module could be found.
+// First the module-path is checked for whether it holds an absolute that can be read
+// by the current user. If this is the case the module is returned. Otherwise either the module-path
+// is used or the user-provided module path is used to match a module containing what is set in the
+// attribute module-name.
+func (uri *Pkcs11URI) GetModule() (string, error) {
+ var searchdirs []string
+ v, ok := uri.queryAttributes["module-path"]
+
+ if ok {
+ info, err := os.Stat(v)
+ if err != nil {
+ return "", fmt.Errorf("module-path '%s' is not accessible", v)
+ }
+ if err == nil && info.Mode().IsRegular() {
+ // it's a file
+ if uri.isAllowedPath(v, uri.allowedModulePaths) {
+ return v, nil
+ }
+ return "", fmt.Errorf("module-path '%s' is not allowed by policy", v)
+ }
+ if !info.IsDir() {
+ return "", fmt.Errorf("module-path '%s' points to an invalid file type", v)
+ }
+ // v is a directory
+ searchdirs = []string{v}
+ } else {
+ searchdirs = uri.GetModuleDirectories()
+ }
+
+ moduleName, ok := uri.queryAttributes["module-name"]
+ if !ok {
+ return "", fmt.Errorf("module-name attribute is not set")
+ }
+ moduleName = strings.ToLower(moduleName)
+
+ for _, dir := range searchdirs {
+ files, err := ioutil.ReadDir(dir)
+ if err != nil {
+ continue
+ }
+ for _, file := range files {
+ fileLower := strings.ToLower(file.Name())
+
+ i := strings.Index(fileLower, moduleName)
+ if i < 0 {
+ continue
+ }
+ // we require that the fileLower ends with moduleName or that
+ // a suffix follows so that softhsm will not match libsofthsm2.so but only
+ // libsofthsm.so
+ if len(fileLower) == i+len(moduleName) || fileLower[i+len(moduleName)] == '.' {
+ f := filepath.Join(dir, file.Name())
+ if uri.isAllowedPath(f, uri.allowedModulePaths) {
+ return f, nil
+ }
+ return "", fmt.Errorf("module '%s' is not allowed by policy", f)
+ }
+ }
+ }
+ return "", fmt.Errorf("No module could be found")
+}