From 22564bb2a332e6455afd0ea66780044ffcbf035b Mon Sep 17 00:00:00 2001 From: Kenneth Hsu Date: Tue, 18 May 2021 09:17:13 -0700 Subject: Cache knowledge of ECDSA support. --- Duplicati/Library/Backend/SSHv2/SSHv2Backend.cs | 54 +++++++++++++++---------- 1 file changed, 32 insertions(+), 22 deletions(-) (limited to 'Duplicati/Library/Backend') diff --git a/Duplicati/Library/Backend/SSHv2/SSHv2Backend.cs b/Duplicati/Library/Backend/SSHv2/SSHv2Backend.cs index 3237d8a4e..1fca6aad7 100644 --- a/Duplicati/Library/Backend/SSHv2/SSHv2Backend.cs +++ b/Duplicati/Library/Backend/SSHv2/SSHv2Backend.cs @@ -59,6 +59,8 @@ namespace Duplicati.Library.Backend private SftpClient m_con; + private readonly Lazy supportsECDSA = new Lazy(SSHv2.SupportsECDSA, true); + public SSHv2() { } @@ -334,32 +336,40 @@ namespace Duplicati.Library.Backend m_con = con; } + /// + /// 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. + /// + /// Mono ECDsaCng implementation. + /// Whether ECDSA algorithms are supported or not. + 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 - { - ECDsaCng unused = new ECDsaCng(); - } - catch (NotImplementedException) - { - List ecdsaKeys = client.ConnectionInfo.HostKeyAlgorithms.Keys.Where(x => x.StartsWith("ecdsa")).ToList(); - foreach (string key in ecdsaKeys) - { - client.ConnectionInfo.HostKeyAlgorithms.Remove(key); - } - } - catch + List ecdsaKeys = client.ConnectionInfo.HostKeyAlgorithms.Keys.Where(x => x.StartsWith("ecdsa")).ToList(); + foreach (string key in ecdsaKeys) { - // Ignore other exceptions and assume that we have ECDSA support. + client.ConnectionInfo.HostKeyAlgorithms.Remove(key); } } -- cgit v1.2.3