Browse Source

Providing more details when verification of the TLS certificate against Windows certificate store fails

Source commit: ae4f02bf530e8ca88ad2166c0cd9c46b3d3e80a5
Martin Prikryl 9 years ago
parent
commit
a0a3e03326

+ 7 - 1
source/core/FtpFileSystem.cpp

@@ -4376,13 +4376,19 @@ bool __fastcall TFTPFileSystem::HandleAsynchRequestVerifyCertificate(
       // as it can take a very long time (up to 1 minute).
       if (!VerificationResult && TryWindowsSystemCertificateStore)
       {
-        if (WindowsValidateCertificate(Data.Certificate, Data.CertificateLen))
+        UnicodeString WindowsCertificateError;
+        if (WindowsValidateCertificate(Data.Certificate, Data.CertificateLen, WindowsCertificateError))
         {
           FTerminal->LogEvent(L"Certificate verified against Windows certificate store");
           VerificationResult = true;
           // certificate is trusted for all purposes
           Trusted = true;
         }
+        else
+        {
+          FTerminal->LogEvent(
+            FORMAT(L"Certificate failed to verify against Windows certificate store: %s", (DefaultStr(WindowsCertificateError, L"no details"))));
+        }
       }
 
       const UnicodeString SummarySeparator = L"\n\n";

+ 3 - 1
source/core/Http.cpp

@@ -226,14 +226,16 @@ int THttp::NeonServerSSLCallbackImpl(int Failures, const ne_ssl_certificate * Ce
 {
   AnsiString AsciiCert = NeonExportCertificate(Certificate);
 
+  UnicodeString WindowsCertificateError;
   if (Failures != 0)
   {
-    NeonWindowsValidateCertificate(Failures, AsciiCert);
+    NeonWindowsValidateCertificate(Failures, AsciiCert, WindowsCertificateError);
   }
 
   if (Failures != 0)
   {
     FCertificateError = NeonCertificateFailuresErrorStr(Failures, FHostName);
+    AddToList(FCertificateError, WindowsCertificateError, L"\n");
   }
 
   return (Failures == 0) ? NE_OK : NE_ERROR;

+ 2 - 2
source/core/NeonIntf.cpp

@@ -243,7 +243,7 @@ AnsiString NeonExportCertificate(const ne_ssl_certificate * Certificate)
   return Result;
 }
 //---------------------------------------------------------------------------
-bool NeonWindowsValidateCertificate(int & Failures, const AnsiString & AsciiCert)
+bool NeonWindowsValidateCertificate(int & Failures, const AnsiString & AsciiCert, UnicodeString & Error)
 {
   bool Result = false;
   // We can accept only unknown certificate authority.
@@ -254,7 +254,7 @@ bool NeonWindowsValidateCertificate(int & Failures, const AnsiString & AsciiCert
 
     if (CertificateLen > 0)
     {
-      if (WindowsValidateCertificate(Certificate, CertificateLen))
+      if (WindowsValidateCertificate(Certificate, CertificateLen, Error))
       {
         Failures &= ~NE_SSL_UNTRUSTED;
         Result = true;

+ 1 - 1
source/core/NeonIntf.h

@@ -22,7 +22,7 @@ void CheckRedirectLoop(const UnicodeString & RedirectUrl, TStrings * AttemptedUr
 typedef void (*TNeonTlsInit)(struct ssl_st * Ssl, ne_session * Session);
 void SetNeonTlsInit(ne_session * Session, TNeonTlsInit OnNeonTlsInit);
 AnsiString NeonExportCertificate(const ne_ssl_certificate * Certificate);
-bool NeonWindowsValidateCertificate(int & Failures, const AnsiString & AsciiCert);
+bool NeonWindowsValidateCertificate(int & Failures, const AnsiString & AsciiCert, UnicodeString & Error);
 UnicodeString NeonCertificateFailuresErrorStr(int Failures, const UnicodeString & HostName);
 //---------------------------------------------------------------------------
 #endif

+ 5 - 1
source/core/Security.cpp

@@ -102,7 +102,7 @@ bool GetExternalEncryptedPassword(RawByteString Encrypted, RawByteString & Passw
   return Result;
 }
 //---------------------------------------------------------------------------
-bool WindowsValidateCertificate(const unsigned char * Certificate, size_t Len)
+bool WindowsValidateCertificate(const unsigned char * Certificate, size_t Len, UnicodeString & Error)
 {
   bool Result = false;
 
@@ -156,6 +156,10 @@ bool WindowsValidateCertificate(const unsigned char * Certificate, size_t Len)
         {
           // Windows thinks the certificate is valid.
           Result = (PolicyStatus.dwError == S_OK);
+          if (!Result)
+          {
+            Error = FORMAT(L"Error: %x, Chain index: %d, Element index: %d", (PolicyStatus.dwError, PolicyStatus.lChainIndex, PolicyStatus.lElementIndex));
+          }
         }
 
         CertFreeCertificateChain(ChainContext);

+ 1 - 1
source/core/Security.h

@@ -12,6 +12,6 @@ UnicodeString DecryptPassword(RawByteString Password, UnicodeString Key, Integer
 RawByteString SetExternalEncryptedPassword(RawByteString Password);
 bool GetExternalEncryptedPassword(RawByteString Encrypted, RawByteString & Password);
 //---------------------------------------------------------------------------
-bool WindowsValidateCertificate(const unsigned char * Certificate, size_t Len);
+bool WindowsValidateCertificate(const unsigned char * Certificate, size_t Len, UnicodeString & Error);
 //---------------------------------------------------------------------------
 #endif

+ 7 - 1
source/core/WebDAVFileSystem.cpp

@@ -2260,12 +2260,18 @@ bool TWebDAVFileSystem::VerifyCertificate(const TWebDAVCertificateData & Data)
 
     if (!Result)
     {
-      if (NeonWindowsValidateCertificate(Failures, Data.AsciiCert))
+      UnicodeString WindowsCertificateError;
+      if (NeonWindowsValidateCertificate(Failures, Data.AsciiCert, WindowsCertificateError))
       {
         FTerminal->LogEvent(L"Certificate verified against Windows certificate store");
         // There can be also other flags, not just the NE_SSL_UNTRUSTED.
         Result = (Failures == 0);
       }
+      else
+      {
+        FTerminal->LogEvent(
+          FORMAT(L"Certificate failed to verify against Windows certificate store: %s", (DefaultStr(WindowsCertificateError, L"no details"))));
+      }
     }
 
     UnicodeString Summary;