sillsdev/chorus

Password Encryption/Decryption will crash LibChorus on Linux .NET6

josephmyers opened this issue · 2 comments

ServerSettingsModel has the methods EncryptPassword and DecryptPassword. These use System.Security.Cryptography.ProtectedData, which compiles for .NET6 but throws a runtime exception on Linux.

var encryptedData = ProtectedData.Protect(Encoding.Unicode.GetBytes(encryptMe),
		Encoding.Unicode.GetBytes(EntropyValue), DataProtectionScope.CurrentUser);
return Convert.ToBase64String(encryptedData);

No one is currently using this, but if they try it will break. We need a cross-platform password solution, or one that at least adapts to platform-specific calls.

I created a cross-platform SIL.PasswordStore library that we could/should use (nuget package). This is a wrapper around OS functionality.

This would change the way we store the password, so we would no longer put it in the config file and we no longer need EncryptPassword/DecryptPassword methods. How the password is stored and encrypted would be left to the OS.

We could consider a migration path where we read the encrypted password from the config file, decrypt it, store it with SIL.PasswordStore, then delete it from the config file.

As a quick mitigation, I suggest that EncryptPassword should be changed to return null if ProtectedData.Protect throws a PlatformNotSupportedException. That will have the same effect as setting RememberPassword = false in the ServerSettingsModel (which is what I had to do in order to make Lexbox Send/Receive tests run on Linux hosts such as GHA runners), because when RememberPassword is false, SaveUserSettings sets Settings.Default.LanguageForgePass to null.

DecryptPassword should not be called on Linux, since EncyptPassword will have failed. However, in case DecryptPassword is somehow called anyway on an unsupported platform, it should catch PlatformNotSupportedException and return its input unmodified.

I'll submit a PR to this effect later, when I'm done with my current task.