From 7dc5785381902e826e1045890208f71ff0c7264a Mon Sep 17 00:00:00 2001
From: Cheena Malhotra <13396919+cheenamalhotra@users.noreply.github.com>
Date: Tue, 21 Mar 2023 21:26:11 -0700
Subject: [PATCH] Handle Encryption keys changed notification (#1955)
---
.../MSALEncryptedCacheHelper.cs | 4 +-
.../Connection/ConnectionService.cs | 53 ++++---------------
.../Contracts/EncryptionKeysChange.cs | 46 ++++++++++++++++
3 files changed, 58 insertions(+), 45 deletions(-)
create mode 100644 src/Microsoft.SqlTools.ServiceLayer/Connection/Contracts/EncryptionKeysChange.cs
diff --git a/src/Microsoft.SqlTools.Authentication/MSALEncryptedCacheHelper.cs b/src/Microsoft.SqlTools.Authentication/MSALEncryptedCacheHelper.cs
index 5371a90b..805b7360 100644
--- a/src/Microsoft.SqlTools.Authentication/MSALEncryptedCacheHelper.cs
+++ b/src/Microsoft.SqlTools.Authentication/MSALEncryptedCacheHelper.cs
@@ -28,7 +28,7 @@ namespace Microsoft.SqlTools.Authentication.Utility
///
/// (out) Key used for encryption/decryption
/// (out) IV used for encryption/decryption
- public delegate void IvKeyReadCallback(out string key, out string iv);
+ public delegate (string key, string iv) IvKeyReadCallback();
///
/// Lock objects for serialization
@@ -97,7 +97,7 @@ namespace Microsoft.SqlTools.Authentication.Utility
{
if (this._key == null || this._iv == null)
{
- this._ivKeyReadCallback(out string key, out string iv);
+ (string key, string iv) = this._ivKeyReadCallback();
if (key != null)
{
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Connection/ConnectionService.cs b/src/Microsoft.SqlTools.ServiceLayer/Connection/ConnectionService.cs
index e946123e..14802cd7 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Connection/ConnectionService.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/Connection/ConnectionService.cs
@@ -26,8 +26,6 @@ using Microsoft.SqlTools.Utility;
using static Microsoft.SqlTools.Shared.Utility.Constants;
using System.Diagnostics;
using Microsoft.SqlTools.Authentication.Sql;
-using Microsoft.SqlTools.Credentials;
-using Microsoft.SqlTools.Credentials.Contracts;
using Microsoft.SqlTools.Authentication;
using Microsoft.SqlTools.Shared.Utility;
using System.IO;
@@ -69,6 +67,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
///
private IAuthenticator authenticator;
+ ///
+ /// IV and Key as received from Encryption Key Notification event.
+ ///
+ private (string key, string iv) encryptionKeys;
+
///
/// The SQL connection factory object
///
@@ -1104,6 +1107,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
serviceHost.SetRequestHandler(ChangeDatabaseRequest.Type, HandleChangeDatabaseRequest, true);
serviceHost.SetRequestHandler(GetConnectionStringRequest.Type, HandleGetConnectionStringRequest, true);
serviceHost.SetRequestHandler(BuildConnectionInfoRequest.Type, HandleBuildConnectionInfoRequest, true);
+ serviceHost.SetEventHandler(EncryptionKeysChangedNotification.Type, HandleEncryptionKeysNotificationEvent, false);
}
///
@@ -1163,50 +1167,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
}
var cachePath = Path.Combine(applicationPath, applicationName, AzureTokenFolder);
- return new Authenticator(new (ApplicationClientId, applicationName, cachePath, MsalCacheName), ReadCacheIvKey);
+ return new Authenticator(new (ApplicationClientId, applicationName, cachePath, MsalCacheName), () => this.encryptionKeys);
}
- private void ReadCacheIvKey(out string? key, out string? iv)
+ private Task HandleEncryptionKeysNotificationEvent(EncryptionKeysChangeParams @params, EventContext context)
{
- Logger.Verbose("Reading Cached IV and Key from OS credential store.");
-
- iv = null;
- key = null;
- try
- {
- // Read Cached Iv for MSAL cache (as Unicode)
- Credential ivCred = CredentialService.Instance.ReadCredential(new($"{AzureAccountProviderCredentials}|{MsalCacheName}-iv"));
- if (!string.IsNullOrEmpty(ivCred.Password))
- {
- iv = ivCred.Password;
- }
- else
- {
- throw new Exception($"Could not read credential: {AzureAccountProviderCredentials}|{MsalCacheName}-iv");
- }
- }
- catch (Exception ex)
- {
- Logger.Error(ex);
- }
-
- try
- {
- // Read Cached Key for MSAL cache (as Unicode)
- Credential keyCred = CredentialService.Instance.ReadCredential(new($"{AzureAccountProviderCredentials}|{MsalCacheName}-key"));
- if (!string.IsNullOrEmpty(keyCred.Password))
- {
- key = keyCred.Password;
- }
- else
- {
- throw new Exception($"Could not read credential: {AzureAccountProviderCredentials}|{MsalCacheName}-key");
- }
- }
- catch (Exception ex)
- {
- Logger.Error(ex);
- }
+ this.encryptionKeys = (@params.Key, @params.Iv);
+ return Task.FromResult(true);
}
private void RunConnectRequestHandlerTask(ConnectParams connectParams)
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Connection/Contracts/EncryptionKeysChange.cs b/src/Microsoft.SqlTools.ServiceLayer/Connection/Contracts/EncryptionKeysChange.cs
new file mode 100644
index 00000000..de35e8d0
--- /dev/null
+++ b/src/Microsoft.SqlTools.ServiceLayer/Connection/Contracts/EncryptionKeysChange.cs
@@ -0,0 +1,46 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+using Microsoft.SqlTools.Hosting.Protocol.Contracts;
+
+namespace Microsoft.SqlTools.ServiceLayer.Connection.Contracts
+{
+
+ ///
+ /// Parameters for the MSAL cache encryption key notification.
+ ///
+ public class EncryptionKeysChangeParams
+ {
+ ///
+ /// Buffer encoded IV string for MSAL cache encryption
+ ///
+ public string Iv { get; set; }
+
+ ///
+ /// Buffer encoded Key string for MSAL cache encryption
+ ///
+ public string Key { get; set; }
+
+ ///
+ /// Default constructor to resolve nullables
+ ///
+ /// Key for MSAL cache encryption
+ /// Iv for MSAL cache encryption
+ public EncryptionKeysChangeParams(string key, string iv) {
+ this.Iv = iv;
+ this.Key = key;
+ }
+ }
+
+ ///
+ /// Defines an event that is sent from the client to notify the encryption keys are changed.
+ ///
+ public class EncryptionKeysChangedNotification
+ {
+ public static readonly
+ EventType Type =
+ EventType.Create("connection/encryptionKeysChanged");
+ }
+}