keys

package module
v0.0.0-...-fb67e4f Latest Latest
Warning

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

Go to latest
Published: Jan 29, 2022 License: Apache-2.0 Imports: 15 Imported by: 0

README

The keys package allows the creation of cryptographic keys on a PKCS11 accessible hardware token (HSM), such as AWS CloudHSM, YubiHSM and Thales Luna devices.

The package provides two APIs:

  1. Keyring

A keyring in this case, is a device that contains one or more keys, but is unwilling to share the private key bytes with the API caller. Such devices include HSMs, secure enclaves, and the WebCrypto feature of modern web browsers. This makes it different than the Cosmos SDK keyring, which requires the key bytes to be shared with the API caller.

  1. Key

The key API itself combines functionality from three different APIs - the PKCS11-based API provided by the Thales go-lang crypto11 package, the go-lang crypto.PublicKey API, and the Cosmos PubKey API used to link public keys to their Cosmos account addresses.

Getting started

  1. git clone this repository.

  2. Install SoftHSM (https://github.com/opendnssec/SoftHSMv2)

    Follow the instructions in the SoftHSM repository to build SoftHSM. Personally my configure line was:

    ./configure --enable-ecc --enable-eddsa --disable-gost

    I run make install to install SoftHSM in /usr/local/lib/softhsm

    Once you've made the software, you need to create a token (an HSM is represented to the client as a "token"):

    This is done using the following command (as shown in the SoftHSM README):

    softhsm2-util --init-token --slot 0 --label "My token 1"

    The token label will then be used in your configuration file (see step 3. below) - make sure the value in your configuration file matches the one you passed into the init-token step.

  3. Install pkcs11-tool as an independent way of verifying you have access to the token, and can see keys

    pkcs11-tool is part of the opensc package, which may already be on your machine if you are using a Linux flavour. If not, install OpenSC from https://github.com/OpenSC/OpenSC/wiki

  4. Create the PKCS11 configuration file with appropriate values

    This repository contains a file called pkcs11-config.template. Configure the file according to your own SoftHSM setup. My example is shown here below:

    {
      "Path": "/usr/local/lib/softhsm/libsofthsm2.so",
      "TokenLabel": "The Cosmos",
      "Pin": "5565455835367496544668"
    }

Building the package

go build . from within this directory, should be sufficient.

Running the tests

The tests for the package are in keyring_test.go, and may be run via go test, if you have previously configured a pkcs11-config file, present in the local directory, as described above.

Documentation

Index

Constants

View Source
const PUBLIC_KEY_SIZE = 33

Variables

This section is empty.

Functions

func NormalizeS

func NormalizeS(sigS *big.Int, curve elliptic.Curve) *big.Int

NormalizeS will invert the s value if not already in the lower half of curve order value by subtracting it from the curve order (N)

Types

type CryptoKey

type CryptoKey struct {
	Label string
	Algo  KeygenAlgorithm
	// contains filtered or unexported fields
}

func (*CryptoKey) Bytes

func (pk *CryptoKey) Bytes() []byte

Bytes will return only an empty byte array because this key does not have access to the actual key bytes

func (*CryptoKey) Delete

func (pk *CryptoKey) Delete() error

func (*CryptoKey) Equals

func (pk *CryptoKey) Equals(other CryptoKey) bool

Equals checks whether two CryptoKeys are equal - because there are no pk bytes to compare, this comparison is done by signing a plaintext with both keys, and if the signature bytes are equal, then the keys are considered equal.

func (*CryptoKey) KeyType

func (pk *CryptoKey) KeyType() KeygenAlgorithm

func (*CryptoKey) PubKey

func (pk *CryptoKey) PubKey() types.PubKey

func (*CryptoKey) PubKeyBytes

func (pk *CryptoKey) PubKeyBytes() []byte

func (*CryptoKey) Public

func (pk *CryptoKey) Public() crypto.PublicKey

func (*CryptoKey) Sign

func (pk *CryptoKey) Sign(plaintext []byte, opts *SigningProfile) ([]byte, error)

Sign a plaintext with this private key. The SigningProfile tells the function which way of pre- and post-encoding of the actual cryptographic signature, which includes prior hashing, and whether or not the signature should be DER-encoded or "raw" (two concatenated big Ints)

func (*CryptoKey) Type

func (pk *CryptoKey) Type() string

type CryptoPrivKey

type CryptoPrivKey interface {
	Bytes() []byte
	Sign(msg []byte, opts *SigningProfile) ([]byte, error)
	PubKey() types.PubKey
	Equals(CryptoPrivKey) bool
	Type() string
}

CryptoPrivKey looks almost exactly the same as the LedgerPrivKey interface from cosmos-sdk/crypto/types. There is no ability to retrieve the private key bytes because these are stored and used only within the HSM.

type KeygenAlgorithm

type KeygenAlgorithm int
const (
	KEYGEN_SECP256K1 KeygenAlgorithm = iota
	KEYGEN_SECP256R1
	KEYGEN_ED25519
)

type Keyring

type Keyring interface {
	NewKey(algorithm KeygenAlgorithm, label string) (CryptoKey, error)
	Key(label string) (CryptoKey, error)
	// @@TODO - not implemented for PKCS11 keyring 9/9/2021
	ListKeys() ([]CryptoKey, error)
}

Keyring interface provides the methods for keyring implementations. NewKey generates a new key, using the given keygen algorithm supported algorithms are in keys.go Key returns a filled out key with the given label, retrieved from the keyring ListKeys lists all of the keys on the keyring

type Pkcs11Keyring

type Pkcs11Keyring struct {
	ModulePath string
	TokenLabel string
	// contains filtered or unexported fields
}

func NewPkcs11FromConfig

func NewPkcs11FromConfig(configPath string) (Pkcs11Keyring, error)

NewPkcs11FromConfig returns a new Pkcs11Keyring structure when given the path to a configuration file that describes the Pkcs11 token which holds the actual cryptographic keys.

func (Pkcs11Keyring) Key

func (ring Pkcs11Keyring) Key(label string) (*CryptoKey, error)

Key retrieves a keypair from the PKCS11 token and populates a CryptoKey object, based on finding the key[air based on the label that is supplied in the API call.

func (Pkcs11Keyring) NewKey

func (ring Pkcs11Keyring) NewKey(algorithm KeygenAlgorithm, label string) (*CryptoKey, error)

NewKey creates a new ECC key on a Pkcs11 token using the given algorithm from the keygen algos supported. A label can be passed in. This is used as a way of uniquely identifying the key and typically is a large (unguessable) random number

type SigningProfile

type SigningProfile int
const (
	// SIGNING_OPTS_BC_ECDSA_SHAXXX means
	//   i) SHAXXX hash prior to signing
	//  ii) Raw signature (R||S, no DER)
	// iii) low-s normalized
	SIGNING_OPTS_BC_ECDSA_SHA256 SigningProfile = iota

	// SIGNING_OPTS_ECDSA means
	//   i) No hash in the signing process
	//  ii) DER signature as in usual ECDSA
	// iii) No low-s normalization
	SIGNING_OPTS_ECDSA
)

SigningProfile is a combination of cryptographic signing mechanism, prior hashing of the plaintext, transformations such as s-normalization of signature, and post-encoding of the signature.

Jump to

Keyboard shortcuts

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