Exemple #1
0
        internal async Task <(byte[], EncryptionKeyWrapMetadata, InMemoryRawDek)> WrapAsync(
            byte[] key,
            CosmosEncryptionAlgorithm encryptionAlgorithmId,
            EncryptionKeyWrapMetadata metadata,
            CosmosDiagnosticsContext diagnosticsContext,
            CancellationToken cancellationToken)
        {
            EncryptionKeyWrapProvider encryptionKeyWrapProvider = this.ClientContext.ClientOptions.EncryptionKeyWrapProvider;

            if (encryptionKeyWrapProvider == null)
            {
                throw new ArgumentException(ClientResources.EncryptionKeyWrapProviderNotConfigured);
            }

            EncryptionKeyWrapResult keyWrapResponse;

            using (diagnosticsContext.CreateScope("WrapDataEncryptionKey"))
            {
                keyWrapResponse = await encryptionKeyWrapProvider.WrapKeyAsync(key, metadata, cancellationToken);
            }

            // Verify
            DataEncryptionKeyProperties tempDekProperties = new DataEncryptionKeyProperties(this.Id, encryptionAlgorithmId, keyWrapResponse.WrappedDataEncryptionKey, keyWrapResponse.EncryptionKeyWrapMetadata);
            InMemoryRawDek roundTripResponse = await this.UnwrapAsync(tempDekProperties, diagnosticsContext, cancellationToken);

            if (!roundTripResponse.RawDek.SequenceEqual(key))
            {
                throw CosmosExceptionFactory.CreateBadRequestException(ClientResources.KeyWrappingDidNotRoundtrip,
                                                                       diagnosticsContext: diagnosticsContext);
            }

            return(keyWrapResponse.WrappedDataEncryptionKey, keyWrapResponse.EncryptionKeyWrapMetadata, roundTripResponse);
        }
Exemple #2
0
        internal async Task <(DataEncryptionKeyProperties, InMemoryRawDek)> FetchUnwrappedAsync(
            CosmosDiagnosticsContext diagnosticsContext,
            CancellationToken cancellationToken)
        {
            DataEncryptionKeyProperties dekProperties = null;

            try
            {
                dekProperties = await this.ClientContext.DekCache.GetOrAddByNameLinkUriAsync(
                    this.LinkUri,
                    this.Database.Id,
                    this.ReadResourceAsync,
                    diagnosticsContext,
                    cancellationToken);
            }
            catch (CosmosException ex) when(ex.StatusCode == HttpStatusCode.NotFound)
            {
                throw CosmosExceptionFactory.CreateNotFoundException(
                          ClientResources.DataEncryptionKeyNotFound,
                          diagnosticsContext: diagnosticsContext,
                          innerException: ex);
            }

            InMemoryRawDek inMemoryRawDek = await this.ClientContext.DekCache.GetOrAddRawDekAsync(
                dekProperties,
                this.UnwrapAsync,
                diagnosticsContext,
                cancellationToken);

            return(dekProperties, inMemoryRawDek);
        }
Exemple #3
0
        internal async Task <(DataEncryptionKeyProperties, InMemoryRawDek)> FetchUnwrappedByRidAsync(
            string rid,
            CosmosDiagnosticsContext diagnosticsContext,
            CancellationToken cancellationToken)
        {
            string dekRidSelfLink = PathsHelper.GeneratePath(ResourceType.ClientEncryptionKey, rid, isFeed: false);

            // Server self links end with / but client generate links don't - match them.
            if (!dekRidSelfLink.EndsWith("/"))
            {
                dekRidSelfLink += "/";
            }

            DataEncryptionKeyProperties dekProperties = null;

            try
            {
                dekProperties = await this.ClientContext.DekCache.GetOrAddByRidSelfLinkAsync(
                    dekRidSelfLink,
                    this.Database.Id,
                    this.ReadResourceByRidSelfLinkAsync,
                    this.LinkUri,
                    diagnosticsContext,
                    cancellationToken);
            }
            catch (CosmosException ex) when(ex.StatusCode == HttpStatusCode.NotFound)
            {
                throw CosmosExceptionFactory.CreateNotFoundException(
                          ClientResources.DataEncryptionKeyNotFound,
                          diagnosticsContext: diagnosticsContext,
                          innerException: ex);
            }

            InMemoryRawDek inMemoryRawDek = await this.ClientContext.DekCache.GetOrAddRawDekAsync(
                dekProperties,
                this.UnwrapAsync,
                diagnosticsContext,
                cancellationToken);

            return(dekProperties, inMemoryRawDek);
        }
        public async Task <InMemoryRawDek> GetOrAddRawDekAsync(
            DataEncryptionKeyProperties dekProperties,
            Func <DataEncryptionKeyProperties, CosmosDiagnosticsContext, CancellationToken, Task <InMemoryRawDek> > unwrapper,
            CosmosDiagnosticsContext diagnosticsContext,
            CancellationToken cancellationToken)
        {
            InMemoryRawDek inMemoryRawDek = await this.RawDekByRidSelfLinkCache.GetAsync(
                dekProperties.SelfLink,
                null,
                () => unwrapper(dekProperties, diagnosticsContext, cancellationToken),
                cancellationToken);

            if (inMemoryRawDek.RawDekExpiry <= DateTime.UtcNow)
            {
                inMemoryRawDek = await this.RawDekByRidSelfLinkCache.GetAsync(
                    dekProperties.SelfLink,
                    null,
                    () => unwrapper(dekProperties, diagnosticsContext, cancellationToken),
                    cancellationToken,
                    forceRefresh : true);
            }

            return(inMemoryRawDek);
        }
 public void SetRawDek(string dekRidSelfLink, InMemoryRawDek inMemoryRawDek)
 {
     this.RawDekByRidSelfLinkCache.Set(dekRidSelfLink, inMemoryRawDek);
 }