storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/cmd/crypto/header_test.go (about) 1 // MinIO Cloud Storage, (C) 2015, 2016, 2017, 2018 MinIO, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package crypto 16 17 import ( 18 "net/http" 19 "sort" 20 "testing" 21 22 xhttp "storj.io/minio/cmd/http" 23 ) 24 25 func TestIsRequested(t *testing.T) { 26 for i, test := range kmsIsRequestedTests { 27 _, got := IsRequested(test.Header) 28 got = got && S3KMS.IsRequested(test.Header) 29 if got != test.Expected { 30 t.Errorf("SSE-KMS: Test %d: Wanted %v but got %v", i, test.Expected, got) 31 } 32 } 33 for i, test := range s3IsRequestedTests { 34 _, got := IsRequested(test.Header) 35 got = got && S3.IsRequested(test.Header) 36 if got != test.Expected { 37 t.Errorf("SSE-S3: Test %d: Wanted %v but got %v", i, test.Expected, got) 38 } 39 } 40 for i, test := range ssecIsRequestedTests { 41 _, got := IsRequested(test.Header) 42 got = got && SSEC.IsRequested(test.Header) 43 if got != test.Expected { 44 t.Errorf("SSE-C: Test %d: Wanted %v but got %v", i, test.Expected, got) 45 } 46 } 47 } 48 49 var kmsIsRequestedTests = []struct { 50 Header http.Header 51 Expected bool 52 }{ 53 {Header: http.Header{}, Expected: false}, // 0 54 {Header: http.Header{"X-Amz-Server-Side-Encryption": []string{"aws:kms"}}, Expected: true}, // 1 55 {Header: http.Header{"X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": []string{"0839-9047947-844842874-481"}}, Expected: true}, // 2 56 {Header: http.Header{"X-Amz-Server-Side-Encryption-Context": []string{"7PpPLAK26ONlVUGOWlusfg=="}}, Expected: true}, // 3 57 { 58 Header: http.Header{ 59 "X-Amz-Server-Side-Encryption": []string{""}, 60 "X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": []string{""}, 61 "X-Amz-Server-Side-Encryption-Context": []string{""}, 62 }, 63 Expected: true, 64 }, // 4 65 { 66 Header: http.Header{ 67 "X-Amz-Server-Side-Encryption": []string{"AES256"}, 68 "X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": []string{""}, 69 }, 70 Expected: true, 71 }, // 5 72 {Header: http.Header{"X-Amz-Server-Side-Encryption": []string{"AES256"}}, Expected: false}, // 6 73 } 74 75 func TestKMSIsRequested(t *testing.T) { 76 for i, test := range kmsIsRequestedTests { 77 if got := S3KMS.IsRequested(test.Header); got != test.Expected { 78 t.Errorf("Test %d: Wanted %v but got %v", i, test.Expected, got) 79 } 80 } 81 } 82 83 var kmsParseHTTPTests = []struct { 84 Header http.Header 85 ShouldFail bool 86 }{ 87 {Header: http.Header{}, ShouldFail: true}, // 0 88 {Header: http.Header{"X-Amz-Server-Side-Encryption": []string{"aws:kms"}}, ShouldFail: false}, // 1 89 {Header: http.Header{ 90 "X-Amz-Server-Side-Encryption": []string{"aws:kms"}, 91 "X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": []string{"s3-007-293847485-724784"}, 92 }, ShouldFail: false}, // 2 93 {Header: http.Header{ 94 "X-Amz-Server-Side-Encryption": []string{"aws:kms"}, 95 "X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": []string{"s3-007-293847485-724784"}, 96 "X-Amz-Server-Side-Encryption-Context": []string{"{}"}, 97 }, ShouldFail: false}, // 3 98 {Header: http.Header{ 99 "X-Amz-Server-Side-Encryption": []string{"aws:kms"}, 100 "X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": []string{"s3-007-293847485-724784"}, 101 "X-Amz-Server-Side-Encryption-Context": []string{"{\"bucket\": \"some-bucket\"}"}, 102 }, ShouldFail: false}, // 4 103 {Header: http.Header{ 104 "X-Amz-Server-Side-Encryption": []string{"aws:kms"}, 105 "X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": []string{"s3-007-293847485-724784"}, 106 "X-Amz-Server-Side-Encryption-Context": []string{"{\"bucket\": \"some-bucket\"}"}, 107 }, ShouldFail: false}, // 5 108 {Header: http.Header{ 109 "X-Amz-Server-Side-Encryption": []string{"AES256"}, 110 "X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": []string{"s3-007-293847485-724784"}, 111 "X-Amz-Server-Side-Encryption-Context": []string{"{\"bucket\": \"some-bucket\"}"}, 112 }, ShouldFail: true}, // 6 113 {Header: http.Header{ 114 "X-Amz-Server-Side-Encryption": []string{"aws:kms"}, 115 "X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": []string{"s3-007-293847485-724784"}, 116 "X-Amz-Server-Side-Encryption-Context": []string{"{\"bucket\": \"some-bucket\""}, // invalid JSON 117 }, ShouldFail: true}, // 7 118 119 } 120 121 func TestKMSParseHTTP(t *testing.T) { 122 for i, test := range kmsParseHTTPTests { 123 _, _, err := S3KMS.ParseHTTP(test.Header) 124 if err == nil && test.ShouldFail { 125 t.Errorf("Test %d: should fail but succeeded", i) 126 } 127 if err != nil && !test.ShouldFail { 128 t.Errorf("Test %d: should pass but failed with: %v", i, err) 129 } 130 } 131 } 132 133 var s3IsRequestedTests = []struct { 134 Header http.Header 135 Expected bool 136 }{ 137 {Header: http.Header{"X-Amz-Server-Side-Encryption": []string{"AES256"}}, Expected: true}, // 0 138 {Header: http.Header{"X-Amz-Server-Side-Encryption": []string{"AES-256"}}, Expected: true}, // 1 139 {Header: http.Header{"X-Amz-Server-Side-Encryption": []string{""}}, Expected: true}, // 2 140 {Header: http.Header{"X-Amz-Server-Side-Encryptio": []string{"AES256"}}, Expected: false}, // 3 141 {Header: http.Header{"X-Amz-Server-Side-Encryption": []string{xhttp.AmzEncryptionKMS}}, Expected: false}, // 4 142 } 143 144 func TestS3IsRequested(t *testing.T) { 145 for i, test := range s3IsRequestedTests { 146 if got := S3.IsRequested(test.Header); got != test.Expected { 147 t.Errorf("Test %d: Wanted %v but got %v", i, test.Expected, got) 148 } 149 } 150 } 151 152 var s3ParseTests = []struct { 153 Header http.Header 154 ExpectedErr error 155 }{ 156 {Header: http.Header{"X-Amz-Server-Side-Encryption": []string{"AES256"}}, ExpectedErr: nil}, // 0 157 {Header: http.Header{"X-Amz-Server-Side-Encryption": []string{"AES-256"}}, ExpectedErr: ErrInvalidEncryptionMethod}, // 1 158 {Header: http.Header{"X-Amz-Server-Side-Encryption": []string{""}}, ExpectedErr: ErrInvalidEncryptionMethod}, // 2 159 {Header: http.Header{"X-Amz-Server-Side-Encryptio": []string{"AES256"}}, ExpectedErr: ErrInvalidEncryptionMethod}, // 3 160 } 161 162 func TestS3Parse(t *testing.T) { 163 for i, test := range s3ParseTests { 164 if err := S3.ParseHTTP(test.Header); err != test.ExpectedErr { 165 t.Errorf("Test %d: Wanted '%v' but got '%v'", i, test.ExpectedErr, err) 166 } 167 } 168 } 169 170 var ssecIsRequestedTests = []struct { 171 Header http.Header 172 Expected bool 173 }{ 174 {Header: http.Header{}, Expected: false}, // 0 175 {Header: http.Header{"X-Amz-Server-Side-Encryption-Customer-Algorithm": []string{"AES256"}}, Expected: true}, // 1 176 {Header: http.Header{"X-Amz-Server-Side-Encryption-Customer-Key": []string{"MzJieXRlc2xvbmdzZWNyZXRrZXltdXN0cHJvdmlkZWQ="}}, Expected: true}, // 2 177 {Header: http.Header{"X-Amz-Server-Side-Encryption-Customer-Key-Md5": []string{"7PpPLAK26ONlVUGOWlusfg=="}}, Expected: true}, // 3 178 { 179 Header: http.Header{ 180 "X-Amz-Server-Side-Encryption-Customer-Algorithm": []string{""}, 181 "X-Amz-Server-Side-Encryption-Customer-Key": []string{""}, 182 "X-Amz-Server-Side-Encryption-Customer-Key-Md5": []string{""}, 183 }, 184 Expected: true, 185 }, // 4 186 { 187 Header: http.Header{ 188 "X-Amz-Server-Side-Encryption-Customer-Algorithm": []string{"AES256"}, 189 "X-Amz-Server-Side-Encryption-Customer-Key": []string{"MzJieXRlc2xvbmdzZWNyZXRrZXltdXN0cHJvdmlkZWQ="}, 190 "X-Amz-Server-Side-Encryption-Customer-Key-Md5": []string{"7PpPLAK26ONlVUGOWlusfg=="}, 191 }, 192 Expected: true, 193 }, // 5 194 { 195 Header: http.Header{ 196 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm": []string{"AES256"}, 197 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key": []string{"MzJieXRlc2xvbmdzZWNyZXRrZXltdXN0cHJvdmlkZWQ="}, 198 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-Md5": []string{"7PpPLAK26ONlVUGOWlusfg=="}, 199 }, 200 Expected: false, 201 }, // 6 202 } 203 204 func TestSSECIsRequested(t *testing.T) { 205 for i, test := range ssecIsRequestedTests { 206 if got := SSEC.IsRequested(test.Header); got != test.Expected { 207 t.Errorf("Test %d: Wanted %v but got %v", i, test.Expected, got) 208 } 209 } 210 } 211 212 var ssecCopyIsRequestedTests = []struct { 213 Header http.Header 214 Expected bool 215 }{ 216 {Header: http.Header{}, Expected: false}, // 0 217 {Header: http.Header{"X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm": []string{"AES256"}}, Expected: true}, // 1 218 {Header: http.Header{"X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key": []string{"MzJieXRlc2xvbmdzZWNyZXRrZXltdXN0cHJvdmlkZWQ="}}, Expected: true}, // 2 219 {Header: http.Header{"X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-Md5": []string{"7PpPLAK26ONlVUGOWlusfg=="}}, Expected: true}, // 3 220 { 221 Header: http.Header{ 222 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm": []string{""}, 223 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key": []string{""}, 224 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-Md5": []string{""}, 225 }, 226 Expected: true, 227 }, // 4 228 { 229 Header: http.Header{ 230 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm": []string{"AES256"}, 231 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key": []string{"MzJieXRlc2xvbmdzZWNyZXRrZXltdXN0cHJvdmlkZWQ="}, 232 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-Md5": []string{"7PpPLAK26ONlVUGOWlusfg=="}, 233 }, 234 Expected: true, 235 }, // 5 236 { 237 Header: http.Header{ 238 "X-Amz-Server-Side-Encryption-Customer-Algorithm": []string{"AES256"}, 239 "X-Amz-Server-Side-Encryption-Customer-Key": []string{"MzJieXRlc2xvbmdzZWNyZXRrZXltdXN0cHJvdmlkZWQ="}, 240 "X-Amz-Server-Side-Encryption-Customer-Key-Md5": []string{"7PpPLAK26ONlVUGOWlusfg=="}, 241 }, 242 Expected: false, 243 }, // 6 244 } 245 246 func TestSSECopyIsRequested(t *testing.T) { 247 for i, test := range ssecCopyIsRequestedTests { 248 if got := SSECopy.IsRequested(test.Header); got != test.Expected { 249 t.Errorf("Test %d: Wanted %v but got %v", i, test.Expected, got) 250 } 251 } 252 } 253 254 var ssecParseTests = []struct { 255 Header http.Header 256 ExpectedErr error 257 }{ 258 { 259 Header: http.Header{ 260 "X-Amz-Server-Side-Encryption-Customer-Algorithm": []string{"AES256"}, 261 "X-Amz-Server-Side-Encryption-Customer-Key": []string{"MzJieXRlc2xvbmdzZWNyZXRrZXltdXN0cHJvdmlkZWQ="}, 262 "X-Amz-Server-Side-Encryption-Customer-Key-Md5": []string{"7PpPLAK26ONlVUGOWlusfg=="}, 263 }, 264 ExpectedErr: nil, // 0 265 }, 266 { 267 Header: http.Header{ 268 "X-Amz-Server-Side-Encryption-Customer-Algorithm": []string{"AES-256"}, // invalid algorithm 269 "X-Amz-Server-Side-Encryption-Customer-Key": []string{"MzJieXRlc2xvbmdzZWNyZXRrZXltdXN0cHJvdmlkZWQ="}, 270 "X-Amz-Server-Side-Encryption-Customer-Key-Md5": []string{"7PpPLAK26ONlVUGOWlusfg=="}, 271 }, 272 ExpectedErr: ErrInvalidCustomerAlgorithm, // 1 273 }, 274 { 275 Header: http.Header{ 276 "X-Amz-Server-Side-Encryption-Customer-Algorithm": []string{"AES256"}, 277 "X-Amz-Server-Side-Encryption-Customer-Key": []string{""}, // no client key 278 "X-Amz-Server-Side-Encryption-Customer-Key-Md5": []string{"7PpPLAK26ONlVUGOWlusfg=="}, 279 }, 280 ExpectedErr: ErrMissingCustomerKey, // 2 281 }, 282 { 283 Header: http.Header{ 284 "X-Amz-Server-Side-Encryption-Customer-Algorithm": []string{"AES256"}, 285 "X-Amz-Server-Side-Encryption-Customer-Key": []string{"MzJieXRlc2xvbmdzZWNyZXRr.ZXltdXN0cHJvdmlkZWQ="}, // invalid key 286 "X-Amz-Server-Side-Encryption-Customer-Key-Md5": []string{"7PpPLAK26ONlVUGOWlusfg=="}, 287 }, 288 ExpectedErr: ErrInvalidCustomerKey, // 3 289 }, 290 { 291 Header: http.Header{ 292 "X-Amz-Server-Side-Encryption-Customer-Algorithm": []string{"AES256"}, 293 "X-Amz-Server-Side-Encryption-Customer-Key": []string{"MzJieXRlc2xvbmdzZWNyZXRrZXltdXN0cHJvdmlkZWQ="}, 294 "X-Amz-Server-Side-Encryption-Customer-Key-Md5": []string{""}, // no key MD5 295 }, 296 ExpectedErr: ErrMissingCustomerKeyMD5, // 4 297 }, 298 { 299 Header: http.Header{ 300 "X-Amz-Server-Side-Encryption-Customer-Algorithm": []string{"AES256"}, 301 "X-Amz-Server-Side-Encryption-Customer-Key": []string{"DzJieXRlc2xvbmdzZWNyZXRrZXltdXN0cHJvdmlkZWQ="}, // wrong client key 302 "X-Amz-Server-Side-Encryption-Customer-Key-Md5": []string{"7PpPLAK26ONlVUGOWlusfg=="}, 303 }, 304 ExpectedErr: ErrCustomerKeyMD5Mismatch, // 5 305 }, 306 { 307 Header: http.Header{ 308 "X-Amz-Server-Side-Encryption-Customer-Algorithm": []string{"AES256"}, 309 "X-Amz-Server-Side-Encryption-Customer-Key": []string{"MzJieXRlc2xvbmdzZWNyZXRrZXltdXN0cHJvdmlkZWQ="}, 310 "X-Amz-Server-Side-Encryption-Customer-Key-Md5": []string{".7PpPLAK26ONlVUGOWlusfg=="}, // wrong key MD5 311 }, 312 ExpectedErr: ErrCustomerKeyMD5Mismatch, // 6 313 }, 314 } 315 316 func TestSSECParse(t *testing.T) { 317 var zeroKey [32]byte 318 for i, test := range ssecParseTests { 319 key, err := SSEC.ParseHTTP(test.Header) 320 if err != test.ExpectedErr { 321 t.Errorf("Test %d: want error '%v' but got '%v'", i, test.ExpectedErr, err) 322 } 323 324 if err != nil && key != zeroKey { 325 t.Errorf("Test %d: parsing failed and client key is not zero key", i) 326 } 327 if err == nil && key == zeroKey { 328 t.Errorf("Test %d: parsed client key is zero key", i) 329 } 330 } 331 } 332 333 var ssecCopyParseTests = []struct { 334 Header http.Header 335 ExpectedErr error 336 }{ 337 { 338 Header: http.Header{ 339 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm": []string{"AES256"}, 340 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key": []string{"MzJieXRlc2xvbmdzZWNyZXRrZXltdXN0cHJvdmlkZWQ="}, 341 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-Md5": []string{"7PpPLAK26ONlVUGOWlusfg=="}, 342 }, 343 ExpectedErr: nil, // 0 344 }, 345 { 346 Header: http.Header{ 347 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm": []string{"AES-256"}, // invalid algorithm 348 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key": []string{"MzJieXRlc2xvbmdzZWNyZXRrZXltdXN0cHJvdmlkZWQ="}, 349 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-Md5": []string{"7PpPLAK26ONlVUGOWlusfg=="}, 350 }, 351 ExpectedErr: ErrInvalidCustomerAlgorithm, // 1 352 }, 353 { 354 Header: http.Header{ 355 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm": []string{"AES256"}, 356 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key": []string{""}, // no client key 357 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-Md5": []string{"7PpPLAK26ONlVUGOWlusfg=="}, 358 }, 359 ExpectedErr: ErrMissingCustomerKey, // 2 360 }, 361 { 362 Header: http.Header{ 363 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm": []string{"AES256"}, 364 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key": []string{"MzJieXRlc2xvbmdzZWNyZXRr.ZXltdXN0cHJvdmlkZWQ="}, // invalid key 365 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-Md5": []string{"7PpPLAK26ONlVUGOWlusfg=="}, 366 }, 367 ExpectedErr: ErrInvalidCustomerKey, // 3 368 }, 369 { 370 Header: http.Header{ 371 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm": []string{"AES256"}, 372 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key": []string{"MzJieXRlc2xvbmdzZWNyZXRrZXltdXN0cHJvdmlkZWQ="}, 373 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-Md5": []string{""}, // no key MD5 374 }, 375 ExpectedErr: ErrMissingCustomerKeyMD5, // 4 376 }, 377 { 378 Header: http.Header{ 379 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm": []string{"AES256"}, 380 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key": []string{"DzJieXRlc2xvbmdzZWNyZXRrZXltdXN0cHJvdmlkZWQ="}, // wrong client key 381 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-Md5": []string{"7PpPLAK26ONlVUGOWlusfg=="}, 382 }, 383 ExpectedErr: ErrCustomerKeyMD5Mismatch, // 5 384 }, 385 { 386 Header: http.Header{ 387 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm": []string{"AES256"}, 388 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key": []string{"MzJieXRlc2xvbmdzZWNyZXRrZXltdXN0cHJvdmlkZWQ="}, 389 "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-Md5": []string{".7PpPLAK26ONlVUGOWlusfg=="}, // wrong key MD5 390 }, 391 ExpectedErr: ErrCustomerKeyMD5Mismatch, // 6 392 }, 393 } 394 395 func TestSSECopyParse(t *testing.T) { 396 var zeroKey [32]byte 397 for i, test := range ssecCopyParseTests { 398 key, err := SSECopy.ParseHTTP(test.Header) 399 if err != test.ExpectedErr { 400 t.Errorf("Test %d: want error '%v' but got '%v'", i, test.ExpectedErr, err) 401 } 402 403 if err != nil && key != zeroKey { 404 t.Errorf("Test %d: parsing failed and client key is not zero key", i) 405 } 406 if err == nil && key == zeroKey { 407 t.Errorf("Test %d: parsed client key is zero key", i) 408 } 409 if _, ok := test.Header[xhttp.AmzServerSideEncryptionCustomerKey]; ok { 410 t.Errorf("Test %d: client key is not removed from HTTP headers after parsing", i) 411 } 412 } 413 } 414 415 var removeSensitiveHeadersTests = []struct { 416 Header, ExpectedHeader http.Header 417 }{ 418 { 419 Header: http.Header{ 420 xhttp.AmzServerSideEncryptionCustomerKey: []string{""}, 421 xhttp.AmzServerSideEncryptionCopyCustomerKey: []string{""}, 422 }, 423 ExpectedHeader: http.Header{}, 424 }, 425 { // Standard SSE-C request headers 426 Header: http.Header{ 427 xhttp.AmzServerSideEncryptionCustomerAlgorithm: []string{xhttp.AmzEncryptionAES}, 428 xhttp.AmzServerSideEncryptionCustomerKey: []string{"MzJieXRlc2xvbmdzZWNyZXRrZXltdXN0cHJvdmlkZWQ="}, 429 xhttp.AmzServerSideEncryptionCustomerKeyMD5: []string{"7PpPLAK26ONlVUGOWlusfg=="}, 430 }, 431 ExpectedHeader: http.Header{ 432 xhttp.AmzServerSideEncryptionCustomerAlgorithm: []string{xhttp.AmzEncryptionAES}, 433 xhttp.AmzServerSideEncryptionCustomerKeyMD5: []string{"7PpPLAK26ONlVUGOWlusfg=="}, 434 }, 435 }, 436 { // Standard SSE-C + SSE-C-copy request headers 437 Header: http.Header{ 438 xhttp.AmzServerSideEncryptionCustomerAlgorithm: []string{xhttp.AmzEncryptionAES}, 439 xhttp.AmzServerSideEncryptionCustomerKey: []string{"MzJieXRlc2xvbmdzZWNyZXRrZXltdXN0cHJvdmlkZWQ="}, 440 xhttp.AmzServerSideEncryptionCustomerKeyMD5: []string{"7PpPLAK26ONlVUGOWlusfg=="}, 441 xhttp.AmzServerSideEncryptionCopyCustomerKey: []string{"MzJieXRlc2xvbmdzZWNyZXRrZXltdXN0cHJvdmlkZWQ="}, 442 xhttp.AmzServerSideEncryptionCopyCustomerKeyMD5: []string{"7PpPLAK26ONlVUGOWlusfg=="}, 443 }, 444 ExpectedHeader: http.Header{ 445 xhttp.AmzServerSideEncryptionCustomerAlgorithm: []string{xhttp.AmzEncryptionAES}, 446 xhttp.AmzServerSideEncryptionCustomerKeyMD5: []string{"7PpPLAK26ONlVUGOWlusfg=="}, 447 xhttp.AmzServerSideEncryptionCopyCustomerKeyMD5: []string{"7PpPLAK26ONlVUGOWlusfg=="}, 448 }, 449 }, 450 { // Standard SSE-C + metadata request headers 451 Header: http.Header{ 452 xhttp.AmzServerSideEncryptionCustomerAlgorithm: []string{xhttp.AmzEncryptionAES}, 453 xhttp.AmzServerSideEncryptionCustomerKey: []string{"MzJieXRlc2xvbmdzZWNyZXRrZXltdXN0cHJvdmlkZWQ="}, 454 xhttp.AmzServerSideEncryptionCustomerKeyMD5: []string{"7PpPLAK26ONlVUGOWlusfg=="}, 455 "X-Amz-Meta-Test-1": []string{"Test-1"}, 456 }, 457 ExpectedHeader: http.Header{ 458 xhttp.AmzServerSideEncryptionCustomerAlgorithm: []string{xhttp.AmzEncryptionAES}, 459 xhttp.AmzServerSideEncryptionCustomerKeyMD5: []string{"7PpPLAK26ONlVUGOWlusfg=="}, 460 "X-Amz-Meta-Test-1": []string{"Test-1"}, 461 }, 462 }, 463 { // https://github.com/google/security-research/security/advisories/GHSA-76wf-9vgp-pj7w 464 Header: http.Header{ 465 "X-Amz-Meta-X-Amz-Unencrypted-Content-Md5": []string{"value"}, 466 "X-Amz-Meta-X-Amz-Unencrypted-Content-Length": []string{"value"}, 467 "X-Amz-Meta-Test-1": []string{"Test-1"}, 468 }, 469 ExpectedHeader: http.Header{ 470 "X-Amz-Meta-Test-1": []string{"Test-1"}, 471 }, 472 }, 473 } 474 475 func TestRemoveSensitiveHeaders(t *testing.T) { 476 isEqual := func(x, y http.Header) bool { 477 if len(x) != len(y) { 478 return false 479 } 480 for k, v := range x { 481 u, ok := y[k] 482 if !ok || len(v) != len(u) { 483 return false 484 } 485 sort.Strings(v) 486 sort.Strings(u) 487 for j := range v { 488 if v[j] != u[j] { 489 return false 490 } 491 } 492 } 493 return true 494 } 495 areKeysEqual := func(h http.Header, metadata map[string]string) bool { 496 if len(h) != len(metadata) { 497 return false 498 } 499 for k := range h { 500 if _, ok := metadata[k]; !ok { 501 return false 502 } 503 } 504 return true 505 } 506 507 for i, test := range removeSensitiveHeadersTests { 508 metadata := make(map[string]string, len(test.Header)) 509 for k := range test.Header { 510 metadata[k] = "" // set metadata key - we don't care about the value 511 } 512 513 RemoveSensitiveHeaders(test.Header) 514 if !isEqual(test.ExpectedHeader, test.Header) { 515 t.Errorf("Test %d: filtered headers do not match expected headers - got: %v , want: %v", i, test.Header, test.ExpectedHeader) 516 } 517 RemoveSensitiveEntries(metadata) 518 if !areKeysEqual(test.ExpectedHeader, metadata) { 519 t.Errorf("Test %d: filtered headers do not match expected headers - got: %v , want: %v", i, test.Header, test.ExpectedHeader) 520 } 521 } 522 }