| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | // MinIO Cloud Storage, (C) 2017-2019 MinIO, Inc.
 | 
					
						
							| 
									
										
										
										
											2018-08-18 03:52:14 +08:00
										 |  |  | //
 | 
					
						
							|  |  |  | // Licensed under the Apache License, Version 2.0 (the "License");
 | 
					
						
							|  |  |  | // you may not use this file except in compliance with the License.
 | 
					
						
							|  |  |  | // You may obtain a copy of the License at
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //    http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Unless required by applicable law or agreed to in writing, software
 | 
					
						
							|  |  |  | // distributed under the License is distributed on an "AS IS" BASIS,
 | 
					
						
							|  |  |  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					
						
							|  |  |  | // See the License for the specific language governing permissions and
 | 
					
						
							|  |  |  | // limitations under the License.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package crypto | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | import ( | 
					
						
							|  |  |  | 	"errors" | 
					
						
							| 
									
										
										
										
											2019-12-19 07:10:57 +08:00
										 |  |  | 	"net/http" | 
					
						
							| 
									
										
										
										
											2019-11-10 01:27:23 +08:00
										 |  |  | 	"reflect" | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | 	"strconv" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	"github.com/minio/minio/cmd/config" | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | 	"github.com/minio/minio/pkg/env" | 
					
						
							| 
									
										
										
										
											2019-10-31 14:39:09 +08:00
										 |  |  | 	xnet "github.com/minio/minio/pkg/net" | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | // KMSConfig has the KMS config for hashicorp vault
 | 
					
						
							|  |  |  | type KMSConfig struct { | 
					
						
							|  |  |  | 	AutoEncryption bool        `json:"-"` | 
					
						
							|  |  |  | 	Vault          VaultConfig `json:"vault"` | 
					
						
							| 
									
										
										
										
											2019-12-14 04:57:11 +08:00
										 |  |  | 	Kes            KesConfig   `json:"kes"` | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // KMS Vault constants.
 | 
					
						
							|  |  |  | const ( | 
					
						
							|  |  |  | 	KMSVaultEndpoint      = "endpoint" | 
					
						
							|  |  |  | 	KMSVaultCAPath        = "capath" | 
					
						
							|  |  |  | 	KMSVaultKeyName       = "key_name" | 
					
						
							|  |  |  | 	KMSVaultKeyVersion    = "key_version" | 
					
						
							|  |  |  | 	KMSVaultNamespace     = "namespace" | 
					
						
							|  |  |  | 	KMSVaultAuthType      = "auth_type" | 
					
						
							|  |  |  | 	KMSVaultAppRoleID     = "auth_approle_id" | 
					
						
							|  |  |  | 	KMSVaultAppRoleSecret = "auth_approle_secret" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-14 04:57:11 +08:00
										 |  |  | // KMS kes constants.
 | 
					
						
							|  |  |  | const ( | 
					
						
							|  |  |  | 	KMSKesEndpoint = "endpoint" | 
					
						
							|  |  |  | 	KMSKesKeyFile  = "key_file" | 
					
						
							|  |  |  | 	KMSKesCertFile = "cert_file" | 
					
						
							|  |  |  | 	KMSKesCAPath   = "capath" | 
					
						
							|  |  |  | 	KMSKesKeyName  = "key_name" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | // DefaultKVS - default KV crypto config
 | 
					
						
							|  |  |  | var ( | 
					
						
							| 
									
										
										
										
											2019-12-14 04:57:11 +08:00
										 |  |  | 	DefaultVaultKVS = config.KVS{ | 
					
						
							| 
									
										
										
										
											2019-11-21 07:10:24 +08:00
										 |  |  | 		config.KV{ | 
					
						
							|  |  |  | 			Key:   KMSVaultEndpoint, | 
					
						
							|  |  |  | 			Value: "", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		config.KV{ | 
					
						
							|  |  |  | 			Key:   KMSVaultKeyName, | 
					
						
							|  |  |  | 			Value: "", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		config.KV{ | 
					
						
							|  |  |  | 			Key:   KMSVaultAuthType, | 
					
						
							|  |  |  | 			Value: "approle", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		config.KV{ | 
					
						
							|  |  |  | 			Key:   KMSVaultAppRoleID, | 
					
						
							|  |  |  | 			Value: "", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		config.KV{ | 
					
						
							|  |  |  | 			Key:   KMSVaultAppRoleSecret, | 
					
						
							|  |  |  | 			Value: "", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		config.KV{ | 
					
						
							|  |  |  | 			Key:   KMSVaultCAPath, | 
					
						
							|  |  |  | 			Value: "", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		config.KV{ | 
					
						
							|  |  |  | 			Key:   KMSVaultKeyVersion, | 
					
						
							|  |  |  | 			Value: "", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		config.KV{ | 
					
						
							|  |  |  | 			Key:   KMSVaultNamespace, | 
					
						
							|  |  |  | 			Value: "", | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-12-14 04:57:11 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	DefaultKesKVS = config.KVS{ | 
					
						
							|  |  |  | 		config.KV{ | 
					
						
							|  |  |  | 			Key:   KMSKesEndpoint, | 
					
						
							|  |  |  | 			Value: "", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		config.KV{ | 
					
						
							|  |  |  | 			Key:   KMSKesKeyName, | 
					
						
							|  |  |  | 			Value: "", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		config.KV{ | 
					
						
							|  |  |  | 			Key:   KMSKesCertFile, | 
					
						
							|  |  |  | 			Value: "", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		config.KV{ | 
					
						
							|  |  |  | 			Key:   KMSKesKeyFile, | 
					
						
							|  |  |  | 			Value: "", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		config.KV{ | 
					
						
							|  |  |  | 			Key:   KMSKesCAPath, | 
					
						
							|  |  |  | 			Value: "", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | const ( | 
					
						
							|  |  |  | 	// EnvKMSMasterKey is the environment variable used to specify
 | 
					
						
							|  |  |  | 	// a KMS master key used to protect SSE-S3 per-object keys.
 | 
					
						
							|  |  |  | 	// Valid values must be of the from: "KEY_ID:32_BYTE_HEX_VALUE".
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	EnvKMSMasterKey = "MINIO_KMS_MASTER_KEY" | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	// EnvKMSAutoEncryption is the environment variable used to en/disable
 | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | 	// SSE-S3 auto-encryption. SSE-S3 auto-encryption, if enabled,
 | 
					
						
							|  |  |  | 	// requires a valid KMS configuration and turns any non-SSE-C
 | 
					
						
							|  |  |  | 	// request into an SSE-S3 request.
 | 
					
						
							|  |  |  | 	// If present EnvAutoEncryption must be either "on" or "off".
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	EnvKMSAutoEncryption = "MINIO_KMS_AUTO_ENCRYPTION" | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const ( | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	// EnvKMSVaultEndpoint is the environment variable used to specify
 | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | 	// the vault HTTPS endpoint.
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	EnvKMSVaultEndpoint = "MINIO_KMS_VAULT_ENDPOINT" | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	// EnvKMSVaultAuthType is the environment variable used to specify
 | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | 	// the authentication type for vault.
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	EnvKMSVaultAuthType = "MINIO_KMS_VAULT_AUTH_TYPE" | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	// EnvKMSVaultAppRoleID is the environment variable used to specify
 | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | 	// the vault AppRole ID.
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	EnvKMSVaultAppRoleID = "MINIO_KMS_VAULT_APPROLE_ID" | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	// EnvKMSVaultAppSecretID is the environment variable used to specify
 | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | 	// the vault AppRole secret corresponding to the AppRole ID.
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	EnvKMSVaultAppSecretID = "MINIO_KMS_VAULT_APPROLE_SECRET" | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	// EnvKMSVaultKeyVersion is the environment variable used to specify
 | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | 	// the vault key version.
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	EnvKMSVaultKeyVersion = "MINIO_KMS_VAULT_KEY_VERSION" | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	// EnvKMSVaultKeyName is the environment variable used to specify
 | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | 	// the vault named key-ring. In the S3 context it's referred as
 | 
					
						
							|  |  |  | 	// customer master key ID (CMK-ID).
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	EnvKMSVaultKeyName = "MINIO_KMS_VAULT_KEY_NAME" | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	// EnvKMSVaultCAPath is the environment variable used to specify the
 | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | 	// path to a directory of PEM-encoded CA cert files. These CA cert
 | 
					
						
							|  |  |  | 	// files are used to authenticate MinIO to Vault over mTLS.
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	EnvKMSVaultCAPath = "MINIO_KMS_VAULT_CAPATH" | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	// EnvKMSVaultNamespace is the environment variable used to specify
 | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | 	// vault namespace. The vault namespace is used if the enterprise
 | 
					
						
							|  |  |  | 	// version of Hashicorp Vault is used.
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	EnvKMSVaultNamespace = "MINIO_KMS_VAULT_NAMESPACE" | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-14 04:57:11 +08:00
										 |  |  | const ( | 
					
						
							|  |  |  | 	// EnvKMSKesEndpoint is the environment variable used to specify
 | 
					
						
							|  |  |  | 	// the kes server HTTPS endpoint.
 | 
					
						
							|  |  |  | 	EnvKMSKesEndpoint = "MINIO_KMS_KES_ENDPOINT" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// EnvKMSKesKeyFile is the environment variable used to specify
 | 
					
						
							|  |  |  | 	// the TLS private key used by MinIO to authenticate to the kes
 | 
					
						
							|  |  |  | 	// server HTTPS via mTLS.
 | 
					
						
							|  |  |  | 	EnvKMSKesKeyFile = "MINIO_KMS_KES_KEY_FILE" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// EnvKMSKesCertFile is the environment variable used to specify
 | 
					
						
							|  |  |  | 	// the TLS certificate used by MinIO to authenticate to the kes
 | 
					
						
							|  |  |  | 	// server HTTPS via mTLS.
 | 
					
						
							|  |  |  | 	EnvKMSKesCertFile = "MINIO_KMS_KES_CERT_FILE" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// EnvKMSKesCAPath is the environment variable used to specify
 | 
					
						
							|  |  |  | 	// the TLS root certificates used by MinIO to verify the certificate
 | 
					
						
							|  |  |  | 	// presented by to the kes server when establishing a TLS connection.
 | 
					
						
							|  |  |  | 	EnvKMSKesCAPath = "MINIO_KMS_KES_CA_PATH" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// EnvKMSKesKeyName is the environment variable used to specify
 | 
					
						
							|  |  |  | 	// the (default) key at the kes server. In the S3 context it's
 | 
					
						
							|  |  |  | 	// referred as customer master key ID (CMK-ID).
 | 
					
						
							|  |  |  | 	EnvKMSKesKeyName = "MINIO_KMS_KES_KEY_NAME" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var defaultVaultCfg = VaultConfig{ | 
					
						
							| 
									
										
										
										
											2019-11-10 01:27:23 +08:00
										 |  |  | 	Auth: VaultAuth{ | 
					
						
							|  |  |  | 		Type: "approle", | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-14 04:57:11 +08:00
										 |  |  | var defaultKesCfg = KesConfig{} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // EnabledVault returns true if HashiCorp Vault is enabled.
 | 
					
						
							|  |  |  | func EnabledVault(kvs config.KVS) bool { | 
					
						
							| 
									
										
										
										
											2019-12-05 07:32:37 +08:00
										 |  |  | 	endpoint := kvs.Get(KMSVaultEndpoint) | 
					
						
							|  |  |  | 	return endpoint != "" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-14 04:57:11 +08:00
										 |  |  | // EnabledKes returns true if kes as KMS is enabled.
 | 
					
						
							|  |  |  | func EnabledKes(kvs config.KVS) bool { | 
					
						
							|  |  |  | 	endpoint := kvs.Get(KMSKesEndpoint) | 
					
						
							|  |  |  | 	return endpoint != "" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // LookupKesConfig lookup kes server configuration.
 | 
					
						
							|  |  |  | func LookupKesConfig(kvs config.KVS) (KesConfig, error) { | 
					
						
							|  |  |  | 	kesCfg := KesConfig{} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	endpointStr := env.Get(EnvKMSKesEndpoint, kvs.Get(KMSKesEndpoint)) | 
					
						
							|  |  |  | 	if endpointStr != "" { | 
					
						
							|  |  |  | 		// Lookup kes configuration & overwrite config entry if ENV var is present
 | 
					
						
							|  |  |  | 		endpoint, err := xnet.ParseHTTPURL(endpointStr) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return kesCfg, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		endpointStr = endpoint.String() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	kesCfg.Endpoint = endpointStr | 
					
						
							|  |  |  | 	kesCfg.KeyFile = env.Get(EnvKMSKesKeyFile, kvs.Get(KMSKesKeyFile)) | 
					
						
							|  |  |  | 	kesCfg.CertFile = env.Get(EnvKMSKesCertFile, kvs.Get(KMSKesCertFile)) | 
					
						
							|  |  |  | 	kesCfg.CAPath = env.Get(EnvKMSKesCAPath, kvs.Get(KMSKesCAPath)) | 
					
						
							|  |  |  | 	kesCfg.DefaultKeyID = env.Get(EnvKMSKesKeyName, kvs.Get(KMSKesKeyName)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if reflect.DeepEqual(kesCfg, defaultKesCfg) { | 
					
						
							|  |  |  | 		return kesCfg, nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Verify all the proper settings.
 | 
					
						
							|  |  |  | 	if err := kesCfg.Verify(); err != nil { | 
					
						
							|  |  |  | 		return kesCfg, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	kesCfg.Enabled = true | 
					
						
							|  |  |  | 	return kesCfg, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func lookupAutoEncryption() (bool, error) { | 
					
						
							|  |  |  | 	autoBool, err := config.ParseBool(env.Get(EnvAutoEncryptionLegacy, config.EnableOff)) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return false, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if !autoBool { | 
					
						
							|  |  |  | 		autoBool, err = config.ParseBool(env.Get(EnvKMSAutoEncryption, config.EnableOff)) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return false, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return autoBool, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // LookupConfig lookup vault or kes config, returns KMSConfig
 | 
					
						
							|  |  |  | // to configure KMS object for object encryption
 | 
					
						
							| 
									
										
										
										
											2019-12-19 07:10:57 +08:00
										 |  |  | func LookupConfig(c config.Config, defaultRootCAsDir string, transport *http.Transport) (KMSConfig, error) { | 
					
						
							| 
									
										
										
										
											2019-12-14 04:57:11 +08:00
										 |  |  | 	vcfg, err := LookupVaultConfig(c[config.KmsVaultSubSys][config.Default]) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return KMSConfig{}, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	kesCfg, err := LookupKesConfig(c[config.KmsKesSubSys][config.Default]) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return KMSConfig{}, err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-12-19 07:10:57 +08:00
										 |  |  | 	kesCfg.Transport = transport | 
					
						
							| 
									
										
										
										
											2019-12-14 04:57:11 +08:00
										 |  |  | 	if kesCfg.Enabled && kesCfg.CAPath == "" { | 
					
						
							|  |  |  | 		kesCfg.CAPath = defaultRootCAsDir | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	autoEncrypt, err := lookupAutoEncryption() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return KMSConfig{}, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	kmsCfg := KMSConfig{ | 
					
						
							|  |  |  | 		AutoEncryption: autoEncrypt, | 
					
						
							|  |  |  | 		Vault:          vcfg, | 
					
						
							|  |  |  | 		Kes:            kesCfg, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return kmsCfg, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // LookupVaultConfig extracts the KMS configuration provided by environment
 | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | // variables and merge them with the provided KMS configuration. The
 | 
					
						
							|  |  |  | // merging follows the following rules:
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // 1. A valid value provided as environment variable is higher prioritized
 | 
					
						
							|  |  |  | // than the provided configuration and overwrites the value from the
 | 
					
						
							|  |  |  | // configuration file.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // 2. A value specified as environment variable never changes the configuration
 | 
					
						
							|  |  |  | // file. So it is never made a persistent setting.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // It sets the global KMS configuration according to the merged configuration
 | 
					
						
							|  |  |  | // on succes.
 | 
					
						
							| 
									
										
										
										
											2019-12-14 04:57:11 +08:00
										 |  |  | func LookupVaultConfig(kvs config.KVS) (VaultConfig, error) { | 
					
						
							|  |  |  | 	if err := config.CheckValidKeys(config.KmsVaultSubSys, kvs, DefaultVaultKVS); err != nil { | 
					
						
							|  |  |  | 		return VaultConfig{}, err | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-12-14 04:57:11 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	vcfg, err := lookupConfigLegacy(kvs) | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2019-12-14 04:57:11 +08:00
										 |  |  | 		return vcfg, err | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-12-14 04:57:11 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if vcfg.Enabled { | 
					
						
							|  |  |  | 		return vcfg, nil | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-11-14 09:38:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-14 04:57:11 +08:00
										 |  |  | 	vcfg = VaultConfig{ | 
					
						
							| 
									
										
										
										
											2019-10-31 14:39:09 +08:00
										 |  |  | 		Auth: VaultAuth{ | 
					
						
							|  |  |  | 			Type: "approle", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-12-14 04:57:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 14:39:09 +08:00
										 |  |  | 	endpointStr := env.Get(EnvKMSVaultEndpoint, kvs.Get(KMSVaultEndpoint)) | 
					
						
							|  |  |  | 	if endpointStr != "" { | 
					
						
							|  |  |  | 		// Lookup Hashicorp-Vault configuration & overwrite config entry if ENV var is present
 | 
					
						
							|  |  |  | 		endpoint, err := xnet.ParseHTTPURL(endpointStr) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2019-12-14 04:57:11 +08:00
										 |  |  | 			return vcfg, err | 
					
						
							| 
									
										
										
										
											2019-10-31 14:39:09 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		endpointStr = endpoint.String() | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-12-14 04:57:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 14:39:09 +08:00
										 |  |  | 	vcfg.Endpoint = endpointStr | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	vcfg.CAPath = env.Get(EnvKMSVaultCAPath, kvs.Get(KMSVaultCAPath)) | 
					
						
							|  |  |  | 	vcfg.Auth.Type = env.Get(EnvKMSVaultAuthType, kvs.Get(KMSVaultAuthType)) | 
					
						
							| 
									
										
										
										
											2019-11-10 01:27:23 +08:00
										 |  |  | 	if vcfg.Auth.Type == "" { | 
					
						
							|  |  |  | 		vcfg.Auth.Type = "approle" | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-12-14 04:57:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	vcfg.Auth.AppRole.ID = env.Get(EnvKMSVaultAppRoleID, kvs.Get(KMSVaultAppRoleID)) | 
					
						
							|  |  |  | 	vcfg.Auth.AppRole.Secret = env.Get(EnvKMSVaultAppSecretID, kvs.Get(KMSVaultAppRoleSecret)) | 
					
						
							|  |  |  | 	vcfg.Key.Name = env.Get(EnvKMSVaultKeyName, kvs.Get(KMSVaultKeyName)) | 
					
						
							|  |  |  | 	vcfg.Namespace = env.Get(EnvKMSVaultNamespace, kvs.Get(KMSVaultNamespace)) | 
					
						
							| 
									
										
										
										
											2019-11-10 01:27:23 +08:00
										 |  |  | 	if keyVersion := env.Get(EnvKMSVaultKeyVersion, kvs.Get(KMSVaultKeyVersion)); keyVersion != "" { | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 		vcfg.Key.Version, err = strconv.Atoi(keyVersion) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2020-01-07 08:15:22 +08:00
										 |  |  | 			return vcfg, Errorf("Unable to parse VaultKeyVersion value (`%s`)", keyVersion) | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-14 04:57:11 +08:00
										 |  |  | 	if reflect.DeepEqual(vcfg, defaultVaultCfg) { | 
					
						
							|  |  |  | 		return vcfg, nil | 
					
						
							| 
									
										
										
										
											2019-11-10 01:27:23 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Verify all the proper settings.
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	if err = vcfg.Verify(); err != nil { | 
					
						
							| 
									
										
										
										
											2019-12-14 04:57:11 +08:00
										 |  |  | 		return vcfg, err | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-10 01:27:23 +08:00
										 |  |  | 	vcfg.Enabled = true | 
					
						
							| 
									
										
										
										
											2019-12-14 04:57:11 +08:00
										 |  |  | 	return vcfg, nil | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // NewKMS - initialize a new KMS.
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | func NewKMS(cfg KMSConfig) (kms KMS, err error) { | 
					
						
							| 
									
										
										
										
											2019-12-14 04:57:11 +08:00
										 |  |  | 	// Lookup KMS master kes - only available through ENV.
 | 
					
						
							| 
									
										
										
										
											2019-10-31 14:39:09 +08:00
										 |  |  | 	if masterKeyLegacy := env.Get(EnvKMSMasterKeyLegacy, ""); len(masterKeyLegacy) != 0 { | 
					
						
							| 
									
										
										
										
											2019-11-10 01:27:23 +08:00
										 |  |  | 		if cfg.Vault.Enabled { // Vault and KMS master key provided
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 			return kms, errors.New("Ambiguous KMS configuration: vault configuration and a master key are provided at the same time") | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-12-14 04:57:11 +08:00
										 |  |  | 		if cfg.Kes.Enabled { | 
					
						
							|  |  |  | 			return kms, errors.New("Ambiguous KMS configuration: kes configuration and a master key are provided at the same time") | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 		kms, err = ParseMasterKey(masterKeyLegacy) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return kms, err | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-10-31 14:39:09 +08:00
										 |  |  | 	} else if masterKey := env.Get(EnvKMSMasterKey, ""); len(masterKey) != 0 { | 
					
						
							| 
									
										
										
										
											2019-11-10 01:27:23 +08:00
										 |  |  | 		if cfg.Vault.Enabled { // Vault and KMS master key provided
 | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | 			return kms, errors.New("Ambiguous KMS configuration: vault configuration and a master key are provided at the same time") | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-12-14 04:57:11 +08:00
										 |  |  | 		if cfg.Kes.Enabled { | 
					
						
							|  |  |  | 			return kms, errors.New("Ambiguous KMS configuration: kes configuration and a master key are provided at the same time") | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | 		kms, err = ParseMasterKey(masterKey) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return kms, err | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-12-14 04:57:11 +08:00
										 |  |  | 	} else if cfg.Vault.Enabled && cfg.Kes.Enabled { | 
					
						
							|  |  |  | 		return kms, errors.New("Ambiguous KMS configuration: vault configuration and kes configuration are provided at the same time") | 
					
						
							| 
									
										
										
										
											2019-11-10 01:27:23 +08:00
										 |  |  | 	} else if cfg.Vault.Enabled { | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 		kms, err = NewVault(cfg.Vault) | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return kms, err | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-12-14 04:57:11 +08:00
										 |  |  | 	} else if cfg.Kes.Enabled { | 
					
						
							|  |  |  | 		kms, err = NewKes(cfg.Kes) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return kms, err | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	if cfg.AutoEncryption && kms == nil { | 
					
						
							| 
									
										
										
										
											2019-10-08 13:47:56 +08:00
										 |  |  | 		return kms, errors.New("Invalid KMS configuration: auto-encryption is enabled but no valid KMS configuration is present") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return kms, nil | 
					
						
							|  |  |  | } |