kp

package module
v0.4.1 Latest Latest
Warning

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

Go to latest
Published: May 12, 2020 License: Apache-2.0 Imports: 25 Imported by: 0

README

keyprotect-go-client

Build Status GoDoc

keyprotect-go-client is a Go client library for interacting with the IBM KeyProtect service.

Questions / Support

There are many channels for asking questions about KeyProtect and this client.

  • Ask a question on Stackoverflow and tag it with key-protect and ibm-cloud
  • Open a Github Issue
  • If you work at IBM and have access to the internal Slack, you can join the #key-protect channel and ask there.

Usage

This client expects that you have an existing IBM Cloud Key Protect Service Instance. To get started, visit the IBM KeyProtect Catalog Page.

Build a client with ClientConfig and New, then use the client to do some operations.

import "github.com/IBM/keyprotect-go-client"

// Use your IAM API Key and your KeyProtect Service Instance GUID/UUID to create a ClientConfig
cc := kp.ClientConfig{
	BaseURL:       kp.DefaultBaseURL,
	APIKey:        "......",
	InstanceID:    "1234abcd-906d-438a-8a68-deadbeef1a2b3",
}

// Build a new client from the config
client := kp.New(cc, kp.DefaultTransport())

// List keys in your KeyProtect instance
keys, err := client.GetKeys(context.Background(), 0, 0)
Migrating

For users of the original key-protect-client that is now deprecated, this library is a drop in replacement. Updating the package reference to github.com/IBM/keyprotect-go-client should be the only change needed. If you are worried about new incompatible changes, version v0.3.1 of key-protect-client is equivalent to version v0.3.3 of keyprotect-go-client, so pinning v0.3.3 of the new library should be sufficient to pull from the new repo with no new functional changes.

Authentication

The KeyProtect client requires a valid IAM API Key that is passed via the APIKey field in the ClientConfig. The client will call IAM to get an access token for that API key, caches the access token, and reuses that token on subsequent calls. If the access token is expired, the client will call IAM to get a new access token.

Alternatively, you may also inject your own tokens during runtime. When using your own tokens, it's the responsibilty of the caller to ensure the access token is valid and is not expired. You can specify the access token in either the ClientConfig structure or on the context (see below.)

To specify authorization token on the context:

// Create a ClientConfig and Client like before, but without an APIKey
cc := kp.ClientConfig{
	BaseURL:       kp.DefaultBaseURL,
	InstanceID:    "1234abcd-906d-438a-8a68-deadbeef1a2b3",
}
client := kp.New(cc, kp.DefaultTransport())

// Use NewContextWithAuth to add your token into the context
ctx := context.Background()
ctx = kp.NewContextWithAuth(ctx, "Bearer ABCDEF123456....")

// List keys with our injected token via the context
keys, err := api.GetKeys(ctx, 0, 0)

For information on IAM API Keys and tokens please refer to the IAM docs

Finding a KeyProtect Service Instance's UUID

The client requires a valid UUID that identifies your KeyProtect Service Instance to be able to interact with your key data in the instance. An instance is somewhat like a folder or directory of keys; you can have many of them per account, but the keys they contain are separate and cannot be shared between instances.

The IBM Cloud CLI can be used to find the UUID for your KeyProtect instance.

$ ic resource service-instances
OK
Name                                                              Location   State    Type
Key Protect-private                                               us-south   active   service_instance
Key Protect-abc123                                                us-east    active   service_instance

Find the name of your KeyProtect instance as you created it, and the use the client to get its details. The Instance ID is the GUID field, or if you do not see GUID, it will be the last part of the CRN. For example:

$ ic resource service-instance "Key Protect-private"
OK

Name:                  Key Protect-private
ID:                    crn:v1:bluemix:public:kms:us-south:a/.......:1234abcd-906d-438a-8a68-deadbeef1a2b3::
GUID:                  1234abcd-906d-438a-8a68-deadbeef1a2b3

Examples

Generating a root key (CRK)
// Create a root key named MyRootKey with no expiration
key, err := client.CreateRootKey(ctx, "MyRootKey", nil)
if err != nil {
    fmt.Println(err)
}
fmt.Println(key.ID, key.Name)

crkID := key.ID
Wrapping and Unwrapping a DEK using a specific Root Key.
myDEK := []byte{"thisisadataencryptionkey"}
// Do some encryption with myDEK
// Wrap the DEK so we can safely store it
wrappedDEK, err := client.Wrap(ctx, crkID, myDEK, nil)


// Unwrap the DEK
dek, err := client.UnWrap(ctx, crkID, wrappedDEK, nil)
// Do some encryption/decryption using the DEK
// Discard the DEK
dek = nil

Note you can also pass additional authentication data (AAD) to wrap and unwrap calls to provide another level of protection for your DEK. The AAD is a string array with each element up to 255 chars. For example:

myAAD := []string{"First aad string", "second aad string", "third aad string"}
myDEK := []byte{"thisisadataencryptionkey"}
// Do some encryption with myDEK
// Wrap the DEK so we can safely store it
wrappedDEK, err := client.Wrap(ctx, crkID, myDEK, &myAAD)


// Unwrap the DEK
dek, err := client.UnWrap(ctx, crkID, wrappedDEK, &myAAD)
// Do some encryption/decryption using the DEK
// Discard the DEK
dek = nil

Have key protect create a DEK for you:

dek, wrappedDek, err := client.WrapCreateDEK(ctx, crkID, nil)
// Do some encrypt/decrypt with the dek
// Discard the DEK
dek = nil

// Save the wrapped DEK for later.  Use Unwrap to use it.

Can also specify AAD:

myAAD := []string{"First aad string", "second aad string", "third aad string"}
dek, wrappedDek, err := client.WrapCreateDEK(ctx, crkID, &myAAD)
// Do some encrypt/decrypt with the dek
// Discard the DEK
dek = nil

// Save the wrapped DEK for later.  Call Unwrap to use it, make
// sure to specify the same AAD.

Documentation

Index

Constants

View Source
const (
	//DualAuthDelete defines the policy type as dual auth delete
	DualAuthDelete = "dualAuthDelete"

	//AllowedNetwork defines the policy type as allowed network
	AllowedNetwork = "allowedNetwork"
)
View Source
const (
	// DefaultBaseURL ...
	DefaultBaseURL = "https://us-south.kms.cloud.ibm.com"
	// DefaultTokenURL ..
	DefaultTokenURL = iam.IAMTokenURL

	// VerboseNone ...
	VerboseNone = 0
	// VerboseBodyOnly ...
	VerboseBodyOnly = 1
	// VerboseAll ...
	VerboseAll = 2
	// VerboseFailOnly ...
	VerboseFailOnly = 3
	// VerboseAllNoRedact ...
	VerboseAllNoRedact = 4
)

Variables

View Source
var (
	// RetryWaitMax is the maximum time to wait between HTTP retries
	RetryWaitMax = 30 * time.Second

	// RetryMax is the max number of attempts to retry for failed HTTP requests
	RetryMax = 4
)

Functions

func DefaultTransport

func DefaultTransport() http.RoundTripper

DefaultTransport ...

func EncryptKey

func EncryptKey(key, pubkey string) (string, error)

EncryptKey will encrypt the user key-material with the public key from key protect

func EncryptNonce

func EncryptNonce(key, value, iv string) (string, string, error)

EncryptNonce will wrap the KP generated nonce with the users key-material

func NewContextWithAuth

func NewContextWithAuth(parent context.Context, auth string) context.Context

NewContextWithAuth ...

Types

type API

type API = Client

API is deprecated. Use Client instead.

type Attributes

type Attributes struct {
	AllowedNetwork string `json:"allowed_network,omitempty"`
}

Attributes contains the detals of allowed network policy type

type CallOpt

type CallOpt interface{}

type Client

type Client struct {
	URL        *url.URL
	HttpClient http.Client
	Dump       Dump
	Config     ClientConfig
	Logger     Logger
	// contains filtered or unexported fields
}

Client holds configuration and auth information to interact with KeyProtect. It is expected that one of these is created per KeyProtect service instance/credential pair.

func New

func New(config ClientConfig, transport http.RoundTripper) (*Client, error)

New creates and returns a Client without logging.

func NewWithLogger

func NewWithLogger(config ClientConfig, transport http.RoundTripper, logger Logger) (*Client, error)

NewWithLogger creates and returns a Client with logging. The error value will be non-nil if the config is invalid.

func (*Client) CreateImportToken

func (c *Client) CreateImportToken(ctx context.Context, expiration, maxAllowedRetrievals int) (*ImportTokenMetadata, error)

CreateImportToken creates a key ImportToken.

func (*Client) CreateImportedKey

func (c *Client) CreateImportedKey(ctx context.Context, name string, expiration *time.Time, payload, encryptedNonce, iv string, extractable bool) (*Key, error)

CreateImportedKey creates a new KP key from the given key material.

func (*Client) CreateImportedRootKey

func (c *Client) CreateImportedRootKey(ctx context.Context, name string, expiration *time.Time, payload, encryptedNonce, iv string) (*Key, error)

CreateImportedRootKey creates a new, non-extractable key resource with the given key material.

func (*Client) CreateImportedStandardKey

func (c *Client) CreateImportedStandardKey(ctx context.Context, name string, expiration *time.Time, payload string) (*Key, error)

CreateStandardKey creates a new, extractable key resource with the given key material.

func (*Client) CreateKey

func (c *Client) CreateKey(ctx context.Context, name string, expiration *time.Time, extractable bool) (*Key, error)

CreateKey creates a new KP key.

func (*Client) CreateRootKey

func (c *Client) CreateRootKey(ctx context.Context, name string, expiration *time.Time) (*Key, error)

CreateRootKey creates a new, non-extractable key resource without key material.

func (*Client) CreateStandardKey

func (c *Client) CreateStandardKey(ctx context.Context, name string, expiration *time.Time) (*Key, error)

CreateStandardKey creates a new, extractable key resource without key material.

func (*Client) DeleteKey

func (c *Client) DeleteKey(ctx context.Context, id string, prefer PreferReturn, callOpts ...CallOpt) (*Key, error)

DeleteKey deletes a key resource by specifying the ID of the key.

func (*Client) GetImportTokenTransportKey

func (c *Client) GetImportTokenTransportKey(ctx context.Context) (*ImportTokenKeyResponse, error)

GetImportTokenTransportKey retrieves the ImportToken transport key.

func (*Client) GetInstancePolicies

func (c *Client) GetInstancePolicies(ctx context.Context) ([]InstancePolicy, error)

GetInstancePolicies retrieves all policies of an Instance.

func (*Client) GetKey

func (c *Client) GetKey(ctx context.Context, id string) (*Key, error)

GetKey retrieves a key by ID.

func (*Client) GetKeys

func (c *Client) GetKeys(ctx context.Context, limit int, offset int) (*Keys, error)

GetKeys retrieves a collection of keys that can be paged through.

func (*Client) GetPolicy

func (c *Client) GetPolicy(ctx context.Context, id string) (*Policy, error)

GetPolicy retrieves a policy by Key ID.

func (*Client) Rotate

func (c *Client) Rotate(ctx context.Context, id, payload string) error

Rotate rotates a CRK.

func (*Client) SetInstancePolicies

func (c *Client) SetInstancePolicies(ctx context.Context, enable bool, networkType, setType string) error

SetInstancePolicies updates a policy resource of an instance to either allowed network or dual auth or both .

func (*Client) SetPolicy

func (c *Client) SetPolicy(ctx context.Context, id string, prefer PreferReturn, rotationInterval int) (*Policy, error)

SetPolicy updates a policy resource by specifying the ID of the key and the rotation interval needed.

func (*Client) Unwrap

func (c *Client) Unwrap(ctx context.Context, id string, cipherText []byte, additionalAuthData *[]string) ([]byte, error)

Unwrap is deprecated since it returns only plaintext and doesn't know how to handle rotation.

func (*Client) UnwrapV2

func (c *Client) UnwrapV2(ctx context.Context, id string, cipherText []byte, additionalAuthData *[]string) ([]byte, []byte, error)

Unwrap with rotation support.

func (*Client) Wrap

func (c *Client) Wrap(ctx context.Context, id string, plainText []byte, additionalAuthData *[]string) ([]byte, error)

Wrap calls the wrap action with the given plain text.

func (*Client) WrapCreateDEK

func (c *Client) WrapCreateDEK(ctx context.Context, id string, additionalAuthData *[]string) ([]byte, []byte, error)

WrapCreateDEK calls the wrap action without plain text.

type ClientConfig

type ClientConfig struct {
	BaseURL       string
	Authorization string  // The IBM Cloud (Bluemix) access token
	APIKey        string  // Service ID API key, can be used instead of an access token
	TokenURL      string  // The URL used to get an access token from the API key
	InstanceID    string  // The IBM Cloud (Bluemix) instance ID that identifies your Key Protect service instance.
	Verbose       int     // See verbose values above
	Timeout       float64 // KP request timeout in seconds.
}

ClientConfig ...

type ContextKey

type ContextKey int

ContextKey provides a type to auth context keys.

type Dump

type Dump func(*http.Request, *http.Response, []byte, []byte, Logger, []string)

Dump writes various parts of an HTTP request and an HTTP response.

type Error

type Error struct {
	URL           string   // URL of request that resulted in this error
	StatusCode    int      // HTTP error code from KeyProtect service
	Message       string   // error message from KeyProtect service
	BodyContent   []byte   // raw body content if more inspection is needed
	CorrelationID string   // string value of a UUID that uniquely identifies the request to KeyProtect
	Reasons       []reason // collection of reason types containing detailed error messages
}

func (Error) Error

func (e Error) Error() string

Error returns correlation id and error message string

type ForceOpt

type ForceOpt struct {
	Force bool
}

type ImportTokenCreateRequest

type ImportTokenCreateRequest struct {
	MaxAllowedRetrievals int `json:"maxAllowedRetrievals,omitempty"`
	ExpiresInSeconds     int `json:"expiration,omitempty"`
}

ImportTokenCreateRequest represents request parameters for creating a ImportToken.

type ImportTokenKeyResponse

type ImportTokenKeyResponse struct {
	ID             string     `json:"id"`
	CreationDate   *time.Time `json:"creationDate"`
	ExpirationDate *time.Time `json:"expirationDate"`
	Payload        string     `json:"payload"`
	Nonce          string     `json:"nonce"`
}

ImportTokenKeyResponse represents the response body for various ImportToken API calls.

type ImportTokenMetadata

type ImportTokenMetadata struct {
	ID                   string     `json:"id"`
	CreationDate         *time.Time `json:"creationDate"`
	ExpirationDate       *time.Time `json:"expirationDate"`
	MaxAllowedRetrievals int        `json:"maxAllowedRetrievals"`
	RemainingRetrievals  int        `json:"remainingRetrievals"`
}

ImportTokenMetadata represents the metadata of a ImportToken.

type InstancePolicies

type InstancePolicies struct {
	Metadata PoliciesMetadata `json:"metadata"`
	Policies []InstancePolicy `json:"resources"`
}

InstancePolicies represents a collection of Policies associated with Key Protect instances.

type InstancePolicy

type InstancePolicy struct {
	CreatedBy  string     `json:"createdBy,omitempty"`
	CreatedAt  *time.Time `json:"creationDate,omitempty"`
	UpdatedAt  *time.Time `json:"lastUpdated,omitempty"`
	UpdatedBy  string     `json:"updatedBy,omitempty"`
	PolicyType string     `json:"policy_type,omitempty"`
	PolicyData PolicyData `json:"policy_data,omitempty" mapstructure:"policyData"`
}

InstancePolicy represents a instance-level policy of a key as returned by the KP API. this policy enables dual authorization for deleting a key

type Key

type Key struct {
	ID                  string     `json:"id,omitempty"`
	Name                string     `json:"name,omitempty"`
	Description         string     `json:"description,omitempty"`
	Type                string     `json:"type,omitempty"`
	Tags                []string   `json:"Tags,omitempty"`
	AlgorithmType       string     `json:"algorithmType,omitempty"`
	CreatedBy           string     `json:"createdBy,omitempty"`
	CreationDate        *time.Time `json:"creationDate,omitempty"`
	LastUpdateDate      *time.Time `json:"lastUpdateDate,omitempty"`
	LastRotateDate      *time.Time `json:"lastRotateDate,omitempty"`
	Extractable         bool       `json:"extractable"`
	Expiration          *time.Time `json:"expirationDate,omitempty"`
	Payload             string     `json:"payload,omitempty"`
	State               int        `json:"state,omitempty"`
	EncryptionAlgorithm string     `json:"encryptionAlgorithm,omitempty"`
	CRN                 string     `json:"crn,omitempty"`
	EncryptedNonce      string     `json:"encryptedNonce,omitempty"`
	IV                  string     `json:"iv,omitempty"`
}

Key represents a key as returned by the KP API.

type Keys

type Keys struct {
	Metadata KeysMetadata `json:"metadata"`
	Keys     []Key        `json:"resources"`
}

Keys represents a collection of Keys.

type KeysActionRequest

type KeysActionRequest struct {
	PlainText  string   `json:"plaintext,omitempty"`
	AAD        []string `json:"aad,omitempty"`
	CipherText string   `json:"ciphertext,omitempty"`
	Payload    string   `json:"payload,omitempty"`
}

KeysActionRequest represents request parameters for a key action API call.

type KeysMetadata

type KeysMetadata struct {
	CollectionType string `json:"collectionType"`
	NumberOfKeys   int    `json:"collectionTotal"`
}

KeysMetadata represents the metadata of a collection of keys.

type Logger

type Logger interface {
	Info(...interface{})
}

Logger writes when called.

func NewLogger

func NewLogger(writer func(...interface{})) Logger

type Policies

type Policies struct {
	Metadata PoliciesMetadata `json:"metadata"`
	Policies []Policy         `json:"resources"`
}

Policies represents a collection of Policies.

type PoliciesMetadata

type PoliciesMetadata struct {
	CollectionType   string `json:"collectionType"`
	NumberOfPolicies int    `json:"collectionTotal"`
}

PoliciesMetadata represents the metadata of a collection of keys.

type Policy

type Policy struct {
	Type      string     `json:"type,omitempty"`
	CreatedBy string     `json:"createdBy,omitempty"`
	CreatedAt *time.Time `json:"creationDate,omitempty"`
	CRN       string     `json:"crn,omitempty"`
	UpdatedAt *time.Time `json:"lastUpdateDate,omitempty"`
	UpdatedBy string     `json:"updatedBy,omitempty"`
	Rotation  struct {
		Interval int `json:"interval_month,omitempty"`
	} `json:"rotation,omitempty"`
}

Policy represents a policy as returned by the KP API.

type PolicyData

type PolicyData struct {
	Enabled    *bool      `json:"enabled,omitempty"`
	Attributes Attributes `json:"attributes,omitempty"`
}

PolicyData contains the details of the policy type

type PreferReturn

type PreferReturn int

PreferReturn designates the value for the "Prefer" header.

const (
	ReturnMinimal        PreferReturn = 0
	ReturnRepresentation PreferReturn = 1
)

type Redact

type Redact func(string, []string) string

Redact replaces various pieces of output.

type URLError

type URLError struct {
	Err           error
	CorrelationID string
}

URLError wraps an error from client.do() calls with a correlation ID from KeyProtect

func (URLError) Error

func (e URLError) Error() string

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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