github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/internal/crypto/metadata.go (about) 1 // Copyright (c) 2015-2021 MinIO, Inc. 2 // 3 // This file is part of MinIO Object Storage stack 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package crypto 19 20 import ( 21 xhttp "github.com/minio/minio/internal/http" 22 ) 23 24 const ( 25 // MetaMultipart indicates that the object has been uploaded 26 // in multiple parts - via the S3 multipart API. 27 MetaMultipart = "X-Minio-Internal-Encrypted-Multipart" 28 29 // MetaIV is the random initialization vector (IV) used for 30 // the MinIO-internal key derivation. 31 MetaIV = "X-Minio-Internal-Server-Side-Encryption-Iv" 32 33 // MetaAlgorithm is the algorithm used to derive internal keys 34 // and encrypt the objects. 35 MetaAlgorithm = "X-Minio-Internal-Server-Side-Encryption-Seal-Algorithm" 36 37 // MetaSealedKeySSEC is the sealed object encryption key in case of SSE-C. 38 MetaSealedKeySSEC = "X-Minio-Internal-Server-Side-Encryption-Sealed-Key" 39 // MetaSealedKeyS3 is the sealed object encryption key in case of SSE-S3 40 MetaSealedKeyS3 = "X-Minio-Internal-Server-Side-Encryption-S3-Sealed-Key" 41 // MetaSealedKeyKMS is the sealed object encryption key in case of SSE-KMS 42 MetaSealedKeyKMS = "X-Minio-Internal-Server-Side-Encryption-Kms-Sealed-Key" 43 44 // MetaKeyID is the KMS master key ID used to generate/encrypt the data 45 // encryption key (DEK). 46 MetaKeyID = "X-Minio-Internal-Server-Side-Encryption-S3-Kms-Key-Id" 47 // MetaDataEncryptionKey is the sealed data encryption key (DEK) received from 48 // the KMS. 49 MetaDataEncryptionKey = "X-Minio-Internal-Server-Side-Encryption-S3-Kms-Sealed-Key" 50 51 // MetaContext is the KMS context provided by a client when encrypting an 52 // object with SSE-KMS. A client may not send a context in which case the 53 // MetaContext will not be present. 54 // MetaContext only contains the bucket/object name if the client explicitly 55 // added it. However, when decrypting an object the bucket/object name must 56 // be part of the object. Therefore, the bucket/object name must be added 57 // to the context, if not present, whenever a decryption is performed. 58 MetaContext = "X-Minio-Internal-Server-Side-Encryption-Context" 59 60 // ARNPrefix prefix for "arn:aws:kms" 61 ARNPrefix = "arn:aws:kms:" 62 ) 63 64 // IsMultiPart returns true if the object metadata indicates 65 // that it was uploaded using some form of server-side-encryption 66 // and the S3 multipart API. 67 func IsMultiPart(metadata map[string]string) bool { 68 if _, ok := metadata[MetaMultipart]; ok { 69 return true 70 } 71 return false 72 } 73 74 // RemoveSensitiveEntries removes confidential encryption 75 // information - e.g. the SSE-C key - from the metadata map. 76 // It has the same semantics as RemoveSensitiveHeaders. 77 func RemoveSensitiveEntries(metadata map[string]string) { // The functions is tested in TestRemoveSensitiveHeaders for compatibility reasons 78 delete(metadata, xhttp.AmzServerSideEncryptionCustomerKey) 79 delete(metadata, xhttp.AmzServerSideEncryptionCopyCustomerKey) 80 delete(metadata, xhttp.AmzMetaUnencryptedContentLength) 81 delete(metadata, xhttp.AmzMetaUnencryptedContentMD5) 82 } 83 84 // RemoveSSEHeaders removes all crypto-specific SSE 85 // header entries from the metadata map. 86 func RemoveSSEHeaders(metadata map[string]string) { 87 delete(metadata, xhttp.AmzServerSideEncryption) 88 delete(metadata, xhttp.AmzServerSideEncryptionKmsID) 89 delete(metadata, xhttp.AmzServerSideEncryptionKmsContext) 90 delete(metadata, xhttp.AmzServerSideEncryptionCustomerAlgorithm) 91 delete(metadata, xhttp.AmzServerSideEncryptionCustomerKey) 92 delete(metadata, xhttp.AmzServerSideEncryptionCustomerKeyMD5) 93 delete(metadata, xhttp.AmzServerSideEncryptionCopyCustomerAlgorithm) 94 delete(metadata, xhttp.AmzServerSideEncryptionCopyCustomerKey) 95 delete(metadata, xhttp.AmzServerSideEncryptionCopyCustomerKeyMD5) 96 } 97 98 // RemoveInternalEntries removes all crypto-specific internal 99 // metadata entries from the metadata map. 100 func RemoveInternalEntries(metadata map[string]string) { 101 delete(metadata, MetaMultipart) 102 delete(metadata, MetaAlgorithm) 103 delete(metadata, MetaIV) 104 delete(metadata, MetaSealedKeySSEC) 105 delete(metadata, MetaSealedKeyS3) 106 delete(metadata, MetaSealedKeyKMS) 107 delete(metadata, MetaKeyID) 108 delete(metadata, MetaDataEncryptionKey) 109 } 110 111 // IsSourceEncrypted returns true if the source is encrypted 112 func IsSourceEncrypted(metadata map[string]string) bool { 113 if _, ok := metadata[xhttp.AmzServerSideEncryptionCustomerAlgorithm]; ok { 114 return true 115 } 116 if _, ok := metadata[xhttp.AmzServerSideEncryption]; ok { 117 return true 118 } 119 return false 120 } 121 122 // IsEncrypted returns true if the object metadata indicates 123 // that it was uploaded using some form of server-side-encryption. 124 // 125 // IsEncrypted only checks whether the metadata contains at least 126 // one entry indicating SSE-C or SSE-S3. 127 func IsEncrypted(metadata map[string]string) (Type, bool) { 128 if S3KMS.IsEncrypted(metadata) { 129 return S3KMS, true 130 } 131 if S3.IsEncrypted(metadata) { 132 return S3, true 133 } 134 if SSEC.IsEncrypted(metadata) { 135 return SSEC, true 136 } 137 if IsMultiPart(metadata) { 138 return nil, true 139 } 140 if _, ok := metadata[MetaIV]; ok { 141 return nil, true 142 } 143 if _, ok := metadata[MetaAlgorithm]; ok { 144 return nil, true 145 } 146 if _, ok := metadata[MetaKeyID]; ok { 147 return nil, true 148 } 149 if _, ok := metadata[MetaDataEncryptionKey]; ok { 150 return nil, true 151 } 152 if _, ok := metadata[MetaContext]; ok { 153 return nil, true 154 } 155 return nil, false 156 } 157 158 // CreateMultipartMetadata adds the multipart flag entry to metadata 159 // and returns modified metadata. It allocates a new metadata map if 160 // metadata is nil. 161 func CreateMultipartMetadata(metadata map[string]string) map[string]string { 162 if metadata == nil { 163 return map[string]string{MetaMultipart: ""} 164 } 165 metadata[MetaMultipart] = "" 166 return metadata 167 } 168 169 // IsETagSealed returns true if the etag seems to be encrypted. 170 func IsETagSealed(etag []byte) bool { return len(etag) > 16 }