| 
									
										
										
										
											2023-02-22 09:43:01 +08:00
										 |  |  | // Copyright (c) 2015-2023 MinIO, Inc.
 | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | //
 | 
					
						
							|  |  |  | // This file is part of MinIO Object Storage stack
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This program is free software: you can redistribute it and/or modify
 | 
					
						
							|  |  |  | // it under the terms of the GNU Affero General Public License as published by
 | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or
 | 
					
						
							|  |  |  | // (at your option) any later version.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This program is distributed in the hope that it will be useful
 | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					
						
							|  |  |  | // GNU Affero General Public License for more details.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // You should have received a copy of the GNU Affero General Public License
 | 
					
						
							|  |  |  | // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package cmd | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"crypto/subtle" | 
					
						
							|  |  |  | 	"encoding/json" | 
					
						
							| 
									
										
										
										
											2023-08-19 22:37:53 +08:00
										 |  |  | 	"io" | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | 	"net/http" | 
					
						
							| 
									
										
										
										
											2023-08-19 22:37:53 +08:00
										 |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | 	"time" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-14 23:19:20 +08:00
										 |  |  | 	"github.com/minio/kes-go" | 
					
						
							| 
									
										
										
										
											2023-06-20 08:53:08 +08:00
										 |  |  | 	"github.com/minio/madmin-go/v3" | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | 	"github.com/minio/minio/internal/kms" | 
					
						
							|  |  |  | 	"github.com/minio/minio/internal/logger" | 
					
						
							| 
									
										
										
										
											2023-09-15 05:50:16 +08:00
										 |  |  | 	"github.com/minio/pkg/v2/policy" | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // KMSStatusHandler - GET /minio/kms/v1/status
 | 
					
						
							|  |  |  | func (a kmsAPIHandlers) KMSStatusHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "KMSStatus") | 
					
						
							|  |  |  | 	defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r)) | 
					
						
							| 
									
										
										
										
											2023-09-15 05:50:16 +08:00
										 |  |  | 	objectAPI, _ := validateAdminReq(ctx, w, r, policy.KMSStatusAction) | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | 	if objectAPI == nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if GlobalKMS == nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrKMSNotConfigured), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	stat, err := GlobalKMS.Stat(ctx) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInternalError), err.Error(), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	status := madmin.KMSStatus{ | 
					
						
							|  |  |  | 		Name:         stat.Name, | 
					
						
							|  |  |  | 		DefaultKeyID: stat.DefaultKey, | 
					
						
							|  |  |  | 		Endpoints:    make(map[string]madmin.ItemState, len(stat.Endpoints)), | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for _, endpoint := range stat.Endpoints { | 
					
						
							|  |  |  | 		status.Endpoints[endpoint] = madmin.ItemOnline // TODO(aead): Implement an online check for mTLS
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	resp, err := json.Marshal(status) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInternalError), err.Error(), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	writeSuccessResponseJSON(w, resp) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-13 03:08:03 +08:00
										 |  |  | // KMSMetricsHandler - POST /minio/kms/v1/metrics
 | 
					
						
							|  |  |  | func (a kmsAPIHandlers) KMSMetricsHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "KMSMetrics") | 
					
						
							|  |  |  | 	defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-15 05:50:16 +08:00
										 |  |  | 	objectAPI, _ := validateAdminReq(ctx, w, r, policy.KMSMetricsAction) | 
					
						
							| 
									
										
										
										
											2022-10-13 03:08:03 +08:00
										 |  |  | 	if objectAPI == nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if GlobalKMS == nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrKMSNotConfigured), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-17 17:40:31 +08:00
										 |  |  | 	if _, ok := GlobalKMS.(kms.KeyManager); !ok { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-13 03:08:03 +08:00
										 |  |  | 	metrics, err := GlobalKMS.Metrics(ctx) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if res, err := json.Marshal(metrics); err != nil { | 
					
						
							|  |  |  | 		writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInternalError), err.Error(), r.URL) | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		writeSuccessResponseJSON(w, res) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // KMSAPIsHandler - POST /minio/kms/v1/apis
 | 
					
						
							|  |  |  | func (a kmsAPIHandlers) KMSAPIsHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "KMSAPIs") | 
					
						
							|  |  |  | 	defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-15 05:50:16 +08:00
										 |  |  | 	objectAPI, _ := validateAdminReq(ctx, w, r, policy.KMSAPIAction) | 
					
						
							| 
									
										
										
										
											2022-10-13 03:08:03 +08:00
										 |  |  | 	if objectAPI == nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if GlobalKMS == nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrKMSNotConfigured), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	manager, ok := GlobalKMS.(kms.StatusManager) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	apis, err := manager.APIs(ctx) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if res, err := json.Marshal(apis); err != nil { | 
					
						
							|  |  |  | 		writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInternalError), err.Error(), r.URL) | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		writeSuccessResponseJSON(w, res) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type versionResponse struct { | 
					
						
							|  |  |  | 	Version string `json:"version"` | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // KMSVersionHandler - POST /minio/kms/v1/version
 | 
					
						
							|  |  |  | func (a kmsAPIHandlers) KMSVersionHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "KMSVersion") | 
					
						
							|  |  |  | 	defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-15 05:50:16 +08:00
										 |  |  | 	objectAPI, _ := validateAdminReq(ctx, w, r, policy.KMSVersionAction) | 
					
						
							| 
									
										
										
										
											2022-10-13 03:08:03 +08:00
										 |  |  | 	if objectAPI == nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if GlobalKMS == nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrKMSNotConfigured), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	manager, ok := GlobalKMS.(kms.StatusManager) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	version, err := manager.Version(ctx) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	res := &versionResponse{Version: version} | 
					
						
							|  |  |  | 	v, err := json.Marshal(res) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInternalError), err.Error(), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	writeSuccessResponseJSON(w, v) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | // KMSCreateKeyHandler - POST /minio/kms/v1/key/create?key-id=<master-key-id>
 | 
					
						
							|  |  |  | func (a kmsAPIHandlers) KMSCreateKeyHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							| 
									
										
										
										
											2023-02-22 09:43:01 +08:00
										 |  |  | 	// If env variable MINIO_KMS_SECRET_KEY is populated, prevent creation of new keys
 | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | 	ctx := newContext(r, w, "KMSCreateKey") | 
					
						
							| 
									
										
										
										
											2023-02-22 09:43:01 +08:00
										 |  |  | 	if GlobalKMS != nil && GlobalKMS.IsLocal() { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrKMSDefaultKeyAlreadyConfigured), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | 	defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-15 05:50:16 +08:00
										 |  |  | 	objectAPI, _ := validateAdminReq(ctx, w, r, policy.KMSCreateKeyAction) | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | 	if objectAPI == nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if GlobalKMS == nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrKMSNotConfigured), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	manager, ok := GlobalKMS.(kms.KeyManager) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := manager.CreateKey(ctx, r.Form.Get("key-id")); err != nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	writeSuccessResponseHeadersOnly(w) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // KMSDeleteKeyHandler - DELETE /minio/kms/v1/key/delete?key-id=<master-key-id>
 | 
					
						
							|  |  |  | func (a kmsAPIHandlers) KMSDeleteKeyHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "KMSDeleteKey") | 
					
						
							|  |  |  | 	defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-15 05:50:16 +08:00
										 |  |  | 	objectAPI, _ := validateAdminReq(ctx, w, r, policy.KMSDeleteKeyAction) | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | 	if objectAPI == nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if GlobalKMS == nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrKMSNotConfigured), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	manager, ok := GlobalKMS.(kms.KeyManager) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err := manager.DeleteKey(ctx, r.Form.Get("key-id")); err != nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	writeSuccessResponseHeadersOnly(w) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // KMSListKeysHandler - GET /minio/kms/v1/key/list?pattern=<pattern>
 | 
					
						
							|  |  |  | func (a kmsAPIHandlers) KMSListKeysHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "KMSListKeys") | 
					
						
							| 
									
										
										
										
											2023-02-22 09:43:01 +08:00
										 |  |  | 	if GlobalKMS != nil && GlobalKMS.IsLocal() { | 
					
						
							|  |  |  | 		res, err := json.Marshal(GlobalKMS.List()) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInternalError), err.Error(), r.URL) | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		writeSuccessResponseJSON(w, res) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | 	defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-15 05:50:16 +08:00
										 |  |  | 	objectAPI, _ := validateAdminReq(ctx, w, r, policy.KMSListKeysAction) | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | 	if objectAPI == nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if GlobalKMS == nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrKMSNotConfigured), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	manager, ok := GlobalKMS.(kms.KeyManager) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							| 
									
										
										
										
											2023-02-22 09:43:01 +08:00
										 |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrKMSNotConfigured), r.URL) | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-08-19 22:37:53 +08:00
										 |  |  | 	keys, err := manager.ListKeys(ctx) | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-08-19 22:37:53 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	pattern := r.Form.Get("pattern") | 
					
						
							|  |  |  | 	if !strings.Contains(pattern, "*") { | 
					
						
							|  |  |  | 		pattern += "*" | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var values []kes.KeyInfo | 
					
						
							|  |  |  | 	for name, err := keys.SeekTo(ctx, pattern); err != io.EOF; name, err = keys.Next(ctx) { | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInternalError), err.Error(), r.URL) | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		values = append(values, kes.KeyInfo{ | 
					
						
							|  |  |  | 			Name: name, | 
					
						
							|  |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if res, err := json.Marshal(values); err != nil { | 
					
						
							|  |  |  | 		writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInternalError), err.Error(), r.URL) | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		writeSuccessResponseJSON(w, res) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type importKeyRequest struct { | 
					
						
							|  |  |  | 	Bytes string | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // KMSImportKeyHandler - POST /minio/kms/v1/key/import?key-id=<master-key-id>
 | 
					
						
							|  |  |  | func (a kmsAPIHandlers) KMSImportKeyHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "KMSImportKey") | 
					
						
							|  |  |  | 	defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-15 05:50:16 +08:00
										 |  |  | 	objectAPI, _ := validateAdminReq(ctx, w, r, policy.KMSImportKeyAction) | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | 	if objectAPI == nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if GlobalKMS == nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrKMSNotConfigured), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	manager, ok := GlobalKMS.(kms.KeyManager) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	var request importKeyRequest | 
					
						
							|  |  |  | 	if err := json.NewDecoder(r.Body).Decode(&request); err != nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err := manager.ImportKey(ctx, r.Form.Get("key-id"), []byte(request.Bytes)); err != nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	writeSuccessResponseHeadersOnly(w) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // KMSKeyStatusHandler - GET /minio/kms/v1/key/status?key-id=<master-key-id>
 | 
					
						
							|  |  |  | func (a kmsAPIHandlers) KMSKeyStatusHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "KMSKeyStatus") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r)) | 
					
						
							| 
									
										
										
										
											2023-09-15 05:50:16 +08:00
										 |  |  | 	objectAPI, _ := validateAdminReq(ctx, w, r, policy.KMSKeyStatusAction) | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | 	if objectAPI == nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if GlobalKMS == nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrKMSNotConfigured), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	stat, err := GlobalKMS.Stat(ctx) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInternalError), err.Error(), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	keyID := r.Form.Get("key-id") | 
					
						
							|  |  |  | 	if keyID == "" { | 
					
						
							|  |  |  | 		keyID = stat.DefaultKey | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	response := madmin.KMSKeyStatus{ | 
					
						
							|  |  |  | 		KeyID: keyID, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	kmsContext := kms.Context{"MinIO admin API": "KMSKeyStatusHandler"} // Context for a test key operation
 | 
					
						
							|  |  |  | 	// 1. Generate a new key using the KMS.
 | 
					
						
							|  |  |  | 	key, err := GlobalKMS.GenerateKey(ctx, keyID, kmsContext) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		response.EncryptionErr = err.Error() | 
					
						
							|  |  |  | 		resp, err := json.Marshal(response) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInternalError), err.Error(), r.URL) | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		writeSuccessResponseJSON(w, resp) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// 2. Verify that we can indeed decrypt the (encrypted) key
 | 
					
						
							|  |  |  | 	decryptedKey, err := GlobalKMS.DecryptKey(key.KeyID, key.Ciphertext, kmsContext) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		response.DecryptionErr = err.Error() | 
					
						
							|  |  |  | 		resp, err := json.Marshal(response) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInternalError), err.Error(), r.URL) | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		writeSuccessResponseJSON(w, resp) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// 3. Compare generated key with decrypted key
 | 
					
						
							|  |  |  | 	if subtle.ConstantTimeCompare(key.Plaintext, decryptedKey) != 1 { | 
					
						
							|  |  |  | 		response.DecryptionErr = "The generated and the decrypted data key do not match" | 
					
						
							|  |  |  | 		resp, err := json.Marshal(response) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInternalError), err.Error(), r.URL) | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		writeSuccessResponseJSON(w, resp) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	resp, err := json.Marshal(response) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInternalError), err.Error(), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	writeSuccessResponseJSON(w, resp) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // KMSDescribePolicyHandler - GET /minio/kms/v1/policy/describe?policy=<policy>
 | 
					
						
							|  |  |  | func (a kmsAPIHandlers) KMSDescribePolicyHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "KMSDescribePolicy") | 
					
						
							|  |  |  | 	defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-15 05:50:16 +08:00
										 |  |  | 	objectAPI, _ := validateAdminReq(ctx, w, r, policy.KMSDescribePolicyAction) | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | 	if objectAPI == nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if GlobalKMS == nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrKMSNotConfigured), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	manager, ok := GlobalKMS.(kms.PolicyManager) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	policy, err := manager.DescribePolicy(ctx, r.Form.Get("policy")) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	p, err := json.Marshal(policy) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInternalError), err.Error(), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	writeSuccessResponseJSON(w, p) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type assignPolicyRequest struct { | 
					
						
							|  |  |  | 	Identity string | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // KMSAssignPolicyHandler - POST /minio/kms/v1/policy/assign?policy=<policy>
 | 
					
						
							|  |  |  | func (a kmsAPIHandlers) KMSAssignPolicyHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "KMSAssignPolicy") | 
					
						
							|  |  |  | 	defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-15 05:50:16 +08:00
										 |  |  | 	objectAPI, _ := validateAdminReq(ctx, w, r, policy.KMSAssignPolicyAction) | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | 	if objectAPI == nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if GlobalKMS == nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrKMSNotConfigured), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	manager, ok := GlobalKMS.(kms.PolicyManager) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	var request assignPolicyRequest | 
					
						
							|  |  |  | 	if err := json.NewDecoder(r.Body).Decode(&request); err != nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	err := manager.AssignPolicy(ctx, r.Form.Get("policy"), request.Identity) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	writeSuccessResponseHeadersOnly(w) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // KMSDeletePolicyHandler - DELETE /minio/kms/v1/policy/delete?policy=<policy>
 | 
					
						
							|  |  |  | func (a kmsAPIHandlers) KMSDeletePolicyHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "KMSDeletePolicy") | 
					
						
							|  |  |  | 	defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-15 05:50:16 +08:00
										 |  |  | 	objectAPI, _ := validateAdminReq(ctx, w, r, policy.KMSDeletePolicyAction) | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | 	if objectAPI == nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if GlobalKMS == nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrKMSNotConfigured), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	manager, ok := GlobalKMS.(kms.PolicyManager) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err := manager.DeletePolicy(ctx, r.Form.Get("policy")); err != nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	writeSuccessResponseHeadersOnly(w) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // KMSListPoliciesHandler - GET /minio/kms/v1/policy/list?pattern=<pattern>
 | 
					
						
							|  |  |  | func (a kmsAPIHandlers) KMSListPoliciesHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "KMSListPolicies") | 
					
						
							|  |  |  | 	defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-15 05:50:16 +08:00
										 |  |  | 	objectAPI, _ := validateAdminReq(ctx, w, r, policy.KMSListPoliciesAction) | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | 	if objectAPI == nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if GlobalKMS == nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrKMSNotConfigured), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	manager, ok := GlobalKMS.(kms.PolicyManager) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-08-19 22:37:53 +08:00
										 |  |  | 	policies, err := manager.ListPolicies(ctx) | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-08-19 22:37:53 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	pattern := r.Form.Get("pattern") | 
					
						
							|  |  |  | 	if !strings.Contains(pattern, "*") { | 
					
						
							|  |  |  | 		pattern += "*" | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var values []kes.PolicyInfo | 
					
						
							|  |  |  | 	for name, err := policies.SeekTo(ctx, pattern); err != io.EOF; name, err = policies.Next(ctx) { | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInternalError), err.Error(), r.URL) | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		values = append(values, kes.PolicyInfo{ | 
					
						
							|  |  |  | 			Name: name, | 
					
						
							|  |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if res, err := json.Marshal(values); err != nil { | 
					
						
							|  |  |  | 		writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInternalError), err.Error(), r.URL) | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		writeSuccessResponseJSON(w, res) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // KMSGetPolicyHandler - GET /minio/kms/v1/policy/get?policy=<policy>
 | 
					
						
							|  |  |  | func (a kmsAPIHandlers) KMSGetPolicyHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "KMSGetPolicy") | 
					
						
							|  |  |  | 	defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-15 05:50:16 +08:00
										 |  |  | 	objectAPI, _ := validateAdminReq(ctx, w, r, policy.KMSGetPolicyAction) | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | 	if objectAPI == nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if GlobalKMS == nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrKMSNotConfigured), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	manager, ok := GlobalKMS.(kms.PolicyManager) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	policy, err := manager.GetPolicy(ctx, r.Form.Get("policy")) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if p, err := json.Marshal(policy); err != nil { | 
					
						
							|  |  |  | 		writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInternalError), err.Error(), r.URL) | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		writeSuccessResponseJSON(w, p) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // KMSDescribeIdentityHandler - GET /minio/kms/v1/identity/describe?identity=<identity>
 | 
					
						
							|  |  |  | func (a kmsAPIHandlers) KMSDescribeIdentityHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "KMSDescribeIdentity") | 
					
						
							|  |  |  | 	defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-15 05:50:16 +08:00
										 |  |  | 	objectAPI, _ := validateAdminReq(ctx, w, r, policy.KMSDescribeIdentityAction) | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | 	if objectAPI == nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if GlobalKMS == nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrKMSNotConfigured), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	manager, ok := GlobalKMS.(kms.IdentityManager) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	identity, err := manager.DescribeIdentity(ctx, r.Form.Get("identity")) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	i, err := json.Marshal(identity) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInternalError), err.Error(), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	writeSuccessResponseJSON(w, i) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type describeSelfIdentityResponse struct { | 
					
						
							|  |  |  | 	Policy     *kes.Policy `json:"policy"` | 
					
						
							|  |  |  | 	PolicyName string      `json:"policyName"` | 
					
						
							|  |  |  | 	Identity   string      `json:"identity"` | 
					
						
							|  |  |  | 	IsAdmin    bool        `json:"isAdmin"` | 
					
						
							|  |  |  | 	CreatedAt  time.Time   `json:"createdAt"` | 
					
						
							|  |  |  | 	CreatedBy  string      `json:"createdBy"` | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // KMSDescribeSelfIdentityHandler - GET /minio/kms/v1/identity/describe-self
 | 
					
						
							|  |  |  | func (a kmsAPIHandlers) KMSDescribeSelfIdentityHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "KMSDescribeSelfIdentity") | 
					
						
							|  |  |  | 	defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-15 05:50:16 +08:00
										 |  |  | 	objectAPI, _ := validateAdminReq(ctx, w, r, policy.KMSDescribeSelfIdentityAction) | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | 	if objectAPI == nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if GlobalKMS == nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrKMSNotConfigured), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	manager, ok := GlobalKMS.(kms.IdentityManager) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	identity, policy, err := manager.DescribeSelfIdentity(ctx) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	res := &describeSelfIdentityResponse{ | 
					
						
							|  |  |  | 		Policy:     policy, | 
					
						
							|  |  |  | 		PolicyName: identity.Policy, | 
					
						
							|  |  |  | 		Identity:   identity.Identity.String(), | 
					
						
							|  |  |  | 		IsAdmin:    identity.IsAdmin, | 
					
						
							|  |  |  | 		CreatedAt:  identity.CreatedAt, | 
					
						
							|  |  |  | 		CreatedBy:  identity.CreatedBy.String(), | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	i, err := json.Marshal(res) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInternalError), err.Error(), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	writeSuccessResponseJSON(w, i) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // KMSDeleteIdentityHandler - DELETE /minio/kms/v1/identity/delete?identity=<identity>
 | 
					
						
							|  |  |  | func (a kmsAPIHandlers) KMSDeleteIdentityHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "KMSDeleteIdentity") | 
					
						
							|  |  |  | 	defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-15 05:50:16 +08:00
										 |  |  | 	objectAPI, _ := validateAdminReq(ctx, w, r, policy.KMSDeleteIdentityAction) | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | 	if objectAPI == nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if GlobalKMS == nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrKMSNotConfigured), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	manager, ok := GlobalKMS.(kms.IdentityManager) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := manager.DeleteIdentity(ctx, r.Form.Get("policy")); err != nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	writeSuccessResponseHeadersOnly(w) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // KMSListIdentitiesHandler - GET /minio/kms/v1/identity/list?pattern=<pattern>
 | 
					
						
							|  |  |  | func (a kmsAPIHandlers) KMSListIdentitiesHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "KMSListIdentities") | 
					
						
							|  |  |  | 	defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-15 05:50:16 +08:00
										 |  |  | 	objectAPI, _ := validateAdminReq(ctx, w, r, policy.KMSListIdentitiesAction) | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | 	if objectAPI == nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if GlobalKMS == nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrKMSNotConfigured), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	manager, ok := GlobalKMS.(kms.IdentityManager) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-08-19 22:37:53 +08:00
										 |  |  | 	identities, err := manager.ListIdentities(ctx) | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-08-19 22:37:53 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	pattern := r.Form.Get("pattern") | 
					
						
							|  |  |  | 	if !strings.Contains(pattern, "*") { | 
					
						
							|  |  |  | 		pattern += "*" | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var values []kes.IdentityInfo | 
					
						
							|  |  |  | 	for name, err := identities.SeekTo(ctx, pattern); err != io.EOF; name, err = identities.Next(ctx) { | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInternalError), err.Error(), r.URL) | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		values = append(values, kes.IdentityInfo{ | 
					
						
							|  |  |  | 			Identity: name, | 
					
						
							|  |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2022-10-05 01:05:09 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if res, err := json.Marshal(values); err != nil { | 
					
						
							|  |  |  | 		writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInternalError), err.Error(), r.URL) | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		writeSuccessResponseJSON(w, res) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |