1
0
Эх сурвалжийг харах

Support for new host key types

Source commit: fff90d73259ac62bf04eac2b9272695754cca58a
Martin Prikryl 9 жил өмнө
parent
commit
470be7604f

+ 1 - 1
dotnet/SessionOptions.cs

@@ -408,7 +408,7 @@ namespace WinSCP
         private string _webdavRoot;
 
         private const string _listPattern = @"{0}(;{0})*";
-        private const string _sshHostKeyPattern = @"((ssh-rsa|ssh-dss)( |-))?(\d+ )?([0-9a-f]{2}(:|-)){15}[0-9a-f]{2}";
+        private const string _sshHostKeyPattern = @"((ssh-rsa|ssh-dss|ssh-ed25519|ecdsa-sha2-nistp(256|384|521))( |-))?(\d+ )?([0-9a-f]{2}(:|-)){15}[0-9a-f]{2}";
         private static readonly Regex _sshHostKeyRegex =
             new Regex(string.Format(CultureInfo.InvariantCulture, _listPattern, _sshHostKeyPattern));
         private const string _tlsCertificatePattern = @"([0-9a-f]{2}:){19}[0-9a-f]{2}";

+ 32 - 33
source/core/PuttyIntf.cpp

@@ -696,48 +696,47 @@ bool __fastcall HasGSSAPI(UnicodeString CustomPath)
   return (has > 0);
 }
 //---------------------------------------------------------------------------
-UnicodeString __fastcall NormalizeFingerprint(UnicodeString Fingerprint)
+static void __fastcall DoNormalizeFingerprint(UnicodeString & Fingerprint, UnicodeString & KeyType)
 {
-  UnicodeString DssName = UnicodeString(ssh_dss.name) + L" ";
-  UnicodeString RsaName = UnicodeString(ssh_rsa.name) + L" ";
+  int Count = 0;
+  const wchar_t NormalizedSeparator = L'-';
+  const ssh_signkey ** SignKeys = get_hostkey_algs(&Count);
 
-  bool IsFingerprint = false;
-  int LenStart;
-  if (StartsStr(DssName, Fingerprint))
-  {
-    LenStart = DssName.Length() + 1;
-    IsFingerprint = true;
-  }
-  else if (StartsStr(RsaName, Fingerprint))
+  for (int Index = 0; Index < Count; Index++)
   {
-    LenStart = RsaName.Length() + 1;
-    IsFingerprint = true;
-  }
-
-  if (IsFingerprint)
-  {
-    Fingerprint[LenStart - 1] = L'-';
-    int Space = Fingerprint.Pos(L" ");
-    DebugAssert(IsNumber(Fingerprint.SubString(LenStart, Space - LenStart)));
-    Fingerprint.Delete(LenStart, Space - LenStart + 1);
-    Fingerprint = ReplaceChar(Fingerprint, L':', L'-');
+    const ssh_signkey * SignKey = SignKeys[Index];
+    UnicodeString Name = UnicodeString(SignKey->name);
+    if (StartsStr(Name + L" ", Fingerprint))
+    {
+      int LenStart = Name.Length() + 1;
+      Fingerprint[LenStart] = NormalizedSeparator;
+      int Space = Fingerprint.Pos(L" ");
+      DebugAssert(IsNumber(Fingerprint.SubString(LenStart + 1, Space - LenStart - 1)));
+      Fingerprint.Delete(LenStart + 1, Space - LenStart);
+      Fingerprint = ReplaceChar(Fingerprint, L':', NormalizedSeparator);
+      KeyType = UnicodeString(SignKey->keytype);
+      return;
+    }
+    else if (StartsStr(Name + NormalizedSeparator, Fingerprint))
+    {
+      KeyType = UnicodeString(SignKey->keytype);
+      return;
+    }
   }
+}
+//---------------------------------------------------------------------------
+UnicodeString __fastcall NormalizeFingerprint(UnicodeString Fingerprint)
+{
+  UnicodeString KeyType; // unused
+  DoNormalizeFingerprint(Fingerprint, KeyType);
   return Fingerprint;
 }
 //---------------------------------------------------------------------------
 UnicodeString __fastcall KeyTypeFromFingerprint(UnicodeString Fingerprint)
 {
-  Fingerprint = NormalizeFingerprint(Fingerprint);
-  UnicodeString Type;
-  if (StartsStr(UnicodeString(ssh_dss.name) + L"-", Fingerprint))
-  {
-    Type = ssh_dss.keytype;
-  }
-  else if (StartsStr(UnicodeString(ssh_rsa.name) + L"-", Fingerprint))
-  {
-    Type = ssh_rsa.keytype;
-  }
-  return Type;
+  UnicodeString KeyType;
+  DoNormalizeFingerprint(Fingerprint, KeyType);
+  return KeyType;
 }
 //---------------------------------------------------------------------------
 UnicodeString __fastcall GetPuTTYVersion()

+ 4 - 1
source/core/SecureShell.cpp

@@ -2110,7 +2110,10 @@ void __fastcall TSecureShell::VerifyHostKey(UnicodeString Host, int Port,
   while (!Result && !Buf.IsEmpty())
   {
     UnicodeString StoredKey = CutToChar(Buf, HostKeyDelimiter, false);
-    bool Fingerprint = (StoredKey.SubString(1, 2) != L"0x");
+    // skip leading ECDH subtype identification
+    int P = StoredKey.Pos(L",");
+    // start from beginning or after the comma, if there 's any
+    bool Fingerprint = (StoredKey.SubString(P + 1, 2) != L"0x");
     // it's probably a fingerprint (stored by TSessionData::CacheHostKey)
     UnicodeString NormalizedExpectedKey;
     if (Fingerprint)

+ 1 - 0
source/putty/puttyexp.h

@@ -21,6 +21,7 @@ int get_ssh_exitcode(void * handle);
 const unsigned int * ssh2_remmaxpkt(void * handle);
 const unsigned int * ssh2_remwindow(void * handle);
 void md5checksum(const char * buffer, int len, unsigned char output[16]);
+const struct ssh_signkey ** get_hostkey_algs(int * count);
 
 // from wingss.c
 

+ 6 - 0
source/putty/ssh.c

@@ -11858,4 +11858,10 @@ void md5checksum(const char * buffer, int len, unsigned char output[16])
   MD5Final(output, &md5c);
 }
 
+const struct ssh_signkey ** get_hostkey_algs(int * count)
+{
+  *count = lenof(hostkey_algs);
+  return hostkey_algs;
+}
+
 #endif