github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/internal/bucket/encryption/bucket-sse-config_test.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 sse
    19  
    20  import (
    21  	"bytes"
    22  	"encoding/xml"
    23  	"errors"
    24  	"testing"
    25  )
    26  
    27  // TestParseBucketSSEConfig performs basic sanity tests on ParseBucketSSEConfig
    28  func TestParseBucketSSEConfig(t *testing.T) {
    29  	actualAES256NoNSConfig := &BucketSSEConfig{
    30  		XMLName: xml.Name{
    31  			Local: "ServerSideEncryptionConfiguration",
    32  		},
    33  		Rules: []Rule{
    34  			{
    35  				DefaultEncryptionAction: EncryptionAction{
    36  					Algorithm: AES256,
    37  				},
    38  			},
    39  		},
    40  	}
    41  
    42  	actualAES256Config := &BucketSSEConfig{
    43  		XMLNS: xmlNS,
    44  		XMLName: xml.Name{
    45  			Local: "ServerSideEncryptionConfiguration",
    46  		},
    47  		Rules: []Rule{
    48  			{
    49  				DefaultEncryptionAction: EncryptionAction{
    50  					Algorithm: AES256,
    51  				},
    52  			},
    53  		},
    54  	}
    55  
    56  	actualKMSConfig := &BucketSSEConfig{
    57  		XMLNS: xmlNS,
    58  		XMLName: xml.Name{
    59  			Local: "ServerSideEncryptionConfiguration",
    60  		},
    61  		Rules: []Rule{
    62  			{
    63  				DefaultEncryptionAction: EncryptionAction{
    64  					Algorithm:   AWSKms,
    65  					MasterKeyID: "arn:aws:kms:my-minio-key",
    66  				},
    67  			},
    68  		},
    69  	}
    70  
    71  	testCases := []struct {
    72  		inputXML       string
    73  		keyID          string
    74  		expectedErr    error
    75  		shouldPass     bool
    76  		expectedConfig *BucketSSEConfig
    77  	}{
    78  		// 1. Valid XML SSE-S3
    79  		{
    80  			inputXML:       `<ServerSideEncryptionConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Rule><ApplyServerSideEncryptionByDefault><SSEAlgorithm>AES256</SSEAlgorithm></ApplyServerSideEncryptionByDefault></Rule></ServerSideEncryptionConfiguration>`,
    81  			expectedErr:    nil,
    82  			shouldPass:     true,
    83  			expectedConfig: actualAES256Config,
    84  		},
    85  		// 2. Valid XML SSE-KMS
    86  		{
    87  			inputXML:       `<ServerSideEncryptionConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Rule><ApplyServerSideEncryptionByDefault><SSEAlgorithm>aws:kms</SSEAlgorithm><KMSMasterKeyID>arn:aws:kms:my-minio-key</KMSMasterKeyID></ApplyServerSideEncryptionByDefault></Rule></ServerSideEncryptionConfiguration>`,
    88  			expectedErr:    nil,
    89  			shouldPass:     true,
    90  			expectedConfig: actualKMSConfig,
    91  			keyID:          "my-minio-key",
    92  		},
    93  		// 3. Invalid - more than one rule
    94  		{
    95  			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>`,
    96  			expectedErr: errors.New("only one server-side encryption rule is allowed at a time"),
    97  			shouldPass:  false,
    98  		},
    99  		// 4. Invalid XML - master key ID present along with AES256
   100  		{
   101  			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>`,
   102  			expectedErr: errors.New("MasterKeyID is allowed with aws:kms only"),
   103  			shouldPass:  false,
   104  		},
   105  		// 5. Invalid XML - master key ID not provided when algorithm is set to aws:kms algorithm
   106  		{
   107  			inputXML:    `<ServerSideEncryptionConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Rule><ApplyServerSideEncryptionByDefault><SSEAlgorithm>aws:kms</SSEAlgorithm></ApplyServerSideEncryptionByDefault></Rule></ServerSideEncryptionConfiguration>`,
   108  			expectedErr: errors.New("MasterKeyID is missing with aws:kms"),
   109  			shouldPass:  false,
   110  		},
   111  		// 6. Invalid Algorithm
   112  		{
   113  			inputXML:    `<ServerSideEncryptionConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Rule><ApplyServerSideEncryptionByDefault><SSEAlgorithm>InvalidAlgorithm</SSEAlgorithm></ApplyServerSideEncryptionByDefault></Rule></ServerSideEncryptionConfiguration>`,
   114  			expectedErr: errors.New("Unknown SSE algorithm"),
   115  			shouldPass:  false,
   116  		},
   117  		// 7. Valid XML without the namespace set
   118  		{
   119  			inputXML:       `<ServerSideEncryptionConfiguration><Rule><ApplyServerSideEncryptionByDefault><SSEAlgorithm>AES256</SSEAlgorithm></ApplyServerSideEncryptionByDefault></Rule></ServerSideEncryptionConfiguration>`,
   120  			expectedErr:    nil,
   121  			shouldPass:     true,
   122  			expectedConfig: actualAES256NoNSConfig,
   123  		},
   124  		// 8. Space characters in MasterKeyID
   125  		{
   126  			inputXML:    `<ServerSideEncryptionConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Rule><ApplyServerSideEncryptionByDefault><SSEAlgorithm>aws:kms</SSEAlgorithm><KMSMasterKeyID> arn:aws:kms:my-minio-key </KMSMasterKeyID></ApplyServerSideEncryptionByDefault></Rule></ServerSideEncryptionConfiguration>`,
   127  			expectedErr: errors.New("MasterKeyID contains unsupported characters"),
   128  			shouldPass:  false,
   129  		},
   130  	}
   131  
   132  	for i, tc := range testCases {
   133  		ssec, err := ParseBucketSSEConfig(bytes.NewReader([]byte(tc.inputXML)))
   134  		if tc.shouldPass && err != nil {
   135  			t.Errorf("Test case %d: Expected to succeed but got %s", i+1, err)
   136  		}
   137  
   138  		if !tc.shouldPass {
   139  			if err == nil || err != nil && err.Error() != tc.expectedErr.Error() {
   140  				t.Errorf("Test case %d: Expected %s but got %s", i+1, tc.expectedErr, err)
   141  			}
   142  			continue
   143  		}
   144  
   145  		if tc.keyID != "" && tc.keyID != ssec.KeyID() {
   146  			t.Errorf("Test case %d: Expected bucket encryption KeyID %s but got %s", i+1, tc.keyID, ssec.KeyID())
   147  		}
   148  
   149  		if expectedXML, err := xml.Marshal(tc.expectedConfig); err != nil || !bytes.Equal(expectedXML, []byte(tc.inputXML)) {
   150  			t.Errorf("Test case %d: Expected bucket encryption XML %s but got %s", i+1, string(expectedXML), tc.inputXML)
   151  		}
   152  	}
   153  }