mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 10:33:35 +00:00
rebase: IBM key protect integration module dependency update
This commit adds the Key protect client SDK for the Key Protect KMS integration to the Ceph CSI driver. Signed-off-by: Humble Chirammal <hchiramm@redhat.com>
This commit is contained in:
committed by
mergify[bot]
parent
967076e4ba
commit
93e43d1a0f
463
vendor/github.com/IBM/keyprotect-go-client/keys.go
generated
vendored
Normal file
463
vendor/github.com/IBM/keyprotect-go-client/keys.go
generated
vendored
Normal file
@ -0,0 +1,463 @@
|
||||
// Copyright 2019 IBM Corp.
|
||||
//
|
||||
// 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 kp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
ReturnMinimal PreferReturn = 0
|
||||
ReturnRepresentation PreferReturn = 1
|
||||
|
||||
keyType = "application/vnd.ibm.kms.key+json"
|
||||
)
|
||||
|
||||
var (
|
||||
preferHeaders = []string{"return=minimal", "return=representation"}
|
||||
)
|
||||
|
||||
// PreferReturn designates the value for the "Prefer" header.
|
||||
type PreferReturn int
|
||||
|
||||
// Key represents a key as returned by the KP API.
|
||||
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"`
|
||||
Aliases []string `json:"aliases,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"`
|
||||
KeyVersion *KeyVersion `json:"keyVersion,omitempty" mapstructure:keyVersion`
|
||||
KeyRingID string `json:"keyRingID,omitempty"`
|
||||
Extractable bool `json:"extractable"`
|
||||
Expiration *time.Time `json:"expirationDate,omitempty"`
|
||||
Imported bool `json:"imported,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"`
|
||||
Deleted *bool `json:"deleted,omitempty"`
|
||||
DeletedBy *string `json:"deletedBy,omitempty"`
|
||||
DeletionDate *time.Time `json:"deletionDate,omitempty"`
|
||||
DualAuthDelete *DualAuth `json:"dualAuthDelete,omitempty"`
|
||||
}
|
||||
|
||||
// KeysMetadata represents the metadata of a collection of keys.
|
||||
type KeysMetadata struct {
|
||||
CollectionType string `json:"collectionType"`
|
||||
NumberOfKeys int `json:"collectionTotal"`
|
||||
}
|
||||
|
||||
// Keys represents a collection of Keys.
|
||||
type Keys struct {
|
||||
Metadata KeysMetadata `json:"metadata"`
|
||||
Keys []Key `json:"resources"`
|
||||
}
|
||||
|
||||
// KeysActionRequest represents request parameters for a key action
|
||||
// API call.
|
||||
type KeysActionRequest struct {
|
||||
PlainText string `json:"plaintext,omitempty"`
|
||||
AAD []string `json:"aad,omitempty"`
|
||||
CipherText string `json:"ciphertext,omitempty"`
|
||||
Payload string `json:"payload,omitempty"`
|
||||
}
|
||||
|
||||
type KeyVersion struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
CreationDate *time.Time `json:"creationDate,omitempty"`
|
||||
}
|
||||
|
||||
// CreateKey creates a new KP key.
|
||||
func (c *Client) CreateKey(ctx context.Context, name string, expiration *time.Time, extractable bool) (*Key, error) {
|
||||
return c.CreateImportedKey(ctx, name, expiration, "", "", "", extractable)
|
||||
}
|
||||
|
||||
// CreateImportedKey creates a new KP key from the given key material.
|
||||
func (c *Client) CreateImportedKey(ctx context.Context, name string, expiration *time.Time, payload, encryptedNonce, iv string, extractable bool) (*Key, error) {
|
||||
key := Key{
|
||||
Name: name,
|
||||
Type: keyType,
|
||||
Extractable: extractable,
|
||||
Payload: payload,
|
||||
}
|
||||
|
||||
if payload != "" && encryptedNonce != "" && iv != "" {
|
||||
key.EncryptedNonce = encryptedNonce
|
||||
key.IV = iv
|
||||
key.EncryptionAlgorithm = importTokenEncAlgo
|
||||
}
|
||||
|
||||
if expiration != nil {
|
||||
key.Expiration = expiration
|
||||
}
|
||||
|
||||
return c.createKey(ctx, key)
|
||||
}
|
||||
|
||||
// CreateRootKey creates a new, non-extractable key resource without
|
||||
// key material.
|
||||
func (c *Client) CreateRootKey(ctx context.Context, name string, expiration *time.Time) (*Key, error) {
|
||||
return c.CreateKey(ctx, name, expiration, false)
|
||||
}
|
||||
|
||||
// CreateStandardKey creates a new, extractable key resource without
|
||||
// key material.
|
||||
func (c *Client) CreateStandardKey(ctx context.Context, name string, expiration *time.Time) (*Key, error) {
|
||||
return c.CreateKey(ctx, name, expiration, true)
|
||||
}
|
||||
|
||||
// CreateImportedRootKey creates a new, non-extractable key resource
|
||||
// with the given key material.
|
||||
func (c *Client) CreateImportedRootKey(ctx context.Context, name string, expiration *time.Time, payload, encryptedNonce, iv string) (*Key, error) {
|
||||
return c.CreateImportedKey(ctx, name, expiration, payload, encryptedNonce, iv, false)
|
||||
}
|
||||
|
||||
// CreateStandardKey creates a new, extractable key resource with the
|
||||
// given key material.
|
||||
func (c *Client) CreateImportedStandardKey(ctx context.Context, name string, expiration *time.Time, payload string) (*Key, error) {
|
||||
return c.CreateImportedKey(ctx, name, expiration, payload, "", "", true)
|
||||
}
|
||||
|
||||
// CreateKeyWithAliaes creats a new key with alias names. A key can have a maximum of 5 alias names.
|
||||
// For more information please refer to the links below:
|
||||
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-create-root-keys#create-root-key-api
|
||||
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-create-standard-keys#create-standard-key-api
|
||||
func (c *Client) CreateKeyWithAliases(ctx context.Context, name string, expiration *time.Time, extractable bool, aliases []string) (*Key, error) {
|
||||
return c.CreateImportedKeyWithAliases(ctx, name, expiration, "", "", "", extractable, aliases)
|
||||
}
|
||||
|
||||
// CreateImportedKeyWithAliases creates a new key with alias name and provided key material. A key can have a maximum of 5 alias names
|
||||
// When importing root keys with import-token encryptedNonce and iv need to passed along with payload.
|
||||
// Standard Keys cannot be imported with an import token hence only payload is required.
|
||||
// For more information please refer to the links below:
|
||||
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-import-root-keys#import-root-key-api
|
||||
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-import-standard-keys#import-standard-key-gui
|
||||
func (c *Client) CreateImportedKeyWithAliases(ctx context.Context, name string, expiration *time.Time, payload, encryptedNonce, iv string, extractable bool, aliases []string) (*Key, error) {
|
||||
key := Key{
|
||||
Name: name,
|
||||
Type: keyType,
|
||||
Extractable: extractable,
|
||||
Payload: payload,
|
||||
Aliases: aliases,
|
||||
}
|
||||
|
||||
if !extractable && payload != "" && encryptedNonce != "" && iv != "" {
|
||||
key.EncryptedNonce = encryptedNonce
|
||||
key.IV = iv
|
||||
key.EncryptionAlgorithm = importTokenEncAlgo
|
||||
}
|
||||
|
||||
if expiration != nil {
|
||||
key.Expiration = expiration
|
||||
}
|
||||
|
||||
return c.createKey(ctx, key)
|
||||
}
|
||||
|
||||
func (c *Client) createKey(ctx context.Context, key Key) (*Key, error) {
|
||||
keysRequest := Keys{
|
||||
Metadata: KeysMetadata{
|
||||
CollectionType: keyType,
|
||||
NumberOfKeys: 1,
|
||||
},
|
||||
Keys: []Key{key},
|
||||
}
|
||||
|
||||
req, err := c.newRequest("POST", "keys", &keysRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
keysResponse := Keys{}
|
||||
if _, err := c.do(ctx, req, &keysResponse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &keysResponse.Keys[0], nil
|
||||
}
|
||||
|
||||
// GetKeys retrieves a collection of keys that can be paged through.
|
||||
func (c *Client) GetKeys(ctx context.Context, limit int, offset int) (*Keys, error) {
|
||||
if limit == 0 {
|
||||
limit = 2000
|
||||
}
|
||||
|
||||
req, err := c.newRequest("GET", "keys", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
v := url.Values{}
|
||||
v.Set("limit", strconv.Itoa(limit))
|
||||
v.Set("offset", strconv.Itoa(offset))
|
||||
req.URL.RawQuery = v.Encode()
|
||||
|
||||
keys := Keys{}
|
||||
_, err = c.do(ctx, req, &keys)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &keys, nil
|
||||
}
|
||||
|
||||
// GetKey retrieves a key by ID or alias name.
|
||||
// For more information on Key Alias please refer to the link below
|
||||
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-retrieve-key
|
||||
func (c *Client) GetKey(ctx context.Context, idOrAlias string) (*Key, error) {
|
||||
return c.getKey(ctx, idOrAlias, "keys/%s")
|
||||
}
|
||||
|
||||
// GetKeyMetadata retrieves the metadata of a Key by ID or alias name.
|
||||
// Note that the "/api/v2/keys/{id}/metadata" API does not return the payload,
|
||||
// therefore the payload attribute in the Key pointer will always be empty.
|
||||
// If you need the payload, you need to use the GetKey() function with the
|
||||
// correct service access role.
|
||||
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-manage-access#service-access-roles
|
||||
func (c *Client) GetKeyMetadata(ctx context.Context, idOrAlias string) (*Key, error) {
|
||||
return c.getKey(ctx, idOrAlias, "keys/%s/metadata")
|
||||
}
|
||||
|
||||
func (c *Client) getKey(ctx context.Context, id string, path string) (*Key, error) {
|
||||
keys := Keys{}
|
||||
|
||||
req, err := c.newRequest("GET", fmt.Sprintf(path, id), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, err = c.do(ctx, req, &keys)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &keys.Keys[0], nil
|
||||
}
|
||||
|
||||
type CallOpt interface{}
|
||||
|
||||
type ForceOpt struct {
|
||||
Force bool
|
||||
}
|
||||
|
||||
// DeleteKey deletes a key resource by specifying the ID of the key.
|
||||
func (c *Client) DeleteKey(ctx context.Context, id string, prefer PreferReturn, callOpts ...CallOpt) (*Key, error) {
|
||||
|
||||
req, err := c.newRequest("DELETE", fmt.Sprintf("keys/%s", id), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, opt := range callOpts {
|
||||
switch v := opt.(type) {
|
||||
case ForceOpt:
|
||||
params := url.Values{}
|
||||
params.Set("force", strconv.FormatBool(v.Force))
|
||||
req.URL.RawQuery = params.Encode()
|
||||
default:
|
||||
log.Printf("WARNING: Ignoring invalid CallOpt passed to DeleteKey: %v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
req.Header.Set("Prefer", preferHeaders[prefer])
|
||||
|
||||
keys := Keys{}
|
||||
_, err = c.do(ctx, req, &keys)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(keys.Keys) > 0 {
|
||||
return &keys.Keys[0], nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// RestoreKey method reverts a delete key status to active key
|
||||
// This method performs restore of any key from deleted state to active state.
|
||||
// For more information please refer to the link below:
|
||||
// https://cloud.ibm.com/dowcs/key-protect?topic=key-protect-restore-keys
|
||||
func (c *Client) RestoreKey(ctx context.Context, id string) (*Key, error) {
|
||||
req, err := c.newRequest("POST", fmt.Sprintf("keys/%s/restore", id), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
keysResponse := Keys{}
|
||||
|
||||
_, err = c.do(ctx, req, &keysResponse)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &keysResponse.Keys[0], nil
|
||||
}
|
||||
|
||||
// Wrap calls the wrap action with the given plain text.
|
||||
func (c *Client) Wrap(ctx context.Context, id string, plainText []byte, additionalAuthData *[]string) ([]byte, error) {
|
||||
_, ct, err := c.wrap(ctx, id, plainText, additionalAuthData)
|
||||
return ct, err
|
||||
}
|
||||
|
||||
// WrapCreateDEK calls the wrap action without plain text.
|
||||
func (c *Client) WrapCreateDEK(ctx context.Context, id string, additionalAuthData *[]string) ([]byte, []byte, error) {
|
||||
return c.wrap(ctx, id, nil, additionalAuthData)
|
||||
}
|
||||
|
||||
func (c *Client) wrap(ctx context.Context, id string, plainText []byte, additionalAuthData *[]string) ([]byte, []byte, error) {
|
||||
keysActionReq := &KeysActionRequest{}
|
||||
|
||||
if plainText != nil {
|
||||
_, err := base64.StdEncoding.DecodeString(string(plainText))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
keysActionReq.PlainText = string(plainText)
|
||||
}
|
||||
|
||||
if additionalAuthData != nil {
|
||||
keysActionReq.AAD = *additionalAuthData
|
||||
}
|
||||
|
||||
keysAction, err := c.doKeysAction(ctx, id, "wrap", keysActionReq)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
pt := []byte(keysAction.PlainText)
|
||||
ct := []byte(keysAction.CipherText)
|
||||
|
||||
return pt, ct, nil
|
||||
}
|
||||
|
||||
// Unwrap is deprecated since it returns only plaintext and doesn't know how to handle rotation.
|
||||
func (c *Client) Unwrap(ctx context.Context, id string, cipherText []byte, additionalAuthData *[]string) ([]byte, error) {
|
||||
plainText, _, err := c.UnwrapV2(ctx, id, cipherText, additionalAuthData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return plainText, nil
|
||||
}
|
||||
|
||||
// Unwrap with rotation support.
|
||||
func (c *Client) UnwrapV2(ctx context.Context, id string, cipherText []byte, additionalAuthData *[]string) ([]byte, []byte, error) {
|
||||
|
||||
keysAction := &KeysActionRequest{
|
||||
CipherText: string(cipherText),
|
||||
}
|
||||
|
||||
if additionalAuthData != nil {
|
||||
keysAction.AAD = *additionalAuthData
|
||||
}
|
||||
|
||||
respAction, err := c.doKeysAction(ctx, id, "unwrap", keysAction)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
plainText := []byte(respAction.PlainText)
|
||||
rewrapped := []byte(respAction.CipherText)
|
||||
|
||||
return plainText, rewrapped, nil
|
||||
}
|
||||
|
||||
// Rotate rotates a CRK.
|
||||
func (c *Client) Rotate(ctx context.Context, id, payload string) error {
|
||||
|
||||
actionReq := &KeysActionRequest{
|
||||
Payload: payload,
|
||||
}
|
||||
|
||||
_, err := c.doKeysAction(ctx, id, "rotate", actionReq)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Disable a key. The key will not be deleted but it will not be active
|
||||
// and key operations cannot be performed on a disabled key.
|
||||
// For more information can refer to the Key Protect docs in the link below:
|
||||
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-disable-keys
|
||||
func (c *Client) DisableKey(ctx context.Context, id string) error {
|
||||
_, err := c.doKeysAction(ctx, id, "disable", nil)
|
||||
return err
|
||||
}
|
||||
|
||||
// Enable a key. Only disabled keys can be enabled. After enable
|
||||
// the key becomes active and key operations can be performed on it.
|
||||
// Note: This does not recover Deleted keys.
|
||||
// For more information can refer to the Key Protect docs in the link below:
|
||||
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-disable-keys#enable-api
|
||||
func (c *Client) EnableKey(ctx context.Context, id string) error {
|
||||
_, err := c.doKeysAction(ctx, id, "enable", nil)
|
||||
return err
|
||||
}
|
||||
|
||||
// InitiateDualAuthDelete sets a key for deletion. The key must be configured with a DualAuthDelete policy.
|
||||
// After the key is set to deletion it can be deleted by another user who has Manager access.
|
||||
// For more information refer to the Key Protect docs in the link below:
|
||||
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-delete-dual-auth-keys#set-key-deletion-api
|
||||
func (c *Client) InitiateDualAuthDelete(ctx context.Context, id string) error {
|
||||
_, err := c.doKeysAction(ctx, id, "setKeyForDeletion", nil)
|
||||
return err
|
||||
}
|
||||
|
||||
// CancelDualAuthDelete unsets the key for deletion. If a key is set for deletion, it can
|
||||
// be prevented from getting deleted by unsetting the key for deletion.
|
||||
// For more information refer to the Key Protect docs in the link below:
|
||||
//https://cloud.ibm.com/docs/key-protect?topic=key-protect-delete-dual-auth-keys#unset-key-deletion-api
|
||||
func (c *Client) CancelDualAuthDelete(ctx context.Context, id string) error {
|
||||
_, err := c.doKeysAction(ctx, id, "unsetKeyForDeletion", nil)
|
||||
return err
|
||||
}
|
||||
|
||||
// doKeysAction calls the KP Client to perform an action on a key.
|
||||
func (c *Client) doKeysAction(ctx context.Context, id string, action string, keysActionReq *KeysActionRequest) (*KeysActionRequest, error) {
|
||||
keyActionRsp := KeysActionRequest{}
|
||||
|
||||
v := url.Values{}
|
||||
v.Set("action", action)
|
||||
|
||||
req, err := c.newRequest("POST", fmt.Sprintf("keys/%s", id), keysActionReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req.URL.RawQuery = v.Encode()
|
||||
|
||||
_, err = c.do(ctx, req, &keyActionRsp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &keyActionRsp, nil
|
||||
}
|
Reference in New Issue
Block a user