Cache knowledge of ECDSA support.

This commit is contained in:
Kenneth Hsu
2021-05-18 10:07:33 -07:00
parent bfa240c8ec
commit 22564bb2a3
+32 -22
View File
@@ -59,6 +59,8 @@ namespace Duplicati.Library.Backend
private SftpClient m_con;
private readonly Lazy<bool> supportsECDSA = new Lazy<bool>(SSHv2.SupportsECDSA, true);
public SSHv2()
{
}
@@ -334,32 +336,40 @@ namespace Duplicati.Library.Backend
m_con = con;
}
/// <summary>
/// SSH.NET relies on the System.Security.Cryptography.ECDsaCng class for
/// ECDSA algorithms, which is not implemented in Mono (as of 6.12.0.144).
/// This prevents clients from connecting if one of the ECDSA algorithms is
/// chosen as the host key algorithm. In this case, we will prevent the
/// client from advertising support for ECDSA algorithms.
/// </summary>
/// <seealso href="https://github.com/mono/mono/blob/mono-6.12.0.144/mcs/class/referencesource/System.Core/System/Security/Cryptography/ECDsaCng.cs">Mono ECDsaCng implementation.</seealso>
/// <returns>Whether ECDSA algorithms are supported or not.</returns>
private static bool SupportsECDSA()
{
try
{
ECDsaCng unused = new ECDsaCng();
return true;
}
catch (NotImplementedException)
{
return false;
}
catch
{
return true;
}
}
private void TryConnect(SftpClient client)
{
if (Utility.Utility.IsMono)
if (!this.supportsECDSA.Value)
{
// SSH.NET relies on the System.Security.Cryptography.ECDsaCng class for
// ECDSA algorithms, which is not implemented in Mono (as of 6.12.0.144).
// This prevents clients from connecting if one of the ECDSA algorithms is
// chosen as the host key algorithm. In this case, we will prevent the
// client from advertising support for ECDSA algorithms.
//
// See https://github.com/mono/mono/blob/mono-6.12.0.144/mcs/class/referencesource/System.Core/System/Security/Cryptography/ECDsaCng.cs
try
List<string> ecdsaKeys = client.ConnectionInfo.HostKeyAlgorithms.Keys.Where(x => x.StartsWith("ecdsa")).ToList();
foreach (string key in ecdsaKeys)
{
ECDsaCng unused = new ECDsaCng();
}
catch (NotImplementedException)
{
List<string> ecdsaKeys = client.ConnectionInfo.HostKeyAlgorithms.Keys.Where(x => x.StartsWith("ecdsa")).ToList();
foreach (string key in ecdsaKeys)
{
client.ConnectionInfo.HostKeyAlgorithms.Remove(key);
}
}
catch
{
// Ignore other exceptions and assume that we have ECDSA support.
client.ConnectionInfo.HostKeyAlgorithms.Remove(key);
}
}