storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/pkg/bucket/encryption/bucket-sse-config_test.go (about)

     1  /*
     2   * MinIO Cloud Storage, (C) 2020 MinIO, Inc.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package cmd
    18  
    19  import (
    20  	"bytes"
    21  	"encoding/xml"
    22  	"errors"
    23  	"testing"
    24  )
    25  
    26  // TestParseBucketSSEConfig performs basic sanity tests on ParseBucketSSEConfig
    27  func TestParseBucketSSEConfig(t *testing.T) {
    28  	actualAES256NoNSConfig := &BucketSSEConfig{
    29  		XMLName: xml.Name{
    30  			Local: "ServerSideEncryptionConfiguration",
    31  		},
    32  		Rules: []SSERule{
    33  			{
    34  				DefaultEncryptionAction: EncryptionAction{
    35  					Algorithm: AES256,
    36  				},
    37  			},
    38  		},
    39  	}
    40  
    41  	actualAES256Config := &BucketSSEConfig{
    42  		XMLNS: xmlNS,
    43  		XMLName: xml.Name{
    44  			Local: "ServerSideEncryptionConfiguration",
    45  		},
    46  		Rules: []SSERule{
    47  			{
    48  				DefaultEncryptionAction: EncryptionAction{
    49  					Algorithm: AES256,
    50  				},
    51  			},
    52  		},
    53  	}
    54  
    55  	actualKMSConfig := &BucketSSEConfig{
    56  		XMLNS: xmlNS,
    57  		XMLName: xml.Name{
    58  			Local: "ServerSideEncryptionConfiguration",
    59  		},
    60  		Rules: []SSERule{
    61  			{
    62  				DefaultEncryptionAction: EncryptionAction{
    63  					Algorithm:   AWSKms,
    64  					MasterKeyID: "arn:aws:kms:us-east-1:1234/5678example",
    65  				},
    66  			},
    67  		},
    68  	}
    69  
    70  	testCases := []struct {
    71  		inputXML       string
    72  		expectedErr    error
    73  		shouldPass     bool
    74  		expectedConfig *BucketSSEConfig
    75  	}{
    76  		// 1. Valid XML SSE-S3
    77  		{
    78  			inputXML:       `<ServerSideEncryptionConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Rule><ApplyServerSideEncryptionByDefault><SSEAlgorithm>AES256</SSEAlgorithm></ApplyServerSideEncryptionByDefault></Rule></ServerSideEncryptionConfiguration>`,
    79  			expectedErr:    nil,
    80  			shouldPass:     true,
    81  			expectedConfig: actualAES256Config,
    82  		},
    83  		// 2. Valid XML SSE-KMS
    84  		{
    85  			inputXML:       `<ServerSideEncryptionConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Rule><ApplyServerSideEncryptionByDefault><SSEAlgorithm>aws:kms</SSEAlgorithm><KMSMasterKeyID>arn:aws:kms:us-east-1:1234/5678example</KMSMasterKeyID></ApplyServerSideEncryptionByDefault></Rule></ServerSideEncryptionConfiguration>`,
    86  			expectedErr:    nil,
    87  			shouldPass:     true,
    88  			expectedConfig: actualKMSConfig,
    89  		},
    90  		// 3. Invalid - more than one rule
    91  		{
    92  			inputXML:    `<ServerSideEncryptionConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Rule><ApplyServerSideEncryptionByDefault><SSEAlgorithm>AES256</SSEAlgorithm></ApplyServerSideEncryptionByDefault></Rule><Rule><ApplyServerSideEncryptionByDefault><SSEAlgorithm>AES256</SSEAlgorithm></ApplyServerSideEncryptionByDefault></Rule></ServerSideEncryptionConfiguration>`,
    93  			expectedErr: errors.New("only one server-side encryption rule is allowed at a time"),
    94  			shouldPass:  false,
    95  		},
    96  		// 4. Invalid XML - master key ID present along with AES256
    97  		{
    98  			inputXML:    `<ServerSideEncryptionConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Rule><ApplyServerSideEncryptionByDefault><SSEAlgorithm>AES256</SSEAlgorithm><KMSMasterKeyID>arn:aws:kms:us-east-1:1234/5678example</KMSMasterKeyID></ApplyServerSideEncryptionByDefault></Rule></ServerSideEncryptionConfiguration>`,
    99  			expectedErr: errors.New("MasterKeyID is allowed with aws:kms only"),
   100  			shouldPass:  false,
   101  		},
   102  		// 5. Invalid XML - master key ID not provided when algorithm is set to aws:kms algorithm
   103  		{
   104  			inputXML:    `<ServerSideEncryptionConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Rule><ApplyServerSideEncryptionByDefault><SSEAlgorithm>aws:kms</SSEAlgorithm></ApplyServerSideEncryptionByDefault></Rule></ServerSideEncryptionConfiguration>`,
   105  			expectedErr: errors.New("MasterKeyID is missing with aws:kms"),
   106  			shouldPass:  false,
   107  		},
   108  		// 6. Invalid Algorithm
   109  		{
   110  			inputXML:    `<ServerSideEncryptionConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Rule><ApplyServerSideEncryptionByDefault><SSEAlgorithm>InvalidAlgorithm</SSEAlgorithm></ApplyServerSideEncryptionByDefault></Rule></ServerSideEncryptionConfiguration>`,
   111  			expectedErr: errors.New("Unknown SSE algorithm"),
   112  			shouldPass:  false,
   113  		},
   114  		// 7. Valid XML without the namespace set
   115  		{
   116  			inputXML:       `<ServerSideEncryptionConfiguration><Rule><ApplyServerSideEncryptionByDefault><SSEAlgorithm>AES256</SSEAlgorithm></ApplyServerSideEncryptionByDefault></Rule></ServerSideEncryptionConfiguration>`,
   117  			expectedErr:    nil,
   118  			shouldPass:     true,
   119  			expectedConfig: actualAES256NoNSConfig,
   120  		},
   121  	}
   122  
   123  	for i, tc := range testCases {
   124  		_, err := ParseBucketSSEConfig(bytes.NewReader([]byte(tc.inputXML)))
   125  		if tc.shouldPass && err != nil {
   126  			t.Fatalf("Test case %d: Expected to succeed but got %s", i+1, err)
   127  		}
   128  
   129  		if !tc.shouldPass {
   130  			if err == nil || err != nil && err.Error() != tc.expectedErr.Error() {
   131  				t.Fatalf("Test case %d: Expected %s but got %s", i+1, tc.expectedErr, err)
   132  			}
   133  			continue
   134  		}
   135  
   136  		if expectedXML, err := xml.Marshal(tc.expectedConfig); err != nil || !bytes.Equal(expectedXML, []byte(tc.inputXML)) {
   137  			t.Fatalf("Test case %d: Expected bucket encryption XML %s but got %s", i+1, string(expectedXML), tc.inputXML)
   138  		}
   139  	}
   140  }