From 003a2a7a4913a22887b28b71147975eba4fbdc85 Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Sun, 24 Dec 2023 14:17:35 -0800 Subject: [PATCH] WIP: include sub-sub-modules? --- go.work | 2 + hack/update-go-workspace.sh | 2 +- .../ThalesIgnite/crypto11/.gitignore | 6 + .../ThalesIgnite/crypto11/.travis.yml | 27 + .../ThalesIgnite/crypto11/LICENCE.txt | 22 + .../ThalesIgnite/crypto11/README.md | 208 ++ .../github.com/ThalesIgnite/crypto11/aead.go | 189 ++ .../ThalesIgnite/crypto11/attributes.go | 510 ++++ .../github.com/ThalesIgnite/crypto11/block.go | 91 + .../ThalesIgnite/crypto11/blockmode.go | 202 ++ .../ThalesIgnite/crypto11/certificates.go | 299 +++ .../ThalesIgnite/crypto11/common.go | 125 + .../github.com/ThalesIgnite/crypto11/config | 5 + .../ThalesIgnite/crypto11/crypto11.go | 485 ++++ .../github.com/ThalesIgnite/crypto11/dsa.go | 175 ++ .../github.com/ThalesIgnite/crypto11/ecdsa.go | 302 +++ .../github.com/ThalesIgnite/crypto11/hmac.go | 215 ++ .../github.com/ThalesIgnite/crypto11/keys.go | 613 +++++ .../github.com/ThalesIgnite/crypto11/rand.go | 54 + .../github.com/ThalesIgnite/crypto11/rsa.go | 325 +++ .../ThalesIgnite/crypto11/sessions.go | 88 + .../ThalesIgnite/crypto11/symmetric.go | 366 +++ vendor/github.com/miekg/pkcs11/.gitignore | 3 + vendor/github.com/miekg/pkcs11/.travis.yml | 14 + vendor/github.com/miekg/pkcs11/LICENSE | 27 + .../github.com/miekg/pkcs11/Makefile.release | 57 + vendor/github.com/miekg/pkcs11/README.md | 68 + vendor/github.com/miekg/pkcs11/const.go | 736 ++++++ vendor/github.com/miekg/pkcs11/error.go | 98 + vendor/github.com/miekg/pkcs11/hsm.db | Bin 0 -> 10240 bytes vendor/github.com/miekg/pkcs11/params.go | 190 ++ vendor/github.com/miekg/pkcs11/pkcs11.go | 1606 +++++++++++++ vendor/github.com/miekg/pkcs11/pkcs11.h | 265 +++ vendor/github.com/miekg/pkcs11/pkcs11f.h | 939 ++++++++ vendor/github.com/miekg/pkcs11/pkcs11go.h | 33 + vendor/github.com/miekg/pkcs11/pkcs11t.h | 2047 +++++++++++++++++ vendor/github.com/miekg/pkcs11/release.go | 17 + vendor/github.com/miekg/pkcs11/softhsm.conf | 1 + vendor/github.com/miekg/pkcs11/softhsm2.conf | 4 + vendor/github.com/miekg/pkcs11/types.go | 303 +++ vendor/github.com/miekg/pkcs11/vendor.go | 127 + .../github.com/thales-e-security/pool/LICENSE | 202 ++ .../thales-e-security/pool/README.md | 7 + .../thales-e-security/pool/atomic.go | 186 ++ .../thales-e-security/pool/resource_pool.go | 383 +++ .../thales-e-security/pool/semaphore.go | 85 + .../thales-e-security/pool/timer.go | 159 ++ vendor/modules.txt | 11 + 48 files changed, 11878 insertions(+), 1 deletion(-) create mode 100644 vendor/github.com/ThalesIgnite/crypto11/.gitignore create mode 100644 vendor/github.com/ThalesIgnite/crypto11/.travis.yml create mode 100644 vendor/github.com/ThalesIgnite/crypto11/LICENCE.txt create mode 100644 vendor/github.com/ThalesIgnite/crypto11/README.md create mode 100644 vendor/github.com/ThalesIgnite/crypto11/aead.go create mode 100644 vendor/github.com/ThalesIgnite/crypto11/attributes.go create mode 100644 vendor/github.com/ThalesIgnite/crypto11/block.go create mode 100644 vendor/github.com/ThalesIgnite/crypto11/blockmode.go create mode 100644 vendor/github.com/ThalesIgnite/crypto11/certificates.go create mode 100644 vendor/github.com/ThalesIgnite/crypto11/common.go create mode 100644 vendor/github.com/ThalesIgnite/crypto11/config create mode 100644 vendor/github.com/ThalesIgnite/crypto11/crypto11.go create mode 100644 vendor/github.com/ThalesIgnite/crypto11/dsa.go create mode 100644 vendor/github.com/ThalesIgnite/crypto11/ecdsa.go create mode 100644 vendor/github.com/ThalesIgnite/crypto11/hmac.go create mode 100644 vendor/github.com/ThalesIgnite/crypto11/keys.go create mode 100644 vendor/github.com/ThalesIgnite/crypto11/rand.go create mode 100644 vendor/github.com/ThalesIgnite/crypto11/rsa.go create mode 100644 vendor/github.com/ThalesIgnite/crypto11/sessions.go create mode 100644 vendor/github.com/ThalesIgnite/crypto11/symmetric.go create mode 100644 vendor/github.com/miekg/pkcs11/.gitignore create mode 100644 vendor/github.com/miekg/pkcs11/.travis.yml create mode 100644 vendor/github.com/miekg/pkcs11/LICENSE create mode 100644 vendor/github.com/miekg/pkcs11/Makefile.release create mode 100644 vendor/github.com/miekg/pkcs11/README.md create mode 100644 vendor/github.com/miekg/pkcs11/const.go create mode 100644 vendor/github.com/miekg/pkcs11/error.go create mode 100644 vendor/github.com/miekg/pkcs11/hsm.db create mode 100644 vendor/github.com/miekg/pkcs11/params.go create mode 100644 vendor/github.com/miekg/pkcs11/pkcs11.go create mode 100644 vendor/github.com/miekg/pkcs11/pkcs11.h create mode 100644 vendor/github.com/miekg/pkcs11/pkcs11f.h create mode 100644 vendor/github.com/miekg/pkcs11/pkcs11go.h create mode 100644 vendor/github.com/miekg/pkcs11/pkcs11t.h create mode 100644 vendor/github.com/miekg/pkcs11/release.go create mode 100644 vendor/github.com/miekg/pkcs11/softhsm.conf create mode 100644 vendor/github.com/miekg/pkcs11/softhsm2.conf create mode 100644 vendor/github.com/miekg/pkcs11/types.go create mode 100644 vendor/github.com/miekg/pkcs11/vendor.go create mode 100644 vendor/github.com/thales-e-security/pool/LICENSE create mode 100644 vendor/github.com/thales-e-security/pool/README.md create mode 100644 vendor/github.com/thales-e-security/pool/atomic.go create mode 100644 vendor/github.com/thales-e-security/pool/resource_pool.go create mode 100644 vendor/github.com/thales-e-security/pool/semaphore.go create mode 100644 vendor/github.com/thales-e-security/pool/timer.go diff --git a/go.work b/go.work index 115087983aad5..73eaf9097578f 100644 --- a/go.work +++ b/go.work @@ -11,6 +11,7 @@ use ( ./staging/src/k8s.io/cloud-provider ./staging/src/k8s.io/cluster-bootstrap ./staging/src/k8s.io/code-generator + ./staging/src/k8s.io/code-generator/examples ./staging/src/k8s.io/component-base ./staging/src/k8s.io/component-helpers ./staging/src/k8s.io/controller-manager @@ -19,6 +20,7 @@ use ( ./staging/src/k8s.io/dynamic-resource-allocation ./staging/src/k8s.io/endpointslice ./staging/src/k8s.io/kms + ./staging/src/k8s.io/kms/internal/plugins/_mock ./staging/src/k8s.io/kube-aggregator ./staging/src/k8s.io/kube-controller-manager ./staging/src/k8s.io/kube-proxy diff --git a/hack/update-go-workspace.sh b/hack/update-go-workspace.sh index 2327087a1ecb1..596a6f9c2ebe2 100755 --- a/hack/update-go-workspace.sh +++ b/hack/update-go-workspace.sh @@ -65,7 +65,7 @@ __EOF__ # Generate the top-level workspace. go work init go work edit -use . -git ls-files -z ':(glob)./staging/src/k8s.io/*/go.mod' \ +git ls-files -z ':(glob)./staging/src/k8s.io/**/go.mod' \ | xargs -0 -n1 dirname -z \ | xargs -0 -n1 go work edit -use fix_go_version_line go.work diff --git a/vendor/github.com/ThalesIgnite/crypto11/.gitignore b/vendor/github.com/ThalesIgnite/crypto11/.gitignore new file mode 100644 index 0000000000000..8e2feb5cddaf5 --- /dev/null +++ b/vendor/github.com/ThalesIgnite/crypto11/.gitignore @@ -0,0 +1,6 @@ +*~ +crypto11.test +demo/*.pem +demo/demo +/.idea/ +/vendor/ diff --git a/vendor/github.com/ThalesIgnite/crypto11/.travis.yml b/vendor/github.com/ThalesIgnite/crypto11/.travis.yml new file mode 100644 index 0000000000000..d383d67d8642e --- /dev/null +++ b/vendor/github.com/ThalesIgnite/crypto11/.travis.yml @@ -0,0 +1,27 @@ +dist: xenial +language: go + +go: + - "1.13.x" + +# Xenial comes with v2.0.0 SoftHSM2, which seems to have issues with ECDSA +# code points +addons: + apt: + sources: + - sourceline: 'ppa:pkg-opendnssec/ppa' + packages: + - softhsm2 + +env: + - GO111MODULE=on + + +script: + - echo directories.tokendir = `pwd`/tokens > softhsm2.conf + - echo objecstore.backend = file >> softhsm2.conf + - cat softhsm2.conf + - mkdir tokens + - export SOFTHSM2_CONF=`pwd`/softhsm2.conf + - softhsm2-util --init-token --slot 0 --label token1 --so-pin sopassword --pin password + - go test -mod readonly -v -bench . diff --git a/vendor/github.com/ThalesIgnite/crypto11/LICENCE.txt b/vendor/github.com/ThalesIgnite/crypto11/LICENCE.txt new file mode 100644 index 0000000000000..2992f5e9c22d2 --- /dev/null +++ b/vendor/github.com/ThalesIgnite/crypto11/LICENCE.txt @@ -0,0 +1,22 @@ +MIT License. + +Copyright 2016, 2017 Thales e-Security, Inc + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/ThalesIgnite/crypto11/README.md b/vendor/github.com/ThalesIgnite/crypto11/README.md new file mode 100644 index 0000000000000..4fccaec344d06 --- /dev/null +++ b/vendor/github.com/ThalesIgnite/crypto11/README.md @@ -0,0 +1,208 @@ +Crypto11 +======== + +[![GoDoc](https://godoc.org/github.com/ThalesIgnite/crypto11?status.svg)](https://godoc.org/github.com/ThalesIgnite/crypto11) +[![Build Status](https://travis-ci.com/ThalesIgnite/crypto11.svg?branch=master)](https://travis-ci.com/ThalesIgnite/crypto11) + +This is an implementation of the standard Golang crypto interfaces that +uses [PKCS#11](http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/errata01/os/pkcs11-base-v2.40-errata01-os-complete.html) as a backend. The supported features are: + +* Generation and retrieval of RSA, DSA and ECDSA keys. +* Importing and retrieval of x509 certificates +* PKCS#1 v1.5 signing. +* PKCS#1 PSS signing. +* PKCS#1 v1.5 decryption +* PKCS#1 OAEP decryption +* ECDSA signing. +* DSA signing. +* Random number generation. +* AES and DES3 encryption and decryption. +* HMAC support. + +Signing is done through the +[crypto.Signer](https://golang.org/pkg/crypto/#Signer) interface and +decryption through +[crypto.Decrypter](https://golang.org/pkg/crypto/#Decrypter). + +To verify signatures or encrypt messages, retrieve the public key and do it in software. + +See [the documentation](https://godoc.org/github.com/ThalesIgnite/crypto11) for details of various limitations, +especially regarding symmetric crypto. + + +Installation +============ + +Since v1.0.0, crypto11 requires Go v1.11+. Install the library by running: + +```bash +go get github.com/ThalesIgnite/crypto11 +``` + +The crypto11 library needs to be configured with information about your PKCS#11 installation. This is either done programmatically +(see the `Config` struct in [the documentation](https://godoc.org/github.com/ThalesIgnite/crypto11)) or via a configuration +file. The configuration file is a JSON representation of the `Config` struct. + +A minimal configuration file looks like this: + +```json +{ + "Path" : "/usr/lib/softhsm/libsofthsm2.so", + "TokenLabel": "token1", + "Pin" : "password" +} +``` + +- `Path` points to the library from your PKCS#11 vendor. +- `TokenLabel` is the `CKA_LABEL` of the token you wish to use. +- `Pin` is the password for the `CKU_USER` user. + +Testing Guidance +================ + +Disabling tests +--------------- + +To disable specific tests, set the environment variable `CRYPTO11_SKIP=` where `` is a comma-separated +list of the following options: + +* `CERTS` - disables certificate-related tests. Needed for AWS CloudHSM, which doesn't support certificates. +* `OAEP_LABEL` - disables RSA OAEP encryption tests that use source data encoding parameter (also known as a 'label' +in some crypto libraries). Needed for AWS CloudHSM. +* `DSA` - disables DSA tests. Needed for AWS CloudHSM (and any other tokens not supporting DSA). + +Testing with Thales Luna HSM +---------------------------- + + + + +Testing with AWS CloudHSM +------------------------- + +A minimal configuration file for CloudHSM will look like this: + +```json +{ + "Path" : "/opt/cloudhsm/lib/libcloudhsm_pkcs11_standard.so", + "TokenLabel": "cavium", + "Pin" : "username:password", + "UseGCMIVFromHSM" : true, +} +``` + +To run the test suite you must skip unsupported tests: + +``` +CRYPTO11_SKIP=CERTS,OAEP_LABEL,DSA go test -v +``` + +Be sure to take note of the supported mechanisms, key types and other idiosyncrasies described at +https://docs.aws.amazon.com/cloudhsm/latest/userguide/pkcs11-library.html. Here's a collection of things we +noticed when testing with the v2.0.4 PKCS#11 library: + +- 1024-bit RSA keys don't appear to be supported, despite what `C_GetMechanismInfo` tells you. +- The `CKM_RSA_PKCS_OAEP` mechanism doesn't support source data. I.e. when constructing a `CK_RSA_PKCS_OAEP_PARAMS`, +one must set `pSourceData` to `NULL` and `ulSourceDataLen` to zero. +- CloudHSM will generate it's own IV for GCM mode. This is described in their documentation, see footnote 4 on +https://docs.aws.amazon.com/cloudhsm/latest/userguide/pkcs11-mechanisms.html. +- It appears that `CKA_ID` values must be unique, otherwise you get a `CKR_ATTRIBUTE_VALUE_INVALID` error. +- Very rapid session opening can trigger the following error: + ``` + C_OpenSession failed with error CKR_ARGUMENTS_BAD : 0x00000007 + HSM error 8c: HSM Error: Already maximum number of sessions are issued + ``` + +Testing with SoftHSM2 +--------------------- + +To set up a slot: + + $ cat softhsm2.conf + directories.tokendir = /home/rjk/go/src/github.com/ThalesIgnite/crypto11/tokens + objectstore.backend = file + log.level = INFO + $ mkdir tokens + $ export SOFTHSM2_CONF=`pwd`/softhsm2.conf + $ softhsm2-util --init-token --slot 0 --label test + === SO PIN (4-255 characters) === + Please enter SO PIN: ******** + Please reenter SO PIN: ******** + === User PIN (4-255 characters) === + Please enter user PIN: ******** + Please reenter user PIN: ******** + The token has been initialized. + +The configuration looks like this: + + $ cat config + { + "Path" : "/usr/lib/softhsm/libsofthsm2.so", + "TokenLabel": "test", + "Pin" : "password" + } + +(At time of writing) OAEP is only partial and HMAC is unsupported, so expect test skips. + +Testing with nCipher nShield +-------------------- + +In all cases, it's worth enabling nShield PKCS#11 log output: + + export CKNFAST_DEBUG=2 + +To protect keys with a 1/N operator cardset: + + $ cat config + { + "Path" : "/opt/nfast/toolkits/pkcs11/libcknfast.so", + "TokenLabel": "rjk", + "Pin" : "password" + } + +You can also identify the token by serial number, which in this case +means the first 16 hex digits of the operator cardset's token hash: + + $ cat config + { + "Path" : "/opt/nfast/toolkits/pkcs11/libcknfast.so", + "TokenSerial": "1d42780caa22efd5", + "Pin" : "password" + } + +A card from the cardset must be in the slot when you run `go test`. + +To protect keys with the module only, use the 'accelerator' token: + + $ cat config + { + "Path" : "/opt/nfast/toolkits/pkcs11/libcknfast.so", + "TokenLabel": "accelerator", + "Pin" : "password" + } + +(At time of writing) GCM is not implemented, so expect test skips. + +Limitations +=========== + + * The [PKCS1v15DecryptOptions SessionKeyLen](https://golang.org/pkg/crypto/rsa/#PKCS1v15DecryptOptions) field +is not implemented and an error is returned if it is nonzero. +The reason for this is that it is not possible for crypto11 to guarantee the constant-time behavior in the specification. +See [issue #5](https://github.com/ThalesIgnite/crypto11/issues/5) for further discussion. + * Symmetric crypto support via [cipher.Block](https://golang.org/pkg/crypto/cipher/#Block) is very slow. +You can use the `BlockModeCloser` API +(over 400 times as fast on my computer) +but you must call the Close() +interface (not found in [cipher.BlockMode](https://golang.org/pkg/crypto/cipher/#BlockMode)). +See [issue #6](https://github.com/ThalesIgnite/crypto11/issues/6) for further discussion. + +Contributions +======== + +Contributions are gratefully received. Before beginning work on sizeable changes, please open an issue first to +discuss. + +Here are some topics we'd like to cover: + +* Full test instructions for additional PKCS#11 implementations. diff --git a/vendor/github.com/ThalesIgnite/crypto11/aead.go b/vendor/github.com/ThalesIgnite/crypto11/aead.go new file mode 100644 index 0000000000000..2b0438d476310 --- /dev/null +++ b/vendor/github.com/ThalesIgnite/crypto11/aead.go @@ -0,0 +1,189 @@ +// Copyright 2018 Thales e-Security, Inc +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package crypto11 + +import ( + "crypto/cipher" + "errors" + "fmt" + + "github.com/miekg/pkcs11" +) + +// cipher.AEAD ---------------------------------------------------------- + +// A PaddingMode is used by a block cipher (see NewCBC). +type PaddingMode int + +const ( + // PaddingNone represents a block cipher with no padding. + PaddingNone PaddingMode = iota + + // PaddingPKCS represents a block cipher used with PKCS#7 padding. + PaddingPKCS +) + +var errBadGCMNonceSize = errors.New("nonce slice too small to hold IV") + +type genericAead struct { + key *SecretKey + + overhead int + + nonceSize int + + // Note - if the GCMParams result is non-nil, the caller must call Free() on the params when + // finished. + makeMech func(nonce []byte, additionalData []byte, encrypt bool) ([]*pkcs11.Mechanism, *pkcs11.GCMParams, error) +} + +// NewGCM returns a given cipher wrapped in Galois Counter Mode, with the standard +// nonce length. +// +// This depends on the HSM supporting the CKM_*_GCM mechanism. If it is not supported +// then you must use cipher.NewGCM; it will be slow. +func (key *SecretKey) NewGCM() (cipher.AEAD, error) { + if key.Cipher.GCMMech == 0 { + return nil, fmt.Errorf("GCM not implemented for key type %#x", key.Cipher.GenParams[0].KeyType) + } + + g := genericAead{ + key: key, + overhead: 16, + nonceSize: key.context.cfg.GCMIVLength, + makeMech: func(nonce []byte, additionalData []byte, encrypt bool) ([]*pkcs11.Mechanism, *pkcs11.GCMParams, error) { + var params *pkcs11.GCMParams + + if (encrypt && key.context.cfg.UseGCMIVFromHSM && + !key.context.cfg.GCMIVFromHSMControl.SupplyIvForHSMGCMEncrypt) || (!encrypt && + key.context.cfg.UseGCMIVFromHSM && !key.context.cfg.GCMIVFromHSMControl.SupplyIvForHSMGCMDecrypt) { + params = pkcs11.NewGCMParams(nil, additionalData, 16*8 /*bits*/) + } else { + params = pkcs11.NewGCMParams(nonce, additionalData, 16*8 /*bits*/) + } + return []*pkcs11.Mechanism{pkcs11.NewMechanism(key.Cipher.GCMMech, params)}, params, nil + }, + } + return g, nil +} + +// NewCBC returns a given cipher wrapped in CBC mode. +// +// Despite the cipher.AEAD return type, there is no support for additional data and no authentication. +// This method exists to provide a convenient way to do bulk (possibly padded) CBC encryption. +// Think carefully before passing the cipher.AEAD to any consumer that expects authentication. +func (key *SecretKey) NewCBC(paddingMode PaddingMode) (cipher.AEAD, error) { + + var pkcsMech uint + + switch paddingMode { + case PaddingNone: + pkcsMech = key.Cipher.CBCMech + case PaddingPKCS: + pkcsMech = key.Cipher.CBCPKCSMech + default: + return nil, errors.New("unrecognized padding mode") + } + + g := genericAead{ + key: key, + overhead: 0, + nonceSize: key.BlockSize(), + makeMech: func(nonce []byte, additionalData []byte, encrypt bool) ([]*pkcs11.Mechanism, *pkcs11.GCMParams, error) { + if len(additionalData) > 0 { + return nil, nil, errors.New("additional data not supported for CBC mode") + } + + return []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcsMech, nonce)}, nil, nil + }, + } + + return g, nil +} + +func (g genericAead) NonceSize() int { + return g.nonceSize +} + +func (g genericAead) Overhead() int { + return g.overhead +} + +func (g genericAead) Seal(dst, nonce, plaintext, additionalData []byte) []byte { + + var result []byte + if err := g.key.context.withSession(func(session *pkcs11Session) (err error) { + mech, params, err := g.makeMech(nonce, additionalData, true) + + if err != nil { + return err + } + defer params.Free() + + if err = session.ctx.EncryptInit(session.handle, mech, g.key.handle); err != nil { + err = fmt.Errorf("C_EncryptInit: %v", err) + return + } + if result, err = session.ctx.Encrypt(session.handle, plaintext); err != nil { + err = fmt.Errorf("C_Encrypt: %v", err) + return + } + + if g.key.context.cfg.UseGCMIVFromHSM && g.key.context.cfg.GCMIVFromHSMControl.SupplyIvForHSMGCMEncrypt { + if len(nonce) != len(params.IV()) { + return errBadGCMNonceSize + } + } + + return + }); err != nil { + panic(err) + } else { + dst = append(dst, result...) + } + return dst +} + +func (g genericAead) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { + var result []byte + if err := g.key.context.withSession(func(session *pkcs11Session) (err error) { + mech, params, err := g.makeMech(nonce, additionalData, false) + if err != nil { + return + } + defer params.Free() + + if err = session.ctx.DecryptInit(session.handle, mech, g.key.handle); err != nil { + err = fmt.Errorf("C_DecryptInit: %v", err) + return + } + if result, err = session.ctx.Decrypt(session.handle, ciphertext); err != nil { + err = fmt.Errorf("C_Decrypt: %v", err) + return + } + return + }); err != nil { + return nil, err + } + dst = append(dst, result...) + return dst, nil +} diff --git a/vendor/github.com/ThalesIgnite/crypto11/attributes.go b/vendor/github.com/ThalesIgnite/crypto11/attributes.go new file mode 100644 index 0000000000000..17ae57525b00a --- /dev/null +++ b/vendor/github.com/ThalesIgnite/crypto11/attributes.go @@ -0,0 +1,510 @@ +package crypto11 + +import ( + "errors" + "fmt" + "strings" + + "github.com/miekg/pkcs11" +) + +// AttributeType represents a PKCS#11 CK_ATTRIBUTE value. +type AttributeType = uint + +// Attribute represents a PKCS#11 CK_ATTRIBUTE type. +type Attribute = pkcs11.Attribute + +//noinspection GoUnusedConst,GoDeprecation +const ( + CkaClass = AttributeType(0x00000000) + CkaToken = AttributeType(0x00000001) + CkaPrivate = AttributeType(0x00000002) + CkaLabel = AttributeType(0x00000003) + CkaApplication = AttributeType(0x00000010) + CkaValue = AttributeType(0x00000011) + CkaObjectId = AttributeType(0x00000012) + CkaCertificateType = AttributeType(0x00000080) + CkaIssuer = AttributeType(0x00000081) + CkaSerialNumber = AttributeType(0x00000082) + CkaAcIssuer = AttributeType(0x00000083) + CkaOwner = AttributeType(0x00000084) + CkaAttrTypes = AttributeType(0x00000085) + CkaTrusted = AttributeType(0x00000086) + CkaCertificateCategory = AttributeType(0x00000087) + CkaJavaMIDPSecurityDomain = AttributeType(0x00000088) + CkaUrl = AttributeType(0x00000089) + CkaHashOfSubjectPublicKey = AttributeType(0x0000008A) + CkaHashOfIssuerPublicKey = AttributeType(0x0000008B) + CkaNameHashAlgorithm = AttributeType(0x0000008C) + CkaCheckValue = AttributeType(0x00000090) + + CkaKeyType = AttributeType(0x00000100) + CkaSubject = AttributeType(0x00000101) + CkaId = AttributeType(0x00000102) + CkaSensitive = AttributeType(0x00000103) + CkaEncrypt = AttributeType(0x00000104) + CkaDecrypt = AttributeType(0x00000105) + CkaWrap = AttributeType(0x00000106) + CkaUnwrap = AttributeType(0x00000107) + CkaSign = AttributeType(0x00000108) + CkaSignRecover = AttributeType(0x00000109) + CkaVerify = AttributeType(0x0000010A) + CkaVerifyRecover = AttributeType(0x0000010B) + CkaDerive = AttributeType(0x0000010C) + CkaStartDate = AttributeType(0x00000110) + CkaEndDate = AttributeType(0x00000111) + CkaModulus = AttributeType(0x00000120) + CkaModulusBits = AttributeType(0x00000121) + CkaPublicExponent = AttributeType(0x00000122) + CkaPrivateExponent = AttributeType(0x00000123) + CkaPrime1 = AttributeType(0x00000124) + CkaPrime2 = AttributeType(0x00000125) + CkaExponent1 = AttributeType(0x00000126) + CkaExponent2 = AttributeType(0x00000127) + CkaCoefficient = AttributeType(0x00000128) + CkaPublicKeyInfo = AttributeType(0x00000129) + CkaPrime = AttributeType(0x00000130) + CkaSubprime = AttributeType(0x00000131) + CkaBase = AttributeType(0x00000132) + + CkaPrimeBits = AttributeType(0x00000133) + CkaSubprimeBits = AttributeType(0x00000134) + /* (To retain backwards-compatibility) */ + CkaSubPrimeBits = CkaSubprimeBits + + CkaValueBits = AttributeType(0x00000160) + CkaValueLen = AttributeType(0x00000161) + CkaExtractable = AttributeType(0x00000162) + CkaLocal = AttributeType(0x00000163) + CkaNeverExtractable = AttributeType(0x00000164) + CkaAlwaysSensitive = AttributeType(0x00000165) + CkaKeyGenMechanism = AttributeType(0x00000166) + + CkaModifiable = AttributeType(0x00000170) + CkaCopyable = AttributeType(0x00000171) + + /* new for v2.40 */ + CkaDestroyable = AttributeType(0x00000172) + + /* CKA_ECDSA_PARAMS is deprecated in v2.11, + * CKA_EC_PARAMS is preferred. */ + CkaEcdsaParams = AttributeType(0x00000180) + CkaEcParams = AttributeType(0x00000180) + + CkaEcPoint = AttributeType(0x00000181) + + /* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS, + * are new for v2.10. Deprecated in v2.11 and onwards. */ + CkaSecondaryAuth = AttributeType(0x00000200) /* Deprecated */ + CkaAuthPinFlags = AttributeType(0x00000201) /* Deprecated */ + + CkaAlwaysAuthenticate = AttributeType(0x00000202) + + CkaWrapWithTrusted = AttributeType(0x00000210) + + ckfArrayAttribute = AttributeType(0x40000000) + + CkaWrapTemplate = ckfArrayAttribute | AttributeType(0x00000211) + CkaUnwrapTemplate = ckfArrayAttribute | AttributeType(0x00000212) + + CkaOtpFormat = AttributeType(0x00000220) + CkaOtpLength = AttributeType(0x00000221) + CkaOtpTimeInterval = AttributeType(0x00000222) + CkaOtpUserFriendlyMode = AttributeType(0x00000223) + CkaOtpChallengeRequirement = AttributeType(0x00000224) + CkaOtpTimeRequirement = AttributeType(0x00000225) + CkaOtpCounterRequirement = AttributeType(0x00000226) + CkaOtpPinRequirement = AttributeType(0x00000227) + CkaOtpCounter = AttributeType(0x0000022E) + CkaOtpTime = AttributeType(0x0000022F) + CkaOtpUserIdentifier = AttributeType(0x0000022A) + CkaOtpServiceIdentifier = AttributeType(0x0000022B) + CkaOtpServiceLogo = AttributeType(0x0000022C) + CkaOtpServiceLogoType = AttributeType(0x0000022D) + + CkaGOSTR3410Params = AttributeType(0x00000250) + CkaGOSTR3411Params = AttributeType(0x00000251) + CkaGOST28147Params = AttributeType(0x00000252) + + CkaHwFeatureType = AttributeType(0x00000300) + CkaResetOnInit = AttributeType(0x00000301) + CkaHasReset = AttributeType(0x00000302) + + CkaPixelX = AttributeType(0x00000400) + CkaPixelY = AttributeType(0x00000401) + CkaResolution = AttributeType(0x00000402) + CkaCharRows = AttributeType(0x00000403) + CkaCharColumns = AttributeType(0x00000404) + CkaColor = AttributeType(0x00000405) + CkaBitsPerPixel = AttributeType(0x00000406) + CkaCharSets = AttributeType(0x00000480) + CkaEncodingMethods = AttributeType(0x00000481) + CkaMimeTypes = AttributeType(0x00000482) + CkaMechanismType = AttributeType(0x00000500) + CkaRequiredCmsAttributes = AttributeType(0x00000501) + CkaDefaultCmsAttributes = AttributeType(0x00000502) + CkaSupportedCmsAttributes = AttributeType(0x00000503) + CkaAllowedMechanisms = ckfArrayAttribute | AttributeType(0x00000600) +) + +// NewAttribute is a helper function that populates a new Attribute for common data types. This function will +// return an error if value is not of type bool, int, uint, string, []byte or time.Time (or is nil). +func NewAttribute(attributeType AttributeType, value interface{}) (a *Attribute, err error) { + // catch any panics from the pkcs11.NewAttribute() call to handle the error cleanly + defer func() { + if r := recover(); r != nil { + err = errors.New(fmt.Sprintf("failed creating Attribute: %v", r)) + } + }() + + pAttr := pkcs11.NewAttribute(attributeType, value) + return pAttr, nil +} + +// CopyAttribute returns a deep copy of the given Attribute. +func CopyAttribute(a *Attribute) *Attribute { + var value []byte + if a.Value != nil && len(a.Value) > 0 { + value = append([]byte(nil), a.Value...) + } + return &pkcs11.Attribute{ + Type: a.Type, + Value: value, + } +} + +// An AttributeSet groups together operations that are common for a collection of Attributes. +type AttributeSet map[AttributeType]*Attribute + +// NewAttributeSet creates an empty AttributeSet. +func NewAttributeSet() AttributeSet { + return make(AttributeSet) +} + +// Set stores a new attribute in the AttributeSet. Any existing value will be overwritten. This function will return an +// error if value is not of type bool, int, uint, string, []byte or time.Time (or is nil). +func (a AttributeSet) Set(attributeType AttributeType, value interface{}) error { + attr, err := NewAttribute(attributeType, value) + if err != nil { + return err + } + a[attributeType] = attr + return nil +} + +// cloneFrom make this AttributeSet a clone of the supplied set. Values are deep copied. +func (a AttributeSet) cloneFrom(set AttributeSet) { + for key := range a { + delete(a, key) + } + + // Use Copy to do the deep cloning for us + c := set.Copy() + for k, v := range c { + a[k] = v + } +} + +// AddIfNotPresent adds the attributes if the Attribute Type is not already present in the AttributeSet. +func (a AttributeSet) AddIfNotPresent(additional []*Attribute) { + for _, additionalAttr := range additional { + // Only add the attribute if it is not already present in the Attribute map + if _, ok := a[additionalAttr.Type]; !ok { + a[additionalAttr.Type] = additionalAttr + } + } +} + +// ToSlice returns a deep copy of Attributes contained in the AttributeSet. +func (a AttributeSet) ToSlice() []*Attribute { + var attributes []*Attribute + for _, v := range a { + duplicateAttr := CopyAttribute(v) + attributes = append(attributes, duplicateAttr) + } + return attributes +} + +// Copy returns a deep copy of the AttributeSet. This function will return an error if value is not of type +// bool, int, uint, string, []byte or time.Time (or is nil). +func (a AttributeSet) Copy() AttributeSet { + b := NewAttributeSet() + for _, v := range a { + b[v.Type] = CopyAttribute(v) + } + return b +} + +// Unset removes an attribute from the attributes set. If the set does not contain the attribute, this +// is a no-op. +func (a AttributeSet) Unset(attributeType AttributeType) { + delete(a, attributeType) +} + +func (a AttributeSet) String() string { + result := new(strings.Builder) + for attr, value := range a { + _, _ = fmt.Fprintf(result, "%s: %x\n", attributeTypeString(attr), value.Value) + } + return result.String() +} + +// NewAttributeSetWithID is a helper function that populates a new slice of Attributes with the provided ID. +// This function returns an error if the ID is an empty slice. +func NewAttributeSetWithID(id []byte) (AttributeSet, error) { + if err := notNilBytes(id, "id"); err != nil { + return nil, err + } + a := NewAttributeSet() + _ = a.Set(CkaId, id) // error not possible for []byte + return a, nil +} + +// NewAttributeSetWithIDAndLabel is a helper function that populates a new slice of Attributes with the +// provided ID and Label. This function returns an error if either the ID or the Label is an empty slice. +func NewAttributeSetWithIDAndLabel(id, label []byte) (a AttributeSet, err error) { + if a, err = NewAttributeSetWithID(id); err != nil { + return nil, err + } + + if err := notNilBytes(label, "label"); err != nil { + return nil, err + } + + _ = a.Set(CkaLabel, label) // error not possible with []byte + return a, nil +} + +func attributeTypeString(a AttributeType) string { + //noinspection GoDeprecation + switch a { + case CkaClass: + return "CkaClass" + case CkaToken: + return "CkaToken" + case CkaPrivate: + return "CkaPrivate" + case CkaLabel: + return "CkaLabel" + case CkaApplication: + return "CkaApplication" + case CkaValue: + return "CkaValue" + case CkaObjectId: + return "CkaObjectId" + case CkaCertificateType: + return "CkaCertificateType" + case CkaIssuer: + return "CkaIssuer" + case CkaSerialNumber: + return "CkaSerialNumber" + case CkaAcIssuer: + return "CkaAcIssuer" + case CkaOwner: + return "CkaOwner" + case CkaAttrTypes: + return "CkaAttrTypes" + case CkaTrusted: + return "CkaTrusted" + case CkaCertificateCategory: + return "CkaCertificateCategory" + case CkaJavaMIDPSecurityDomain: + return "CkaJavaMIDPSecurityDomain" + case CkaUrl: + return "CkaUrl" + case CkaHashOfSubjectPublicKey: + return "CkaHashOfSubjectPublicKey" + case CkaHashOfIssuerPublicKey: + return "CkaHashOfIssuerPublicKey" + case CkaNameHashAlgorithm: + return "CkaNameHashAlgorithm" + case CkaCheckValue: + return "CkaCheckValue" + + case CkaKeyType: + return "CkaKeyType" + case CkaSubject: + return "CkaSubject" + case CkaId: + return "CkaId" + case CkaSensitive: + return "CkaSensitive" + case CkaEncrypt: + return "CkaEncrypt" + case CkaDecrypt: + return "CkaDecrypt" + case CkaWrap: + return "CkaWrap" + case CkaUnwrap: + return "CkaUnwrap" + case CkaSign: + return "CkaSign" + case CkaSignRecover: + return "CkaSignRecover" + case CkaVerify: + return "CkaVerify" + case CkaVerifyRecover: + return "CkaVerifyRecover" + case CkaDerive: + return "CkaDerive" + case CkaStartDate: + return "CkaStartDate" + case CkaEndDate: + return "CkaEndDate" + case CkaModulus: + return "CkaModulus" + case CkaModulusBits: + return "CkaModulusBits" + case CkaPublicExponent: + return "CkaPublicExponent" + case CkaPrivateExponent: + return "CkaPrivateExponent" + case CkaPrime1: + return "CkaPrime1" + case CkaPrime2: + return "CkaPrime2" + case CkaExponent1: + return "CkaExponent1" + case CkaExponent2: + return "CkaExponent2" + case CkaCoefficient: + return "CkaCoefficient" + case CkaPublicKeyInfo: + return "CkaPublicKeyInfo" + case CkaPrime: + return "CkaPrime" + case CkaSubprime: + return "CkaSubprime" + case CkaBase: + return "CkaBase" + + case CkaPrimeBits: + return "CkaPrimeBits" + case CkaSubprimeBits: + return "CkaSubprimeBits" + + case CkaValueBits: + return "CkaValueBits" + case CkaValueLen: + return "CkaValueLen" + case CkaExtractable: + return "CkaExtractable" + case CkaLocal: + return "CkaLocal" + case CkaNeverExtractable: + return "CkaNeverExtractable" + case CkaAlwaysSensitive: + return "CkaAlwaysSensitive" + case CkaKeyGenMechanism: + return "CkaKeyGenMechanism" + + case CkaModifiable: + return "CkaModifiable" + case CkaCopyable: + return "CkaCopyable" + + case CkaDestroyable: + return "CkaDestroyable" + + case CkaEcParams: + return "CkaEcParams" + + case CkaEcPoint: + return "CkaEcPoint" + + case CkaSecondaryAuth: + return "CkaSecondaryAuth" + case CkaAuthPinFlags: + return "CkaAuthPinFlags" + + case CkaAlwaysAuthenticate: + return "CkaAlwaysAuthenticate" + + case CkaWrapWithTrusted: + return "CkaWrapWithTrusted" + + case ckfArrayAttribute: + return "ckfArrayAttribute" + + case CkaWrapTemplate: + return "CkaWrapTemplate" + case CkaUnwrapTemplate: + return "CkaUnwrapTemplate" + + case CkaOtpFormat: + return "CkaOtpFormat" + case CkaOtpLength: + return "CkaOtpLength" + case CkaOtpTimeInterval: + return "CkaOtpTimeInterval" + case CkaOtpUserFriendlyMode: + return "CkaOtpUserFriendlyMode" + case CkaOtpChallengeRequirement: + return "CkaOtpChallengeRequirement" + case CkaOtpTimeRequirement: + return "CkaOtpTimeRequirement" + case CkaOtpCounterRequirement: + return "CkaOtpCounterRequirement" + case CkaOtpPinRequirement: + return "CkaOtpPinRequirement" + case CkaOtpCounter: + return "CkaOtpCounter" + case CkaOtpTime: + return "CkaOtpTime" + case CkaOtpUserIdentifier: + return "CkaOtpUserIdentifier" + case CkaOtpServiceIdentifier: + return "CkaOtpServiceIdentifier" + case CkaOtpServiceLogo: + return "CkaOtpServiceLogo" + case CkaOtpServiceLogoType: + return "CkaOtpServiceLogoType" + + case CkaGOSTR3410Params: + return "CkaGOSTR3410Params" + case CkaGOSTR3411Params: + return "CkaGOSTR3411Params" + case CkaGOST28147Params: + return "CkaGOST28147Params" + + case CkaHwFeatureType: + return "CkaHwFeatureType" + case CkaResetOnInit: + return "CkaResetOnInit" + case CkaHasReset: + return "CkaHasReset" + + case CkaPixelX: + return "CkaPixelX" + case CkaPixelY: + return "CkaPixelY" + case CkaResolution: + return "CkaResolution" + case CkaCharRows: + return "CkaCharRows" + case CkaCharColumns: + return "CkaCharColumns" + case CkaColor: + return "CkaColor" + case CkaBitsPerPixel: + return "CkaBitsPerPixel" + case CkaCharSets: + return "CkaCharSets" + case CkaEncodingMethods: + return "CkaEncodingMethods" + case CkaMimeTypes: + return "CkaMimeTypes" + case CkaMechanismType: + return "CkaMechanismType" + case CkaRequiredCmsAttributes: + return "CkaRequiredCmsAttributes" + case CkaDefaultCmsAttributes: + return "CkaDefaultCmsAttributes" + case CkaSupportedCmsAttributes: + return "CkaSupportedCmsAttributes" + case CkaAllowedMechanisms: + return "CkaAllowedMechanisms" + default: + return "Unknown" + } +} diff --git a/vendor/github.com/ThalesIgnite/crypto11/block.go b/vendor/github.com/ThalesIgnite/crypto11/block.go new file mode 100644 index 0000000000000..6c612c948437a --- /dev/null +++ b/vendor/github.com/ThalesIgnite/crypto11/block.go @@ -0,0 +1,91 @@ +// Copyright 2018 Thales e-Security, Inc +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package crypto11 + +import ( + "fmt" + + "github.com/miekg/pkcs11" +) + +// cipher.Block --------------------------------------------------------- + +// BlockSize returns the cipher's block size in bytes. +func (key *SecretKey) BlockSize() int { + return key.Cipher.BlockSize +} + +// Decrypt decrypts the first block in src into dst. +// Dst and src must overlap entirely or not at all. +// +// Using this method for bulk operation is very inefficient, as it makes a round trip to the HSM +// (which may be network-connected) for each block. +// For more efficient operation, see NewCBCDecrypterCloser, NewCBCDecrypter or NewCBC. +func (key *SecretKey) Decrypt(dst, src []byte) { + var result []byte + if err := key.context.withSession(func(session *pkcs11Session) (err error) { + mech := []*pkcs11.Mechanism{pkcs11.NewMechanism(key.Cipher.ECBMech, nil)} + if err = session.ctx.DecryptInit(session.handle, mech, key.handle); err != nil { + return + } + if result, err = session.ctx.Decrypt(session.handle, src[:key.Cipher.BlockSize]); err != nil { + return + } + if len(result) != key.Cipher.BlockSize { + err = fmt.Errorf("C_Decrypt: returned %v bytes, wanted %v", len(result), key.Cipher.BlockSize) + return + } + return + }); err != nil { + panic(err) + } else { + copy(dst[:key.Cipher.BlockSize], result) + } +} + +// Encrypt encrypts the first block in src into dst. +// Dst and src must overlap entirely or not at all. +// +// Using this method for bulk operation is very inefficient, as it makes a round trip to the HSM +// (which may be network-connected) for each block. +// For more efficient operation, see NewCBCEncrypterCloser, NewCBCEncrypter or NewCBC. +func (key *SecretKey) Encrypt(dst, src []byte) { + var result []byte + if err := key.context.withSession(func(session *pkcs11Session) (err error) { + mech := []*pkcs11.Mechanism{pkcs11.NewMechanism(key.Cipher.ECBMech, nil)} + if err = session.ctx.EncryptInit(session.handle, mech, key.handle); err != nil { + return + } + if result, err = session.ctx.Encrypt(session.handle, src[:key.Cipher.BlockSize]); err != nil { + return + } + if len(result) != key.Cipher.BlockSize { + err = fmt.Errorf("C_Encrypt: unexpectedly returned %v bytes, wanted %v", len(result), key.Cipher.BlockSize) + return + } + return + }); err != nil { + panic(err) + } else { + copy(dst[:key.Cipher.BlockSize], result) + } +} diff --git a/vendor/github.com/ThalesIgnite/crypto11/blockmode.go b/vendor/github.com/ThalesIgnite/crypto11/blockmode.go new file mode 100644 index 0000000000000..f9cea6ab109cd --- /dev/null +++ b/vendor/github.com/ThalesIgnite/crypto11/blockmode.go @@ -0,0 +1,202 @@ +// Copyright 2018 Thales e-Security, Inc +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package crypto11 + +import ( + "crypto/cipher" + "runtime" + + "github.com/miekg/pkcs11" +) + +// cipher.BlockMode ----------------------------------------------------- + +// BlockModeCloser represents a block cipher running in a block-based mode (e.g. CBC). +// +// BlockModeCloser embeds cipher.BlockMode, and can be used as such. +// However, in this case +// (or if the Close() method is not explicitly called for any other reason), +// resources allocated to it may remain live indefinitely. +type BlockModeCloser interface { + cipher.BlockMode + + // Close() releases resources associated with the block mode. + Close() +} + +const ( + modeEncrypt = iota // blockModeCloser is in encrypt mode + modeDecrypt // blockModeCloser is in decrypt mode +) + +// NewCBCEncrypter returns a cipher.BlockMode which encrypts in cipher block chaining mode, using the given key. +// The length of iv must be the same as the key's block size. +// +// The new BlockMode acquires persistent resources which are released (eventually) by a finalizer. +// If this is a problem for your application then use NewCBCEncrypterCloser instead. +// +// If that is not possible then adding calls to runtime.GC() may help. +func (key *SecretKey) NewCBCEncrypter(iv []byte) (cipher.BlockMode, error) { + return key.newBlockModeCloser(key.Cipher.CBCMech, modeEncrypt, iv, true) +} + +// NewCBCDecrypter returns a cipher.BlockMode which decrypts in cipher block chaining mode, using the given key. +// The length of iv must be the same as the key's block size and must match the iv used to encrypt the data. +// +// The new BlockMode acquires persistent resources which are released (eventually) by a finalizer. +// If this is a problem for your application then use NewCBCDecrypterCloser instead. +// +// If that is not possible then adding calls to runtime.GC() may help. +func (key *SecretKey) NewCBCDecrypter(iv []byte) (cipher.BlockMode, error) { + return key.newBlockModeCloser(key.Cipher.CBCMech, modeDecrypt, iv, true) +} + +// NewCBCEncrypterCloser returns a BlockModeCloser which encrypts in cipher block chaining mode, using the given key. +// The length of iv must be the same as the key's block size. +// +// Use of NewCBCEncrypterCloser rather than NewCBCEncrypter represents a commitment to call the Close() method +// of the returned BlockModeCloser. +func (key *SecretKey) NewCBCEncrypterCloser(iv []byte) (BlockModeCloser, error) { + return key.newBlockModeCloser(key.Cipher.CBCMech, modeEncrypt, iv, false) +} + +// NewCBCDecrypterCloser returns a BlockModeCloser which decrypts in cipher block chaining mode, using the given key. +// The length of iv must be the same as the key's block size and must match the iv used to encrypt the data. +// +// Use of NewCBCDecrypterCloser rather than NewCBCEncrypter represents a commitment to call the Close() method +// of the returned BlockModeCloser. +func (key *SecretKey) NewCBCDecrypterCloser(iv []byte) (BlockModeCloser, error) { + return key.newBlockModeCloser(key.Cipher.CBCMech, modeDecrypt, iv, false) +} + +// blockModeCloser is a concrete implementation of BlockModeCloser supporting CBC. +type blockModeCloser struct { + // PKCS#11 session to use + session *pkcs11Session + + // Cipher block size + blockSize int + + // modeDecrypt or modeEncrypt + mode int + + // Cleanup function + cleanup func() +} + +// newBlockModeCloser creates a new blockModeCloser for the chosen mechanism and mode. +func (key *SecretKey) newBlockModeCloser(mech uint, mode int, iv []byte, setFinalizer bool) (*blockModeCloser, error) { + + session, err := key.context.getSession() + if err != nil { + return nil, err + } + + bmc := &blockModeCloser{ + session: session, + blockSize: key.Cipher.BlockSize, + mode: mode, + cleanup: func() { + key.context.pool.Put(session) + }, + } + mechDescription := []*pkcs11.Mechanism{pkcs11.NewMechanism(mech, iv)} + + switch mode { + case modeDecrypt: + err = session.ctx.DecryptInit(session.handle, mechDescription, key.handle) + case modeEncrypt: + err = session.ctx.EncryptInit(bmc.session.handle, mechDescription, key.handle) + default: + panic("unexpected mode") + } + if err != nil { + bmc.cleanup() + return nil, err + } + if setFinalizer { + runtime.SetFinalizer(bmc, finalizeBlockModeCloser) + } + + return bmc, nil +} + +func finalizeBlockModeCloser(obj interface{}) { + obj.(*blockModeCloser).Close() +} + +func (bmc *blockModeCloser) BlockSize() int { + return bmc.blockSize +} + +func (bmc *blockModeCloser) CryptBlocks(dst, src []byte) { + if len(dst) < len(src) { + panic("destination buffer too small") + } + if len(src)%bmc.blockSize != 0 { + panic("input is not a whole number of blocks") + } + var result []byte + var err error + switch bmc.mode { + case modeDecrypt: + result, err = bmc.session.ctx.DecryptUpdate(bmc.session.handle, src) + case modeEncrypt: + result, err = bmc.session.ctx.EncryptUpdate(bmc.session.handle, src) + } + if err != nil { + panic(err) + } + // PKCS#11 2.40 s5.2 says that the operation must produce as much output + // as possible, so we should never have less than we submitted for CBC. + // This could be different for other modes but we don't implement any yet. + if len(result) != len(src) { + panic("nontrivial result from *Final operation") + } + copy(dst[:len(result)], result) + runtime.KeepAlive(bmc) +} + +func (bmc *blockModeCloser) Close() { + if bmc.session == nil { + return + } + var result []byte + var err error + switch bmc.mode { + case modeDecrypt: + result, err = bmc.session.ctx.DecryptFinal(bmc.session.handle) + case modeEncrypt: + result, err = bmc.session.ctx.EncryptFinal(bmc.session.handle) + } + bmc.session = nil + bmc.cleanup() + if err != nil { + panic(err) + } + // PKCS#11 2.40 s5.2 says that the operation must produce as much output + // as possible, so we should never have any left over for CBC. + // This could be different for other modes but we don't implement any yet. + if len(result) > 0 { + panic("nontrivial result from *Final operation") + } +} diff --git a/vendor/github.com/ThalesIgnite/crypto11/certificates.go b/vendor/github.com/ThalesIgnite/crypto11/certificates.go new file mode 100644 index 0000000000000..e430ecce2b7ba --- /dev/null +++ b/vendor/github.com/ThalesIgnite/crypto11/certificates.go @@ -0,0 +1,299 @@ +// Copyright 2019 Thales e-Security, Inc +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package crypto11 + +import ( + "crypto/tls" + "crypto/x509" + "encoding/asn1" + "math/big" + + "github.com/miekg/pkcs11" + "github.com/pkg/errors" +) + +// FindCertificate retrieves a previously imported certificate. Any combination of id, label +// and serial can be provided. An error is return if all are nil. +func findCertificate(session *pkcs11Session, id []byte, label []byte, serial *big.Int) (cert *x509.Certificate, err error) { + + rawCertificate, err := findRawCertificate(session, id, label, serial) + if err != nil { + return nil, err + } + + if rawCertificate != nil { + cert, err = x509.ParseCertificate(rawCertificate) + if err != nil { + return nil, err + } + } + + return cert, err +} + +func findRawCertificate(session *pkcs11Session, id []byte, label []byte, serial *big.Int) (rawCertificate []byte, err error) { + if id == nil && label == nil && serial == nil { + return nil, errors.New("id, label and serial cannot all be nil") + } + + var template []*pkcs11.Attribute + + if id != nil { + template = append(template, pkcs11.NewAttribute(pkcs11.CKA_ID, id)) + } + if label != nil { + template = append(template, pkcs11.NewAttribute(pkcs11.CKA_LABEL, label)) + } + if serial != nil { + derSerial, err := asn1.Marshal(serial) + if err != nil { + return nil, errors.WithMessage(err, "failed to encode serial") + } + + template = append(template, pkcs11.NewAttribute(pkcs11.CKA_SERIAL_NUMBER, derSerial)) + } + + template = append(template, pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_CERTIFICATE)) + + if err = session.ctx.FindObjectsInit(session.handle, template); err != nil { + return nil, err + } + defer func() { + finalErr := session.ctx.FindObjectsFinal(session.handle) + if err == nil { + err = finalErr + } + }() + + handles, _, err := session.ctx.FindObjects(session.handle, 1) + if err != nil { + return nil, err + } + if len(handles) == 0 { + return nil, nil + } + + attributes := []*pkcs11.Attribute{ + pkcs11.NewAttribute(pkcs11.CKA_VALUE, 0), + } + + if attributes, err = session.ctx.GetAttributeValue(session.handle, handles[0], attributes); err != nil { + return nil, err + } + + rawCertificate = attributes[0].Value + + return +} + +// FindCertificate retrieves a previously imported certificate. Any combination of id, label +// and serial can be provided. An error is return if all are nil. +func (c *Context) FindCertificate(id []byte, label []byte, serial *big.Int) (*x509.Certificate, error) { + + if c.closed.Get() { + return nil, errClosed + } + + var cert *x509.Certificate + err := c.withSession(func(session *pkcs11Session) (err error) { + cert, err = findCertificate(session, id, label, serial) + return err + }) + + return cert, err +} + +func (c *Context) FindAllPairedCertificates() (certificates []tls.Certificate, err error) { + if c.closed.Get() { + return nil, errClosed + } + + err = c.withSession(func(session *pkcs11Session) error { + // Add the private key class to the template to find the private half + privAttributes := AttributeSet{} + err = privAttributes.Set(CkaClass, pkcs11.CKO_PRIVATE_KEY) + if err != nil { + return err + } + + privHandles, err := findKeysWithAttributes(session, privAttributes.ToSlice()) + if err != nil { + return err + } + + for _, privHandle := range privHandles { + + privateKey, certificate, err := c.makeKeyPair(session, &privHandle) + + if err == errNoCkaId || err == errNoPublicHalf { + continue + } + + if err != nil { + return err + } + + if certificate == nil { + continue + } + + tlsCert := tls.Certificate{ + Leaf: certificate, + PrivateKey: privateKey, + } + + tlsCert.Certificate = append(tlsCert.Certificate, certificate.Raw) + certificates = append(certificates, tlsCert) + } + + return nil + }) + + if err != nil { + return nil, err + } + + return +} + +// ImportCertificate imports a certificate onto the token. The id parameter is used to +// set CKA_ID and must be non-nil. +func (c *Context) ImportCertificate(id []byte, certificate *x509.Certificate) error { + if c.closed.Get() { + return errClosed + } + + if err := notNilBytes(id, "id"); err != nil { + return err + } + + template, err := NewAttributeSetWithID(id) + if err != nil { + return err + } + return c.ImportCertificateWithAttributes(template, certificate) +} + +// ImportCertificateWithLabel imports a certificate onto the token. The id and label parameters are used to +// set CKA_ID and CKA_LABEL respectively and must be non-nil. +func (c *Context) ImportCertificateWithLabel(id []byte, label []byte, certificate *x509.Certificate) error { + if c.closed.Get() { + return errClosed + } + + if err := notNilBytes(id, "id"); err != nil { + return err + } + if err := notNilBytes(label, "label"); err != nil { + return err + } + + template, err := NewAttributeSetWithIDAndLabel(id, label) + if err != nil { + return err + } + return c.ImportCertificateWithAttributes(template, certificate) +} + +// ImportCertificateWithAttributes imports a certificate onto the token. After this function returns, template +// will contain the attributes applied to the certificate. If required attributes are missing, they will be set to a +// default value. +func (c *Context) ImportCertificateWithAttributes(template AttributeSet, certificate *x509.Certificate) error { + if c.closed.Get() { + return errClosed + } + + if certificate == nil { + return errors.New("certificate cannot be nil") + } + + serial, err := asn1.Marshal(certificate.SerialNumber) + if err != nil { + return err + } + + template.AddIfNotPresent([]*pkcs11.Attribute{ + pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_CERTIFICATE), + pkcs11.NewAttribute(pkcs11.CKA_CERTIFICATE_TYPE, pkcs11.CKC_X_509), + pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true), + pkcs11.NewAttribute(pkcs11.CKA_PRIVATE, false), + pkcs11.NewAttribute(pkcs11.CKA_SUBJECT, certificate.RawSubject), + pkcs11.NewAttribute(pkcs11.CKA_ISSUER, certificate.RawIssuer), + pkcs11.NewAttribute(pkcs11.CKA_SERIAL_NUMBER, serial), + pkcs11.NewAttribute(pkcs11.CKA_VALUE, certificate.Raw), + }) + + err = c.withSession(func(session *pkcs11Session) error { + _, err = session.ctx.CreateObject(session.handle, template.ToSlice()) + return err + }) + + return err +} + +// DeleteCertificate destroys a previously imported certificate. it will return +// nil if succeeds or if the certificate does not exist. Any combination of id, +// label and serial can be provided. An error is return if all are nil. +func (c *Context) DeleteCertificate(id []byte, label []byte, serial *big.Int) error { + if id == nil && label == nil && serial == nil { + return errors.New("id, label and serial cannot all be nil") + } + + template := []*pkcs11.Attribute{ + pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_CERTIFICATE), + } + + if id != nil { + template = append(template, pkcs11.NewAttribute(pkcs11.CKA_ID, id)) + } + if label != nil { + template = append(template, pkcs11.NewAttribute(pkcs11.CKA_LABEL, label)) + } + if serial != nil { + asn1Serial, err := asn1.Marshal(serial) + if err != nil { + return err + } + template = append(template, pkcs11.NewAttribute(pkcs11.CKA_SERIAL_NUMBER, asn1Serial)) + } + + err := c.withSession(func(session *pkcs11Session) error { + err := session.ctx.FindObjectsInit(session.handle, template) + if err != nil { + return err + } + handles, _, err := session.ctx.FindObjects(session.handle, 1) + finalErr := session.ctx.FindObjectsFinal(session.handle) + if err != nil { + return err + } + if finalErr != nil { + return finalErr + } + if len(handles) == 0 { + return nil + } + return session.ctx.DestroyObject(session.handle, handles[0]) + }) + + return err +} diff --git a/vendor/github.com/ThalesIgnite/crypto11/common.go b/vendor/github.com/ThalesIgnite/crypto11/common.go new file mode 100644 index 0000000000000..1823c17ac3a8e --- /dev/null +++ b/vendor/github.com/ThalesIgnite/crypto11/common.go @@ -0,0 +1,125 @@ +// Copyright 2017 Thales e-Security, Inc +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package crypto11 + +import ( + "C" + "encoding/asn1" + "math/big" + "unsafe" + + "github.com/miekg/pkcs11" + "github.com/pkg/errors" +) + +func ulongToBytes(n uint) []byte { + return C.GoBytes(unsafe.Pointer(&n), C.sizeof_ulong) // ugh! +} + +func bytesToUlong(bs []byte) (n uint) { + sliceSize := len(bs) + if sliceSize == 0 { + return 0 + } + + value := *(*uint)(unsafe.Pointer(&bs[0])) + if sliceSize > C.sizeof_ulong { + return value + } + + // truncate the value to the # of bits present in the byte slice since + // the unsafe pointer will always grab/convert ULONG # of bytes + var mask uint + for i := 0; i < sliceSize; i++ { + mask |= 0xff << uint(i * 8) + } + return value & mask +} + +func concat(slices ...[]byte) []byte { + n := 0 + for _, slice := range slices { + n += len(slice) + } + r := make([]byte, n) + n = 0 + for _, slice := range slices { + n += copy(r[n:], slice) + } + return r +} + +// Representation of a *DSA signature +type dsaSignature struct { + R, S *big.Int +} + +// Populate a dsaSignature from a raw byte sequence +func (sig *dsaSignature) unmarshalBytes(sigBytes []byte) error { + if len(sigBytes) == 0 || len(sigBytes)%2 != 0 { + return errors.New("DSA signature length is invalid from token") + } + n := len(sigBytes) / 2 + sig.R, sig.S = new(big.Int), new(big.Int) + sig.R.SetBytes(sigBytes[:n]) + sig.S.SetBytes(sigBytes[n:]) + return nil +} + +// Populate a dsaSignature from DER encoding +func (sig *dsaSignature) unmarshalDER(sigDER []byte) error { + if rest, err := asn1.Unmarshal(sigDER, sig); err != nil { + return errors.WithMessage(err, "DSA signature contains invalid ASN.1 data") + } else if len(rest) > 0 { + return errors.New("unexpected data found after DSA signature") + } + return nil +} + +// Return the DER encoding of a dsaSignature +func (sig *dsaSignature) marshalDER() ([]byte, error) { + return asn1.Marshal(*sig) +} + +// Compute *DSA signature and marshal the result in DER form +func (c *Context) dsaGeneric(key pkcs11.ObjectHandle, mechanism uint, digest []byte) ([]byte, error) { + var err error + var sigBytes []byte + var sig dsaSignature + mech := []*pkcs11.Mechanism{pkcs11.NewMechanism(mechanism, nil)} + err = c.withSession(func(session *pkcs11Session) error { + if err = c.ctx.SignInit(session.handle, mech, key); err != nil { + return err + } + sigBytes, err = c.ctx.Sign(session.handle, digest) + return err + }) + if err != nil { + return nil, err + } + err = sig.unmarshalBytes(sigBytes) + if err != nil { + return nil, err + } + + return sig.marshalDER() +} diff --git a/vendor/github.com/ThalesIgnite/crypto11/config b/vendor/github.com/ThalesIgnite/crypto11/config new file mode 100644 index 0000000000000..c51f9c58529e0 --- /dev/null +++ b/vendor/github.com/ThalesIgnite/crypto11/config @@ -0,0 +1,5 @@ +{ + "Path" : "/usr/lib/softhsm/libsofthsm2.so", + "TokenLabel": "token1", + "Pin" : "password" +} diff --git a/vendor/github.com/ThalesIgnite/crypto11/crypto11.go b/vendor/github.com/ThalesIgnite/crypto11/crypto11.go new file mode 100644 index 0000000000000..f68fd93a983b7 --- /dev/null +++ b/vendor/github.com/ThalesIgnite/crypto11/crypto11.go @@ -0,0 +1,485 @@ +// Copyright 2016 Thales e-Security, Inc +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +// Package crypto11 enables access to cryptographic keys from PKCS#11 using Go crypto API. +// +// Configuration +// +// PKCS#11 tokens are accessed via Context objects. Each Context connects to one token. +// +// Context objects are created by calling Configure or ConfigureFromFile. +// In the latter case, the file should contain a JSON representation of +// a Config. +// +// Key Generation and Usage +// +// There is support for generating DSA, RSA and ECDSA keys. These keys +// can be found later using FindKeyPair. All three key types implement +// the crypto.Signer interface and the RSA keys also implement crypto.Decrypter. +// +// RSA keys obtained through FindKeyPair will need a type assertion to be +// used for decryption. Assert either crypto.Decrypter or SignerDecrypter, as you +// prefer. +// +// Symmetric keys can also be generated. These are found later using FindKey. +// See the documentation for SecretKey for further information. +// +// Sessions and concurrency +// +// Note that PKCS#11 session handles must not be used concurrently +// from multiple threads. Consumers of the Signer interface know +// nothing of this and expect to be able to sign from multiple threads +// without constraint. We address this as follows. +// +// 1. When a Context is created, a session is created and the user is +// logged in. This session remains open until the Context is closed, +// to ensure all object handles remain valid and to avoid repeatedly +// calling C_Login. +// +// 2. The Context also maintains a pool of read-write sessions. The pool expands +// dynamically as needed, but never beyond the maximum number of r/w sessions +// supported by the token (as reported by C_GetInfo). If other applications +// are using the token, a lower limit should be set in the Config. +// +// 3. Each operation transiently takes a session from the pool. They +// have exclusive use of the session, meeting PKCS#11's concurrency +// requirements. Sessions are returned to the pool afterwards and may +// be re-used. +// +// Behaviour of the pool can be tweaked via Config fields: +// +// - PoolWaitTimeout controls how long an operation can block waiting on a +// session from the pool. A zero value means there is no limit. Timeouts +// occur if the pool is fully used and additional operations are requested. +// +// - MaxSessions sets an upper bound on the number of sessions. If this value is zero, +// a default maximum is used (see DefaultMaxSessions). In every case the maximum +// supported sessions as reported by the token is obeyed. +// +// Limitations +// +// The PKCS1v15DecryptOptions SessionKeyLen field is not implemented +// and an error is returned if it is nonzero. +// The reason for this is that it is not possible for crypto11 to guarantee the constant-time behavior in the specification. +// See https://github.com/thalesignite/crypto11/issues/5 for further discussion. +// +// Symmetric crypto support via cipher.Block is very slow. +// You can use the BlockModeCloser API +// but you must call the Close() interface (not found in cipher.BlockMode). +// See https://github.com/ThalesIgnite/crypto11/issues/6 for further discussion. +package crypto11 + +import ( + "crypto" + "encoding/json" + "fmt" + "io" + "os" + "strings" + "sync" + "time" + + "github.com/miekg/pkcs11" + "github.com/pkg/errors" + "github.com/thales-e-security/pool" +) + +const ( + // DefaultMaxSessions controls the maximum number of concurrent sessions to + // open, unless otherwise specified in the Config object. + DefaultMaxSessions = 1024 + + // DefaultGCMIVLength controls the expected length of IVs generated by the token + DefaultGCMIVLength = 16 + + // Thales vendor constant for CKU_CRYPTO_USER + CryptoUser = 0x80000001 + DefaultUserType = 1 // 1 -> CKU_USER +) + +// errTokenNotFound represents the failure to find the requested PKCS#11 token +var errTokenNotFound = errors.New("could not find PKCS#11 token") + +// errClosed is returned if a Context is used after a call to Close. +var errClosed = errors.New("cannot used closed Context") + +// pkcs11Object contains a reference to a loaded PKCS#11 object. +type pkcs11Object struct { + // The PKCS#11 object handle. + handle pkcs11.ObjectHandle + + // The PKCS#11 context. This is used to find a session handle that can + // access this object. + context *Context +} + +func (o *pkcs11Object) Delete() error { + return o.context.withSession(func(session *pkcs11Session) error { + err := session.ctx.DestroyObject(session.handle, o.handle) + return errors.WithMessage(err, "failed to destroy key") + }) +} + +// pkcs11PrivateKey contains a reference to a loaded PKCS#11 private key object. +type pkcs11PrivateKey struct { + pkcs11Object + + // pubKeyHandle is a handle to the public key. + pubKeyHandle pkcs11.ObjectHandle + + // pubKey is an exported copy of the public key. We pre-export the key material because crypto.Signer.Public + // doesn't allow us to return errors. + pubKey crypto.PublicKey +} + +// Delete implements Signer.Delete. +func (k *pkcs11PrivateKey) Delete() error { + err := k.pkcs11Object.Delete() + if err != nil { + return err + } + + return k.context.withSession(func(session *pkcs11Session) error { + err := session.ctx.DestroyObject(session.handle, k.pubKeyHandle) + return errors.WithMessage(err, "failed to destroy public key") + }) +} + +// A Context stores the connection state to a PKCS#11 token. Use Configure or ConfigureFromFile to create a new +// Context. Call Close when finished with the token, to free up resources. +// +// All functions, except Close, are safe to call from multiple goroutines. +type Context struct { + // Atomic fields must be at top (according to the package owners) + closed pool.AtomicBool + + ctx *pkcs11.Ctx + cfg *Config + + token *pkcs11.TokenInfo + slot uint + pool *pool.ResourcePool + + // persistentSession is a session held open so we can be confident handles and login status + // persist for the duration of this context + persistentSession pkcs11.SessionHandle +} + +// Signer is a PKCS#11 key that implements crypto.Signer. +type Signer interface { + crypto.Signer + + // Delete deletes the key pair from the token. + Delete() error +} + +// SignerDecrypter is a PKCS#11 key implements crypto.Signer and crypto.Decrypter. +type SignerDecrypter interface { + Signer + + // Decrypt implements crypto.Decrypter. + Decrypt(rand io.Reader, msg []byte, opts crypto.DecrypterOpts) (plaintext []byte, err error) +} + +// findToken finds a token given exactly one of serial, label or slotNumber +func (c *Context) findToken(slots []uint, serial, label string, slotNumber *int) (uint, *pkcs11.TokenInfo, error) { + for _, slot := range slots { + + tokenInfo, err := c.ctx.GetTokenInfo(slot) + if err != nil { + return 0, nil, err + } + + if (slotNumber != nil && uint(*slotNumber) == slot) || + (tokenInfo.SerialNumber != "" && tokenInfo.SerialNumber == serial) || + (tokenInfo.Label != "" && tokenInfo.Label == label) { + + return slot, &tokenInfo, nil + } + + } + return 0, nil, errTokenNotFound +} + +// Config holds PKCS#11 configuration information. +// +// A token may be selected by label, serial number or slot number. It is an error to specify +// more than one way to select the token. +// +// Supply this to Configure(), or alternatively use ConfigureFromFile(). +type Config struct { + // Full path to PKCS#11 library. + Path string + + // Token serial number. + TokenSerial string + + // Token label. + TokenLabel string + + // SlotNumber identifies a token to use by the slot containing it. + SlotNumber *int + + // User PIN (password). + Pin string + + // Maximum number of concurrent sessions to open. If zero, DefaultMaxSessions is used. + // Otherwise, the value specified must be at least 2. + MaxSessions int + + // User type identifies the user type logging in. If zero, DefaultUserType is used. + UserType int + + // Maximum time to wait for a session from the sessions pool. Zero means wait indefinitely. + PoolWaitTimeout time.Duration + + // LoginNotSupported should be set to true for tokens that do not support logging in. + LoginNotSupported bool + + // UseGCMIVFromHSM should be set to true for tokens such as CloudHSM, which ignore the supplied IV for + // GCM mode and generate their own. In this case, the token will write the IV used into the CK_GCM_PARAMS. + // If UseGCMIVFromHSM is true, we will copy this IV and overwrite the 'nonce' slice passed to Seal and Open. It + // is therefore necessary that the nonce is the correct length (12 bytes for CloudHSM). + UseGCMIVFromHSM bool + + // GCMIVLength is the length of IVs to use in GCM mode. Refer to NIST SP800-38 for guidance on the length of + // RBG-based IVs in GCM mode. When the UseGCMIVFromHSM parameter is true + GCMIVLength int + + GCMIVFromHSMControl GCMIVFromHSMConfig +} + +type GCMIVFromHSMConfig struct { + + // SupplyIvForHSMGCM_encrypt controls the supply of a non-nil IV for GCM use during C_EncryptInit + SupplyIvForHSMGCMEncrypt bool + + // SupplyIvForHSMGCM_decrypt controls the supply of a non-nil IV for GCM use during C_DecryptInit + SupplyIvForHSMGCMDecrypt bool +} + +// refCount counts the number of contexts using a particular P11 library. It must not be read or modified +// without holding refCountMutex. +var refCount = map[string]int{} +var refCountMutex = sync.Mutex{} + +// Configure creates a new Context based on the supplied PKCS#11 configuration. +func Configure(config *Config) (*Context, error) { + // Have we been given exactly one way to select a token? + var fields []string + if config.SlotNumber != nil { + fields = append(fields, "slot number") + } + if config.TokenLabel != "" { + fields = append(fields, "token label") + } + if config.TokenSerial != "" { + fields = append(fields, "token serial number") + } + if len(fields) == 0 { + return nil, fmt.Errorf("config must specify exactly one way to select a token: none given") + } else if len(fields) > 1 { + return nil, fmt.Errorf("config must specify exactly one way to select a token: %v given", strings.Join(fields, ", ")) + } + + if config.MaxSessions == 0 { + config.MaxSessions = DefaultMaxSessions + } + if config.MaxSessions == 1 { + return nil, errors.New("MaxSessions must be larger than 1") + } + + if config.UserType == 0 { + config.UserType = DefaultUserType + } + + if config.GCMIVLength == 0 { + config.GCMIVLength = DefaultGCMIVLength + } + + instance := &Context{ + cfg: config, + ctx: pkcs11.New(config.Path), + } + + if instance.ctx == nil { + return nil, errors.New("could not open PKCS#11") + } + + // Check how many contexts are currently using this library + refCountMutex.Lock() + defer refCountMutex.Unlock() + numExistingContexts := refCount[config.Path] + + // Only Initialize if we are the first Context using the library + if numExistingContexts == 0 { + if err := instance.ctx.Initialize(); err != nil { + instance.ctx.Destroy() + return nil, errors.WithMessage(err, "failed to initialize PKCS#11 library") + } + } + slots, err := instance.ctx.GetSlotList(true) + if err != nil { + _ = instance.ctx.Finalize() + instance.ctx.Destroy() + return nil, errors.WithMessage(err, "failed to list PKCS#11 slots") + } + + instance.slot, instance.token, err = instance.findToken(slots, config.TokenSerial, config.TokenLabel, config.SlotNumber) + if err != nil { + _ = instance.ctx.Finalize() + instance.ctx.Destroy() + return nil, err + } + + // Create the session pool. + maxSessions := instance.cfg.MaxSessions + tokenMaxSessions := instance.token.MaxRwSessionCount + if tokenMaxSessions != pkcs11.CK_EFFECTIVELY_INFINITE && tokenMaxSessions != pkcs11.CK_UNAVAILABLE_INFORMATION { + maxSessions = min(maxSessions, castDown(tokenMaxSessions)) + } + + // We will use one session to keep state alive, so the pool gets maxSessions - 1 + instance.pool = pool.NewResourcePool(instance.resourcePoolFactoryFunc, maxSessions-1, maxSessions-1, 0, 0) + + // Create a long-term session and log it in (if supported). This session won't be used by callers, instead it is + // used to keep a connection alive to the token to ensure object handles and the log in status remain accessible. + instance.persistentSession, err = instance.ctx.OpenSession(instance.slot, pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION) + if err != nil { + _ = instance.ctx.Finalize() + instance.ctx.Destroy() + return nil, errors.WithMessagef(err, "failed to create long term session") + } + + if !config.LoginNotSupported { + // Try to log in our persistent session. This may fail with CKR_USER_ALREADY_LOGGED_IN if another instance + // already exists. + if instance.cfg.UserType == 1 { + err = instance.ctx.Login(instance.persistentSession, pkcs11.CKU_USER, instance.cfg.Pin) + } else { + err = instance.ctx.Login(instance.persistentSession, CryptoUser, instance.cfg.Pin) + } + if err != nil { + + pErr, isP11Error := err.(pkcs11.Error) + + if !isP11Error || pErr != pkcs11.CKR_USER_ALREADY_LOGGED_IN { + _ = instance.ctx.Finalize() + instance.ctx.Destroy() + return nil, errors.WithMessagef(err, "failed to log into long term session") + } + } + } + + // Increment the reference count + refCount[config.Path] = numExistingContexts + 1 + + return instance, nil +} + +func min(a, b int) int { + if b < a { + return b + } + return a +} + +// castDown returns orig as a signed integer. If an overflow would have occurred, +// the maximum possible value is returned. +func castDown(orig uint) int { + // From https://stackoverflow.com/a/6878625/474189 + const maxUint = ^uint(0) + const maxInt = int(maxUint >> 1) + + if orig > uint(maxInt) { + return maxInt + } + + return int(orig) +} + +// ConfigureFromFile is a convenience method, which parses the configuration file +// and calls Configure. The configuration file should be a JSON representation +// of a Config object. +func ConfigureFromFile(configLocation string) (*Context, error) { + config, err := loadConfigFromFile(configLocation) + if err != nil { + return nil, err + } + + return Configure(config) +} + +// loadConfigFromFile reads a Config struct from a file. +func loadConfigFromFile(configLocation string) (*Config, error) { + file, err := os.Open(configLocation) + if err != nil { + return nil, errors.WithMessagef(err, "could not open config file: %s", configLocation) + } + defer func() { + closeErr := file.Close() + if err == nil { + err = closeErr + } + }() + + configDecoder := json.NewDecoder(file) + config := &Config{} + err = configDecoder.Decode(config) + return config, errors.WithMessage(err, "could decode config file:") +} + +// Close releases resources used by the Context and unloads the PKCS #11 library if there are no other +// Contexts using it. Close blocks until existing operations have finished. A closed Context cannot be reused. +func (c *Context) Close() error { + + // Take lock on the reference count + refCountMutex.Lock() + defer refCountMutex.Unlock() + + c.closed.Set(true) + + // Block until all resources returned to pool + c.pool.Close() + + // Close our long-term session. We ignore any returned error, + // since we plan to kill our collection to the library anyway. + _ = c.ctx.CloseSession(c.persistentSession) + + count, found := refCount[c.cfg.Path] + if !found || count == 0 { + // We have somehow lost track of reference counts, this is very bad + panic("invalid reference count for PKCS#11 library") + } + + refCount[c.cfg.Path] = count - 1 + + // If we were the last Context, finalize the library + if count == 1 { + err := c.ctx.Finalize() + if err != nil { + return err + } + } + + c.ctx.Destroy() + return nil +} diff --git a/vendor/github.com/ThalesIgnite/crypto11/dsa.go b/vendor/github.com/ThalesIgnite/crypto11/dsa.go new file mode 100644 index 0000000000000..562f3dd0e611c --- /dev/null +++ b/vendor/github.com/ThalesIgnite/crypto11/dsa.go @@ -0,0 +1,175 @@ +// Copyright 2016, 2017 Thales e-Security, Inc +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package crypto11 + +import ( + "crypto" + "crypto/dsa" + "io" + "math/big" + + "github.com/pkg/errors" + + pkcs11 "github.com/miekg/pkcs11" +) + +// pkcs11PrivateKeyDSA contains a reference to a loaded PKCS#11 DSA private key object. +type pkcs11PrivateKeyDSA struct { + pkcs11PrivateKey +} + +// Export the public key corresponding to a private DSA key. +func exportDSAPublicKey(session *pkcs11Session, pubHandle pkcs11.ObjectHandle) (crypto.PublicKey, error) { + template := []*pkcs11.Attribute{ + pkcs11.NewAttribute(pkcs11.CKA_PRIME, nil), + pkcs11.NewAttribute(pkcs11.CKA_SUBPRIME, nil), + pkcs11.NewAttribute(pkcs11.CKA_BASE, nil), + pkcs11.NewAttribute(pkcs11.CKA_VALUE, nil), + } + exported, err := session.ctx.GetAttributeValue(session.handle, pubHandle, template) + if err != nil { + return nil, err + } + var p, q, g, y big.Int + p.SetBytes(exported[0].Value) + q.SetBytes(exported[1].Value) + g.SetBytes(exported[2].Value) + y.SetBytes(exported[3].Value) + result := dsa.PublicKey{ + Parameters: dsa.Parameters{ + P: &p, + Q: &q, + G: &g, + }, + Y: &y, + } + return &result, nil +} + +func notNilBytes(obj []byte, name string) error { + if obj == nil { + return errors.Errorf("%s cannot be nil", name) + } + return nil +} + +// GenerateDSAKeyPair creates a DSA key pair on the token. The id parameter is used to +// set CKA_ID and must be non-nil. +func (c *Context) GenerateDSAKeyPair(id []byte, params *dsa.Parameters) (Signer, error) { + if c.closed.Get() { + return nil, errClosed + } + + public, err := NewAttributeSetWithID(id) + if err != nil { + return nil, err + } + // Copy the AttributeSet to allow modifications. + private := public.Copy() + + return c.GenerateDSAKeyPairWithAttributes(public, private, params) +} + +// GenerateDSAKeyPairWithLabel creates a DSA key pair on the token. The id and label parameters are used to +// set CKA_ID and CKA_LABEL respectively and must be non-nil. +func (c *Context) GenerateDSAKeyPairWithLabel(id, label []byte, params *dsa.Parameters) (Signer, error) { + if c.closed.Get() { + return nil, errClosed + } + + public, err := NewAttributeSetWithIDAndLabel(id, label) + if err != nil { + return nil, err + } + // Copy the AttributeSet to allow modifications. + private := public.Copy() + + return c.GenerateDSAKeyPairWithAttributes(public, private, params) +} + +// GenerateDSAKeyPairWithAttributes creates a DSA key pair on the token. After this function returns, public and private +// will contain the attributes applied to the key pair. If required attributes are missing, they will be set to a +// default value. +func (c *Context) GenerateDSAKeyPairWithAttributes(public, private AttributeSet, params *dsa.Parameters) (Signer, error) { + if c.closed.Get() { + return nil, errClosed + } + + var k Signer + err := c.withSession(func(session *pkcs11Session) error { + p := params.P.Bytes() + q := params.Q.Bytes() + g := params.G.Bytes() + + public.AddIfNotPresent([]*pkcs11.Attribute{ + pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PUBLIC_KEY), + pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_DSA), + pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true), + pkcs11.NewAttribute(pkcs11.CKA_VERIFY, true), + pkcs11.NewAttribute(pkcs11.CKA_PRIME, p), + pkcs11.NewAttribute(pkcs11.CKA_SUBPRIME, q), + pkcs11.NewAttribute(pkcs11.CKA_BASE, g), + }) + private.AddIfNotPresent([]*pkcs11.Attribute{ + pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true), + pkcs11.NewAttribute(pkcs11.CKA_SIGN, true), + pkcs11.NewAttribute(pkcs11.CKA_SENSITIVE, true), + pkcs11.NewAttribute(pkcs11.CKA_EXTRACTABLE, false), + }) + + mech := []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_DSA_KEY_PAIR_GEN, nil)} + pubHandle, privHandle, err := session.ctx.GenerateKeyPair(session.handle, + mech, + public.ToSlice(), + private.ToSlice()) + if err != nil { + return err + } + pub, err := exportDSAPublicKey(session, pubHandle) + if err != nil { + return err + } + k = &pkcs11PrivateKeyDSA{ + pkcs11PrivateKey: pkcs11PrivateKey{ + pkcs11Object: pkcs11Object{ + handle: privHandle, + context: c, + }, + pubKeyHandle: pubHandle, + pubKey: pub, + }} + return nil + + }) + return k, err +} + +// Sign signs a message using a DSA key. +// +// This completes the implemention of crypto.Signer for pkcs11PrivateKeyDSA. +// +// PKCS#11 expects to pick its own random data for signatures, so the rand argument is ignored. +// +// The return value is a DER-encoded byteblock. +func (signer *pkcs11PrivateKeyDSA) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) { + return signer.context.dsaGeneric(signer.handle, pkcs11.CKM_DSA, digest) +} diff --git a/vendor/github.com/ThalesIgnite/crypto11/ecdsa.go b/vendor/github.com/ThalesIgnite/crypto11/ecdsa.go new file mode 100644 index 0000000000000..c09423256234d --- /dev/null +++ b/vendor/github.com/ThalesIgnite/crypto11/ecdsa.go @@ -0,0 +1,302 @@ +// Copyright 2016, 2017 Thales e-Security, Inc +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package crypto11 + +import ( + "bytes" + "crypto" + "crypto/ecdsa" + "crypto/elliptic" + "encoding/asn1" + "io" + "math/big" + + "github.com/miekg/pkcs11" + "github.com/pkg/errors" +) + +// errUnsupportedEllipticCurve is returned when an elliptic curve +// unsupported by crypto11 is specified. Note that the error behavior +// for an elliptic curve unsupported by the underlying PKCS#11 +// implementation will be different. +var errUnsupportedEllipticCurve = errors.New("unsupported elliptic curve") + +// pkcs11PrivateKeyECDSA contains a reference to a loaded PKCS#11 ECDSA private key object. +type pkcs11PrivateKeyECDSA struct { + pkcs11PrivateKey +} + +// Information about an Elliptic Curve +type curveInfo struct { + // ASN.1 marshaled OID + oid []byte + + // Curve definition in Go form + curve elliptic.Curve +} + +// ASN.1 marshal some value and panic on error +func mustMarshal(val interface{}) []byte { + if b, err := asn1.Marshal(val); err != nil { + panic(err) + } else { + return b + } +} + +// Note: some of these are outside what crypto/elliptic currently +// knows about. So I'm making a (reasonable) assumption about what +// they will be called if they are either added or if someone +// specifies them explicitly. +// +// For public key export, the curve has to be a known one, otherwise +// you're stuffed. This is probably better fixed by adding well-known +// curves to crypto/elliptic rather than having a private copy here. +var wellKnownCurves = map[string]curveInfo{ + "P-192": { + mustMarshal(asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 1}), + nil, + }, + "P-224": { + mustMarshal(asn1.ObjectIdentifier{1, 3, 132, 0, 33}), + elliptic.P224(), + }, + "P-256": { + mustMarshal(asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7}), + elliptic.P256(), + }, + "P-384": { + mustMarshal(asn1.ObjectIdentifier{1, 3, 132, 0, 34}), + elliptic.P384(), + }, + "P-521": { + mustMarshal(asn1.ObjectIdentifier{1, 3, 132, 0, 35}), + elliptic.P521(), + }, + + "K-163": { + mustMarshal(asn1.ObjectIdentifier{1, 3, 132, 0, 1}), + nil, + }, + "K-233": { + mustMarshal(asn1.ObjectIdentifier{1, 3, 132, 0, 26}), + nil, + }, + "K-283": { + mustMarshal(asn1.ObjectIdentifier{1, 3, 132, 0, 16}), + nil, + }, + "K-409": { + mustMarshal(asn1.ObjectIdentifier{1, 3, 132, 0, 36}), + nil, + }, + "K-571": { + mustMarshal(asn1.ObjectIdentifier{1, 3, 132, 0, 38}), + nil, + }, + + "B-163": { + mustMarshal(asn1.ObjectIdentifier{1, 3, 132, 0, 15}), + nil, + }, + "B-233": { + mustMarshal(asn1.ObjectIdentifier{1, 3, 132, 0, 27}), + nil, + }, + "B-283": { + mustMarshal(asn1.ObjectIdentifier{1, 3, 132, 0, 17}), + nil, + }, + "B-409": { + mustMarshal(asn1.ObjectIdentifier{1, 3, 132, 0, 37}), + nil, + }, + "B-571": { + mustMarshal(asn1.ObjectIdentifier{1, 3, 132, 0, 39}), + nil, + }, +} + +func marshalEcParams(c elliptic.Curve) ([]byte, error) { + if ci, ok := wellKnownCurves[c.Params().Name]; ok { + return ci.oid, nil + } + // TODO use ANSI X9.62 ECParameters representation instead + return nil, errUnsupportedEllipticCurve +} + +func unmarshalEcParams(b []byte) (elliptic.Curve, error) { + // See if it's a well-known curve + for _, ci := range wellKnownCurves { + if bytes.Equal(b, ci.oid) { + if ci.curve != nil { + return ci.curve, nil + } + return nil, errUnsupportedEllipticCurve + } + } + // TODO try ANSI X9.62 ECParameters representation + return nil, errUnsupportedEllipticCurve +} + +func unmarshalEcPoint(b []byte, c elliptic.Curve) (*big.Int, *big.Int, error) { + var pointBytes []byte + extra, err := asn1.Unmarshal(b, &pointBytes) + if err != nil { + return nil, nil, errors.WithMessage(err, "elliptic curve point is invalid ASN.1") + } + + if len(extra) > 0 { + // We weren't expecting extra data + return nil, nil, errors.New("unexpected data found when parsing elliptic curve point") + } + + x, y := elliptic.Unmarshal(c, pointBytes) + if x == nil || y == nil { + return nil, nil, errors.New("failed to parse elliptic curve point") + } + return x, y, nil +} + +// Export the public key corresponding to a private ECDSA key. +func exportECDSAPublicKey(session *pkcs11Session, pubHandle pkcs11.ObjectHandle) (crypto.PublicKey, error) { + var err error + var attributes []*pkcs11.Attribute + var pub ecdsa.PublicKey + template := []*pkcs11.Attribute{ + pkcs11.NewAttribute(pkcs11.CKA_ECDSA_PARAMS, nil), + pkcs11.NewAttribute(pkcs11.CKA_EC_POINT, nil), + } + if attributes, err = session.ctx.GetAttributeValue(session.handle, pubHandle, template); err != nil { + return nil, err + } + if pub.Curve, err = unmarshalEcParams(attributes[0].Value); err != nil { + return nil, err + } + if pub.X, pub.Y, err = unmarshalEcPoint(attributes[1].Value, pub.Curve); err != nil { + return nil, err + } + return &pub, nil +} + +// GenerateECDSAKeyPair creates a ECDSA key pair on the token using curve c. The id parameter is used to +// set CKA_ID and must be non-nil. Only a limited set of named elliptic curves are supported. The +// underlying PKCS#11 implementation may impose further restrictions. +func (c *Context) GenerateECDSAKeyPair(id []byte, curve elliptic.Curve) (Signer, error) { + if c.closed.Get() { + return nil, errClosed + } + + public, err := NewAttributeSetWithID(id) + if err != nil { + return nil, err + } + // Copy the AttributeSet to allow modifications. + private := public.Copy() + + return c.GenerateECDSAKeyPairWithAttributes(public, private, curve) +} + +// GenerateECDSAKeyPairWithLabel creates a ECDSA key pair on the token using curve c. The id and label parameters are used to +// set CKA_ID and CKA_LABEL respectively and must be non-nil. Only a limited set of named elliptic curves are supported. The +// underlying PKCS#11 implementation may impose further restrictions. +func (c *Context) GenerateECDSAKeyPairWithLabel(id, label []byte, curve elliptic.Curve) (Signer, error) { + if c.closed.Get() { + return nil, errClosed + } + + public, err := NewAttributeSetWithIDAndLabel(id, label) + if err != nil { + return nil, err + } + // Copy the AttributeSet to allow modifications. + private := public.Copy() + + return c.GenerateECDSAKeyPairWithAttributes(public, private, curve) +} + +// GenerateECDSAKeyPairWithAttributes generates an ECDSA key pair on the token. After this function returns, public and +// private will contain the attributes applied to the key pair. If required attributes are missing, they will be set to +// a default value. +func (c *Context) GenerateECDSAKeyPairWithAttributes(public, private AttributeSet, curve elliptic.Curve) (Signer, error) { + if c.closed.Get() { + return nil, errClosed + } + + var k Signer + err := c.withSession(func(session *pkcs11Session) error { + + parameters, err := marshalEcParams(curve) + if err != nil { + return err + } + public.AddIfNotPresent([]*pkcs11.Attribute{ + pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PUBLIC_KEY), + pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_ECDSA), + pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true), + pkcs11.NewAttribute(pkcs11.CKA_VERIFY, true), + pkcs11.NewAttribute(pkcs11.CKA_ECDSA_PARAMS, parameters), + }) + private.AddIfNotPresent([]*pkcs11.Attribute{ + pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true), + pkcs11.NewAttribute(pkcs11.CKA_SIGN, true), + pkcs11.NewAttribute(pkcs11.CKA_SENSITIVE, true), + pkcs11.NewAttribute(pkcs11.CKA_EXTRACTABLE, false), + }) + + mech := []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_ECDSA_KEY_PAIR_GEN, nil)} + pubHandle, privHandle, err := session.ctx.GenerateKeyPair(session.handle, + mech, + public.ToSlice(), + private.ToSlice()) + if err != nil { + return err + } + + pub, err := exportECDSAPublicKey(session, pubHandle) + if err != nil { + return err + } + k = &pkcs11PrivateKeyECDSA{ + pkcs11PrivateKey: pkcs11PrivateKey{ + pkcs11Object: pkcs11Object{ + handle: privHandle, + context: c, + }, + pubKeyHandle: pubHandle, + pubKey: pub, + }} + return nil + }) + return k, err +} + +// Sign signs a message using an ECDSA key. +// +// This completes the implemention of crypto.Signer for pkcs11PrivateKeyECDSA. +// +// PKCS#11 expects to pick its own random data where necessary for signatures, so the rand argument is ignored. +// +// The return value is a DER-encoded byteblock. +func (signer *pkcs11PrivateKeyECDSA) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) { + return signer.context.dsaGeneric(signer.handle, pkcs11.CKM_ECDSA, digest) +} diff --git a/vendor/github.com/ThalesIgnite/crypto11/hmac.go b/vendor/github.com/ThalesIgnite/crypto11/hmac.go new file mode 100644 index 0000000000000..16b741501e3f1 --- /dev/null +++ b/vendor/github.com/ThalesIgnite/crypto11/hmac.go @@ -0,0 +1,215 @@ +// Copyright 2018 Thales e-Security, Inc +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package crypto11 + +import ( + "errors" + "hash" + + "github.com/miekg/pkcs11" +) + +const ( + // NFCK_VENDOR_NCIPHER distinguishes nShield vendor-specific mechanisms. + NFCK_VENDOR_NCIPHER = 0xde436972 + + // CKM_NCIPHER is the base for nShield vendor-specific mechanisms. + CKM_NCIPHER = (pkcs11.CKM_VENDOR_DEFINED | NFCK_VENDOR_NCIPHER) + + // CKM_NC_MD5_HMAC_KEY_GEN is the nShield-specific HMACMD5 key-generation mechanism + CKM_NC_MD5_HMAC_KEY_GEN = (CKM_NCIPHER + 0x6) + + // CKM_NC_SHA_1_HMAC_KEY_GEN is the nShield-specific HMACSHA1 key-generation mechanism + CKM_NC_SHA_1_HMAC_KEY_GEN = (CKM_NCIPHER + 0x3) + + // CKM_NC_SHA224_HMAC_KEY_GEN is the nShield-specific HMACSHA224 key-generation mechanism + CKM_NC_SHA224_HMAC_KEY_GEN = (CKM_NCIPHER + 0x24) + + // CKM_NC_SHA256_HMAC_KEY_GEN is the nShield-specific HMACSHA256 key-generation mechanism + CKM_NC_SHA256_HMAC_KEY_GEN = (CKM_NCIPHER + 0x25) + + // CKM_NC_SHA384_HMAC_KEY_GEN is the nShield-specific HMACSHA384 key-generation mechanism + CKM_NC_SHA384_HMAC_KEY_GEN = (CKM_NCIPHER + 0x26) + + // CKM_NC_SHA512_HMAC_KEY_GEN is the nShield-specific HMACSHA512 key-generation mechanism + CKM_NC_SHA512_HMAC_KEY_GEN = (CKM_NCIPHER + 0x27) +) + +type hmacImplementation struct { + // PKCS#11 session to use + session *pkcs11Session + + // Signing key + key *SecretKey + + // Hash size + size int + + // Block size + blockSize int + + // PKCS#11 mechanism information + mechDescription []*pkcs11.Mechanism + + // Cleanup function + cleanup func() + + // Count of updates + updates uint64 + + // Result, or nil if we don't have the answer yet + result []byte +} + +type hmacInfo struct { + size int + blockSize int + general bool +} + +var hmacInfos = map[int]*hmacInfo{ + pkcs11.CKM_MD5_HMAC: {20, 64, false}, + pkcs11.CKM_MD5_HMAC_GENERAL: {20, 64, true}, + pkcs11.CKM_SHA_1_HMAC: {20, 64, false}, + pkcs11.CKM_SHA_1_HMAC_GENERAL: {20, 64, true}, + pkcs11.CKM_SHA224_HMAC: {28, 64, false}, + pkcs11.CKM_SHA224_HMAC_GENERAL: {28, 64, true}, + pkcs11.CKM_SHA256_HMAC: {32, 64, false}, + pkcs11.CKM_SHA256_HMAC_GENERAL: {32, 64, true}, + pkcs11.CKM_SHA384_HMAC: {48, 64, false}, + pkcs11.CKM_SHA384_HMAC_GENERAL: {48, 64, true}, + pkcs11.CKM_SHA512_HMAC: {64, 128, false}, + pkcs11.CKM_SHA512_HMAC_GENERAL: {64, 128, true}, + pkcs11.CKM_SHA512_224_HMAC: {28, 128, false}, + pkcs11.CKM_SHA512_224_HMAC_GENERAL: {28, 128, true}, + pkcs11.CKM_SHA512_256_HMAC: {32, 128, false}, + pkcs11.CKM_SHA512_256_HMAC_GENERAL: {32, 128, true}, + pkcs11.CKM_RIPEMD160_HMAC: {20, 64, false}, + pkcs11.CKM_RIPEMD160_HMAC_GENERAL: {20, 64, true}, +} + +// errHmacClosed is called if an HMAC is updated after it has finished. +var errHmacClosed = errors.New("already called Sum()") + +// NewHMAC returns a new HMAC hash using the given PKCS#11 mechanism +// and key. +// length specifies the output size, for _GENERAL mechanisms. +// +// If the mechanism is not in the built-in list of known mechanisms then the +// Size() function will return whatever length was, even if it is wrong. +// BlockSize() will always return 0 in this case. +// +// The Reset() method is not implemented. +// After Sum() is called no new data may be added. +func (key *SecretKey) NewHMAC(mech int, length int) (hash.Hash, error) { + hi := hmacImplementation{ + key: key, + } + var params []byte + if info, ok := hmacInfos[mech]; ok { + hi.blockSize = info.blockSize + if info.general { + hi.size = length + params = ulongToBytes(uint(length)) + } else { + hi.size = info.size + } + } else { + hi.size = length + } + hi.mechDescription = []*pkcs11.Mechanism{pkcs11.NewMechanism(uint(mech), params)} + if err := hi.initialize(); err != nil { + return nil, err + } + return &hi, nil +} + +func (hi *hmacImplementation) initialize() (err error) { + session, err := hi.key.context.getSession() + if err != nil { + return err + } + + hi.session = session + hi.cleanup = func() { + hi.key.context.pool.Put(session) + hi.session = nil + } + if err = hi.session.ctx.SignInit(hi.session.handle, hi.mechDescription, hi.key.handle); err != nil { + hi.cleanup() + return + } + hi.updates = 0 + hi.result = nil + return +} + +func (hi *hmacImplementation) Write(p []byte) (n int, err error) { + if hi.result != nil { + if len(p) > 0 { + err = errHmacClosed + } + return + } + if err = hi.session.ctx.SignUpdate(hi.session.handle, p); err != nil { + return + } + hi.updates++ + n = len(p) + return +} + +func (hi *hmacImplementation) Sum(b []byte) []byte { + if hi.result == nil { + var err error + if hi.updates == 0 { + // http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/os/pkcs11-base-v2.40-os.html#_Toc322855304 + // We must ensure that C_SignUpdate is called _at least once_. + if err = hi.session.ctx.SignUpdate(hi.session.handle, []byte{}); err != nil { + panic(err) + } + } + hi.result, err = hi.session.ctx.SignFinal(hi.session.handle) + hi.cleanup() + if err != nil { + panic(err) + } + } + return append(b, hi.result...) +} + +func (hi *hmacImplementation) Reset() { + hi.Sum(nil) // Clean up + + // Assign the error to "_" to indicate we are knowingly ignoring this. It may have been + // sensible to panic at this stage, but we cannot add a panic without breaking backwards + // compatibility. + _ = hi.initialize() +} + +func (hi *hmacImplementation) Size() int { + return hi.size +} + +func (hi *hmacImplementation) BlockSize() int { + return hi.blockSize +} diff --git a/vendor/github.com/ThalesIgnite/crypto11/keys.go b/vendor/github.com/ThalesIgnite/crypto11/keys.go new file mode 100644 index 0000000000000..998663a5b5f36 --- /dev/null +++ b/vendor/github.com/ThalesIgnite/crypto11/keys.go @@ -0,0 +1,613 @@ +// Copyright 2016, 2017 Thales e-Security, Inc +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package crypto11 + +import ( + "crypto" + "crypto/x509" + "github.com/miekg/pkcs11" + "github.com/pkg/errors" +) + +const maxHandlePerFind = 20 + +// errNoCkaId is returned if a private key is found which has no CKA_ID attribute +var errNoCkaId = errors.New("private key has no CKA_ID") + +// errNoPublicHalf is returned if a public half cannot be found to match a given private key +var errNoPublicHalf = errors.New("could not find public key to match private key") + +func findKeysWithAttributes(session *pkcs11Session, template []*pkcs11.Attribute) (handles []pkcs11.ObjectHandle, err error) { + if err = session.ctx.FindObjectsInit(session.handle, template); err != nil { + return nil, err + } + defer func() { + finalErr := session.ctx.FindObjectsFinal(session.handle) + if err == nil { + err = finalErr + } + }() + + newhandles, _, err := session.ctx.FindObjects(session.handle, maxHandlePerFind) + if err != nil { + return nil, err + } + + for len(newhandles) > 0 { + handles = append(handles, newhandles...) + + newhandles, _, err = session.ctx.FindObjects(session.handle, maxHandlePerFind) + if err != nil { + return nil, err + } + } + + return handles, nil +} + +// Find key objects. For asymmetric keys this only finds one half so +// callers will call it twice. Returns nil if the key does not exist on the token. +func findKeys(session *pkcs11Session, id []byte, label []byte, keyclass *uint, keytype *uint) (handles []pkcs11.ObjectHandle, err error) { + var template []*pkcs11.Attribute + + if keyclass != nil { + template = append(template, pkcs11.NewAttribute(pkcs11.CKA_CLASS, *keyclass)) + } + if keytype != nil { + template = append(template, pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, *keytype)) + } + if id != nil { + template = append(template, pkcs11.NewAttribute(pkcs11.CKA_ID, id)) + } + if label != nil { + template = append(template, pkcs11.NewAttribute(pkcs11.CKA_LABEL, label)) + } + + if handles, err = findKeysWithAttributes(session, template); err != nil { + return nil, err + } + + return handles, nil +} + +// Find a key object. For asymmetric keys this only finds one half so +// callers will call it twice. Returns nil if the key does not exist on the token. +func findKey(session *pkcs11Session, id []byte, label []byte, keyclass *uint, keytype *uint) (obj *pkcs11.ObjectHandle, err error) { + handles, err := findKeys(session, id, label, keyclass, keytype) + if err != nil { + return nil, err + } + + if len(handles) == 0 { + return nil, nil + } + return &handles[0], nil +} + +// Takes a handles to the private half of a keypair, locates the public half with the matching CKA_ID and CKA_LABEL +// values and constructs a keypair object from them both. +func (c *Context) makeKeyPair(session *pkcs11Session, privHandle *pkcs11.ObjectHandle) (signer Signer, certificate *x509.Certificate, err error) { + attributes := []*pkcs11.Attribute{ + pkcs11.NewAttribute(pkcs11.CKA_ID, nil), + pkcs11.NewAttribute(pkcs11.CKA_LABEL, nil), + pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, 0), + } + if attributes, err = session.ctx.GetAttributeValue(session.handle, *privHandle, attributes); err != nil { + return nil, nil, err + } + id := attributes[0].Value + label := attributes[1].Value + keyType := bytesToUlong(attributes[2].Value) + + // Ensure the private key actually has a non-empty CKA_ID to match on + if id == nil || len(id) == 0 { + return nil, nil, errNoCkaId + } + + var pubHandle *pkcs11.ObjectHandle + + // Find the public half which has a matching CKA_ID + pubHandle, err = findKey(session, id, label, uintPtr(pkcs11.CKO_PUBLIC_KEY), &keyType) + if err != nil { + p11Err, ok := err.(pkcs11.Error) + + if len(label) == 0 && ok && p11Err == pkcs11.CKR_TEMPLATE_INCONSISTENT { + // This probably means we are using a token that doesn't like us passing empty attributes in a template. + // For instance CloudHSM cannot search for a key with CKA_LABEL="". So if the private key doesn't have a + // label, we need to pass nil into findKeys, then match against the first key without a label. + + pubHandles, err := findKeys(session, id, nil, uintPtr(pkcs11.CKO_PUBLIC_KEY), &keyType) + if err != nil { + return nil, nil, err + } + + for _, handle := range pubHandles { + template := []*pkcs11.Attribute{pkcs11.NewAttribute(pkcs11.CKA_LABEL, nil)} + template, err = session.ctx.GetAttributeValue(session.handle, handle, template) + if err != nil { + return nil, nil, err + } + if len(template[0].Value) == 0 { + pubHandle = &handle + break + } + } + } else { + return nil, nil, err + } + } + + if pubHandle == nil { + // Try harder to find a matching public key, based on CKA_ID alone + pubHandle, err = findKey(session, id, nil, uintPtr(pkcs11.CKO_PUBLIC_KEY), &keyType) + } + + resultPkcs11PrivateKey := pkcs11PrivateKey{ + pkcs11Object: pkcs11Object{ + handle: *privHandle, + context: c, + }, + } + + var pub crypto.PublicKey + certificate, _ = findCertificate(session, id, nil, nil) + if certificate != nil && pubHandle == nil { + pub = certificate.PublicKey + } + + if pub == nil && pubHandle == nil { + // We can't return a Signer if we don't have private and public key. Treat it as an error. + return nil, nil, errNoPublicHalf + } + + switch keyType { + case pkcs11.CKK_DSA: + result := &pkcs11PrivateKeyDSA{pkcs11PrivateKey: resultPkcs11PrivateKey} + if pubHandle != nil { + if pub, err = exportDSAPublicKey(session, *pubHandle); err != nil { + return nil, nil, err + } + result.pkcs11PrivateKey.pubKeyHandle = *pubHandle + } + + result.pkcs11PrivateKey.pubKey = pub + return result, certificate, nil + + case pkcs11.CKK_RSA: + result := &pkcs11PrivateKeyRSA{pkcs11PrivateKey: resultPkcs11PrivateKey} + if pubHandle != nil { + if pub, err = exportRSAPublicKey(session, *pubHandle); err != nil { + return nil, nil, err + } + result.pkcs11PrivateKey.pubKeyHandle = *pubHandle + } + + result.pkcs11PrivateKey.pubKey = pub + return result, certificate, nil + + case pkcs11.CKK_ECDSA: + result := &pkcs11PrivateKeyECDSA{pkcs11PrivateKey: resultPkcs11PrivateKey} + if pubHandle != nil { + if pub, err = exportECDSAPublicKey(session, *pubHandle); err != nil { + return nil, nil, err + } + result.pkcs11PrivateKey.pubKeyHandle = *pubHandle + } + + result.pkcs11PrivateKey.pubKey = pub + return result, certificate, nil + + default: + return nil, nil, errors.Errorf("unsupported key type: %X", keyType) + } +} + +// FindKeyPair retrieves a previously created asymmetric key pair, or nil if it cannot be found. +// +// At least one of id and label must be specified. +// Only private keys that have a non-empty CKA_ID will be found, as this is required to locate the matching public key. +// If the private key is found, but the public key with a corresponding CKA_ID is not, the key is not returned +// because we cannot implement crypto.Signer without the public key. +func (c *Context) FindKeyPair(id []byte, label []byte) (Signer, error) { + if c.closed.Get() { + return nil, errClosed + } + + result, err := c.FindKeyPairs(id, label) + if err != nil { + return nil, err + } + + if len(result) == 0 { + return nil, nil + } + + return result[0], nil +} + +// FindKeyPairs retrieves all matching asymmetric key pairs, or a nil slice if none can be found. +// +// At least one of id and label must be specified. +// Only private keys that have a non-empty CKA_ID will be found, as this is required to locate the matching public key. +// If the private key is found, but the public key with a corresponding CKA_ID is not, the key is not returned +// because we cannot implement crypto.Signer without the public key. +func (c *Context) FindKeyPairs(id []byte, label []byte) (signer []Signer, err error) { + if c.closed.Get() { + return nil, errClosed + } + + if id == nil && label == nil { + return nil, errors.New("id and label cannot both be nil") + } + + attributes := NewAttributeSet() + + if id != nil { + err = attributes.Set(CkaId, id) + if err != nil { + return nil, err + } + } + if label != nil { + err = attributes.Set(CkaLabel, label) + if err != nil { + return nil, err + } + } + + return c.FindKeyPairsWithAttributes(attributes) +} + +// FindKeyPairWithAttributes retrieves a previously created asymmetric key pair, or nil if it cannot be found. +// The given attributes are matched against the private half only. Then the public half with a matching CKA_ID +// and CKA_LABEL values is found. +// +// Only private keys that have a non-empty CKA_ID will be found, as this is required to locate the matching public key. +// If the private key is found, but the public key with a corresponding CKA_ID is not, the key is not returned +// because we cannot implement crypto.Signer without the public key. +func (c *Context) FindKeyPairWithAttributes(attributes AttributeSet) (Signer, error) { + if c.closed.Get() { + return nil, errClosed + } + + result, err := c.FindKeyPairsWithAttributes(attributes) + if err != nil { + return nil, err + } + + if len(result) == 0 { + return nil, nil + } + + return result[0], nil +} + +// FindKeyPairsWithAttributes retrieves previously created asymmetric key pairs, or nil if none can be found. +// The given attributes are matched against the private half only. Then the public half with a matching CKA_ID +// and CKA_LABEL values is found. +// +// Only private keys that have a non-empty CKA_ID will be found, as this is required to locate the matching public key. +// If the private key is found, but the public key with a corresponding CKA_ID is not, the key is not returned +// because we cannot implement crypto.Signer without the public key. +func (c *Context) FindKeyPairsWithAttributes(attributes AttributeSet) (signer []Signer, err error) { + if c.closed.Get() { + return nil, errClosed + } + + var keys []Signer + + if _, ok := attributes[CkaClass]; ok { + return nil, errors.Errorf("keypair attribute set must not contain CkaClass") + } + + err = c.withSession(func(session *pkcs11Session) error { + // Add the private key class to the template to find the private half + privAttributes := attributes.Copy() + err = privAttributes.Set(CkaClass, pkcs11.CKO_PRIVATE_KEY) + if err != nil { + return err + } + + privHandles, err := findKeysWithAttributes(session, privAttributes.ToSlice()) + if err != nil { + return err + } + + for _, privHandle := range privHandles { + k, _, err := c.makeKeyPair(session, &privHandle) + + if err == errNoCkaId || err == errNoPublicHalf { + continue + } + if err != nil { + return err + } + + keys = append(keys, k) + } + + return nil + }) + + if err != nil { + return nil, err + } + + return keys, nil +} + +// FindAllKeyPairs retrieves all existing asymmetric key pairs, or a nil slice if none can be found. +// +// If a private key is found, but the corresponding public key is not, the key is not returned because we cannot +// implement crypto.Signer without the public key. +func (c *Context) FindAllKeyPairs() ([]Signer, error) { + if c.closed.Get() { + return nil, errClosed + } + + return c.FindKeyPairsWithAttributes(NewAttributeSet()) +} + +// Public returns the public half of a private key. +// +// This partially implements the go.crypto.Signer and go.crypto.Decrypter interfaces for +// pkcs11PrivateKey. (The remains of the implementation is in the +// key-specific types.) +func (k pkcs11PrivateKey) Public() crypto.PublicKey { + return k.pubKey +} + +// FindKey retrieves a previously created symmetric key, or nil if it cannot be found. +// +// Either (but not both) of id and label may be nil, in which case they are ignored. +func (c *Context) FindKey(id []byte, label []byte) (*SecretKey, error) { + if c.closed.Get() { + return nil, errClosed + } + + result, err := c.FindKeys(id, label) + if err != nil { + return nil, err + } + + if len(result) == 0 { + return nil, nil + } + + return result[0], nil +} + +// FindKeys retrieves all matching symmetric keys, or a nil slice if none can be found. +// +// At least one of id and label must be specified. +func (c *Context) FindKeys(id []byte, label []byte) (key []*SecretKey, err error) { + if c.closed.Get() { + return nil, errClosed + } + + if id == nil && label == nil { + return nil, errors.New("id and label cannot both be nil") + } + + attributes := NewAttributeSet() + + if id != nil { + err = attributes.Set(CkaId, id) + if err != nil { + return nil, err + } + } + if label != nil { + err = attributes.Set(CkaLabel, label) + if err != nil { + return nil, err + } + } + + return c.FindKeysWithAttributes(attributes) +} + +// FindKeyWithAttributes retrieves a previously created symmetric key, or nil if it cannot be found. +func (c *Context) FindKeyWithAttributes(attributes AttributeSet) (*SecretKey, error) { + if c.closed.Get() { + return nil, errClosed + } + + result, err := c.FindKeysWithAttributes(attributes) + if err != nil { + return nil, err + } + + if len(result) == 0 { + return nil, nil + } + + return result[0], nil +} + +// FindKeysWithAttributes retrieves previously created symmetric keys, or a nil slice if none can be found. +func (c *Context) FindKeysWithAttributes(attributes AttributeSet) ([]*SecretKey, error) { + if c.closed.Get() { + return nil, errClosed + } + + var keys []*SecretKey + + if _, ok := attributes[CkaClass]; ok { + return nil, errors.Errorf("key attribute set must not contain CkaClass") + } + + err := c.withSession(func(session *pkcs11Session) error { + // Add the private key class to the template to find the private half + privAttributes := attributes.Copy() + err := privAttributes.Set(CkaClass, pkcs11.CKO_SECRET_KEY) + if err != nil { + return err + } + + privHandles, err := findKeysWithAttributes(session, privAttributes.ToSlice()) + if err != nil { + return err + } + + for _, privHandle := range privHandles { + attributes := []*pkcs11.Attribute{ + pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, 0), + } + if attributes, err = session.ctx.GetAttributeValue(session.handle, privHandle, attributes); err != nil { + return err + } + keyType := bytesToUlong(attributes[0].Value) + + if cipher, ok := Ciphers[int(keyType)]; ok { + k := &SecretKey{pkcs11Object{privHandle, c}, cipher} + keys = append(keys, k) + } else { + return errors.Errorf("unsupported key type: %X", keyType) + } + } + + return nil + }) + + if err != nil { + return nil, err + } + return keys, nil +} + +// FindAllKeyPairs retrieves all existing symmetric keys, or a nil slice if none can be found. +func (c *Context) FindAllKeys() ([]*SecretKey, error) { + if c.closed.Get() { + return nil, errClosed + } + + return c.FindKeysWithAttributes(NewAttributeSet()) +} + +func uintPtr(i uint) *uint { return &i } + +func (c *Context) getAttributes(handle pkcs11.ObjectHandle, attributes []AttributeType) (a AttributeSet, err error) { + values := NewAttributeSet() + + err = c.withSession(func(session *pkcs11Session) error { + var attrs []*pkcs11.Attribute + for _, a := range attributes { + attrs = append(attrs, pkcs11.NewAttribute(a, nil)) + } + + p11values, err := session.ctx.GetAttributeValue(session.handle, handle, attrs) + if err != nil { + return err + } + + values.AddIfNotPresent(p11values) + + return nil + }) + + return values, err +} + +// GetAttributes gets the values of the specified attributes on the given key or keypair. +// If the key is asymmetric, then the attributes are retrieved from the private half. +// +// If the object is not a crypto11 key or keypair then an error is returned. +func (c *Context) GetAttributes(key interface{}, attributes []AttributeType) (a AttributeSet, err error) { + if c.closed.Get() { + return nil, errClosed + } + + var handle pkcs11.ObjectHandle + + switch k := (key).(type) { + case *pkcs11PrivateKeyDSA: + handle = k.handle + case *pkcs11PrivateKeyRSA: + handle = k.handle + case *pkcs11PrivateKeyECDSA: + handle = k.handle + case *SecretKey: + handle = k.handle + default: + return nil, errors.Errorf("not a PKCS#11 key") + } + + return c.getAttributes(handle, attributes) +} + +// GetAttribute gets the value of the specified attribute on the given key or keypair. +// If the key is asymmetric, then the attribute is retrieved from the private half. +// +// If the object is not a crypto11 key or keypair then an error is returned. +func (c *Context) GetAttribute(key interface{}, attribute AttributeType) (a *Attribute, err error) { + if c.closed.Get() { + return nil, errClosed + } + + set, err := c.GetAttributes(key, []AttributeType{attribute}) + if err != nil { + return nil, err + } + + return set[attribute], nil +} + +// GetPubAttributes gets the values of the specified attributes on the public half of the given keypair. +// +// If the object is not a crypto11 keypair then an error is returned. +func (c *Context) GetPubAttributes(key interface{}, attributes []AttributeType) (a AttributeSet, err error) { + if c.closed.Get() { + return nil, errClosed + } + + var handle pkcs11.ObjectHandle + + switch k := (key).(type) { + case *pkcs11PrivateKeyDSA: + handle = k.pubKeyHandle + case *pkcs11PrivateKeyRSA: + handle = k.pubKeyHandle + case *pkcs11PrivateKeyECDSA: + handle = k.pubKeyHandle + default: + return nil, errors.Errorf("not an asymmetric PKCS#11 key") + } + + return c.getAttributes(handle, attributes) +} + +// GetPubAttribute gets the value of the specified attribute on the public half of the given key. +// +// If the object is not a crypto11 keypair then an error is returned. +func (c *Context) GetPubAttribute(key interface{}, attribute AttributeType) (a *Attribute, err error) { + if c.closed.Get() { + return nil, errClosed + } + + set, err := c.GetPubAttributes(key, []AttributeType{attribute}) + if err != nil { + return nil, err + } + + return set[attribute], nil +} diff --git a/vendor/github.com/ThalesIgnite/crypto11/rand.go b/vendor/github.com/ThalesIgnite/crypto11/rand.go new file mode 100644 index 0000000000000..c820e552ce0cb --- /dev/null +++ b/vendor/github.com/ThalesIgnite/crypto11/rand.go @@ -0,0 +1,54 @@ +// Copyright 2016, 2017 Thales e-Security, Inc +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package crypto11 + +import ( + "io" +) + +// NewRandomReader returns a reader for the random number generator on the token. +func (c *Context) NewRandomReader() (io.Reader, error) { + if c.closed.Get() { + return nil, errClosed + } + + return pkcs11RandReader{c}, nil +} + +// pkcs11RandReader is a random number reader that uses PKCS#11. +type pkcs11RandReader struct { + context *Context +} + +// This implements the Reader interface for pkcs11RandReader. +func (r pkcs11RandReader) Read(data []byte) (n int, err error) { + var result []byte + + if err = r.context.withSession(func(session *pkcs11Session) error { + result, err = r.context.ctx.GenerateRandom(session.handle, len(data)) + return err + }); err != nil { + return 0, err + } + copy(data, result) + return len(result), err +} diff --git a/vendor/github.com/ThalesIgnite/crypto11/rsa.go b/vendor/github.com/ThalesIgnite/crypto11/rsa.go new file mode 100644 index 0000000000000..234fd0a0bf4a6 --- /dev/null +++ b/vendor/github.com/ThalesIgnite/crypto11/rsa.go @@ -0,0 +1,325 @@ +// Copyright 2016, 2017 Thales e-Security, Inc +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package crypto11 + +import ( + "crypto" + "crypto/rsa" + "errors" + "io" + "math/big" + + "github.com/miekg/pkcs11" +) + +// errMalformedRSAPublicKey is returned when an RSA public key is not in a suitable form. +// +// Currently this means that the public exponent is either bigger than +// 32 bits, or less than 2. +var errMalformedRSAPublicKey = errors.New("malformed RSA public key") + +// errUnsupportedRSAOptions is returned when an unsupported RSA option is requested. +// +// Currently this means a nontrivial SessionKeyLen when decrypting; or +// an unsupported hash function; or crypto.rsa.PSSSaltLengthAuto was +// requested. +var errUnsupportedRSAOptions = errors.New("unsupported RSA option value") + +// pkcs11PrivateKeyRSA contains a reference to a loaded PKCS#11 RSA private key object. +type pkcs11PrivateKeyRSA struct { + pkcs11PrivateKey +} + +// Export the public key corresponding to a private RSA key. +func exportRSAPublicKey(session *pkcs11Session, pubHandle pkcs11.ObjectHandle) (crypto.PublicKey, error) { + template := []*pkcs11.Attribute{ + pkcs11.NewAttribute(pkcs11.CKA_MODULUS, nil), + pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_EXPONENT, nil), + } + exported, err := session.ctx.GetAttributeValue(session.handle, pubHandle, template) + if err != nil { + return nil, err + } + var modulus = new(big.Int) + modulus.SetBytes(exported[0].Value) + var bigExponent = new(big.Int) + bigExponent.SetBytes(exported[1].Value) + if bigExponent.BitLen() > 32 { + return nil, errMalformedRSAPublicKey + } + if bigExponent.Sign() < 1 { + return nil, errMalformedRSAPublicKey + } + exponent := int(bigExponent.Uint64()) + result := rsa.PublicKey{ + N: modulus, + E: exponent, + } + if result.E < 2 { + return nil, errMalformedRSAPublicKey + } + return &result, nil +} + +// GenerateRSAKeyPair creates an RSA key pair on the token. The id parameter is used to +// set CKA_ID and must be non-nil. RSA private keys are generated with both sign and decrypt +// permissions, and a public exponent of 65537. +func (c *Context) GenerateRSAKeyPair(id []byte, bits int) (SignerDecrypter, error) { + if c.closed.Get() { + return nil, errClosed + } + + public, err := NewAttributeSetWithID(id) + if err != nil { + return nil, err + } + // Copy the AttributeSet to allow modifications. + private := public.Copy() + + return c.GenerateRSAKeyPairWithAttributes(public, private, bits) +} + +// GenerateRSAKeyPairWithLabel creates an RSA key pair on the token. The id and label parameters are used to +// set CKA_ID and CKA_LABEL respectively and must be non-nil. RSA private keys are generated with both sign and decrypt +// permissions, and a public exponent of 65537. +func (c *Context) GenerateRSAKeyPairWithLabel(id, label []byte, bits int) (SignerDecrypter, error) { + if c.closed.Get() { + return nil, errClosed + } + + public, err := NewAttributeSetWithIDAndLabel(id, label) + if err != nil { + return nil, err + } + // Copy the AttributeSet to allow modifications. + private := public.Copy() + + return c.GenerateRSAKeyPairWithAttributes(public, private, bits) +} + +// GenerateRSAKeyPairWithAttributes generates an RSA key pair on the token. After this function returns, public and +// private will contain the attributes applied to the key pair. If required attributes are missing, they will be set to +// a default value. +func (c *Context) GenerateRSAKeyPairWithAttributes(public, private AttributeSet, bits int) (SignerDecrypter, error) { + if c.closed.Get() { + return nil, errClosed + } + + var k SignerDecrypter + + err := c.withSession(func(session *pkcs11Session) error { + + public.AddIfNotPresent([]*pkcs11.Attribute{ + pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PUBLIC_KEY), + pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_RSA), + pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true), + pkcs11.NewAttribute(pkcs11.CKA_VERIFY, true), + pkcs11.NewAttribute(pkcs11.CKA_ENCRYPT, true), + pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_EXPONENT, []byte{1, 0, 1}), + pkcs11.NewAttribute(pkcs11.CKA_MODULUS_BITS, bits), + }) + private.AddIfNotPresent([]*pkcs11.Attribute{ + pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true), + pkcs11.NewAttribute(pkcs11.CKA_SIGN, true), + pkcs11.NewAttribute(pkcs11.CKA_DECRYPT, true), + pkcs11.NewAttribute(pkcs11.CKA_SENSITIVE, true), + pkcs11.NewAttribute(pkcs11.CKA_EXTRACTABLE, false), + }) + + mech := []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS_KEY_PAIR_GEN, nil)} + pubHandle, privHandle, err := session.ctx.GenerateKeyPair(session.handle, + mech, + public.ToSlice(), + private.ToSlice()) + if err != nil { + return err + } + + pub, err := exportRSAPublicKey(session, pubHandle) + if err != nil { + return err + } + k = &pkcs11PrivateKeyRSA{ + pkcs11PrivateKey: pkcs11PrivateKey{ + pkcs11Object: pkcs11Object{ + handle: privHandle, + context: c, + }, + pubKeyHandle: pubHandle, + pubKey: pub, + }} + return nil + }) + return k, err +} + +// Decrypt decrypts a message using a RSA key. +// +// This completes the implemention of crypto.Decrypter for pkcs11PrivateKeyRSA. +// +// Note that the SessionKeyLen option (for PKCS#1v1.5 decryption) is not supported. +// +// The underlying PKCS#11 implementation may impose further restrictions. +func (priv *pkcs11PrivateKeyRSA) Decrypt(rand io.Reader, ciphertext []byte, options crypto.DecrypterOpts) (plaintext []byte, err error) { + err = priv.context.withSession(func(session *pkcs11Session) error { + if options == nil { + plaintext, err = decryptPKCS1v15(session, priv, ciphertext, 0) + } else { + switch o := options.(type) { + case *rsa.PKCS1v15DecryptOptions: + plaintext, err = decryptPKCS1v15(session, priv, ciphertext, o.SessionKeyLen) + case *rsa.OAEPOptions: + plaintext, err = decryptOAEP(session, priv, ciphertext, o.Hash, o.Label) + default: + err = errUnsupportedRSAOptions + } + } + return err + }) + return plaintext, err +} + +func decryptPKCS1v15(session *pkcs11Session, key *pkcs11PrivateKeyRSA, ciphertext []byte, sessionKeyLen int) ([]byte, error) { + if sessionKeyLen != 0 { + return nil, errUnsupportedRSAOptions + } + mech := []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS, nil)} + if err := session.ctx.DecryptInit(session.handle, mech, key.handle); err != nil { + return nil, err + } + return session.ctx.Decrypt(session.handle, ciphertext) +} + +func decryptOAEP(session *pkcs11Session, key *pkcs11PrivateKeyRSA, ciphertext []byte, hashFunction crypto.Hash, + label []byte) ([]byte, error) { + + hashAlg, mgfAlg, _, err := hashToPKCS11(hashFunction) + if err != nil { + return nil, err + } + + mech := pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS_OAEP, + pkcs11.NewOAEPParams(hashAlg, mgfAlg, pkcs11.CKZ_DATA_SPECIFIED, label)) + + err = session.ctx.DecryptInit(session.handle, []*pkcs11.Mechanism{mech}, key.handle) + if err != nil { + return nil, err + } + return session.ctx.Decrypt(session.handle, ciphertext) +} + +func hashToPKCS11(hashFunction crypto.Hash) (hashAlg uint, mgfAlg uint, hashLen uint, err error) { + switch hashFunction { + case crypto.SHA1: + return pkcs11.CKM_SHA_1, pkcs11.CKG_MGF1_SHA1, 20, nil + case crypto.SHA224: + return pkcs11.CKM_SHA224, pkcs11.CKG_MGF1_SHA224, 28, nil + case crypto.SHA256: + return pkcs11.CKM_SHA256, pkcs11.CKG_MGF1_SHA256, 32, nil + case crypto.SHA384: + return pkcs11.CKM_SHA384, pkcs11.CKG_MGF1_SHA384, 48, nil + case crypto.SHA512: + return pkcs11.CKM_SHA512, pkcs11.CKG_MGF1_SHA512, 64, nil + default: + return 0, 0, 0, errUnsupportedRSAOptions + } +} + +func signPSS(session *pkcs11Session, key *pkcs11PrivateKeyRSA, digest []byte, opts *rsa.PSSOptions) ([]byte, error) { + var hMech, mgf, hLen, sLen uint + var err error + if hMech, mgf, hLen, err = hashToPKCS11(opts.Hash); err != nil { + return nil, err + } + switch opts.SaltLength { + case rsa.PSSSaltLengthAuto: // parseltongue constant + // TODO we could (in principle) work out the biggest + // possible size from the key, but until someone has + // the effort to do that... + return nil, errUnsupportedRSAOptions + case rsa.PSSSaltLengthEqualsHash: + sLen = hLen + default: + sLen = uint(opts.SaltLength) + } + // TODO this is pretty horrible, maybe the PKCS#11 wrapper + // could be improved to help us out here + parameters := concat(ulongToBytes(hMech), + ulongToBytes(mgf), + ulongToBytes(sLen)) + mech := []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS_PSS, parameters)} + if err = session.ctx.SignInit(session.handle, mech, key.handle); err != nil { + return nil, err + } + return session.ctx.Sign(session.handle, digest) +} + +var pkcs1Prefix = map[crypto.Hash][]byte{ + crypto.SHA1: {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14}, + crypto.SHA224: {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c}, + crypto.SHA256: {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20}, + crypto.SHA384: {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30}, + crypto.SHA512: {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40}, +} + +func signPKCS1v15(session *pkcs11Session, key *pkcs11PrivateKeyRSA, digest []byte, hash crypto.Hash) (signature []byte, err error) { + /* Calculate T for EMSA-PKCS1-v1_5. */ + oid := pkcs1Prefix[hash] + T := make([]byte, len(oid)+len(digest)) + copy(T[0:len(oid)], oid) + copy(T[len(oid):], digest) + mech := []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS, nil)} + err = session.ctx.SignInit(session.handle, mech, key.handle) + if err == nil { + signature, err = session.ctx.Sign(session.handle, T) + } + return +} + +// Sign signs a message using a RSA key. +// +// This completes the implemention of crypto.Signer for pkcs11PrivateKeyRSA. +// +// PKCS#11 expects to pick its own random data where necessary for signatures, so the rand argument is ignored. +// +// Note that (at present) the crypto.rsa.PSSSaltLengthAuto option is +// not supported. The caller must either use +// crypto.rsa.PSSSaltLengthEqualsHash (recommended) or pass an +// explicit salt length. Moreover the underlying PKCS#11 +// implementation may impose further restrictions. +func (priv *pkcs11PrivateKeyRSA) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) { + err = priv.context.withSession(func(session *pkcs11Session) error { + switch opts.(type) { + case *rsa.PSSOptions: + signature, err = signPSS(session, priv, digest, opts.(*rsa.PSSOptions)) + default: /* PKCS1-v1_5 */ + signature, err = signPKCS1v15(session, priv, digest, opts.HashFunc()) + } + return err + }) + + if err != nil { + return nil, err + } + + return signature, err +} diff --git a/vendor/github.com/ThalesIgnite/crypto11/sessions.go b/vendor/github.com/ThalesIgnite/crypto11/sessions.go new file mode 100644 index 0000000000000..af86b7efe9902 --- /dev/null +++ b/vendor/github.com/ThalesIgnite/crypto11/sessions.go @@ -0,0 +1,88 @@ +// Copyright 2016, 2017 Thales e-Security, Inc +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package crypto11 + +import ( + "context" + "errors" + + "github.com/miekg/pkcs11" + "github.com/thales-e-security/pool" +) + +// pkcs11Session wraps a PKCS#11 session handle so we can use it in a resource pool. +type pkcs11Session struct { + ctx *pkcs11.Ctx + handle pkcs11.SessionHandle +} + +// Close is required to satisfy the pools.Resource interface. It closes the session, but swallows any +// errors that occur. +func (s pkcs11Session) Close() { + // We cannot return an error, so we swallow it + _ = s.ctx.CloseSession(s.handle) +} + +// withSession executes a function with a session. +func (c *Context) withSession(f func(session *pkcs11Session) error) error { + session, err := c.getSession() + if err != nil { + return err + } + defer c.pool.Put(session) + + return f(session) +} + +// getSession retrieves a session from the pool, respecting the timeout defined in the Context config. +// Callers are responsible for putting this session back in the pool. +func (c *Context) getSession() (*pkcs11Session, error) { + ctx := context.Background() + + if c.cfg.PoolWaitTimeout > 0 { + var cancel context.CancelFunc + ctx, cancel = context.WithTimeout(context.Background(), c.cfg.PoolWaitTimeout) + defer cancel() + } + + resource, err := c.pool.Get(ctx) + if err == pool.ErrClosed { + // Our Context must have been closed, return a nicer error. + // We don't use errClosed to ensure our tests identify functions that aren't checking for closure + // correctly. + return nil, errors.New("context is closed") + } + if err != nil { + return nil, err + } + + return resource.(*pkcs11Session), nil +} + +// resourcePoolFactoryFunc is called by the resource pool when a new session is needed. +func (c *Context) resourcePoolFactoryFunc() (pool.Resource, error) { + session, err := c.ctx.OpenSession(c.slot, pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION) + if err != nil { + return nil, err + } + return &pkcs11Session{c.ctx, session}, nil +} diff --git a/vendor/github.com/ThalesIgnite/crypto11/symmetric.go b/vendor/github.com/ThalesIgnite/crypto11/symmetric.go new file mode 100644 index 0000000000000..4a01248b70166 --- /dev/null +++ b/vendor/github.com/ThalesIgnite/crypto11/symmetric.go @@ -0,0 +1,366 @@ +// Copyright 2018 Thales e-Security, Inc +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package crypto11 + +import ( + "errors" + + "github.com/miekg/pkcs11" +) + +// SymmetricGenParams holds a consistent (key type, mechanism) key generation pair. +type SymmetricGenParams struct { + // Key type (CKK_...) + KeyType uint + + // Key generation mechanism (CKM_..._KEY_GEN) + GenMech uint +} + +// SymmetricCipher represents information about a symmetric cipher. +type SymmetricCipher struct { + // Possible key generation parameters + // (For HMAC this varies between PKCS#11 implementations.) + GenParams []SymmetricGenParams + + // Block size in bytes + BlockSize int + + // True if encryption supported + Encrypt bool + + // True if MAC supported + MAC bool + + // ECB mechanism (CKM_..._ECB) + ECBMech uint + + // CBC mechanism (CKM_..._CBC) + CBCMech uint + + // CBC mechanism with PKCS#7 padding (CKM_..._CBC) + CBCPKCSMech uint + + // GCM mechanism (CKM_..._GCM) + GCMMech uint +} + +// CipherAES describes the AES cipher. Use this with the +// GenerateSecretKey... functions. +var CipherAES = &SymmetricCipher{ + GenParams: []SymmetricGenParams{ + { + KeyType: pkcs11.CKK_AES, + GenMech: pkcs11.CKM_AES_KEY_GEN, + }, + }, + BlockSize: 16, + Encrypt: true, + MAC: false, + ECBMech: pkcs11.CKM_AES_ECB, + CBCMech: pkcs11.CKM_AES_CBC, + CBCPKCSMech: pkcs11.CKM_AES_CBC_PAD, + GCMMech: pkcs11.CKM_AES_GCM, +} + +// CipherDES3 describes the three-key triple-DES cipher. Use this with the +// GenerateSecretKey... functions. +var CipherDES3 = &SymmetricCipher{ + GenParams: []SymmetricGenParams{ + { + KeyType: pkcs11.CKK_DES3, + GenMech: pkcs11.CKM_DES3_KEY_GEN, + }, + }, + BlockSize: 8, + Encrypt: true, + MAC: false, + ECBMech: pkcs11.CKM_DES3_ECB, + CBCMech: pkcs11.CKM_DES3_CBC, + CBCPKCSMech: pkcs11.CKM_DES3_CBC_PAD, + GCMMech: 0, +} + +// CipherGeneric describes the CKK_GENERIC_SECRET key type. Use this with the +// GenerateSecretKey... functions. +// +// The spec promises that this mechanism can be used to perform HMAC +// operations, although implementations vary; +// CipherHMACSHA1 and so on may give better results. +var CipherGeneric = &SymmetricCipher{ + GenParams: []SymmetricGenParams{ + { + KeyType: pkcs11.CKK_GENERIC_SECRET, + GenMech: pkcs11.CKM_GENERIC_SECRET_KEY_GEN, + }, + }, + BlockSize: 64, + Encrypt: false, + MAC: true, + ECBMech: 0, + CBCMech: 0, + GCMMech: 0, +} + +// CipherHMACSHA1 describes the CKK_SHA_1_HMAC key type. Use this with the +// GenerateSecretKey... functions. +var CipherHMACSHA1 = &SymmetricCipher{ + GenParams: []SymmetricGenParams{ + { + KeyType: pkcs11.CKK_SHA_1_HMAC, + GenMech: CKM_NC_SHA_1_HMAC_KEY_GEN, + }, + { + KeyType: pkcs11.CKK_GENERIC_SECRET, + GenMech: pkcs11.CKM_GENERIC_SECRET_KEY_GEN, + }, + }, + BlockSize: 64, + Encrypt: false, + MAC: true, + ECBMech: 0, + CBCMech: 0, + GCMMech: 0, +} + +// CipherHMACSHA224 describes the CKK_SHA224_HMAC key type. Use this with the +// GenerateSecretKey... functions. +var CipherHMACSHA224 = &SymmetricCipher{ + GenParams: []SymmetricGenParams{ + { + KeyType: pkcs11.CKK_SHA224_HMAC, + GenMech: CKM_NC_SHA224_HMAC_KEY_GEN, + }, + { + KeyType: pkcs11.CKK_GENERIC_SECRET, + GenMech: pkcs11.CKM_GENERIC_SECRET_KEY_GEN, + }, + }, + BlockSize: 64, + Encrypt: false, + MAC: true, + ECBMech: 0, + CBCMech: 0, + GCMMech: 0, +} + +// CipherHMACSHA256 describes the CKK_SHA256_HMAC key type. Use this with the +// GenerateSecretKey... functions. +var CipherHMACSHA256 = &SymmetricCipher{ + GenParams: []SymmetricGenParams{ + { + KeyType: pkcs11.CKK_SHA256_HMAC, + GenMech: CKM_NC_SHA256_HMAC_KEY_GEN, + }, + { + KeyType: pkcs11.CKK_GENERIC_SECRET, + GenMech: pkcs11.CKM_GENERIC_SECRET_KEY_GEN, + }, + }, + BlockSize: 64, + Encrypt: false, + MAC: true, + ECBMech: 0, + CBCMech: 0, + GCMMech: 0, +} + +// CipherHMACSHA384 describes the CKK_SHA384_HMAC key type. Use this with the +// GenerateSecretKey... functions. +var CipherHMACSHA384 = &SymmetricCipher{ + GenParams: []SymmetricGenParams{ + { + KeyType: pkcs11.CKK_SHA384_HMAC, + GenMech: CKM_NC_SHA384_HMAC_KEY_GEN, + }, + { + KeyType: pkcs11.CKK_GENERIC_SECRET, + GenMech: pkcs11.CKM_GENERIC_SECRET_KEY_GEN, + }, + }, + BlockSize: 64, + Encrypt: false, + MAC: true, + ECBMech: 0, + CBCMech: 0, + GCMMech: 0, +} + +// CipherHMACSHA512 describes the CKK_SHA512_HMAC key type. Use this with the +// GenerateSecretKey... functions. +var CipherHMACSHA512 = &SymmetricCipher{ + GenParams: []SymmetricGenParams{ + { + KeyType: pkcs11.CKK_SHA512_HMAC, + GenMech: CKM_NC_SHA512_HMAC_KEY_GEN, + }, + { + KeyType: pkcs11.CKK_GENERIC_SECRET, + GenMech: pkcs11.CKM_GENERIC_SECRET_KEY_GEN, + }, + }, + BlockSize: 128, + Encrypt: false, + MAC: true, + ECBMech: 0, + CBCMech: 0, + GCMMech: 0, +} + +// Ciphers is a map of PKCS#11 key types (CKK_...) to symmetric cipher information. +var Ciphers = map[int]*SymmetricCipher{ + pkcs11.CKK_AES: CipherAES, + pkcs11.CKK_DES3: CipherDES3, + pkcs11.CKK_GENERIC_SECRET: CipherGeneric, + pkcs11.CKK_SHA_1_HMAC: CipherHMACSHA1, + pkcs11.CKK_SHA224_HMAC: CipherHMACSHA224, + pkcs11.CKK_SHA256_HMAC: CipherHMACSHA256, + pkcs11.CKK_SHA384_HMAC: CipherHMACSHA384, + pkcs11.CKK_SHA512_HMAC: CipherHMACSHA512, +} + +// SecretKey contains a reference to a loaded PKCS#11 symmetric key object. +// +// A *SecretKey implements the cipher.Block interface, allowing it be used +// as the argument to cipher.NewCBCEncrypter and similar methods. +// For bulk operation this is very inefficient; +// using NewCBCEncrypterCloser, NewCBCEncrypter or NewCBC from this package is +// much faster. +type SecretKey struct { + pkcs11Object + + // Symmetric cipher information + Cipher *SymmetricCipher +} + +// GenerateSecretKey creates an secret key of given length and type. The id parameter is used to +// set CKA_ID and must be non-nil. +func (c *Context) GenerateSecretKey(id []byte, bits int, cipher *SymmetricCipher) (*SecretKey, error) { + if c.closed.Get() { + return nil, errClosed + } + + template, err := NewAttributeSetWithID(id) + if err != nil { + return nil, err + } + return c.GenerateSecretKeyWithAttributes(template, bits, cipher) +} + +// GenerateSecretKey creates an secret key of given length and type. The id and label parameters are used to +// set CKA_ID and CKA_LABEL respectively and must be non-nil. +func (c *Context) GenerateSecretKeyWithLabel(id, label []byte, bits int, cipher *SymmetricCipher) (*SecretKey, error) { + if c.closed.Get() { + return nil, errClosed + } + + template, err := NewAttributeSetWithIDAndLabel(id, label) + if err != nil { + return nil, err + } + return c.GenerateSecretKeyWithAttributes(template, bits, cipher) + +} + +// GenerateSecretKeyWithAttributes creates an secret key of given length and type. After this function returns, template +// will contain the attributes applied to the key. If required attributes are missing, they will be set to a default +// value. +func (c *Context) GenerateSecretKeyWithAttributes(template AttributeSet, bits int, cipher *SymmetricCipher) (k *SecretKey, err error) { + if c.closed.Get() { + return nil, errClosed + } + + err = c.withSession(func(session *pkcs11Session) error { + + // CKK_*_HMAC exists but there is no specific corresponding CKM_*_KEY_GEN + // mechanism. Therefore we attempt both CKM_GENERIC_SECRET_KEY_GEN and + // vendor-specific mechanisms. + + template.AddIfNotPresent([]*pkcs11.Attribute{ + pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_SECRET_KEY), + pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true), + pkcs11.NewAttribute(pkcs11.CKA_SIGN, cipher.MAC), + pkcs11.NewAttribute(pkcs11.CKA_VERIFY, cipher.MAC), + pkcs11.NewAttribute(pkcs11.CKA_ENCRYPT, cipher.Encrypt), // Not supported on CloudHSM + pkcs11.NewAttribute(pkcs11.CKA_DECRYPT, cipher.Encrypt), // Not supported on CloudHSM + pkcs11.NewAttribute(pkcs11.CKA_SENSITIVE, true), + pkcs11.NewAttribute(pkcs11.CKA_EXTRACTABLE, false), + }) + if bits > 0 { + _ = template.Set(pkcs11.CKA_VALUE_LEN, bits/8) // safe for an int + } + + for n, genMech := range cipher.GenParams { + + _ = template.Set(CkaKeyType, genMech.KeyType) + + mech := []*pkcs11.Mechanism{pkcs11.NewMechanism(genMech.GenMech, nil)} + + privHandle, err := session.ctx.GenerateKey(session.handle, mech, template.ToSlice()) + if err == nil { + k = &SecretKey{pkcs11Object{privHandle, c}, cipher} + return nil + } + + // As a special case, AWS CloudHSM does not accept CKA_ENCRYPT and CKA_DECRYPT on a + // Generic Secret key. If we are in that special case, try again without those attributes. + if e, ok := err.(pkcs11.Error); ok && e == pkcs11.CKR_ARGUMENTS_BAD && genMech.GenMech == pkcs11.CKM_GENERIC_SECRET_KEY_GEN { + adjustedTemplate := template.Copy() + adjustedTemplate.Unset(CkaEncrypt) + adjustedTemplate.Unset(CkaDecrypt) + + privHandle, err = session.ctx.GenerateKey(session.handle, mech, adjustedTemplate.ToSlice()) + if err == nil { + // Store the actual attributes + template.cloneFrom(adjustedTemplate) + + k = &SecretKey{pkcs11Object{privHandle, c}, cipher} + return nil + } + } + + if n == len(cipher.GenParams)-1 { + // If we have tried all available gen params, we should return a sensible error. So we skip the + // retry logic below and return directly. + return err + } + + // nShield returns CKR_TEMPLATE_INCONSISTENT if if doesn't like the CKK/CKM combination. + // AWS CloudHSM returns CKR_ATTRIBUTE_VALUE_INVALID in the same circumstances. + if e, ok := err.(pkcs11.Error); ok && + e == pkcs11.CKR_TEMPLATE_INCONSISTENT || e == pkcs11.CKR_ATTRIBUTE_VALUE_INVALID { + continue + } + + return err + } + + // We can only get here if there were no GenParams + return errors.New("cipher must have GenParams") + }) + return +} + +// Delete deletes the secret key from the token. +func (key *SecretKey) Delete() error { + return key.pkcs11Object.Delete() +} diff --git a/vendor/github.com/miekg/pkcs11/.gitignore b/vendor/github.com/miekg/pkcs11/.gitignore new file mode 100644 index 0000000000000..5fde17f998f45 --- /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 0000000000000..687044d830a87 --- /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 0000000000000..ce25d13ab8439 --- /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 0000000000000..4f58165f96915 --- /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 0000000000000..0a5c1b7b6e758 --- /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 0000000000000..4088561461661 --- /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 0000000000000..7df0e93a6b559 --- /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/hsm.db b/vendor/github.com/miekg/pkcs11/hsm.db new file mode 100644 index 0000000000000000000000000000000000000000..eb3f10dadcdf6af2416c79bc91280e9f13f41c72 GIT binary patch literal 10240 zcmeHN4RBP|6@KTOx4Z9cHk;ifu;d5w@<$Q~klk!TQV`i>HyHA>5Eeq1N}HceSmh^# zg%Ht^#evp#6s&a+hejx-TI-aSs@Ph^LPc$-N}&Y-8Emam`LVPr6ouM*_r5Iwwa!=_ zEbg1x_kHKQbI;y$-rjS6k{Q$ML*by-xu|DBYgj9lWC=i;tZ9-YC9;p1ePWl15jiF> z1or6|B!3i5l*atIfIBk6B#Aas1AYTe!FncK6<4#-=*Z88-q6C1;POz%@<3mAa8~R5 zr9n?P+!JbB8V)WoRyX-P0iRae==IIk2HR-~Fgv z*dD%UZMfX4Fu2_1qG+>PZ?VRm7eyShDWf1miS)AGb#(=MI)d|q;b1@r!o?EZbD*hq z$`oIdc8Q5r<*V^G`82Pu-p68M0qBj`gDJI*F?~&wzhQ7_&DZ%@qgZFOYczkocWg|Y zp!piTk!mtIva?~;^l)q2{6Xov7_uDen5U}VH`se&Yb@EdUY6#7k9T`oQ*DE%sYR>v zwG_v`=|2y>z8cTW`heCrv%bEVXXc}yL|=tgRqwB2femUgKe(_fJnutoN{SlL=*Y-` zCD9o4%;-Ru^j=qLg&*qLpney%fyv=;KqNQnFR8Wu$%WJAC+>BSU$~wNr>vmSTyd_@vEWG4OBsGMC%fs4# zx%l`;`lm$a*)4v>GZ4?fmm&j*C?TL^V9^4-&tp~ud?~_@2N};mJOh#`lW*|Luu7tL z=>)w_n`tZUrX%z?Jxvi>Of3|mR@y)wsw5{BQ8uNKou!Z$u8B2 z-K7(oQxIuQiLNn@(@DZuotVeyL@w5eWwcQS6>yX;cNdvt06;9%6;PlP94VeqzOHD` z(@AHpPNW>>OaaU`%fLFmlFfdaMFs=l2Ols&$}-6+0_2Ynm^WNtZl=JT41rp@Kzo`% z+c1G04uNe$1)7EkR8s{iDFO}20)uveWQ!tVl0chP=q-r`SyjOzr0xWxtg^_>LIhPH zDp56=gxGEr*l7?b$;^iWq{^xcJYY1-szDX;B8wU5G`mY?0i4FKcn0DbxJomiCdily zkj)SCOZomk6V^-YO#Wfm14rN_ypKjq$2=U16L^yTN2(RAp36)O8j~wF-(hP?L0ul4{cp2voaHgP(Wwd4p*n4oREJJGKpDoVMFE?VrZamaA>G83t1JlG^E0+&y*Ou!J#c*`xk7IQHR5SF>=1?RdGuE+OW%lovJ+vWHd*bMU1I5Rr z+%#|c@H1~KnEc?_=B$&;4yLrs2|eJy(~#)aiss&tcyq=R%Ci^hew_G*Hp}vdGe>@Y z=7u%f54FR}6?d&#-G8>#9BJ-9_s!n4;XjEyeB&(#UbruGeAnLIcYgD7ZSEVER@>-x z6MV1#z_P9hLYr5gtLtB#A+6-&KMndN=!fH2j#F_l-imASe*6(WgTKZ7_$NGtXNf3@ zGN^z`=~|jfGbu>#M1NE9+vl2rsl)kCC1L@{JF<7@wOQZWxbApI>4~?x{|1NKt6CR- zWwP(-)29|4>TUemU!24Ib4HactlR%$?VJ0)o3wpb!uZGTbqty0o}=CFo^^2Y)DbaX z`Ny2nJp&`Yz3I6}ZLh4@;r}4(-Ha`ni+?rHdtlxE((A2#`%;XfhVHy|Tl%;=mhKvO z>b+b1Db8sP2XD%*q4JFrcmI8Ia+Xm7R-W`lbF@C?YfQ)LQ*=%J@de6~&CFPVV&_k+ z23d2M#3~f(CCZu`lSPd(=W&@AoOVdbXPgx&99*T;k=#I1*cL=Bh*3}rxhZRgU@qcX z?x7o$QH--n#k8YiT8m^Zj&T{xV`AJ4=CLuJ0OoNqZUl3Q&ZRYy>g3$QzTT#~V$^Oe z<&;Mion+;R#cg5=R*Sw6#mHQy2LL%_#`~l^n8*GGfXSGHKAeX=Y^J}N?cKkFn_(Vq z!zb}M+=qwpH9UcD<9RZWl^mq8(*PGuATKr0ESgK5w2+oT-{(3U{*Rs82tkw0nCfuC%msWKn)>;+~=8DE|d+qGH&MhReB zT(Ghc!}hjOEMyk^KTa-BoJo<<3T)_=h-EA@VRd8>&oRl!20z~%N3lR4DmspgIsjse z1@4KR0uD4Hkham2^lREfudq|Wx9Ds%&GB12 z1D`enVr=9PJ0|3#C5JL%gW!s +#include +#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 = ¶ms + return C.GoBytes(unsafe.Pointer(¶ms), 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(¶ms, buf, len) + } + return C.GoBytes(unsafe.Pointer(¶ms), 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(¶ms, sharedData, sharedDataLen) + } + + publicKeyData, publicKeyDataLen := arena.Allocate(p.PublicKeyData) + C.putECDH1PublicParams(¶ms, publicKeyData, publicKeyDataLen) + + return C.GoBytes(unsafe.Pointer(¶ms), 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 0000000000000..e21d23b73e699 --- /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 +#include +#include +#include + +#include "pkcs11go.h" + +#ifdef _WIN32 +#include + +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 + +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 0000000000000..0d78dd711369f --- /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 0000000000000..ed90affc5e32c --- /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 0000000000000..1b98bad21b474 --- /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 +#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 0000000000000..321c3075aa7ec --- /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 0000000000000..f110043b416e1 --- /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, 2} + +// 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 0000000000000..f95862b104643 --- /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 0000000000000..876990cdd1bf3 --- /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 0000000000000..970db9061b6ab --- /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 +#include +#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 0000000000000..83188e50017df --- /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/thales-e-security/pool/LICENSE b/vendor/github.com/thales-e-security/pool/LICENSE new file mode 100644 index 0000000000000..7a4a3ea2424c0 --- /dev/null +++ b/vendor/github.com/thales-e-security/pool/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://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 + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. \ No newline at end of file diff --git a/vendor/github.com/thales-e-security/pool/README.md b/vendor/github.com/thales-e-security/pool/README.md new file mode 100644 index 0000000000000..99acca4978d71 --- /dev/null +++ b/vendor/github.com/thales-e-security/pool/README.md @@ -0,0 +1,7 @@ +pool is a copy of a few packages from https://github.com/vitessio/vitess. + +Vitess has some useful Go packages, however they are not versioned with Go modules, +which causes issues (e.g. https://github.com/ThalesIgnite/crypto11/issues/56). They +are also buried inside a large project, which forms a heavyweight dependency. + +This package exposes the resource pool implementation and some of the atomic types. diff --git a/vendor/github.com/thales-e-security/pool/atomic.go b/vendor/github.com/thales-e-security/pool/atomic.go new file mode 100644 index 0000000000000..99324b78f1bc7 --- /dev/null +++ b/vendor/github.com/thales-e-security/pool/atomic.go @@ -0,0 +1,186 @@ +/* +Copyright 2017 Google Inc. + +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 pool + +import ( + "sync" + "sync/atomic" + "time" +) + +// AtomicInt32 is a wrapper with a simpler interface around atomic.(Add|Store|Load|CompareAndSwap)Int32 functions. +type AtomicInt32 struct { + int32 +} + +// NewAtomicInt32 initializes a new AtomicInt32 with a given value. +func NewAtomicInt32(n int32) AtomicInt32 { + return AtomicInt32{n} +} + +// Add atomically adds n to the value. +func (i *AtomicInt32) Add(n int32) int32 { + return atomic.AddInt32(&i.int32, n) +} + +// Set atomically sets n as new value. +func (i *AtomicInt32) Set(n int32) { + atomic.StoreInt32(&i.int32, n) +} + +// Get atomically returns the current value. +func (i *AtomicInt32) Get() int32 { + return atomic.LoadInt32(&i.int32) +} + +// CompareAndSwap atomatically swaps the old with the new value. +func (i *AtomicInt32) CompareAndSwap(oldval, newval int32) (swapped bool) { + return atomic.CompareAndSwapInt32(&i.int32, oldval, newval) +} + +// AtomicInt64 is a wrapper with a simpler interface around atomic.(Add|Store|Load|CompareAndSwap)Int64 functions. +type AtomicInt64 struct { + int64 +} + +// NewAtomicInt64 initializes a new AtomicInt64 with a given value. +func NewAtomicInt64(n int64) AtomicInt64 { + return AtomicInt64{n} +} + +// Add atomically adds n to the value. +func (i *AtomicInt64) Add(n int64) int64 { + return atomic.AddInt64(&i.int64, n) +} + +// Set atomically sets n as new value. +func (i *AtomicInt64) Set(n int64) { + atomic.StoreInt64(&i.int64, n) +} + +// Get atomically returns the current value. +func (i *AtomicInt64) Get() int64 { + return atomic.LoadInt64(&i.int64) +} + +// CompareAndSwap atomatically swaps the old with the new value. +func (i *AtomicInt64) CompareAndSwap(oldval, newval int64) (swapped bool) { + return atomic.CompareAndSwapInt64(&i.int64, oldval, newval) +} + +// AtomicDuration is a wrapper with a simpler interface around atomic.(Add|Store|Load|CompareAndSwap)Int64 functions. +type AtomicDuration struct { + int64 +} + +// NewAtomicDuration initializes a new AtomicDuration with a given value. +func NewAtomicDuration(duration time.Duration) AtomicDuration { + return AtomicDuration{int64(duration)} +} + +// Add atomically adds duration to the value. +func (d *AtomicDuration) Add(duration time.Duration) time.Duration { + return time.Duration(atomic.AddInt64(&d.int64, int64(duration))) +} + +// Set atomically sets duration as new value. +func (d *AtomicDuration) Set(duration time.Duration) { + atomic.StoreInt64(&d.int64, int64(duration)) +} + +// Get atomically returns the current value. +func (d *AtomicDuration) Get() time.Duration { + return time.Duration(atomic.LoadInt64(&d.int64)) +} + +// CompareAndSwap atomatically swaps the old with the new value. +func (d *AtomicDuration) CompareAndSwap(oldval, newval time.Duration) (swapped bool) { + return atomic.CompareAndSwapInt64(&d.int64, int64(oldval), int64(newval)) +} + +// AtomicBool gives an atomic boolean variable. +type AtomicBool struct { + int32 +} + +// NewAtomicBool initializes a new AtomicBool with a given value. +func NewAtomicBool(n bool) AtomicBool { + if n { + return AtomicBool{1} + } + return AtomicBool{0} +} + +// Set atomically sets n as new value. +func (i *AtomicBool) Set(n bool) { + if n { + atomic.StoreInt32(&i.int32, 1) + } else { + atomic.StoreInt32(&i.int32, 0) + } +} + +// Get atomically returns the current value. +func (i *AtomicBool) Get() bool { + return atomic.LoadInt32(&i.int32) != 0 +} + +// CompareAndSwap atomatically swaps the old with the new value. +func (i *AtomicBool) CompareAndSwap(o, n bool) bool { + var old, new int32 + if o { + old = 1 + } + if n { + new = 1 + } + return atomic.CompareAndSwapInt32(&i.int32, old, new) +} + +// AtomicString gives you atomic-style APIs for string, but +// it's only a convenience wrapper that uses a mutex. So, it's +// not as efficient as the rest of the atomic types. +type AtomicString struct { + mu sync.Mutex + str string +} + +// Set atomically sets str as new value. +func (s *AtomicString) Set(str string) { + s.mu.Lock() + s.str = str + s.mu.Unlock() +} + +// Get atomically returns the current value. +func (s *AtomicString) Get() string { + s.mu.Lock() + str := s.str + s.mu.Unlock() + return str +} + +// CompareAndSwap atomatically swaps the old with the new value. +func (s *AtomicString) CompareAndSwap(oldval, newval string) (swqpped bool) { + s.mu.Lock() + defer s.mu.Unlock() + if s.str == oldval { + s.str = newval + return true + } + return false +} diff --git a/vendor/github.com/thales-e-security/pool/resource_pool.go b/vendor/github.com/thales-e-security/pool/resource_pool.go new file mode 100644 index 0000000000000..cab3f488c81db --- /dev/null +++ b/vendor/github.com/thales-e-security/pool/resource_pool.go @@ -0,0 +1,383 @@ +/* +Copyright 2017 Google Inc. + +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 pools provides functionality to manage and reuse resources +// like connections. +// +// Modified by Duncan Jones to reduce the number of external dependencies. +package pool + +import ( + "context" + "errors" + "fmt" + "sync" + "time" +) + +var ( + // ErrClosed is returned if ResourcePool is used when it's closed. + ErrClosed = errors.New("resource pool is closed") + + // ErrTimeout is returned if a resource get times out. + ErrTimeout = errors.New("resource pool timed out") + + prefillTimeout = 30 * time.Second +) + +// Factory is a function that can be used to create a resource. +type Factory func() (Resource, error) + +// Resource defines the interface that every resource must provide. +// Thread synchronization between Close() and IsClosed() +// is the responsibility of the caller. +type Resource interface { + Close() +} + +// ResourcePool allows you to use a pool of resources. +type ResourcePool struct { + // stats. Atomic fields must remain at the top in order to prevent panics on certain architectures. + available AtomicInt64 + active AtomicInt64 + inUse AtomicInt64 + waitCount AtomicInt64 + waitTime AtomicDuration + idleClosed AtomicInt64 + + capacity AtomicInt64 + idleTimeout AtomicDuration + + resources chan resourceWrapper + factory Factory + idleTimer *Timer +} + +type resourceWrapper struct { + resource Resource + timeUsed time.Time +} + +// NewResourcePool creates a new ResourcePool pool. +// capacity is the number of possible resources in the pool: +// there can be up to 'capacity' of these at a given time. +// maxCap specifies the extent to which the pool can be resized +// in the future through the SetCapacity function. +// You cannot resize the pool beyond maxCap. +// If a resource is unused beyond idleTimeout, it's replaced +// with a new one. +// An idleTimeout of 0 means that there is no timeout. +// A non-zero value of prefillParallelism causes the pool to be pre-filled. +// The value specifies how many resources can be opened in parallel. +func NewResourcePool(factory Factory, capacity, maxCap int, idleTimeout time.Duration, prefillParallelism int) *ResourcePool { + if capacity <= 0 || maxCap <= 0 || capacity > maxCap { + panic(errors.New("invalid/out of range capacity")) + } + rp := &ResourcePool{ + resources: make(chan resourceWrapper, maxCap), + factory: factory, + available: NewAtomicInt64(int64(capacity)), + capacity: NewAtomicInt64(int64(capacity)), + idleTimeout: NewAtomicDuration(idleTimeout), + } + for i := 0; i < capacity; i++ { + rp.resources <- resourceWrapper{} + } + + ctx, cancel := context.WithTimeout(context.TODO(), prefillTimeout) + defer cancel() + if prefillParallelism != 0 { + sem := NewSemaphore(prefillParallelism, 0 /* timeout */) + var wg sync.WaitGroup + for i := 0; i < capacity; i++ { + wg.Add(1) + go func() { + defer wg.Done() + _ = sem.Acquire() + defer sem.Release() + + // If context has expired, give up. + select { + case <-ctx.Done(): + return + default: + } + + r, err := rp.Get(ctx) + if err != nil { + return + } + rp.Put(r) + }() + } + wg.Wait() + } + + if idleTimeout != 0 { + rp.idleTimer = NewTimer(idleTimeout / 10) + rp.idleTimer.Start(rp.closeIdleResources) + } + return rp +} + +// Close empties the pool calling Close on all its resources. +// You can call Close while there are outstanding resources. +// It waits for all resources to be returned (Put). +// After a Close, Get is not allowed. +func (rp *ResourcePool) Close() { + if rp.idleTimer != nil { + rp.idleTimer.Stop() + } + _ = rp.SetCapacity(0) +} + +// IsClosed returns true if the resource pool is closed. +func (rp *ResourcePool) IsClosed() (closed bool) { + return rp.capacity.Get() == 0 +} + +// closeIdleResources scans the pool for idle resources +func (rp *ResourcePool) closeIdleResources() { + available := int(rp.Available()) + idleTimeout := rp.IdleTimeout() + + for i := 0; i < available; i++ { + var wrapper resourceWrapper + select { + case wrapper = <-rp.resources: + default: + // stop early if we don't get anything new from the pool + return + } + + func() { + defer func() { rp.resources <- wrapper }() + + if wrapper.resource != nil && idleTimeout > 0 && time.Until(wrapper.timeUsed.Add(idleTimeout)) < 0 { + wrapper.resource.Close() + rp.idleClosed.Add(1) + rp.reopenResource(&wrapper) + } + }() + + } +} + +// Get will return the next available resource. If capacity +// has not been reached, it will create a new one using the factory. Otherwise, +// it will wait till the next resource becomes available or a timeout. +// A timeout of 0 is an indefinite wait. +func (rp *ResourcePool) Get(ctx context.Context) (resource Resource, err error) { + return rp.get(ctx) +} + +func (rp *ResourcePool) get(ctx context.Context) (resource Resource, err error) { + // If ctx has already expired, avoid racing with rp's resource channel. + select { + case <-ctx.Done(): + return nil, ErrTimeout + default: + } + + // Fetch + var wrapper resourceWrapper + var ok bool + select { + case wrapper, ok = <-rp.resources: + default: + startTime := time.Now() + select { + case wrapper, ok = <-rp.resources: + case <-ctx.Done(): + return nil, ErrTimeout + } + rp.recordWait(startTime) + } + if !ok { + return nil, ErrClosed + } + + // Unwrap + if wrapper.resource == nil { + wrapper.resource, err = rp.factory() + if err != nil { + rp.resources <- resourceWrapper{} + return nil, err + } + rp.active.Add(1) + } + rp.available.Add(-1) + rp.inUse.Add(1) + return wrapper.resource, err +} + +// Put will return a resource to the pool. For every successful Get, +// a corresponding Put is required. If you no longer need a resource, +// you will need to call Put(nil) instead of returning the closed resource. +// This will cause a new resource to be created in its place. +func (rp *ResourcePool) Put(resource Resource) { + var wrapper resourceWrapper + if resource != nil { + wrapper = resourceWrapper{ + resource: resource, + timeUsed: time.Now(), + } + } else { + rp.reopenResource(&wrapper) + } + select { + case rp.resources <- wrapper: + default: + panic(errors.New("attempt to Put into a full ResourcePool")) + } + rp.inUse.Add(-1) + rp.available.Add(1) +} + +func (rp *ResourcePool) reopenResource(wrapper *resourceWrapper) { + if r, err := rp.factory(); err == nil { + wrapper.resource = r + wrapper.timeUsed = time.Now() + } else { + wrapper.resource = nil + rp.active.Add(-1) + } +} + +// SetCapacity changes the capacity of the pool. +// You can use it to shrink or expand, but not beyond +// the max capacity. If the change requires the pool +// to be shrunk, SetCapacity waits till the necessary +// number of resources are returned to the pool. +// A SetCapacity of 0 is equivalent to closing the ResourcePool. +func (rp *ResourcePool) SetCapacity(capacity int) error { + if capacity < 0 || capacity > cap(rp.resources) { + return fmt.Errorf("capacity %d is out of range", capacity) + } + + // Atomically swap new capacity with old, but only + // if old capacity is non-zero. + var oldcap int + for { + oldcap = int(rp.capacity.Get()) + if oldcap == 0 { + return ErrClosed + } + if oldcap == capacity { + return nil + } + if rp.capacity.CompareAndSwap(int64(oldcap), int64(capacity)) { + break + } + } + + if capacity < oldcap { + for i := 0; i < oldcap-capacity; i++ { + wrapper := <-rp.resources + if wrapper.resource != nil { + wrapper.resource.Close() + rp.active.Add(-1) + } + rp.available.Add(-1) + } + } else { + for i := 0; i < capacity-oldcap; i++ { + rp.resources <- resourceWrapper{} + rp.available.Add(1) + } + } + if capacity == 0 { + close(rp.resources) + } + return nil +} + +func (rp *ResourcePool) recordWait(start time.Time) { + rp.waitCount.Add(1) + rp.waitTime.Add(time.Since(start)) +} + +// SetIdleTimeout sets the idle timeout. It can only be used if there was an +// idle timeout set when the pool was created. +func (rp *ResourcePool) SetIdleTimeout(idleTimeout time.Duration) { + if rp.idleTimer == nil { + panic("SetIdleTimeout called when timer not initialized") + } + + rp.idleTimeout.Set(idleTimeout) + rp.idleTimer.SetInterval(idleTimeout / 10) +} + +// StatsJSON returns the stats in JSON format. +func (rp *ResourcePool) StatsJSON() string { + return fmt.Sprintf(`{"Capacity": %v, "Available": %v, "Active": %v, "InUse": %v, "MaxCapacity": %v, "WaitCount": %v, "WaitTime": %v, "IdleTimeout": %v, "IdleClosed": %v}`, + rp.Capacity(), + rp.Available(), + rp.Active(), + rp.InUse(), + rp.MaxCap(), + rp.WaitCount(), + rp.WaitTime().Nanoseconds(), + rp.IdleTimeout().Nanoseconds(), + rp.IdleClosed(), + ) +} + +// Capacity returns the capacity. +func (rp *ResourcePool) Capacity() int64 { + return rp.capacity.Get() +} + +// Available returns the number of currently unused and available resources. +func (rp *ResourcePool) Available() int64 { + return rp.available.Get() +} + +// Active returns the number of active (i.e. non-nil) resources either in the +// pool or claimed for use +func (rp *ResourcePool) Active() int64 { + return rp.active.Get() +} + +// InUse returns the number of claimed resources from the pool +func (rp *ResourcePool) InUse() int64 { + return rp.inUse.Get() +} + +// MaxCap returns the max capacity. +func (rp *ResourcePool) MaxCap() int64 { + return int64(cap(rp.resources)) +} + +// WaitCount returns the total number of waits. +func (rp *ResourcePool) WaitCount() int64 { + return rp.waitCount.Get() +} + +// WaitTime returns the total wait time. +func (rp *ResourcePool) WaitTime() time.Duration { + return rp.waitTime.Get() +} + +// IdleTimeout returns the idle timeout. +func (rp *ResourcePool) IdleTimeout() time.Duration { + return rp.idleTimeout.Get() +} + +// IdleClosed returns the count of resources closed due to idle timeout. +func (rp *ResourcePool) IdleClosed() int64 { + return rp.idleClosed.Get() +} diff --git a/vendor/github.com/thales-e-security/pool/semaphore.go b/vendor/github.com/thales-e-security/pool/semaphore.go new file mode 100644 index 0000000000000..6e67d2d704c38 --- /dev/null +++ b/vendor/github.com/thales-e-security/pool/semaphore.go @@ -0,0 +1,85 @@ +/* +Copyright 2017 Google Inc. + +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 pool + +// What's in a name? Channels have all you need to emulate a counting +// semaphore with a boatload of extra functionality. However, in some +// cases, you just want a familiar API. + +import ( + "time" +) + +// Semaphore is a counting semaphore with the option to +// specify a timeout. +type Semaphore struct { + slots chan struct{} + timeout time.Duration +} + +// NewSemaphore creates a Semaphore. The count parameter must be a positive +// number. A timeout of zero means that there is no timeout. +func NewSemaphore(count int, timeout time.Duration) *Semaphore { + sem := &Semaphore{ + slots: make(chan struct{}, count), + timeout: timeout, + } + for i := 0; i < count; i++ { + sem.slots <- struct{}{} + } + return sem +} + +// Acquire returns true on successful acquisition, and +// false on a timeout. +func (sem *Semaphore) Acquire() bool { + if sem.timeout == 0 { + <-sem.slots + return true + } + tm := time.NewTimer(sem.timeout) + defer tm.Stop() + select { + case <-sem.slots: + return true + case <-tm.C: + return false + } +} + +// TryAcquire acquires a semaphore if it's immediately available. +// It returns false otherwise. +func (sem *Semaphore) TryAcquire() bool { + select { + case <-sem.slots: + return true + default: + return false + } +} + +// Release releases the acquired semaphore. You must +// not release more than the number of semaphores you've +// acquired. +func (sem *Semaphore) Release() { + sem.slots <- struct{}{} +} + +// Size returns the current number of available slots. +func (sem *Semaphore) Size() int { + return len(sem.slots) +} diff --git a/vendor/github.com/thales-e-security/pool/timer.go b/vendor/github.com/thales-e-security/pool/timer.go new file mode 100644 index 0000000000000..e88ed2ccc1b51 --- /dev/null +++ b/vendor/github.com/thales-e-security/pool/timer.go @@ -0,0 +1,159 @@ +/* +Copyright 2017 Google Inc. + +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. + +Modified by Duncan Jones to remove the external dependency. +*/ + +// Package timer provides various enhanced timer functions. +package pool + +import ( + "sync" + "time" +) + +// Out-of-band messages +type typeAction int + +const ( + timerStop typeAction = iota + timerReset + timerTrigger +) + +/* +Timer provides timer functionality that can be controlled +by the user. You start the timer by providing it a callback function, +which it will call at the specified interval. + + var t = timer.NewTimer(1e9) + t.Start(KeepHouse) + + func KeepHouse() { + // do house keeping work + } + +You can stop the timer by calling t.Stop, which is guaranteed to +wait if KeepHouse is being executed. + +You can create an untimely trigger by calling t.Trigger. You can also +schedule an untimely trigger by calling t.TriggerAfter. + +The timer interval can be changed on the fly by calling t.SetInterval. +A zero value interval will cause the timer to wait indefinitely, and it +will react only to an explicit Trigger or Stop. +*/ +type Timer struct { + interval AtomicDuration + + // state management + mu sync.Mutex + running bool + + // msg is used for out-of-band messages + msg chan typeAction +} + +// NewTimer creates a new Timer object +func NewTimer(interval time.Duration) *Timer { + tm := &Timer{ + msg: make(chan typeAction), + } + tm.interval.Set(interval) + return tm +} + +// Start starts the timer. +func (tm *Timer) Start(keephouse func()) { + tm.mu.Lock() + defer tm.mu.Unlock() + if tm.running { + return + } + tm.running = true + go tm.run(keephouse) +} + +func (tm *Timer) run(keephouse func()) { + var timer *time.Timer + for { + var ch <-chan time.Time + interval := tm.interval.Get() + if interval > 0 { + timer = time.NewTimer(interval) + ch = timer.C + } + select { + case action := <-tm.msg: + if timer != nil { + timer.Stop() + timer = nil + } + switch action { + case timerStop: + return + case timerReset: + continue + } + case <-ch: + } + keephouse() + } +} + +// SetInterval changes the wait interval. +// It will cause the timer to restart the wait. +func (tm *Timer) SetInterval(ns time.Duration) { + tm.interval.Set(ns) + tm.mu.Lock() + defer tm.mu.Unlock() + if tm.running { + tm.msg <- timerReset + } +} + +// Trigger will cause the timer to immediately execute the keephouse function. +// It will then cause the timer to restart the wait. +func (tm *Timer) Trigger() { + tm.mu.Lock() + defer tm.mu.Unlock() + if tm.running { + tm.msg <- timerTrigger + } +} + +// TriggerAfter waits for the specified duration and triggers the next event. +func (tm *Timer) TriggerAfter(duration time.Duration) { + go func() { + time.Sleep(duration) + tm.Trigger() + }() +} + +// Stop will stop the timer. It guarantees that the timer will not execute +// any more calls to keephouse once it has returned. +func (tm *Timer) Stop() { + tm.mu.Lock() + defer tm.mu.Unlock() + if tm.running { + tm.msg <- timerStop + tm.running = false + } +} + +// Interval returns the current interval. +func (tm *Timer) Interval() time.Duration { + return tm.interval.Get() +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 76dbb515f0ade..4e75166474194 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -98,6 +98,9 @@ github.com/Microsoft/hcsshim/osversion # github.com/NYTimes/gziphandler v1.1.1 ## explicit; go 1.11 github.com/NYTimes/gziphandler +# github.com/ThalesIgnite/crypto11 v1.2.5 +## explicit; go 1.13 +github.com/ThalesIgnite/crypto11 # github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df ## explicit; go 1.18 github.com/antlr/antlr4/runtime/Go/antlr/v4 @@ -515,6 +518,9 @@ github.com/mailru/easyjson/jwriter # github.com/matttproud/golang_protobuf_extensions v1.0.4 ## explicit; go 1.9 github.com/matttproud/golang_protobuf_extensions/pbutil +# github.com/miekg/pkcs11 v1.0.3-0.20190429190417-a667d056470f +## explicit; go 1.12 +github.com/miekg/pkcs11 # github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible ## explicit github.com/mistifyio/go-zfs @@ -704,6 +710,9 @@ github.com/stretchr/testify/require # github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 ## explicit github.com/syndtr/gocapability/capability +# github.com/thales-e-security/pool v0.0.2 +## explicit; go 1.12 +github.com/thales-e-security/pool # github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 ## explicit; go 1.15 github.com/tmc/grpc-websocket-proxy/wsproxy @@ -1335,6 +1344,8 @@ k8s.io/klog/v2/ktesting k8s.io/klog/v2/ktesting/init k8s.io/klog/v2/test k8s.io/klog/v2/textlogger +# k8s.io/kms v0.0.0-00010101000000-000000000000 => ./staging/src/k8s.io/kms +## explicit; go 1.21 # k8s.io/kms v0.0.0 => ./staging/src/k8s.io/kms ## explicit; go 1.21 # k8s.io/kube-aggregator v0.0.0 => ./staging/src/k8s.io/kube-aggregator