diff --git a/internal/kms/kes.go b/internal/kms/kes.go index 1d2cb548a4ceb6..f97021f25211f8 100644 --- a/internal/kms/kes.go +++ b/internal/kms/kes.go @@ -159,7 +159,7 @@ func (c *kesClient) keepKeyInCache() { case <-ctx.Done(): return } - _ = c.Verify(ctx) + _ = c.ValidateKey(ctx) } } @@ -472,3 +472,45 @@ func (c *kesClient) Verify(ctx context.Context) []VerifyResult { } return results } + +// ValidateKey checks the validity of the KMS Master Key +func (c *kesClient) ValidateKey(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. 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} + key, err := client.GenerateKey(ctx, env.Get(EnvKESKeyName, ""), kmsCtx) + if err != nil { + result.Encrypt = fmt.Sprintf("Encryption failed: %v", err) + } else { + result.Encrypt = "success" + } + // 2. 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" + } + fmt.Println(result.Endpoint, result.Status, result.Encrypt, result.Decrypt) + results = append(results, result) + } + return results +}