storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/pkg/kms/kms.go (about)

     1  // MinIO Cloud Storage, (C) 2021 MinIO, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package kms
    16  
    17  import (
    18  	"encoding"
    19  	"encoding/json"
    20  )
    21  
    22  // KMS is the generic interface that abstracts over
    23  // different KMS implementations.
    24  type KMS interface {
    25  	// Stat returns the current KMS status.
    26  	Stat() (Status, error)
    27  
    28  	// CreateKey creates a new key at the KMS with the given key ID.
    29  	CreateKey(keyID string) error
    30  
    31  	// GenerateKey generates a new data encryption key using the
    32  	// key referenced by the key ID.
    33  	//
    34  	// The KMS may use a default key if the key ID is empty.
    35  	// GenerateKey returns an error if the referenced key does
    36  	// not exist.
    37  	//
    38  	// The context is associated and tied to the generated DEK.
    39  	// The same context must be provided when the generated key
    40  	// should be decrypted. Therefore, it is the callers
    41  	// responsibility to remember the corresponding context for
    42  	// a particular DEK. The context may be nil.
    43  	GenerateKey(keyID string, context Context) (DEK, error)
    44  
    45  	// DecryptKey decrypts the ciphertext with the key referenced
    46  	// by the key ID. The context must match the context value
    47  	// used to generate the ciphertext.
    48  	DecryptKey(keyID string, ciphertext []byte, context Context) ([]byte, error)
    49  }
    50  
    51  // Status describes the current state of a KMS.
    52  type Status struct {
    53  	Name      string   // The name of the KMS
    54  	Endpoints []string // A set of the KMS endpoints
    55  
    56  	// DefaultKey is the key used when no explicit key ID
    57  	// is specified. It is empty if the KMS does not support
    58  	// a default key.
    59  	DefaultKey string
    60  }
    61  
    62  // DEK is a data encryption key. It consists of a
    63  // plaintext-ciphertext pair and the ID of the key
    64  // used to generate the ciphertext.
    65  //
    66  // The plaintext can be used for cryptographic
    67  // operations - like encrypting some data. The
    68  // ciphertext is the encrypted version of the
    69  // plaintext data and can be stored on untrusted
    70  // storage.
    71  type DEK struct {
    72  	KeyID      string
    73  	Plaintext  []byte
    74  	Ciphertext []byte
    75  }
    76  
    77  var (
    78  	_ encoding.TextMarshaler   = (*DEK)(nil)
    79  	_ encoding.TextUnmarshaler = (*DEK)(nil)
    80  )
    81  
    82  // MarshalText encodes the DEK's key ID and ciphertext
    83  // as JSON.
    84  func (d DEK) MarshalText() ([]byte, error) {
    85  	type JSON struct {
    86  		KeyID      string `json:"keyid"`
    87  		Ciphertext []byte `json:"ciphertext"`
    88  	}
    89  	return json.Marshal(JSON{
    90  		KeyID:      d.KeyID,
    91  		Ciphertext: d.Ciphertext,
    92  	})
    93  }
    94  
    95  // UnmarshalText tries to decode text as JSON representation
    96  // of a DEK and sets DEK's key ID and ciphertext to the
    97  // decoded values.
    98  //
    99  // It sets DEK's plaintext to nil.
   100  func (d *DEK) UnmarshalText(text []byte) error {
   101  	type JSON struct {
   102  		KeyID      string `json:"keyid"`
   103  		Ciphertext []byte `json:"ciphertext"`
   104  	}
   105  	var v JSON
   106  	if err := json.Unmarshal(text, &v); err != nil {
   107  		return err
   108  	}
   109  	d.KeyID, d.Plaintext, d.Ciphertext = v.KeyID, nil, v.Ciphertext
   110  	return nil
   111  }