storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/pkg/bucket/encryption/bucket-sse-config.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  	"encoding/xml"
    21  	"errors"
    22  	"io"
    23  )
    24  
    25  const (
    26  	// AES256 is used with SSE-S3
    27  	AES256 SSEAlgorithm = "AES256"
    28  	// AWSKms is used with SSE-KMS
    29  	AWSKms SSEAlgorithm = "aws:kms"
    30  )
    31  
    32  // SSEAlgorithm - represents valid SSE algorithms supported; currently only AES256 is supported
    33  type SSEAlgorithm string
    34  
    35  // UnmarshalXML - Unmarshals XML tag to valid SSE algorithm
    36  func (alg *SSEAlgorithm) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
    37  	var s string
    38  	if err := d.DecodeElement(&s, &start); err != nil {
    39  		return err
    40  	}
    41  
    42  	switch s {
    43  	case string(AES256):
    44  		*alg = AES256
    45  	case string(AWSKms):
    46  		*alg = AWSKms
    47  	default:
    48  		return errors.New("Unknown SSE algorithm")
    49  	}
    50  
    51  	return nil
    52  }
    53  
    54  // MarshalXML - Marshals given SSE algorithm to valid XML
    55  func (alg *SSEAlgorithm) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
    56  	return e.EncodeElement(string(*alg), start)
    57  }
    58  
    59  // EncryptionAction - for ApplyServerSideEncryptionByDefault XML tag
    60  type EncryptionAction struct {
    61  	Algorithm   SSEAlgorithm `xml:"SSEAlgorithm,omitempty"`
    62  	MasterKeyID string       `xml:"KMSMasterKeyID,omitempty"`
    63  }
    64  
    65  // SSERule - for ServerSideEncryptionConfiguration XML tag
    66  type SSERule struct {
    67  	DefaultEncryptionAction EncryptionAction `xml:"ApplyServerSideEncryptionByDefault"`
    68  }
    69  
    70  const xmlNS = "http://s3.amazonaws.com/doc/2006-03-01/"
    71  
    72  // BucketSSEConfig - represents default bucket encryption configuration
    73  type BucketSSEConfig struct {
    74  	XMLNS   string    `xml:"xmlns,attr,omitempty"`
    75  	XMLName xml.Name  `xml:"ServerSideEncryptionConfiguration"`
    76  	Rules   []SSERule `xml:"Rule"`
    77  }
    78  
    79  // ParseBucketSSEConfig - Decodes given XML to a valid default bucket encryption config
    80  func ParseBucketSSEConfig(r io.Reader) (*BucketSSEConfig, error) {
    81  	var config BucketSSEConfig
    82  	err := xml.NewDecoder(r).Decode(&config)
    83  	if err != nil {
    84  		return nil, err
    85  	}
    86  
    87  	// Validates server-side encryption config rules
    88  	// Only one rule is allowed on AWS S3
    89  	if len(config.Rules) != 1 {
    90  		return nil, errors.New("only one server-side encryption rule is allowed at a time")
    91  	}
    92  
    93  	for _, rule := range config.Rules {
    94  		switch rule.DefaultEncryptionAction.Algorithm {
    95  		case AES256:
    96  			if rule.DefaultEncryptionAction.MasterKeyID != "" {
    97  				return nil, errors.New("MasterKeyID is allowed with aws:kms only")
    98  			}
    99  		case AWSKms:
   100  			if rule.DefaultEncryptionAction.MasterKeyID == "" {
   101  				return nil, errors.New("MasterKeyID is missing with aws:kms")
   102  			}
   103  		}
   104  	}
   105  
   106  	if config.XMLNS == "" {
   107  		config.XMLNS = xmlNS
   108  	}
   109  
   110  	return &config, nil
   111  }