github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/internal/kms/kms.go (about) 1 // Copyright (c) 2015-2021 MinIO, Inc. 2 // 3 // This file is part of MinIO Object Storage stack 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package kms 19 20 import ( 21 "context" 22 "encoding" 23 "encoding/json" 24 25 jsoniter "github.com/json-iterator/go" 26 "github.com/minio/kms-go/kes" 27 ) 28 29 // KMS is the generic interface that abstracts over 30 // different KMS implementations. 31 type KMS interface { 32 // Stat returns the current KMS status. 33 Stat(cxt context.Context) (Status, error) 34 35 // IsLocal returns true if the KMS is a local implementation 36 IsLocal() bool 37 38 // List returns an array of local KMS Names 39 List() []kes.KeyInfo 40 41 // Metrics returns a KMS metric snapshot. 42 Metrics(ctx context.Context) (kes.Metric, error) 43 44 // CreateKey creates a new key at the KMS with the given key ID. 45 CreateKey(ctx context.Context, keyID string) error 46 47 // GenerateKey generates a new data encryption key using the 48 // key referenced by the key ID. 49 // 50 // The KMS may use a default key if the key ID is empty. 51 // GenerateKey returns an error if the referenced key does 52 // not exist. 53 // 54 // The context is associated and tied to the generated DEK. 55 // The same context must be provided when the generated key 56 // should be decrypted. Therefore, it is the callers 57 // responsibility to remember the corresponding context for 58 // a particular DEK. The context may be nil. 59 GenerateKey(ctx context.Context, keyID string, context Context) (DEK, error) 60 61 // DecryptKey decrypts the ciphertext with the key referenced 62 // by the key ID. The context must match the context value 63 // used to generate the ciphertext. 64 DecryptKey(keyID string, ciphertext []byte, context Context) ([]byte, error) 65 66 // DecryptAll decrypts all ciphertexts with the key referenced 67 // by the key ID. The contexts must match the context value 68 // used to generate the ciphertexts. 69 DecryptAll(ctx context.Context, keyID string, ciphertext [][]byte, context []Context) ([][]byte, error) 70 71 // Verify verifies all KMS endpoints and returns the details 72 Verify(cxt context.Context) []VerifyResult 73 } 74 75 // VerifyResult describes the verification result details a KMS endpoint 76 type VerifyResult struct { 77 Endpoint string 78 Decrypt string 79 Encrypt string 80 Version string 81 Status string 82 } 83 84 // Status describes the current state of a KMS. 85 type Status struct { 86 Name string // The name of the KMS 87 Endpoints []string // A set of the KMS endpoints 88 89 // DefaultKey is the key used when no explicit key ID 90 // is specified. It is empty if the KMS does not support 91 // a default key. 92 DefaultKey string 93 94 // Details provides more details about the KMS endpoint status. 95 // including uptime, version and available CPUs. 96 // Could be more in future. 97 Details kes.State 98 } 99 100 // DEK is a data encryption key. It consists of a 101 // plaintext-ciphertext pair and the ID of the key 102 // used to generate the ciphertext. 103 // 104 // The plaintext can be used for cryptographic 105 // operations - like encrypting some data. The 106 // ciphertext is the encrypted version of the 107 // plaintext data and can be stored on untrusted 108 // storage. 109 type DEK struct { 110 KeyID string 111 Plaintext []byte 112 Ciphertext []byte 113 } 114 115 var ( 116 _ encoding.TextMarshaler = (*DEK)(nil) 117 _ encoding.TextUnmarshaler = (*DEK)(nil) 118 ) 119 120 // MarshalText encodes the DEK's key ID and ciphertext 121 // as JSON. 122 func (d DEK) MarshalText() ([]byte, error) { 123 type JSON struct { 124 KeyID string `json:"keyid"` 125 Ciphertext []byte `json:"ciphertext"` 126 } 127 return json.Marshal(JSON{ 128 KeyID: d.KeyID, 129 Ciphertext: d.Ciphertext, 130 }) 131 } 132 133 // UnmarshalText tries to decode text as JSON representation 134 // of a DEK and sets DEK's key ID and ciphertext to the 135 // decoded values. 136 // 137 // It sets DEK's plaintext to nil. 138 func (d *DEK) UnmarshalText(text []byte) error { 139 type JSON struct { 140 KeyID string `json:"keyid"` 141 Ciphertext []byte `json:"ciphertext"` 142 } 143 var v JSON 144 json := jsoniter.ConfigCompatibleWithStandardLibrary 145 if err := json.Unmarshal(text, &v); err != nil { 146 return err 147 } 148 d.KeyID, d.Plaintext, d.Ciphertext = v.KeyID, nil, v.Ciphertext 149 return nil 150 }