Documentation
¶
Overview ¶
Package gcpkmscrypto implements cryptoprov.Provider and cryptoprov.KeyManager over Google Cloud KMS (HSM protection level). It registers itself as manufacturer "GCPKMS"; the token config Attributes field must carry "Keyring=projects/P/locations/L/keyRings/R" and may carry "Endpoint=host:port" for a non-default API endpoint. Authentication uses Application Default Credentials. Call Close to release the gRPC client.
Keys are ASYMMETRIC_SIGN keys. A key ID is a CryptoKey id, "K", or one of its versions, "K/cryptoKeyVersions/N". Generated and loaded signers name their version, so the URI from ExportKey pins it. A bare id is resolved at each call: GetKey uses the newest enabled version, KeyInfo the newest enabled or else the newest non-destroyed version, and DestroyKeyPairOnSlot every enabled or disabled version. Sign accepts only the hash and padding of the version's KMS algorithm.
Index ¶
- Constants
- Variables
- func Crc32c(data []byte) uint32
- func KeyLabelAndID(val string) (label string, id string)
- func KmsLoader(tc cryptoprov.TokenConfig) (cryptoprov.Provider, error)
- func NewSigner(keyID string, label string, publicKey crypto.PublicKey, ...) crypto.Signer
- type KmsClient
- type Provider
- func (p *Provider) Close() error
- func (p *Provider) CurrentSlotID() uint
- func (p *Provider) DestroyKeyPairOnSlot(slotID uint, keyID string) error
- func (p *Provider) EnumKeys(slotID uint, prefix string) ([]cryptoprov.KeyInfo, error)
- func (p *Provider) EnumTokens(currentSlotOnly bool) ([]cryptoprov.TokenInfo, error)
- func (p *Provider) ExportKey(keyID string) (string, []byte, error)
- func (p *Provider) FindKeyPairOnSlot(slotID uint, keyID, label string) (crypto.PrivateKey, error)
- func (p *Provider) GenerateECDSAKey(label string, curve elliptic.Curve) (crypto.PrivateKey, error)
- func (p *Provider) GenerateRSAKey(label string, bits int, purpose int) (crypto.PrivateKey, error)
- func (p *Provider) GetKey(keyID string) (crypto.PrivateKey, error)
- func (p *Provider) IdentifyKey(priv crypto.PrivateKey) (keyID, label string, err error)
- func (p *Provider) KeyInfo(slotID uint, keyID string, includePublic bool) (*cryptoprov.KeyInfo, error)
- func (p *Provider) Manufacturer() string
- func (p *Provider) Model() string
- type Signer
- func (s *Signer) Algorithm() kmspb.CryptoKeyVersion_CryptoKeyVersionAlgorithm
- func (s *Signer) KeyID() string
- func (s *Signer) Label() string
- func (s *Signer) Public() crypto.PublicKey
- func (s *Signer) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error)
- func (s *Signer) SignatureAlgorithm() x509.SignatureAlgorithm
- func (s *Signer) String() string
Constants ¶
const ProviderName = "GCPKMS"
ProviderName specifies a provider name
Variables ¶
var ErrClosed = errors.New("gcpkms: provider is closed")
ErrClosed is returned after Close by the operations that call KMS: GetKey, KeyInfo, EnumKeys, DestroyKeyPairOnSlot, GenerateRSAKey, GenerateECDSAKey and Signer.Sign. Operations that do not call KMS, such as EnumTokens, ExportKey and IdentifyKey, keep working.
var KmsClientFactory = func(endpoint string) (KmsClient, error) { return newKmsClient(context.Background(), endpoint) }
KmsClientFactory creates the KMS client for Init. endpoint is the Endpoint attribute of the token config, empty for the default endpoint (XPKI-021). The default factory uses Application Default Credentials. Tests override the variable.
Functions ¶
func KeyLabelAndID ¶
KeyLabelAndID returns the KMS label and CryptoKey id for a requested key name. A trailing "*" is dropped. The label is the name lower-cased, with every character outside [a-z0-9_-] replaced by "-" and cut to 63 characters, which KMS accepts as a label value. The id is the label cut to 54 characters, "-" and 8 random characters from crypto/rand (40 bits), so it is at most 63 characters and always keeps its random suffix (XPKI-022). For an empty name the id is the suffix alone.
func KmsLoader ¶
func KmsLoader(tc cryptoprov.TokenConfig) (cryptoprov.Provider, error)
KmsLoader provides loader for KMS provider
func NewSigner ¶
func NewSigner(keyID string, label string, publicKey crypto.PublicKey, algorithm kmspb.CryptoKeyVersion_CryptoKeyVersionAlgorithm, prov *Provider) crypto.Signer
NewSigner creates a signer for the key version keyID, "K/cryptoKeyVersions/N", whose KMS algorithm is algorithm; Sign accepts only options that match it. A keyID that names no version makes every Sign fail.
Types ¶
type KmsClient ¶
type KmsClient interface {
ListCryptoKeys(context.Context, *kmspb.ListCryptoKeysRequest, ...gax.CallOption) *kms.CryptoKeyIterator
ListCryptoKeyVersions(context.Context, *kmspb.ListCryptoKeyVersionsRequest, ...gax.CallOption) *kms.CryptoKeyVersionIterator
GetCryptoKey(context.Context, *kmspb.GetCryptoKeyRequest, ...gax.CallOption) (*kmspb.CryptoKey, error)
GetPublicKey(context.Context, *kmspb.GetPublicKeyRequest, ...gax.CallOption) (*kmspb.PublicKey, error)
GetCryptoKeyVersion(context.Context, *kmspb.GetCryptoKeyVersionRequest, ...gax.CallOption) (*kmspb.CryptoKeyVersion, error)
DestroyCryptoKeyVersion(context.Context, *kmspb.DestroyCryptoKeyVersionRequest, ...gax.CallOption) (*kmspb.CryptoKeyVersion, error)
AsymmetricSign(context.Context, *kmspb.AsymmetricSignRequest, ...gax.CallOption) (*kmspb.AsymmetricSignResponse, error)
CreateCryptoKey(context.Context, *kmspb.CreateCryptoKeyRequest, ...gax.CallOption) (*kmspb.CryptoKey, error)
Close() error
}
KmsClient is the subset of the KMS client the provider uses.
type Provider ¶
type Provider struct {
KmsClient
// contains filtered or unexported fields
}
Provider implements Provider interface for KMS.
A key ID is a CryptoKey id, "K", or one of its versions, "K/cryptoKeyVersions/N" (XPKI-020). GetKey, KeyInfo and DestroyKeyPairOnSlot use the named version. A bare id is resolved at each call: GetKey signs with the newest ENABLED version (none is an error), KeyInfo describes the newest ENABLED version, else the newest one not DESTROYED, else the key alone (XPKI-117), and DestroyKeyPairOnSlot schedules every ENABLED or DISABLED version for destruction (XPKI-116). Generated and loaded signers identify themselves by their version, so the URI from ExportKey pins it; ExportKey itself makes no RPC and does not resolve a bare id.
Its methods and signers are safe for concurrent use with Close: Close rejects new operations with ErrClosed, waits for those in flight, then closes the client. A wait for key generation ends as soon as Close is called. The embedded KmsClient is set up by Init; its methods called directly bypass that guard.
func Init ¶
func Init(tc cryptoprov.TokenConfig) (*Provider, error)
Init configures the KMS provider from the token config. The Keyring attribute is required (XPKI-120); Endpoint is optional.
func (*Provider) Close ¶
Close rejects new operations with ErrClosed, ends any wait for key generation, waits for the operations in flight, then closes the client and returns its error. Later and concurrent calls wait for the first one and return nil. The KmsClient field is kept (XPKI-018).
func (*Provider) CurrentSlotID ¶
CurrentSlotID returns current slot id. For KMS only one slot is assumed to be available.
func (*Provider) DestroyKeyPairOnSlot ¶
DestroyKeyPairOnSlot schedules key material for destruction. A version id, "K/cryptoKeyVersions/N", destroys that version only; a bare "K" destroys every ENABLED or DISABLED version of the key, newest first, so the key can no longer sign (XPKI-020, XPKI-116). A key with no such version is an error. The first failure stops the loop. slotID is ignored.
func (*Provider) EnumKeys ¶
EnumKeys returns list of keys on the slot. For KMS slotID is ignored. Versions are not listed: CurrentVersionID is set only for keys with a primary version, which asymmetric keys do not have.
func (*Provider) EnumTokens ¶
func (p *Provider) EnumTokens(currentSlotOnly bool) ([]cryptoprov.TokenInfo, error)
EnumTokens lists tokens. For KMS currentSlotOnly is ignored and only one slot is assumed to be available.
func (*Provider) ExportKey ¶
ExportKey returns the PKCS#11 URI of the key ID, without key bytes and without an RPC. The id attribute is keyID as given: a signer's key ID (from IdentifyKey) names its version, so the URI pins it; a bare id is resolved again when the URI is loaded (XPKI-020). serial is always 1.
func (*Provider) FindKeyPairOnSlot ¶
FindKeyPairOnSlot retrieves a previously created asymmetric key, using a specified slot.
func (*Provider) GenerateECDSAKey ¶
GenerateECDSAKey creates a signer using a newly generated ECDSA signing key: P-256 with SHA-256 or P-384 with SHA-384.
func (*Provider) GenerateRSAKey ¶
GenerateRSAKey creates a signer using a newly generated RSA signing key. This provider has no decrypter, so the encryption purpose (2) is an error before any RPC (XPKI-019); any other purpose is a signing key. The KMS algorithm is PKCS#1 v1.5 with SHA-256 for 2048 and 3072 bits and SHA-512 for 4096 bits, and Sign accepts only that hash.
func (*Provider) GetKey ¶
func (p *Provider) GetKey(keyID string) (crypto.PrivateKey, error)
GetKey returns the signer of the version that keyID names, "K" for the newest enabled version or "K/cryptoKeyVersions/N" (XPKI-020). The version must be ENABLED with a supported signing algorithm.
func (*Provider) IdentifyKey ¶
func (p *Provider) IdentifyKey(priv crypto.PrivateKey) (keyID, label string, err error)
IdentifyKey returns key id and label for the given private key
func (*Provider) KeyInfo ¶
func (p *Provider) KeyInfo(slotID uint, keyID string, includePublic bool) (*cryptoprov.KeyInfo, error)
KeyInfo retrieves info about the key with the specified id. The described version supplies CurrentVersionID, the state, algo and protection Meta and, with includePublic, the public key: the version keyID names, or for a bare id the newest ENABLED version, else the newest one not DESTROYED (XPKI-020, XPKI-117). A key with no such version is described without version fields, and includePublic is then an error.
func (*Provider) Manufacturer ¶
Manufacturer returns manufacturer for the provider
type Signer ¶
type Signer struct {
// contains filtered or unexported fields
}
Signer implements crypto.Signer interface
func (*Signer) Algorithm ¶ added in v0.29.306
func (s *Signer) Algorithm() kmspb.CryptoKeyVersion_CryptoKeyVersionAlgorithm
Algorithm returns the KMS algorithm of the signer's key version.
func (*Signer) Sign ¶
func (s *Signer) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error)
Sign signs digest with the KMS key version. opts is required: its hash must be the key algorithm's, digest must have that hash's length, and *rsa.PSSOptions with the hash-length salt (rsa.PSSSaltLengthEqualsHash or the explicit size; KMS cannot honour PSSSaltLengthAuto, XPKI-124) are required for PSS algorithms and rejected for others (XPKI-019, XPKI-025). Invalid options fail before any RPC. The response is accepted only when KMS verified the digest checksum and the signature matches its checksum (XPKI-023). After the provider is closed, Sign returns ErrClosed.
func (*Signer) SignatureAlgorithm ¶ added in v1.0.310
func (s *Signer) SignatureAlgorithm() x509.SignatureAlgorithm
SignatureAlgorithm returns the X.509 signature algorithm the key version's KMS algorithm produces, or x509.UnknownSignatureAlgorithm for an algorithm Sign does not support. It implements csr.SignatureAlgorithmer, so csr.DefaultSigAlgo signs CSRs and certificates with the hash and padding KMS accepts for the key, for example SHA-256 for a 3072-bit key and SHA-256 or SHA-512 for a 4096-bit key as its algorithm says (XPKI-114).