Added endpoint and versions attributes to KMS details (#17350)

Now it would list details of all KMS instances with additional
attributes `endpoint` and `version`. In the case of k8s-based
deployment the list would consist of a single entry.

Signed-off-by: Shubhendu Ram Tripathi <shubhendu@minio.io>
This commit is contained in:
Shubhendu
2023-07-13 12:20:38 +05:30
committed by GitHub
parent f80b6926d3
commit 9b9871cfbb
6 changed files with 96 additions and 6 deletions

View File

@@ -20,9 +20,11 @@ package kms
import (
"bytes"
"context"
"crypto/subtle"
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"strings"
"sync"
@@ -467,3 +469,51 @@ func (c *kesClient) ListIdentities(ctx context.Context, pattern string) (*kes.Id
return c.enclave.ListIdentities(ctx, pattern)
}
// Verify verifies all KMS endpoints and returns details
func (c *kesClient) Verify(ctx context.Context) []VerifyResult {
c.lock.RLock()
defer c.lock.RUnlock()
results := []VerifyResult{}
kmsContext := Context{"MinIO admin API": "ServerInfoHandler"} // Context for a test key operation
for _, endpoint := range c.client.Endpoints {
client := kes.Client{
Endpoints: []string{endpoint},
HTTPClient: c.client.HTTPClient,
}
// 1. Get stats for the KES instance
state, err := client.Status(ctx)
if err != nil {
results = append(results, VerifyResult{Status: "offline", Endpoint: endpoint})
continue
}
// 2. Generate a new key using the KMS.
kmsCtx, err := kmsContext.MarshalText()
if err != nil {
results = append(results, VerifyResult{Status: "offline", Endpoint: endpoint})
continue
}
result := VerifyResult{Status: "online", Endpoint: endpoint, Version: state.Version}
key, err := client.GenerateKey(ctx, env.Get(EnvKESKeyName, ""), kmsCtx)
if err != nil {
result.Encrypt = fmt.Sprintf("Encryption failed: %v", err)
} else {
result.Encrypt = "success"
}
// 3. Verify that we can indeed decrypt the (encrypted) key
decryptedKey, err := client.Decrypt(ctx, env.Get(EnvKESKeyName, ""), key.Ciphertext, kmsCtx)
switch {
case err != nil:
result.Decrypt = fmt.Sprintf("Decryption failed: %v", err)
case subtle.ConstantTimeCompare(key.Plaintext, decryptedKey) != 1:
result.Decrypt = "Decryption failed: decrypted key does not match generated key"
default:
result.Decrypt = "success"
}
results = append(results, result)
}
return results
}

View File

@@ -67,6 +67,18 @@ type KMS interface {
// by the key ID. The contexts must match the context value
// used to generate the ciphertexts.
DecryptAll(ctx context.Context, keyID string, ciphertext [][]byte, context []Context) ([][]byte, error)
// Verify verifies all KMS endpoints and returns the details
Verify(cxt context.Context) []VerifyResult
}
// VerifyResult describes the verification result details a KMS endpoint
type VerifyResult struct {
Endpoint string
Decrypt string
Encrypt string
Version string
Status string
}
// Status describes the current state of a KMS.

View File

@@ -303,6 +303,13 @@ func (kms secretKey) DecryptAll(_ context.Context, keyID string, ciphertexts [][
return plaintexts, nil
}
// Verify verifies all KMS endpoints and returns details
func (kms secretKey) Verify(cxt context.Context) []VerifyResult {
return []VerifyResult{
{Endpoint: "self"},
}
}
type encryptedKey struct {
Algorithm string `json:"aead"`
IV []byte `json:"iv"`