crypto11

package module
v1.2.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 9, 2021 License: MIT Imports: 27 Imported by: 39

README

Crypto11

GoDoc Build Status

This is an implementation of the standard Golang crypto interfaces that uses PKCS#11 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 interface and decryption through crypto.Decrypter.

To verify signatures or encrypt messages, retrieve the public key and do it in software.

See the documentation for details of various limitations, especially regarding symmetric crypto.

Installation

Since v1.0.0, crypto11 requires Go v1.11+. Install the library by running:

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) or via a configuration file. The configuration file is a JSON representation of the Config struct.

A minimal configuration file looks like this:

{
  "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=<flags> where <flags> 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:

{
  "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 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 for further discussion.
  • Symmetric crypto support via 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). See issue #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.

Documentation

Overview

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.

Index

Constants

View Source
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)

	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)
	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)
)

noinspection GoUnusedConst,GoDeprecation

View Source
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
)
View Source
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)
)

Variables

View Source
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,
}

CipherAES describes the AES cipher. Use this with the GenerateSecretKey... functions.

View Source
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,
}

CipherDES3 describes the three-key triple-DES cipher. Use this with the GenerateSecretKey... functions.

View Source
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,
}

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.

View Source
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,
}

CipherHMACSHA1 describes the CKK_SHA_1_HMAC key type. Use this with the GenerateSecretKey... functions.

View Source
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,
}

CipherHMACSHA224 describes the CKK_SHA224_HMAC key type. Use this with the GenerateSecretKey... functions.

View Source
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,
}

CipherHMACSHA256 describes the CKK_SHA256_HMAC key type. Use this with the GenerateSecretKey... functions.

View Source
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,
}

CipherHMACSHA384 describes the CKK_SHA384_HMAC key type. Use this with the GenerateSecretKey... functions.

View Source
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,
}

CipherHMACSHA512 describes the CKK_SHA512_HMAC key type. Use this with the GenerateSecretKey... functions.

Ciphers is a map of PKCS#11 key types (CKK_...) to symmetric cipher information.

Functions

This section is empty.

Types

type Attribute added in v1.1.0

type Attribute = pkcs11.Attribute

Attribute represents a PKCS#11 CK_ATTRIBUTE type.

func CopyAttribute added in v1.1.0

func CopyAttribute(a *Attribute) *Attribute

CopyAttribute returns a deep copy of the given Attribute.

func NewAttribute added in v1.1.0

func NewAttribute(attributeType AttributeType, value interface{}) (a *Attribute, err error)

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).

type AttributeSet added in v1.1.0

type AttributeSet map[AttributeType]*Attribute

An AttributeSet groups together operations that are common for a collection of Attributes.

func NewAttributeSet added in v1.1.0

func NewAttributeSet() AttributeSet

NewAttributeSet creates an empty AttributeSet.

func NewAttributeSetWithID added in v1.1.0

func NewAttributeSetWithID(id []byte) (AttributeSet, error)

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 NewAttributeSetWithIDAndLabel added in v1.1.0

func NewAttributeSetWithIDAndLabel(id, label []byte) (a AttributeSet, err error)

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 (AttributeSet) AddIfNotPresent added in v1.1.0

func (a AttributeSet) AddIfNotPresent(additional []*Attribute)

AddIfNotPresent adds the attributes if the Attribute Type is not already present in the AttributeSet.

func (AttributeSet) Copy added in v1.1.0

func (a AttributeSet) Copy() AttributeSet

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 (AttributeSet) Set added in v1.1.0

func (a AttributeSet) Set(attributeType AttributeType, value interface{}) error

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 (AttributeSet) String added in v1.2.0

func (a AttributeSet) String() string

func (AttributeSet) ToSlice added in v1.1.0

func (a AttributeSet) ToSlice() []*Attribute

ToSlice returns a deep copy of Attributes contained in the AttributeSet.

func (AttributeSet) Unset added in v1.2.0

func (a AttributeSet) Unset(attributeType AttributeType)

Unset removes an attribute from the attributes set. If the set does not contain the attribute, this is a no-op.

type AttributeType added in v1.1.0

type AttributeType = uint

AttributeType represents a PKCS#11 CK_ATTRIBUTE value.

type BlockModeCloser

type BlockModeCloser interface {
	cipher.BlockMode

	// Close() releases resources associated with the block mode.
	Close()
}

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 Config added in v1.0.0

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
}

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 Context added in v1.0.0

type Context struct {
	// contains filtered or unexported fields
}

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.

func Configure

func Configure(config *Config) (*Context, error)

Configure creates a new Context based on the supplied PKCS#11 configuration.

func ConfigureFromFile

func ConfigureFromFile(configLocation string) (*Context, error)

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 (*Context) Close added in v1.0.0

func (c *Context) Close() error

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 (*Context) DeleteCertificate added in v1.2.4

func (c *Context) DeleteCertificate(id []byte, label []byte, serial *big.Int) error

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 (*Context) FindAllKeyPairs added in v1.1.0

func (c *Context) FindAllKeyPairs() ([]Signer, error)

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 (*Context) FindAllKeys added in v1.1.0

func (c *Context) FindAllKeys() ([]*SecretKey, error)

FindAllKeyPairs retrieves all existing symmetric keys, or a nil slice if none can be found.

func (*Context) FindAllPairedCertificates added in v1.2.4

func (c *Context) FindAllPairedCertificates() (certificates []tls.Certificate, err error)

func (*Context) FindCertificate added in v1.1.0

func (c *Context) FindCertificate(id []byte, label []byte, serial *big.Int) (*x509.Certificate, error)

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 (*Context) FindKey added in v1.0.0

func (c *Context) FindKey(id []byte, label []byte) (*SecretKey, error)

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 (*Context) FindKeyPair added in v1.0.0

func (c *Context) FindKeyPair(id []byte, label []byte) (Signer, error)

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 (*Context) FindKeyPairWithAttributes added in v1.1.0

func (c *Context) FindKeyPairWithAttributes(attributes AttributeSet) (Signer, error)

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 (*Context) FindKeyPairs added in v1.1.0

func (c *Context) FindKeyPairs(id []byte, label []byte) (signer []Signer, err error)

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 (*Context) FindKeyPairsWithAttributes added in v1.1.0

func (c *Context) FindKeyPairsWithAttributes(attributes AttributeSet) (signer []Signer, err error)

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 (*Context) FindKeyWithAttributes added in v1.1.0

func (c *Context) FindKeyWithAttributes(attributes AttributeSet) (*SecretKey, error)

FindKeyWithAttributes retrieves a previously created symmetric key, or nil if it cannot be found.

func (*Context) FindKeys added in v1.1.0

func (c *Context) FindKeys(id []byte, label []byte) (key []*SecretKey, err error)

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 (*Context) FindKeysWithAttributes added in v1.1.0

func (c *Context) FindKeysWithAttributes(attributes AttributeSet) ([]*SecretKey, error)

FindKeysWithAttributes retrieves previously created symmetric keys, or a nil slice if none can be found.

func (*Context) GenerateDSAKeyPair added in v1.0.0

func (c *Context) GenerateDSAKeyPair(id []byte, params *dsa.Parameters) (Signer, error)

GenerateDSAKeyPair creates a DSA key pair on the token. The id parameter is used to set CKA_ID and must be non-nil.

func (*Context) GenerateDSAKeyPairWithAttributes added in v1.1.0

func (c *Context) GenerateDSAKeyPairWithAttributes(public, private AttributeSet, params *dsa.Parameters) (Signer, error)

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 (*Context) GenerateDSAKeyPairWithLabel added in v1.0.0

func (c *Context) GenerateDSAKeyPairWithLabel(id, label []byte, params *dsa.Parameters) (Signer, error)

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 (*Context) GenerateECDSAKeyPair added in v1.0.0

func (c *Context) GenerateECDSAKeyPair(id []byte, curve elliptic.Curve) (Signer, error)

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 (*Context) GenerateECDSAKeyPairWithAttributes added in v1.1.0

func (c *Context) GenerateECDSAKeyPairWithAttributes(public, private AttributeSet, curve elliptic.Curve) (Signer, error)

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 (*Context) GenerateECDSAKeyPairWithLabel added in v1.0.0

func (c *Context) GenerateECDSAKeyPairWithLabel(id, label []byte, curve elliptic.Curve) (Signer, error)

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 (*Context) GenerateRSAKeyPair added in v1.0.0

func (c *Context) GenerateRSAKeyPair(id []byte, bits int) (SignerDecrypter, error)

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 (*Context) GenerateRSAKeyPairWithAttributes added in v1.1.0

func (c *Context) GenerateRSAKeyPairWithAttributes(public, private AttributeSet, bits int) (SignerDecrypter, error)

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 (*Context) GenerateRSAKeyPairWithLabel added in v1.0.0

func (c *Context) GenerateRSAKeyPairWithLabel(id, label []byte, bits int) (SignerDecrypter, error)

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 (*Context) GenerateSecretKey added in v1.0.0

func (c *Context) GenerateSecretKey(id []byte, bits int, cipher *SymmetricCipher) (*SecretKey, error)

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 (*Context) GenerateSecretKeyWithAttributes added in v1.1.0

func (c *Context) GenerateSecretKeyWithAttributes(template AttributeSet, bits int, cipher *SymmetricCipher) (k *SecretKey, err error)

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 (*Context) GenerateSecretKeyWithLabel added in v1.0.0

func (c *Context) GenerateSecretKeyWithLabel(id, label []byte, bits int, cipher *SymmetricCipher) (*SecretKey, error)

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 (*Context) GetAttribute added in v1.1.0

func (c *Context) GetAttribute(key interface{}, attribute AttributeType) (a *Attribute, err error)

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 (*Context) GetAttributes added in v1.1.0

func (c *Context) GetAttributes(key interface{}, attributes []AttributeType) (a AttributeSet, err error)

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 (*Context) GetPubAttribute added in v1.1.0

func (c *Context) GetPubAttribute(key interface{}, attribute AttributeType) (a *Attribute, err error)

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 (*Context) GetPubAttributes added in v1.1.0

func (c *Context) GetPubAttributes(key interface{}, attributes []AttributeType) (a AttributeSet, err error)

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 (*Context) ImportCertificate added in v1.1.0

func (c *Context) ImportCertificate(id []byte, certificate *x509.Certificate) error

ImportCertificate imports a certificate onto the token. The id parameter is used to set CKA_ID and must be non-nil.

func (*Context) ImportCertificateWithAttributes added in v1.1.0

func (c *Context) ImportCertificateWithAttributes(template AttributeSet, certificate *x509.Certificate) error

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 (*Context) ImportCertificateWithLabel added in v1.1.0

func (c *Context) ImportCertificateWithLabel(id []byte, label []byte, certificate *x509.Certificate) error

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 (*Context) NewRandomReader added in v1.0.0

func (c *Context) NewRandomReader() (io.Reader, error)

NewRandomReader returns a reader for the random number generator on the token.

type GCMIVFromHSMConfig added in v1.2.3

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
}

type PaddingMode added in v1.0.0

type PaddingMode int

A PaddingMode is used by a block cipher (see NewCBC).

const (
	// PaddingNone represents a block cipher with no padding.
	PaddingNone PaddingMode = iota

	// PaddingPKCS represents a block cipher used with PKCS#7 padding.
	PaddingPKCS
)

type SecretKey added in v1.0.0

type SecretKey struct {

	// Symmetric cipher information
	Cipher *SymmetricCipher
	// contains filtered or unexported fields
}

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.

func (*SecretKey) BlockSize added in v1.0.0

func (key *SecretKey) BlockSize() int

BlockSize returns the cipher's block size in bytes.

func (*SecretKey) Decrypt added in v1.0.0

func (key *SecretKey) Decrypt(dst, src []byte)

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 (*SecretKey) Delete added in v1.0.0

func (key *SecretKey) Delete() error

Delete deletes the secret key from the token.

func (*SecretKey) Encrypt added in v1.0.0

func (key *SecretKey) Encrypt(dst, src []byte)

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 (*SecretKey) NewCBC added in v1.0.0

func (key *SecretKey) NewCBC(paddingMode PaddingMode) (cipher.AEAD, error)

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 (*SecretKey) NewCBCDecrypter added in v1.0.0

func (key *SecretKey) NewCBCDecrypter(iv []byte) (cipher.BlockMode, error)

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 (*SecretKey) NewCBCDecrypterCloser added in v1.0.0

func (key *SecretKey) NewCBCDecrypterCloser(iv []byte) (BlockModeCloser, error)

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 (*SecretKey) NewCBCEncrypter added in v1.0.0

func (key *SecretKey) NewCBCEncrypter(iv []byte) (cipher.BlockMode, error)

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 (*SecretKey) NewCBCEncrypterCloser added in v1.0.0

func (key *SecretKey) NewCBCEncrypterCloser(iv []byte) (BlockModeCloser, error)

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 (*SecretKey) NewGCM added in v1.0.0

func (key *SecretKey) NewGCM() (cipher.AEAD, 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 (*SecretKey) NewHMAC added in v1.0.0

func (key *SecretKey) NewHMAC(mech int, length int) (hash.Hash, error)

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.

type Signer added in v1.0.0

type Signer interface {
	crypto.Signer

	// Delete deletes the key pair from the token.
	Delete() error
}

Signer is a PKCS#11 key that implements crypto.Signer.

type SignerDecrypter added in v1.0.0

type SignerDecrypter interface {
	Signer

	// Decrypt implements crypto.Decrypter.
	Decrypt(rand io.Reader, msg []byte, opts crypto.DecrypterOpts) (plaintext []byte, err error)
}

SignerDecrypter is a PKCS#11 key implements crypto.Signer and crypto.Decrypter.

type SymmetricCipher

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
}

SymmetricCipher represents information about a symmetric cipher.

type SymmetricGenParams

type SymmetricGenParams struct {
	// Key type (CKK_...)
	KeyType uint

	// Key generation mechanism (CKM_..._KEY_GEN)
	GenMech uint
}

SymmetricGenParams holds a consistent (key type, mechanism) key generation pair.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL