github.com/aavshr/aws-sdk-go@v1.41.3/service/s3/s3crypto/encryption_client_v2.go (about)

     1  package s3crypto
     2  
     3  import (
     4  	"github.com/aavshr/aws-sdk-go/aws"
     5  	"github.com/aavshr/aws-sdk-go/aws/client"
     6  	"github.com/aavshr/aws-sdk-go/aws/request"
     7  	"github.com/aavshr/aws-sdk-go/service/s3"
     8  	"github.com/aavshr/aws-sdk-go/service/s3/s3iface"
     9  )
    10  
    11  const customTypeWarningMessage = "WARNING: The S3 Encryption Client is configured to write encrypted objects using types not provided by AWS. Security and compatibility with these types can not be guaranteed."
    12  
    13  // EncryptionClientV2 is an S3 crypto client. By default the SDK will use Authentication mode which
    14  // will use KMS for key wrapping and AES GCM for content encryption.
    15  // AES GCM will load all data into memory. However, the rest of the content algorithms
    16  // do not load the entire contents into memory.
    17  type EncryptionClientV2 struct {
    18  	options EncryptionClientOptions
    19  }
    20  
    21  // EncryptionClientOptions is the configuration options for EncryptionClientV2
    22  type EncryptionClientOptions struct {
    23  	S3Client             s3iface.S3API
    24  	ContentCipherBuilder ContentCipherBuilder
    25  	// SaveStrategy will dictate where the envelope is saved.
    26  	//
    27  	// Defaults to the object's metadata
    28  	SaveStrategy SaveStrategy
    29  	// TempFolderPath is used to store temp files when calling PutObject.
    30  	// Temporary files are needed to compute the X-Amz-Content-Sha256 header.
    31  	TempFolderPath string
    32  	// MinFileSize is the minimum size for the content to write to a
    33  	// temporary file instead of using memory.
    34  	MinFileSize int64
    35  }
    36  
    37  // NewEncryptionClientV2 instantiates a new S3 crypto client. An error will be returned to the caller if the provided
    38  // contentCipherBuilder has been deprecated or was constructed with a deprecated component.
    39  //
    40  // Example:
    41  //	cmkID := "arn:aws:kms:region:000000000000:key/00000000-0000-0000-0000-000000000000"
    42  //  sess := session.Must(session.NewSession())
    43  //	var matdesc s3crypto.MaterialDescription
    44  //	handler := s3crypto.NewKMSContextKeyGenerator(kms.New(sess), cmkID, matdesc)
    45  //	svc := s3crypto.NewEncryptionClientV2(sess, s3crypto.AESGCMContentCipherBuilderV2(handler))
    46  func NewEncryptionClientV2(prov client.ConfigProvider, contentCipherBuilder ContentCipherBuilder, options ...func(clientOptions *EncryptionClientOptions),
    47  ) (
    48  	client *EncryptionClientV2, err error,
    49  ) {
    50  	s3client := s3.New(prov)
    51  	s3client.Handlers.Build.PushBack(func(r *request.Request) {
    52  		request.AddToUserAgent(r, "S3CryptoV2")
    53  	})
    54  
    55  	clientOptions := &EncryptionClientOptions{
    56  		S3Client:             s3client,
    57  		ContentCipherBuilder: contentCipherBuilder,
    58  		SaveStrategy:         HeaderV2SaveStrategy{},
    59  		MinFileSize:          DefaultMinFileSize,
    60  	}
    61  	for _, option := range options {
    62  		option(clientOptions)
    63  	}
    64  
    65  	// Check that the configured client uses a compatible ContentCipherBuilder.
    66  	// User provided types will not implement this method
    67  	if fixture, ok := contentCipherBuilder.(compatibleEncryptionFixture); ok {
    68  		if err := fixture.isEncryptionVersionCompatible(v2ClientVersion); err != nil {
    69  			return nil, err
    70  		}
    71  	}
    72  
    73  	// Check if the passed in type is an fixture, if not log a warning message to the user
    74  	if fixture, ok := contentCipherBuilder.(awsFixture); !ok || !fixture.isAWSFixture() {
    75  		if s3client.Config.Logger != nil {
    76  			s3client.Config.Logger.Log(customTypeWarningMessage)
    77  		}
    78  	}
    79  
    80  	client = &EncryptionClientV2{
    81  		*clientOptions,
    82  	}
    83  
    84  	return client, err
    85  }
    86  
    87  // PutObjectRequest creates a temp file to encrypt the contents into. It then streams
    88  // that data to S3.
    89  //
    90  // Example:
    91  //	req, out := svc.PutObjectRequest(&s3.PutObjectInput {
    92  //	  Key: aws.String("testKey"),
    93  //	  Bucket: aws.String("testBucket"),
    94  //	  Body: strings.NewReader("test data"),
    95  //	})
    96  //	err := req.Send()
    97  func (c *EncryptionClientV2) PutObjectRequest(input *s3.PutObjectInput) (*request.Request, *s3.PutObjectOutput) {
    98  	return putObjectRequest(c.options, input)
    99  }
   100  
   101  // PutObject is a wrapper for PutObjectRequest
   102  func (c *EncryptionClientV2) PutObject(input *s3.PutObjectInput) (*s3.PutObjectOutput, error) {
   103  	return putObject(c.options, input)
   104  }
   105  
   106  // PutObjectWithContext is a wrapper for PutObjectRequest with the additional
   107  // context, and request options support.
   108  //
   109  // PutObjectWithContext is the same as PutObject with the additional support for
   110  // Context input parameters. The Context must not be nil. A nil Context will
   111  // cause a panic. Use the Context to add deadlining, timeouts, etc. In the future
   112  // this may create sub-contexts for individual underlying requests.
   113  func (c *EncryptionClientV2) PutObjectWithContext(ctx aws.Context, input *s3.PutObjectInput, opts ...request.Option) (*s3.PutObjectOutput, error) {
   114  	return putObjectWithContext(c.options, ctx, input, opts...)
   115  }