/* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ using Amazon.Runtime; using Amazon.Runtime.SharedInterfaces; using Amazon.Runtime.SharedInterfaces.Internal; using Amazon.S3.Internal; using Amazon.S3.Model; using System.Collections.Generic; using Amazon.KeyManagementService; using Amazon.S3; namespace Amazon.Extensions.S3.Encryption { /// /// Base class for AmazonS3Encryption clients /// Encapsulates common properties and methods of the encryption clients /// public abstract class AmazonS3EncryptionClientBase : AmazonS3Client, IAmazonS3Encryption { private IAmazonKeyManagementService kmsClient; private readonly object kmsClientLock = new object(); internal EncryptionMaterialsBase EncryptionMaterials { get; private set; } internal IAmazonKeyManagementService KMSClient { get { if (kmsClient == null) { lock (kmsClientLock) { if (kmsClient == null) { var kmsConfig = new AmazonKeyManagementServiceConfig { RegionEndpoint = this.Config.RegionEndpoint, Timeout = this.Config.Timeout }; var proxySettings = this.Config.GetWebProxy(); if(proxySettings != null) { kmsConfig.SetWebProxy(proxySettings); } kmsClient = new AmazonKeyManagementServiceClient(Credentials, kmsConfig); } } } return kmsClient; } } private AmazonS3Client s3ClientForInstructionFile; internal AmazonS3Client S3ClientForInstructionFile { get { if (s3ClientForInstructionFile == null) { s3ClientForInstructionFile = new AmazonS3Client(Credentials, S3CryptoConfig); } return s3ClientForInstructionFile; } } internal AmazonS3CryptoConfigurationBase S3CryptoConfig { get; set; } #if BCL35 internal readonly Amazon.Extensions.S3.Encryption.Utils.ConcurrentDictionary CurrentMultiPartUploadKeys = new Amazon.Extensions.S3.Encryption.Utils.ConcurrentDictionary(); internal readonly Amazon.Extensions.S3.Encryption.Utils.ConcurrentDictionary AllMultiPartUploadRequestContexts = new Amazon.Extensions.S3.Encryption.Utils.ConcurrentDictionary(); #else internal readonly System.Collections.Concurrent.ConcurrentDictionary CurrentMultiPartUploadKeys = new System.Collections.Concurrent.ConcurrentDictionary(); internal readonly System.Collections.Concurrent.ConcurrentDictionary AllMultiPartUploadRequestContexts = new System.Collections.Concurrent.ConcurrentDictionary(); #endif internal const string S3CryptoStream = "S3-Crypto-Stream"; #region Constructors /// /// Constructs AmazonS3EncryptionClient with the Encryption materials and credentials loaded from the application's /// default configuration, and if unsuccessful from the Instance Profile service on an EC2 instance. /// /// Example App.config with credentials set. /// /// <?xml version="1.0" encoding="utf-8" ?> /// <configuration> /// <appSettings> /// <add key="AWSProfileName" value="AWS Default"/> /// </appSettings> /// </configuration> /// /// /// /// /// The encryption materials to be used to encrypt and decrypt envelope key. /// public AmazonS3EncryptionClientBase(EncryptionMaterialsBase materials) : base() { this.EncryptionMaterials = materials; } /// /// Constructs AmazonS3EncryptionClient with the Encryption materials and credentials loaded from the application's /// default configuration, and if unsuccessful from the Instance Profile service on an EC2 instance. /// /// Example App.config with credentials set. /// /// <?xml version="1.0" encoding="utf-8" ?> /// <configuration> /// <appSettings> /// <add key="AWSProfileName" value="AWS Default"/> /// </appSettings> /// </configuration> /// /// /// /// /// The region to connect. /// /// /// The encryption materials to be used to encrypt and decrypt envelope key. /// public AmazonS3EncryptionClientBase(RegionEndpoint region, EncryptionMaterialsBase materials) : base(region) { this.EncryptionMaterials = materials; } /// /// Constructs AmazonS3EncryptionClient with the Encryption materials, /// AmazonS3 CryptoConfiguration object and credentials loaded from the application's /// default configuration, and if unsuccessful from the Instance Profile service on an EC2 instance. /// /// Example App.config with credentials set. /// /// <?xml version="1.0" encoding="utf-8" ?> /// <configuration> /// <appSettings> /// <add key="AWSProfileName" value="AWS Default"/> /// </appSettings> /// </configuration> /// /// /// /// /// The AmazonS3EncryptionClient CryptoConfiguration Object /// /// /// The encryption materials to be used to encrypt and decrypt envelope key. /// public AmazonS3EncryptionClientBase(AmazonS3CryptoConfigurationBase config, EncryptionMaterialsBase materials) : base(config) { this.EncryptionMaterials = materials; S3CryptoConfig = config; } /// /// Constructs AmazonS3EncryptionClient with AWS Credentials and Encryption materials. /// /// /// The encryption materials to be used to encrypt and decrypt envelope key. /// /// AWS Credentials public AmazonS3EncryptionClientBase(AWSCredentials credentials, EncryptionMaterialsBase materials) : base(credentials) { this.EncryptionMaterials = materials; } /// /// Constructs AmazonS3EncryptionClient with AWS Credentials, Region and Encryption materials /// /// AWS Credentials /// The region to connect. /// /// The encryption materials to be used to encrypt and decrypt envelope key. /// public AmazonS3EncryptionClientBase(AWSCredentials credentials, RegionEndpoint region, EncryptionMaterialsBase materials) : base(credentials, region) { this.EncryptionMaterials = materials; } /// /// Constructs AmazonS3EncryptionClient with AWS Credentials, AmazonS3CryptoConfigurationBase Configuration object /// and Encryption materials /// /// AWS Credentials /// The AmazonS3EncryptionClient CryptoConfiguration Object /// /// The encryption materials to be used to encrypt and decrypt envelope key. /// public AmazonS3EncryptionClientBase(AWSCredentials credentials, AmazonS3CryptoConfigurationBase config, EncryptionMaterialsBase materials) : base(credentials, config) { this.EncryptionMaterials = materials; S3CryptoConfig = config; } /// /// Constructs AmazonS3EncryptionClient with AWS Access Key ID, /// AWS Secret Key and Encryption materials /// /// AWS Access Key ID /// AWS Secret Access Key /// The encryption materials to be used to encrypt and decrypt envelope key. public AmazonS3EncryptionClientBase(string awsAccessKeyId, string awsSecretAccessKey, EncryptionMaterialsBase materials) : base(awsAccessKeyId, awsSecretAccessKey) { this.EncryptionMaterials = materials; } /// /// Constructs AmazonS3EncryptionClient with AWS Access Key ID, /// AWS Secret Key, Region and Encryption materials /// /// AWS Access Key ID /// AWS Secret Access Key /// The region to connect. /// The encryption materials to be used to encrypt and decrypt envelope key. public AmazonS3EncryptionClientBase(string awsAccessKeyId, string awsSecretAccessKey, RegionEndpoint region, EncryptionMaterialsBase materials) : base(awsAccessKeyId, awsSecretAccessKey, region) { this.EncryptionMaterials = materials; } /// /// Constructs AmazonS3EncryptionClient with AWS Access Key ID, Secret Key, /// AmazonS3 CryptoConfiguration object and Encryption materials. /// /// AWS Access Key ID /// AWS Secret Access Key /// The AmazonS3EncryptionClient CryptoConfiguration Object /// The encryption materials to be used to encrypt and decrypt envelope key. public AmazonS3EncryptionClientBase(string awsAccessKeyId, string awsSecretAccessKey, AmazonS3CryptoConfigurationBase config, EncryptionMaterialsBase materials) : base(awsAccessKeyId, awsSecretAccessKey, config) { this.EncryptionMaterials = materials; S3CryptoConfig = config; } /// /// Constructs AmazonS3EncryptionClient with AWS Access Key ID, Secret Key, /// SessionToken and Encryption materials. /// /// AWS Access Key ID /// AWS Secret Access Key /// AWS Session Token /// /// The encryption materials to be used to encrypt and decrypt envelope key. /// public AmazonS3EncryptionClientBase(string awsAccessKeyId, string awsSecretAccessKey, string awsSessionToken, EncryptionMaterialsBase materials) : base(awsAccessKeyId, awsSecretAccessKey, awsSessionToken) { this.EncryptionMaterials = materials; } /// /// Constructs AmazonS3EncryptionClient with AWS Access Key ID, Secret Key, /// SessionToken, Region and Encryption materials. /// /// AWS Access Key ID /// AWS Secret Access Key /// AWS Session Token /// The region to connect. /// The encryption materials to be used to encrypt and decrypt envelope key. public AmazonS3EncryptionClientBase(string awsAccessKeyId, string awsSecretAccessKey, string awsSessionToken, RegionEndpoint region, EncryptionMaterialsBase materials) : base(awsAccessKeyId, awsSecretAccessKey, awsSessionToken, region) { this.EncryptionMaterials = materials; } /// /// Constructs AmazonS3EncryptionClient with AWS Access Key ID, Secret Key, SessionToken /// AmazonS3EncryptionClient CryptoConfiguration object and Encryption materials. /// /// AWS Access Key ID /// AWS Secret Access Key /// AWS Session Token /// The AmazonS3EncryptionClient CryptoConfiguration Object /// /// The encryption materials to be used to encrypt and decrypt envelope key. /// public AmazonS3EncryptionClientBase(string awsAccessKeyId, string awsSecretAccessKey, string awsSessionToken, AmazonS3CryptoConfigurationBase config, EncryptionMaterialsBase materials) : base(awsAccessKeyId, awsSecretAccessKey, awsSessionToken, config) { this.EncryptionMaterials = materials; S3CryptoConfig = config; } #endregion /// /// Turn off response logging because it will interfere with decrypt of the data coming back from S3. /// protected override bool SupportResponseLogging { get { return false; } } /// /// Dispose this instance /// /// protected override void Dispose(bool disposing) { lock (kmsClientLock) { if (kmsClient != null) { kmsClient.Dispose(); kmsClient = null; } } base.Dispose(disposing); } } }