//Downloads and decrypts client side encrypted blob, then reuploads blob with server side encryption using an encryption scope with a customer managed key private static void EncryptWithCustomerManagedKey( string connectionString, string containerName, string blobName, string blobNameAfterMigration, string filePath, ClientSideEncryptionOptions clientSideOption, string encryptionScopeName) { //Download and decrypt Client Side Encrypted blob using BlobClient with Client Side Encryption Options string downloadFilePath = filePath + ".download"; BlobClient blobClient = new BlobClient( connectionString, containerName, blobName).WithClientSideEncryptionOptions(clientSideOption); blobClient.DownloadTo(downloadFilePath); //Set Blob Client Options with the created Encryption Scope BlobClientOptions blobClientOptions = new BlobClientOptions() { EncryptionScope = encryptionScopeName }; //Reupload Blob with Server Side Encryption blobClient = new BlobClient( connectionString, containerName, blobNameAfterMigration, blobClientOptions); blobClient.Upload(downloadFilePath, true); }
/*Creates example container and client side encrypted blob for sample * * NOTE: This program requires the following to be stored in the App.Config file: * Azure Active Directory Tenant ID - tenantId * Service Principal Application ID - clientId * Service Principal Password - clientSecret * Storage Account Connection String- connectionString * Client Side Key Vault Key Uri - clientSideKeyVaultKeyUri * Key Wrap Algorithm - keyWrapAlgorithm * * Creates example objects using names from Constants.cs, which may be edited as needed */ static void Main() { //Credentials of Service Principal TokenCredential credential = new ClientSecretCredential( Constants.TenantId, Constants.ClientId, Constants.ClientSecret ); //Get Uri for Key Vault key Uri keyVaultKeyUri = new Uri(Constants.ClientSideKeyVaultKeyUri); //Create CryptographyClient using Key Vault Key CryptographyClient cryptographyClient = new CryptographyClient(keyVaultKeyUri, credential); //Set up Client Side Encryption Options used for Client Side Encryption ClientSideEncryptionOptions clientSideOptions = new ClientSideEncryptionOptions(ClientSideEncryptionVersion.V1_0) { KeyEncryptionKey = cryptographyClient, KeyWrapAlgorithm = Constants.KeyWrapAlgorithm }; //Create Blob Service Client BlobServiceClient blobServiceClient = new BlobServiceClient(Constants.ConnectionString); //Run Setup Function that creates and example container and blob SetupForExample( blobServiceClient, Constants.ContainerName, Constants.BlobName, clientSideOptions); Console.WriteLine("Completed creation of example container and blob"); }
//Downloads and decrypts client side encrypted blob, then reuploads blob with server side encryption using a customer provided key private static void EncryptWithCustomerProvidedKey( string connectionString, string containerName, string blobName, string blobNameAfterMigration, string filePath, ClientSideEncryptionOptions clientSideOption, byte[] keyBytes) { //Download and decrypt Client Side Encrypted blob using BlobClient with Client Side Encryption Options string downloadFilePath = filePath + "download"; BlobClient blobClient = new BlobClient( connectionString, containerName, blobName).WithClientSideEncryptionOptions(clientSideOption); blobClient.DownloadTo(downloadFilePath); //Set Blob Client Options with the given Customer Provided Key CustomerProvidedKey customerProvidedKey = new CustomerProvidedKey(keyBytes); BlobClientOptions blobClientOptions = new BlobClientOptions() { CustomerProvidedKey = customerProvidedKey, }; //Reupload Blob with Server Side Encryption blobClient = new BlobClient( connectionString, containerName, blobNameAfterMigration, blobClientOptions); blobClient.Upload(downloadFilePath, true); }
/*Creates example container, client side encrypted blob, Key Vault key, and encryption scope for sample * * NOTE: This program requires the following to be stored in the App.Config file: * Subscription ID - subscriptionId * Resource Group Name - resourceGroup * Storage Account Name - storageAccount * Storage Account Connection String- connectionString * * Creates example objects using names from Constants.cs, which may be edited as needed */ public static void SetupForExample( BlobServiceClient blobService, string containerName, string fileName, string encryptionScopeName, ClientSideEncryptionOptions clientSideOption, string keyVaultName, string keyVaultKeyName, TokenCredential credential ) { //Create example Container and .txt file, upload .txt file as client side encrypted blob BlobContainerClient containerClient = blobService.CreateBlobContainer(containerName); //Create BlobClient with Client Side Encryption Options to upload client side encrypted data BlobClient blobClient = containerClient.GetBlobClient(fileName).WithClientSideEncryptionOptions(clientSideOption); //Upload blob with client side encryption blobClient.Upload(Path.Combine(Constants.SamplePath, Constants.BlobName)); Console.WriteLine("Uploaded to Blob storage as blob: \n\t {0}\n", blobClient.Uri); //Create key and use created key to create encryption scope KeyVaultKey keyVaultKey = Setup.CreateKeyVaultKey(keyVaultName, keyVaultKeyName, credential); Setup.CreateEncryptionScopeCMK(encryptionScopeName, keyVaultKey.Id); }
/*Creates example container, client side encrypted blob, Key Vault key, and encryption scope for sample * * NOTE: This program requires the following to be stored in the App.Config file: * Subscription ID - subscriptionId * Resource Group Name - resourceGroup * Storage Account Name - storageAccount * Storage Account Connection String- connectionString * Key Vault Name - keyVaultName * * Creates example objects using names from Constants.cs, which may be edited as needed */ static void Main() { //Creating Key Encryption Key object for Client Side Encryption SampleKeyEncryptionKey keyEncryption = new SampleKeyEncryptionKey(Constants.ClientSideCustomerProvidedKey); //Set up Client Side Encryption Options used for Client Side Encryption ClientSideEncryptionOptions clientSideOptions = new ClientSideEncryptionOptions(ClientSideEncryptionVersion.V1_0) { KeyEncryptionKey = keyEncryption, KeyWrapAlgorithm = Constants.KeyWrapAlgorithm }; //Create Blob Service Client BlobServiceClient blobServiceClient = new BlobServiceClient(Constants.ConnectionString); //Run Setup Function that creates and example container and blob SetupForExample( blobServiceClient, Constants.ContainerName, Constants.BlobName, Constants.EncryptionScopeName, clientSideOptions); Console.WriteLine("Completed creation of example container, blob, and encryption scope"); }
/// <summary> /// Extension method to clone an instance of <see cref="ClientSideEncryptionOptions"/>. /// </summary> /// <param name="options"></param> /// <returns></returns> public static ClientSideEncryptionOptions Clone(this ClientSideEncryptionOptions options) { var newOptions = new ClientSideEncryptionOptions(options.EncryptionVersion); CopyOptions(options, newOptions); return(newOptions); }
public static IClientSideEncryptor GetClientSideEncryptor(this ClientSideEncryptionOptions options) { return(options.EncryptionVersion switch { ClientSideEncryptionVersion.V1_0 => new ClientSideEncryptorV1_0(options), ClientSideEncryptionVersion.V2_0 => new ClientSideEncryptorV2_0(options), _ => throw Errors.ClientSideEncryption.ClientSideEncryptionVersionNotSupported() });
/// <summary> /// Initializes a new instance of the <see cref="QueueServiceClient"/> /// class. /// </summary> /// <param name="serviceUri"> /// A <see cref="Uri"/> referencing the queue service. /// This is likely to be similar to "https://{account_name}.queue.core.windows.net". /// </param> /// <param name="authentication"> /// An optional authentication policy used to sign requests. /// </param> /// <param name="options"> /// Optional client options that define the transport pipeline /// policies for authentication, retries, etc., that are applied to /// every request. /// </param> internal QueueServiceClient(Uri serviceUri, HttpPipelinePolicy authentication, QueueClientOptions options) { _uri = serviceUri; options ??= new QueueClientOptions(); _pipeline = options.Build(authentication); _version = options.Version; _clientDiagnostics = new ClientDiagnostics(options); _clientSideEncryption = QueueClientSideEncryptionOptions.CloneFrom(options._clientSideEncryptionOptions); }
/// <summary> /// Initializes a new instance of the <see cref="QueueServiceClient"/> /// class. /// </summary> /// <param name="connectionString"> /// A connection string includes the authentication information /// required for your application to access data in an Azure Storage /// account at runtime. /// /// For more information, see /// <see href="https://docs.microsoft.com/azure/storage/common/storage-configure-connection-string"> /// Configure Azure Storage connection strings</see>. /// </param> /// <param name="options"> /// Optional client options that define the transport pipeline /// policies for authentication, retries, etc., that are applied to /// every request. /// </param> public QueueServiceClient(string connectionString, QueueClientOptions options) { var conn = StorageConnectionString.Parse(connectionString); _uri = conn.QueueEndpoint; options ??= new QueueClientOptions(); _pipeline = options.Build(conn.Credentials); _version = options.Version; _clientDiagnostics = new ClientDiagnostics(options); _clientSideEncryption = QueueClientSideEncryptionOptions.CloneFrom(options._clientSideEncryptionOptions); }
/// <summary> /// Rotates the Key Encryption Key (KEK) for a client-side encrypted blob without /// needing to reupload the entire blob. /// </summary> /// <param name="client"> /// Client to the blob. /// </param> /// <param name="encryptionOptionsOverride"> /// Optional override for client-side encryption options to use when updating the key encryption key. /// Defaults to the <see cref="ClientSideEncryptionOptions"/> configured on the client when this is /// not populated. New key encryption key for the blob will be the /// <see cref="ClientSideEncryptionOptions.KeyEncryptionKey"/> on whichever encryption options are /// used for the operation. Options must have a resolver that can resolve the old key on the blob. /// </param> /// <param name="conditions"> /// Optional request conditions for the operation. /// </param> /// <param name="cancellationToken"> /// Cancellation token for the operation. /// </param> public static async Task UpdateClientSideKeyEncryptionKeyAsync( this BlobClient client, ClientSideEncryptionOptions encryptionOptionsOverride = default, BlobRequestConditions conditions = default, CancellationToken cancellationToken = default) => await UpdateClientsideKeyEncryptionKeyInternal( client, encryptionOptionsOverride, conditions, async : true, cancellationToken).ConfigureAwait(false);
/// <summary> /// Rotates the Key Encryption Key (KEK) for a client-side encrypted blob without /// needing to reupload the entire blob. /// </summary> /// <param name="client"> /// Client to the blob. /// </param> /// <param name="encryptionOptionsOverride"> /// Optional override for client-side encryption options to use when updating the key encryption key. /// Defaults to the <see cref="ClientSideEncryptionOptions"/> configured on the client when this is /// not populated. New key encryption key for the blob will be the /// <see cref="ClientSideEncryptionOptions.KeyEncryptionKey"/> on whichever encryption options are /// used for the operation. Options must have a resolver that can resolve the old key on the blob. /// </param> /// <param name="conditions"> /// Optional request conditions for the operation. /// </param> /// <param name="cancellationToken"> /// Cancellation token for the operation. /// </param> public static void UpdateClientSideKeyEncryptionKey( this BlobClient client, ClientSideEncryptionOptions encryptionOptionsOverride = default, BlobRequestConditions conditions = default, CancellationToken cancellationToken = default) => UpdateClientsideKeyEncryptionKeyInternal( client, encryptionOptionsOverride, conditions, async: false, cancellationToken).EnsureCompleted();
public ClientSideEncryptorV2_0(ClientSideEncryptionOptions options) { Argument.AssertNotNull(options, nameof(options)); if (options.EncryptionVersion != ClientSideEncryptionVersion.V2_0) { Errors.InvalidArgument(nameof(options.EncryptionVersion)); } _keyEncryptionKey = options.KeyEncryptionKey; _keyWrapAlgorithm = options.KeyWrapAlgorithm; }
/// <summary> /// Initializes a new instance of the <see cref="BlobClient"/> /// class. /// </summary> /// <param name="blobUri"> /// A <see cref="Uri"/> referencing the blob that includes the /// name of the account, the name of the container, and the name of /// the blob. /// This is likely to be similar to "https://{account_name}.blob.core.windows.net/{container_name}/{blob_name}". /// </param> /// <param name="pipeline"> /// The transport pipeline used to send every request. /// </param> /// <param name="version"> /// The version of the service to use when sending requests. /// </param> /// <param name="clientDiagnostics">Client diagnostics.</param> /// <param name="customerProvidedKey">Customer provided key.</param> /// <param name="clientSideEncryption">Client-side encryption options.</param> /// <param name="encryptionScope">Encryption scope.</param> internal BlobClient( Uri blobUri, HttpPipeline pipeline, BlobClientOptions.ServiceVersion version, ClientDiagnostics clientDiagnostics, CustomerProvidedKey?customerProvidedKey, ClientSideEncryptionOptions clientSideEncryption, string encryptionScope) : base(blobUri, pipeline, version, clientDiagnostics, customerProvidedKey, clientSideEncryption, encryptionScope) { }
/* * Program migrates a client side encrypted blob to server side encryption using Customer Provided Keys * * NOTE: This program requires the following to be stored in the App.Config file: * Azure Active Directory Tenant ID - tenantId * Service Principal Application ID - clientId * Storage Account Connection String- connectionString * Client Side Key Vault Key Uri - clientSideKeyVaultKeyUri * Key Wrap Algorithm - keyWrapAlgorithm * Container Name - containerName * Blob Name - blobName * Blob Name After Migration - blobNameAfterMigration * Customer Provided Key for Server Side Encryption - serverSideCustomerProvidedKey */ static void Main() { //Credentials of Service Principal TokenCredential credential = new ClientSecretCredential( Constants.TenantId, Constants.ClientId, Constants.ClientSecret ); //Get bytes for customer provided key byte[] localKeyBytes = ASCIIEncoding.UTF8.GetBytes(Constants.ServerSideCustomerProvidedKey); //File Path for local file used to download and reupload string localPath = "./data" + Guid.NewGuid().ToString() + "/"; Directory.CreateDirectory(localPath); string localFilePath = Path.Combine(localPath, Constants.BlobName); //Get Uri for Key Vault key Uri keyVaultKeyUri = new Uri(Constants.ClientSideKeyVaultKeyUri); //Create CryptographyClient using Key Vault Key CryptographyClient cryptographyClient = new CryptographyClient(keyVaultKeyUri, credential); //Set up Client Side Encryption Options used for Client Side Encryption ClientSideEncryptionOptions clientSideOptions = new ClientSideEncryptionOptions(ClientSideEncryptionVersion.V1_0) { KeyEncryptionKey = cryptographyClient, KeyWrapAlgorithm = Constants.KeyWrapAlgorithm }; try { //Convert Client Side Encryption Blob to Server Side Encrytion with Customer Provided Keys EncryptWithCustomerProvidedKey( Constants.ConnectionString, Constants.ContainerName, Constants.BlobName, Constants.BlobNameAfterMigration, localFilePath, clientSideOptions, localKeyBytes); } finally { //Delete downloaded files CleanUp(localPath); } Console.WriteLine("Completed migration to Customer Provided Key Server Side Encryption"); }
/// <summary> /// Initializes a new instance of the <see cref="QueueServiceClient"/> /// class. /// </summary> /// <param name="serviceUri"> /// A <see cref="Uri"/> referencing the queue service. /// This is likely to be similar to "https://{account_name}.queue.core.windows.net". /// </param> /// <param name="authentication"> /// An optional authentication policy used to sign requests. /// </param> /// <param name="options"> /// Optional client options that define the transport pipeline /// policies for authentication, retries, etc., that are applied to /// every request. /// </param> /// <param name="storageSharedKeyCredential"> /// The shared key credential used to sign requests. /// </param> internal QueueServiceClient( Uri serviceUri, HttpPipelinePolicy authentication, QueueClientOptions options, StorageSharedKeyCredential storageSharedKeyCredential) { _uri = serviceUri; options ??= new QueueClientOptions(); _pipeline = options.Build(authentication); _version = options.Version; _clientDiagnostics = new ClientDiagnostics(options); _clientSideEncryption = QueueClientSideEncryptionOptions.CloneFrom(options._clientSideEncryptionOptions); _storageSharedKeyCredential = storageSharedKeyCredential; _messageEncoding = options.MessageEncoding; }
//Creates example container and client side encrypted blob for sample public static void SetupForExample( BlobServiceClient blobService, string containerName, string fileName, ClientSideEncryptionOptions clientSideOption) { //Create example Container and .txt file, upload .txt file as client side encrypted blob BlobContainerClient containerClient = blobService.CreateBlobContainer(containerName); //Create BlobClient with Client Side Encryption Options to upload client side encrypted data BlobClient blobClient = containerClient.GetBlobClient(fileName).WithClientSideEncryptionOptions(clientSideOption); //Upload blob with client side encryption blobClient.Upload(Path.Combine(Constants.SamplePath, Constants.BlobName)); Console.WriteLine("Uploaded to Blob storage as blob: \n\t {0}\n", blobClient.Uri); }
/// <summary> /// Creates an encrypted queue client from a normal queue client. Note that this method does not copy over any /// client options from the container client. You must pass in your own options. These options will be mutated. /// </summary> public async Task <DisposingQueue> GetTestEncryptedQueueAsync( ClientSideEncryptionOptions encryptionOptions, string queueName = default, IDictionary <string, string> metadata = default) { // normally set through property on subclass; this is easier to hook up in current test infra with internals access var options = GetOptions(); options._clientSideEncryptionOptions = encryptionOptions; var service = GetServiceClient_SharedKey(options); metadata ??= new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); QueueClient queue = InstrumentClient(service.GetQueueClient(GetNewQueueName())); return(await DisposingQueue.CreateAsync(queue, metadata)); }
private async Task <DisposingContainer> GetTestContainerEncryptionAsync( ClientSideEncryptionOptions encryptionOptions, string containerName = default, IDictionary <string, string> metadata = default) { // normally set through property on subclass; this is easier to hook up in current test infra with internals access var options = GetOptions(); options._clientSideEncryptionOptions = encryptionOptions; containerName ??= GetNewContainerName(); var service = GetServiceClient_SharedKey(options); BlobContainerClient container = InstrumentClient(service.GetBlobContainerClient(containerName)); await container.CreateAsync(metadata : metadata); return(new DisposingContainer(container)); }
/* * Program migrates a client side encrypted blob to server side encryption using customer provided keys * * NOTE: This program requires the following to be stored in the App.Config file: * Storage Account Connection String- connectionString * Key Wrap Algorithm for Client Side Encryption - keyWrapAlgorithm * Customer Provided Key for Client Side Encryption - clientSideCustomerProvidedKey * Container Name - containerName * Blob Name - blobName * Blob Name After Migration - blobNameAfterMigration * Customer Provided Key for Server Side Encryption - serverSideCustomerProvidedKey */ static void Main() { //Get bytes for customer provided key byte[] localKeyBytes = ASCIIEncoding.UTF8.GetBytes(Constants.ServerSideCustomerProvidedKey); //File Path for local file used to download and reupload string localPath = "./data" + Guid.NewGuid().ToString() + "/"; Directory.CreateDirectory(localPath); string localFilePath = Path.Combine(localPath, Constants.BlobName); //Creating Key Encryption Key object for Client Side Encryption SampleKeyEncryptionKey keyEncryption = new SampleKeyEncryptionKey(Constants.ClientSideCustomerProvidedKey); //Set up Client Side Encryption Options used for Client Side Encryption ClientSideEncryptionOptions clientSideOptions = new ClientSideEncryptionOptions(ClientSideEncryptionVersion.V1_0) { KeyEncryptionKey = keyEncryption, KeyWrapAlgorithm = Constants.KeyWrapAlgorithm }; try { //Convert Client Side Encryption Blob to Server Side Encrytion with Customer Provided Keys EncryptWithCustomerProvidedKey( Constants.ConnectionString, Constants.ContainerName, Constants.BlobName, Constants.BlobNameAfterMigration, localFilePath, clientSideOptions, localKeyBytes); } finally { //Delete downloaded files CleanUp(localPath); } Console.WriteLine("Completed Migration to Customer Provided Key Server Side Encryption"); }
public async Task HashingAndClientSideEncryptionIncompatible(TransactionalHashAlgorithm algorithm) { await using var disposingContainer = await GetDisposingContainerAsync(); // Arrange const int dataSize = Constants.KB; var data = GetRandomBuffer(dataSize); var hashingOptions = new UploadTransactionalHashingOptions { Algorithm = algorithm }; var encryptionOptions = new ClientSideEncryptionOptions(ClientSideEncryptionVersion.V1_0) { KeyEncryptionKey = new Mock <Core.Cryptography.IKeyEncryptionKey>().Object, KeyWrapAlgorithm = "foo" }; var clientOptions = ClientBuilder.GetOptions(); clientOptions._clientSideEncryptionOptions = encryptionOptions; var client = await GetResourceClientAsync( disposingContainer.Container, resourceLength : dataSize, createResource : true, options : clientOptions); // Act using var stream = new MemoryStream(data); var exception = Assert.ThrowsAsync <ArgumentException>(async() => await ParallelUploadAsync(client, stream, hashingOptions, transferOptions: default)); Assert.AreEqual("Client-side encryption and transactional hashing are not supported at the same time.", exception.Message); }
private static async Task UpdateClientsideKeyEncryptionKeyInternal( BlobClient client, ClientSideEncryptionOptions encryptionOptionsOverride, BlobRequestConditions conditions, bool async, CancellationToken cancellationToken) { // argument validation Argument.AssertNotNull(client, nameof(client)); ClientSideEncryptionOptions operationEncryptionOptions = encryptionOptionsOverride ?? client.ClientSideEncryption ?? throw new ArgumentException($"{nameof(ClientSideEncryptionOptions)} are not configured on this client and none were provided for the operation."); Argument.AssertNotNull(operationEncryptionOptions.KeyEncryptionKey, nameof(ClientSideEncryptionOptions.KeyEncryptionKey)); Argument.AssertNotNull(operationEncryptionOptions.KeyResolver, nameof(ClientSideEncryptionOptions.KeyResolver)); Argument.AssertNotNull(operationEncryptionOptions.KeyWrapAlgorithm, nameof(ClientSideEncryptionOptions.KeyWrapAlgorithm)); using (client.ClientConfiguration.Pipeline.BeginLoggingScope(nameof(BlobClient))) { client.ClientConfiguration.Pipeline.LogMethodEnter( nameof(BlobBaseClient), message: $"{nameof(Uri)}: {client.Uri}\n" + $"{nameof(conditions)}: {conditions}"); DiagnosticScope scope = client.ClientConfiguration.ClientDiagnostics.CreateScope($"{nameof(BlobClient)}.{nameof(UpdateClientSideKeyEncryptionKey)}"); try { // hold onto etag, metadata, encryptiondata BlobProperties getPropertiesResponse = await client.GetPropertiesInternal(conditions, async, cancellationToken).ConfigureAwait(false); ETag etag = getPropertiesResponse.ETag; IDictionary <string, string> metadata = getPropertiesResponse.Metadata; EncryptionData encryptionData = BlobClientSideDecryptor.GetAndValidateEncryptionDataOrDefault(metadata) ?? throw new InvalidOperationException("Resource has no client-side encryption key to rotate."); // rotate keywrapping byte[] newWrappedKey = await WrapKeyInternal( await UnwrapKeyInternal( encryptionData, operationEncryptionOptions.KeyResolver, async, cancellationToken).ConfigureAwait(false), operationEncryptionOptions.KeyWrapAlgorithm, operationEncryptionOptions.KeyEncryptionKey, async, cancellationToken).ConfigureAwait(false); // set new wrapped key info and reinsert into metadata encryptionData.WrappedContentKey = new KeyEnvelope { EncryptedKey = newWrappedKey, Algorithm = operationEncryptionOptions.KeyWrapAlgorithm, KeyId = operationEncryptionOptions.KeyEncryptionKey.KeyId }; metadata[Constants.ClientSideEncryption.EncryptionDataKey] = EncryptionDataSerializer.Serialize(encryptionData); // update blob ONLY IF ETAG MATCHES (do not take chances encryption info is now out of sync) BlobRequestConditions modifiedRequestConditions = BlobRequestConditions.CloneOrDefault(conditions) ?? new BlobRequestConditions(); modifiedRequestConditions.IfMatch = etag; await client.SetMetadataInternal(metadata, modifiedRequestConditions, async, cancellationToken).ConfigureAwait(false); } catch (Exception ex) { client.ClientConfiguration.Pipeline.LogException(ex); scope.Failed(ex); throw; } finally { client.ClientConfiguration.Pipeline.LogMethodExit(nameof(BlobBaseClient)); scope.Dispose(); } } }
/// <summary> /// Copies all properties from one instance to another. It cannot copy /// <see cref="ClientSideEncryptionOptions.EncryptionVersion"/>; /// that is the responsibility of the caller who made the instance. /// </summary> /// <param name="source">Object to copy from.</param> /// <param name="destination">Object to copy to.</param> /// <remarks> /// This functionality has been pulled out to be accessible by other /// clone methods available on subclasses. They need the ability to /// instantiate the subclass destination first before copying over the /// properties. /// </remarks> internal static void CopyOptions(ClientSideEncryptionOptions source, ClientSideEncryptionOptions destination) { destination.KeyEncryptionKey = source.KeyEncryptionKey; destination.KeyResolver = source.KeyResolver; destination.KeyWrapAlgorithm = source.KeyWrapAlgorithm; }
/// <summary> /// Clones the given <see cref="ClientSideEncryptionOptions"/> as an instance of /// <see cref="QueueClientSideEncryptionOptions"/>. If the given instance is also a /// <see cref="QueueClientSideEncryptionOptions"/>, this clones it's specialty data as well. /// </summary> /// <returns></returns> internal static QueueClientSideEncryptionOptions CloneFrom(ClientSideEncryptionOptions options) { if (options == default) { return(default);
public ClientSideDecryptor(ClientSideEncryptionOptions options) { _potentialCachedIKeyEncryptionKey = options.KeyEncryptionKey; _keyResolver = options.KeyResolver; }
public ClientSideEncryptor(ClientSideEncryptionOptions options) { _keyEncryptionKey = options.KeyEncryptionKey; _keyWrapAlgorithm = options.KeyWrapAlgorithm; }