private static async Task <byte[]> UnwrapKeyInternal(EncryptionData encryptionData, IKeyEncryptionKeyResolver keyResolver, bool async, CancellationToken cancellationToken) { IKeyEncryptionKey oldKey = async ? await keyResolver.ResolveAsync(encryptionData.WrappedContentKey.KeyId, cancellationToken).ConfigureAwait(false) : keyResolver.Resolve(encryptionData.WrappedContentKey.KeyId, cancellationToken); if (oldKey == default) { throw Errors.ClientSideEncryption.KeyNotFound(encryptionData.WrappedContentKey.KeyId); } return(async ? await oldKey.UnwrapKeyAsync( encryptionData.WrappedContentKey.Algorithm, encryptionData.WrappedContentKey.EncryptedKey, cancellationToken).ConfigureAwait(false) : oldKey.UnwrapKey( encryptionData.WrappedContentKey.Algorithm, encryptionData.WrappedContentKey.EncryptedKey, cancellationToken)); }
#pragma warning disable CS1587 // XML comment is not placed on a valid language element /// <summary> /// Returns the content encryption key for blob. First tries to get the key encryption key from KeyResolver, /// then falls back to IKey stored on this EncryptionPolicy. Unwraps the content encryption key with the /// correct key wrapper. /// </summary> /// <param name="encryptionData">The encryption data.</param> /// <param name="async">Whether to perform asynchronously.</param> /// <param name="cancellationToken"></param> /// <returns> /// Encryption key as a byte array. /// </returns> /// <exception cref="Exception"> /// Exceptions thrown based on implementations of <see cref="IKeyEncryptionKey"/> and /// <see cref="IKeyEncryptionKeyResolver"/>. /// </exception> private async Task <Memory <byte> > GetContentEncryptionKeyAsync( #pragma warning restore CS1587 // XML comment is not placed on a valid language element EncryptionData encryptionData, bool async, CancellationToken cancellationToken) { IKeyEncryptionKey key = default; // If we already have a local key and it is the correct one, use that. if (encryptionData.WrappedContentKey.KeyId == _potentialCachedIKeyEncryptionKey?.KeyId) { key = _potentialCachedIKeyEncryptionKey; } // Otherwise, use the resolver. else if (_keyResolver != null) { key = async ? await _keyResolver.ResolveAsync(encryptionData.WrappedContentKey.KeyId, cancellationToken).ConfigureAwait(false) : _keyResolver.Resolve(encryptionData.WrappedContentKey.KeyId, cancellationToken); } // We throw for every other reason that decryption couldn't happen. Throw a reasonable // exception here instead of nullref. if (key == default) { throw Errors.ClientSideEncryption.KeyNotFound(encryptionData.WrappedContentKey.KeyId); } return(async ? await key.UnwrapKeyAsync( encryptionData.WrappedContentKey.Algorithm, encryptionData.WrappedContentKey.EncryptedKey, cancellationToken).ConfigureAwait(false) : key.UnwrapKey( encryptionData.WrappedContentKey.Algorithm, encryptionData.WrappedContentKey.EncryptedKey, cancellationToken)); }