Martin Prikryl 12 years ago
parent
commit
538d62e8fb
100 changed files with 2152 additions and 662 deletions
  1. 1 1
      Console.cbproj
  2. 1 1
      DragExt.cbproj
  3. 2 2
      DragExt64.rc
  4. 2 2
      WinSCP.cbproj
  5. 13 6
      core/Common.cpp
  6. 34 15
      core/Common.h
  7. 159 93
      core/FtpFileSystem.cpp
  8. 8 4
      core/FtpFileSystem.h
  9. 2 1
      core/Queue.cpp
  10. 8 0
      core/Script.cpp
  11. 1 0
      core/Script.h
  12. 13 3
      core/SessionInfo.cpp
  13. 43 17
      core/Terminal.cpp
  14. 2 0
      core/Terminal.h
  15. 2 1
      filezilla/ControlSocket.cpp
  16. 3 1
      filezilla/ControlSocket.h
  17. 6 5
      filezilla/FileZillaApi.cpp
  18. 5 3
      filezilla/FileZillaApi.h
  19. 21 15
      filezilla/FileZillaIntf.cpp
  20. 19 11
      filezilla/FileZillaIntf.h
  21. 14 0
      filezilla/FilezillaTools.h
  22. 80 135
      filezilla/FtpControlSocket.cpp
  23. 2 1
      filezilla/FtpControlSocket.h
  24. 2 1
      filezilla/MainThread.cpp
  25. 1 0
      filezilla/MainThread.h
  26. 1 0
      filezilla/stdafx.h
  27. 29 15
      forms/CustomScpExplorer.cpp
  28. 3 3
      forms/CustomScpExplorer.h
  29. 1 5
      forms/Login.cpp
  30. 16 16
      forms/NonVisual.cpp
  31. 6 1
      forms/NonVisual.h
  32. 4 0
      openssl/Makefile
  33. 1 0
      openssl/crypto/asn1/a_strex.c
  34. 6 0
      openssl/crypto/asn1/a_verify.c
  35. 4 1
      openssl/crypto/asn1/x_pubkey.c
  36. 2 0
      openssl/crypto/bn/bn_div.c
  37. 1 0
      openssl/crypto/bn/bn_gcd.c
  38. 9 2
      openssl/crypto/bn/bn_lcl.h
  39. 8 17
      openssl/crypto/bn/bn_word.c
  40. 2 2
      openssl/crypto/buildinf.h
  41. 1 0
      openssl/crypto/conf/conf_mall.c
  42. 15 1
      openssl/crypto/cryptlib.c
  43. 1 1
      openssl/crypto/cryptlib.h
  44. 9 2
      openssl/crypto/crypto.h
  45. 1 2
      openssl/crypto/des/set_key.c
  46. 1 1
      openssl/crypto/des/str2key.c
  47. 10 9
      openssl/crypto/err/err_all.c
  48. 1 0
      openssl/crypto/evp/digest.c
  49. 3 2
      openssl/crypto/evp/e_aes.c
  50. 195 21
      openssl/crypto/evp/e_aes_cbc_hmac_sha1.c
  51. 11 4
      openssl/crypto/evp/evp.h
  52. 125 0
      openssl/crypto/evp/evp_cnf.c
  53. 6 0
      openssl/crypto/evp/evp_err.c
  54. 1 1
      openssl/crypto/evp/m_dss.c
  55. 1 1
      openssl/crypto/evp/m_dss1.c
  56. 1 1
      openssl/crypto/evp/m_sha1.c
  57. 1 1
      openssl/crypto/evp/p_sign.c
  58. 1 1
      openssl/crypto/evp/p_verify.c
  59. 16 15
      openssl/crypto/md4/md4_dgst.c
  60. 4 4
      openssl/crypto/md4/md4_locl.h
  61. 4 4
      openssl/crypto/md5/md5_locl.h
  62. 1 1
      openssl/crypto/mem.c
  63. 2 2
      openssl/crypto/modes/gcm128.c
  64. 1 1
      openssl/crypto/objects/o_names.c
  65. 7 3
      openssl/crypto/ocsp/ocsp_vfy.c
  66. 3 3
      openssl/crypto/opensslv.h
  67. 161 0
      openssl/crypto/pem/pem_all.c
  68. 17 10
      openssl/crypto/pem/pem_lib.c
  69. 4 2
      openssl/crypto/pem/pem_seal.c
  70. 16 8
      openssl/crypto/pkcs12/p12_key.c
  71. 1 1
      openssl/crypto/pkcs7/bio_pk7.c
  72. 11 0
      openssl/crypto/ppccap.c
  73. 1 1
      openssl/crypto/rand/md_rand.c
  74. 5 2
      openssl/crypto/rand/rand_lib.c
  75. 15 15
      openssl/crypto/ripemd/rmd_dgst.c
  76. 5 5
      openssl/crypto/ripemd/rmd_locl.h
  77. 1 1
      openssl/crypto/rsa/rsa.h
  78. 3 3
      openssl/crypto/rsa/rsa_eay.c
  79. 1 1
      openssl/crypto/rsa/rsa_oaep.c
  80. 1 1
      openssl/crypto/sha/sha1_one.c
  81. 1 1
      openssl/crypto/sha/sha1dgst.c
  82. 3 3
      openssl/crypto/sha/sha256.c
  83. 1 1
      openssl/crypto/sha/sha_dgst.c
  84. 20 20
      openssl/crypto/sha/sha_locl.h
  85. 3 2
      openssl/crypto/srp/srp_vfy.c
  86. 6 8
      openssl/crypto/symhacks.h
  87. 6 0
      openssl/crypto/ui/ui_openssl.c
  88. 7 8
      openssl/crypto/x509/x509_cmp.c
  89. 2 2
      openssl/crypto/x509/x509_vfy.c
  90. 2 2
      openssl/crypto/x509v3/v3_purp.c
  91. 15 44
      openssl/ssl/d1_enc.c
  92. 54 37
      openssl/ssl/d1_pkt.c
  93. 3 2
      openssl/ssl/d1_srtp.c
  94. 6 2
      openssl/ssl/dtls1.h
  95. 8 6
      openssl/ssl/s2_clnt.c
  96. 1 2
      openssl/ssl/s2_pkt.c
  97. 11 5
      openssl/ssl/s2_srvr.c
  98. 9 5
      openssl/ssl/s3_both.c
  99. 790 0
      openssl/ssl/s3_cbc.c
  100. 3 1
      openssl/ssl/s3_clnt.c

+ 1 - 1
Console.cbproj

@@ -41,7 +41,7 @@
 			<PackageImports>rtl.bpi;$(PackageImports)</PackageImports>
 			<ProjectType>CppConsoleApplication</ProjectType>
 			<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
-			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=Console interface for WinSCP;FileVersion=3.2.1.0;InternalName=console;LegalCopyright=(c) 2000-2013 Martin Prikryl;LegalTrademarks=;OriginalFilename=winscp.com;ProductName=WinSCP;ProductVersion=5.1.3.0;ReleaseType=stable;WWW=http://winscp.net/</VerInfo_Keys>
+			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=Console interface for WinSCP;FileVersion=3.2.1.0;InternalName=console;LegalCopyright=(c) 2000-2013 Martin Prikryl;LegalTrademarks=;OriginalFilename=winscp.com;ProductName=WinSCP;ProductVersion=5.1.4.0;ReleaseType=stable;WWW=http://winscp.net/</VerInfo_Keys>
 			<VerInfo_Locale>1033</VerInfo_Locale>
 			<VerInfo_MajorVer>3</VerInfo_MajorVer>
 			<VerInfo_MinorVer>2</VerInfo_MinorVer>

+ 1 - 1
DragExt.cbproj

@@ -42,7 +42,7 @@
 			<ProjectType>CppDynamicLibrary</ProjectType>
 			<VerInfo_DLL>true</VerInfo_DLL>
 			<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
-			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=Drag&amp;Drop shell extension for WinSCP (32-bit);FileVersion=1.2.1.0;InternalName=dragext32;LegalCopyright=(c) 2000-2013 Martin Prikryl;LegalTrademarks=;OriginalFilename=dragext.dll;ProductName=WinSCP;ProductVersion=5.1.3.0;ReleaseType=stable;WWW=http://winscp.net/</VerInfo_Keys>
+			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=Drag&amp;Drop shell extension for WinSCP (32-bit);FileVersion=1.2.1.0;InternalName=dragext32;LegalCopyright=(c) 2000-2013 Martin Prikryl;LegalTrademarks=;OriginalFilename=dragext.dll;ProductName=WinSCP;ProductVersion=5.1.4.0;ReleaseType=stable;WWW=http://winscp.net/</VerInfo_Keys>
 			<VerInfo_Locale>1033</VerInfo_Locale>
 			<VerInfo_MinorVer>2</VerInfo_MinorVer>
 			<VerInfo_Release>1</VerInfo_Release>

+ 2 - 2
DragExt64.rc

@@ -1,6 +1,6 @@
 1 VERSIONINFO
 FILEVERSION 1,2,1,0
-PRODUCTVERSION 5,1,3,0
+PRODUCTVERSION 5,1,4,0
 FILEOS 0x4
 FILETYPE 0x2
 {
@@ -16,7 +16,7 @@ FILETYPE 0x2
             VALUE "LegalTrademarks", "\0"
             VALUE "OriginalFilename", "dragext64.dll\0"
             VALUE "ProductName", "WinSCP\0"
-            VALUE "ProductVersion", "5.1.3.0\0"
+            VALUE "ProductVersion", "5.1.4.0\0"
             VALUE "ReleaseType", "stable\0"
             VALUE "WWW", "http://winscp.net/\0"
         }

+ 2 - 2
WinSCP.cbproj

@@ -51,11 +51,11 @@
 			<ProjectType>CppVCLApplication</ProjectType>
 			<UsingDelphiRTL>true</UsingDelphiRTL>
 			<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
-			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=WinSCP: SFTP, FTP and SCP client;FileVersion=5.1.3.0;InternalName=winscp;LegalCopyright=(c) 2000-2013 Martin Prikryl;LegalTrademarks=;OriginalFilename=winscp.exe;ProductName=WinSCP;ProductVersion=5.1.3.0;ReleaseType=stable;WWW=http://winscp.net/</VerInfo_Keys>
+			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=WinSCP: SFTP, FTP and SCP client;FileVersion=5.1.4.0;InternalName=winscp;LegalCopyright=(c) 2000-2013 Martin Prikryl;LegalTrademarks=;OriginalFilename=winscp.exe;ProductName=WinSCP;ProductVersion=5.1.4.0;ReleaseType=stable;WWW=http://winscp.net/</VerInfo_Keys>
 			<VerInfo_Locale>1033</VerInfo_Locale>
 			<VerInfo_MajorVer>5</VerInfo_MajorVer>
 			<VerInfo_MinorVer>1</VerInfo_MinorVer>
-			<VerInfo_Release>3</VerInfo_Release>
+			<VerInfo_Release>4</VerInfo_Release>
 		</PropertyGroup>
 		<PropertyGroup Condition="'$(Cfg_1)'!=''">
 			<BCC_DebugLineNumbers>true</BCC_DebugLineNumbers>

+ 13 - 6
core/Common.cpp

@@ -1186,7 +1186,7 @@ __int64 __fastcall ConvertTimestampToUnix(const FILETIME & FileTime,
   return Result;
 }
 //---------------------------------------------------------------------------
-static TDateTime __fastcall ConvertTimestampToUTC(TDateTime DateTime)
+TDateTime __fastcall ConvertTimestampToUTC(TDateTime DateTime)
 {
 
   const TDateTimeParams * Params = GetDateTimeParams(DecodeYear(DateTime));
@@ -1204,16 +1204,13 @@ static TDateTime __fastcall ConvertTimestampToUTC(TDateTime DateTime)
   return DateTime;
 }
 //---------------------------------------------------------------------------
-TDateTime __fastcall ConvertFileTimestampFromUTC(TDateTime DateTime)
+TDateTime __fastcall ConvertTimestampFromUTC(TDateTime DateTime)
 {
 
   const TDateTimeParams * Params = GetDateTimeParams(DecodeYear(DateTime));
   DateTime -=
     (IsDateInDST(DateTime) ?
-      // Note the difference to ConvertTimestampToUTC()
-      // This is to compensate CTime::GetGmtTm for MFMT FTP conversion
-      Params->DaylightDifference : -Params->DaylightDifference);
-
+      Params->DaylightDifference : Params->StandardDifference);
   DateTime -= Params->BaseDifference;
 
   if (Params->DaylightHack)
@@ -1406,6 +1403,16 @@ int __fastcall CompareFileTime(TDateTime T1, TDateTime T2)
   return Result;
 }
 //---------------------------------------------------------------------------
+int __fastcall TimeToMSec(TDateTime T)
+{
+  return int(Round(double(T) * double(MSecsPerDay)));
+}
+//---------------------------------------------------------------------------
+int __fastcall TimeToMinutes(TDateTime T)
+{
+  return TimeToMSec(T) / MSecsPerSec / SecsPerMin;
+}
+//---------------------------------------------------------------------------
 bool __fastcall RecursiveDeleteFile(const UnicodeString FileName, bool ToRecycleBin)
 {
   SHFILEOPSTRUCT Data;

+ 34 - 15
core/Common.h

@@ -111,7 +111,8 @@ bool __fastcall UsesDaylightHack();
 TDateTime __fastcall EncodeDateVerbose(Word Year, Word Month, Word Day);
 TDateTime __fastcall EncodeTimeVerbose(Word Hour, Word Min, Word Sec, Word MSec);
 TDateTime __fastcall UnixToDateTime(__int64 TimeStamp, TDSTMode DSTMode);
-TDateTime __fastcall ConvertFileTimestampFromUTC(TDateTime DateTime);
+TDateTime __fastcall ConvertTimestampToUTC(TDateTime DateTime);
+TDateTime __fastcall ConvertTimestampFromUTC(TDateTime DateTime);
 FILETIME __fastcall DateTimeToFileTime(const TDateTime DateTime, TDSTMode DSTMode);
 TDateTime __fastcall AdjustDateTimeFromUnix(TDateTime DateTime, TDSTMode DSTMode);
 void __fastcall UnifyDateTimePrecision(TDateTime & DateTime1, TDateTime & DateTime2);
@@ -125,6 +126,8 @@ UnicodeString __fastcall StandardTimestamp(const TDateTime & DateTime);
 UnicodeString __fastcall StandardTimestamp();
 UnicodeString __fastcall GetTimeZoneLogString();
 int __fastcall CompareFileTime(TDateTime T1, TDateTime T2);
+int __fastcall TimeToMSec(TDateTime T);
+int __fastcall TimeToMinutes(TDateTime T);
 //---------------------------------------------------------------------------
 template<class MethodT>
 MethodT __fastcall MakeMethod(void * Data, void * Code)
@@ -155,6 +158,19 @@ private:
   TCriticalSection * FCriticalSection;
 };
 //---------------------------------------------------------------------------
+//---------------------------------------------------------------------------
+#include <assert.h>
+#ifndef _DEBUG
+#undef assert
+#define assert(p)   ((void)0)
+#define CHECK(p) p
+#define FAIL
+#else
+#define CHECK(p) { bool __CHECK_RESULT__ = (p); assert(__CHECK_RESULT__); }
+#define FAIL assert(false)
+#endif
+#define USEDPARAM(p) ((&p) == (&p))
+//---------------------------------------------------------------------------
 template<class T>
 class TValueRestorer
 {
@@ -170,9 +186,9 @@ public:
     FTarget = FValue;
   }
 
-private:
+protected:
   T & FTarget;
-  const T & FValue;
+  T FValue;
 };
 //---------------------------------------------------------------------------
 class TBoolRestorer : TValueRestorer<bool>
@@ -184,17 +200,20 @@ public:
   }
 };
 //---------------------------------------------------------------------------
-//---------------------------------------------------------------------------
-#include <assert.h>
-#ifndef _DEBUG
-#undef assert
-#define assert(p)   ((void)0)
-#define CHECK(p) p
-#define FAIL
-#else
-#define CHECK(p) { bool __CHECK_RESULT__ = (p); assert(__CHECK_RESULT__); }
-#define FAIL assert(false)
-#endif
-#define USEDPARAM(p) ((&p) == (&p))
+class TAutoNestingCounter : TValueRestorer<int>
+{
+public:
+  __fastcall TAutoNestingCounter(int & Target) :
+    TValueRestorer<int>(Target, Target)
+  {
+    assert(Target >= 0);
+    ++Target;
+  }
+
+  __fastcall ~TAutoNestingCounter()
+  {
+    assert(FTarget == (FValue + 1));
+  }
+};
 //---------------------------------------------------------------------------
 #endif

+ 159 - 93
core/FtpFileSystem.cpp

@@ -45,8 +45,8 @@ protected:
   virtual bool __fastcall HandleAsynchRequestOverwrite(
     wchar_t * FileName1, size_t FileName1Len, const wchar_t * FileName2,
     const wchar_t * Path1, const wchar_t * Path2,
-    __int64 Size1, __int64 Size2, time_t Time1, time_t Time2,
-    bool HasTime1, bool HasTime2, void * UserData, int & RequestResult);
+    __int64 Size1, __int64 Size2, time_t LocalTime,
+    bool HasLocalTime, const TRemoteFileTime & RemoteTime, void * UserData, int & RequestResult);
   virtual bool __fastcall HandleAsynchRequestVerifyCertificate(
     const TFtpsCertificateData & Data, int & RequestResult);
   virtual bool __fastcall HandleAsynchRequestNeedPass(
@@ -60,6 +60,9 @@ protected:
   virtual bool __fastcall HandleCapabilities(TFTPServerCapabilities * ServerCapabilities);
   virtual bool __fastcall CheckError(int ReturnCode, const wchar_t * Context);
 
+  virtual void PreserveDownloadFileTime(HANDLE Handle, void * UserData);
+  virtual bool GetFileModificationTimeInUtc(const wchar_t * FileName, struct tm & Time);
+
 private:
   TFTPFileSystem * FFileSystem;
 };
@@ -93,12 +96,12 @@ bool __fastcall TFileZillaImpl::HandleStatus(const wchar_t * Status, int Type)
 bool __fastcall TFileZillaImpl::HandleAsynchRequestOverwrite(
   wchar_t * FileName1, size_t FileName1Len, const wchar_t * FileName2,
   const wchar_t * Path1, const wchar_t * Path2,
-  __int64 Size1, __int64 Size2, time_t Time1, time_t Time2,
-  bool HasTime1, bool HasTime2, void * UserData, int & RequestResult)
+  __int64 Size1, __int64 Size2, time_t LocalTime,
+  bool HasLocalTime, const TRemoteFileTime & RemoteTime, void * UserData, int & RequestResult)
 {
   return FFileSystem->HandleAsynchRequestOverwrite(
-    FileName1, FileName1Len, FileName2, Path1, Path2, Size1, Size2, Time1, Time2,
-    HasTime1, HasTime2, UserData, RequestResult);
+    FileName1, FileName1Len, FileName2, Path1, Path2, Size1, Size2, LocalTime,
+    HasLocalTime, RemoteTime, UserData, RequestResult);
 }
 //---------------------------------------------------------------------------
 bool __fastcall TFileZillaImpl::HandleAsynchRequestVerifyCertificate(
@@ -142,6 +145,16 @@ bool __fastcall TFileZillaImpl::CheckError(int ReturnCode, const wchar_t * Conte
   return FFileSystem->CheckError(ReturnCode, Context);
 }
 //---------------------------------------------------------------------------
+void TFileZillaImpl::PreserveDownloadFileTime(HANDLE Handle, void * UserData)
+{
+  return FFileSystem->PreserveDownloadFileTime(Handle, UserData);
+}
+//---------------------------------------------------------------------------
+bool TFileZillaImpl::GetFileModificationTimeInUtc(const wchar_t * FileName, struct tm & Time)
+{
+  return FFileSystem->GetFileModificationTimeInUtc(FileName, Time);
+}
+//---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
 class TMessageQueue : public std::list<std::pair<WPARAM, LPARAM> >
 {
@@ -163,6 +176,7 @@ struct TFileTransferData
   bool AutoResume;
   int OverwriteResult;
   const TCopyParamType * CopyParam;
+  TDateTime Modification;
 };
 //---------------------------------------------------------------------------
 const int tfFirstLevel = 0x01;
@@ -364,7 +378,7 @@ void __fastcall TFTPFileSystem::Open()
       break;
   }
   int Pasv = (Data->FtpPasvMode ? 1 : 2);
-  int TimeZoneOffset = int(double(Data->TimeDifference) * MinsPerDay);
+  int TimeZoneOffset = TimeToMinutes(Data->TimeDifference);
   int UTF8 = 0;
   switch (Data->NotUtf)
   {
@@ -755,19 +769,27 @@ bool __fastcall TFTPFileSystem::ConfirmOverwrite(UnicodeString & FileName,
 {
   bool Result;
   bool CanAutoResume = FLAGSET(Params, cpNoConfirmation) && AutoResume;
+  bool DestIsSmaller = (FileParams != NULL) && (FileParams->DestSize < FileParams->SourceSize);
+  bool DestIsSame = (FileParams != NULL) && (FileParams->DestSize == FileParams->SourceSize);
   // when resuming transfer after interrupted connection,
   // do nothing (dummy resume) when the files has the same size.
   // this is workaround for servers that strangely fails just after successful
   // upload.
   bool CanResume =
-    (FileParams != NULL) &&
-    (((FileParams->DestSize < FileParams->SourceSize)) ||
-     ((FileParams->DestSize == FileParams->SourceSize) && CanAutoResume));
+    (DestIsSmaller || (DestIsSame && CanAutoResume));
 
   unsigned int Answer;
   if (CanAutoResume && CanResume)
   {
-    Answer = qaRetry;
+    if (DestIsSame)
+    {
+      assert(CanAutoResume);
+      Answer = qaSkip;
+    }
+    else
+    {
+      Answer = qaRetry;
+    }
   }
   else
   {
@@ -846,6 +868,10 @@ bool __fastcall TFTPFileSystem::ConfirmOverwrite(UnicodeString & FileName,
       Result = false;
       break;
 
+    case qaSkip:
+      OverwriteMode = omComplete;
+      break;
+
     default:
       assert(false);
       Result = false;
@@ -1153,6 +1179,7 @@ void __fastcall TFTPFileSystem::Sink(const UnicodeString FileName,
       UserData.Params = Params;
       UserData.AutoResume = FLAGSET(Flags, tfAutoResume);
       UserData.CopyParam = CopyParam;
+      UserData.Modification = File->Modification;
       FileTransfer(FileName, DestFullName, OnlyFileName,
         FilePath, true, File->Size, TransferType, UserData, OperationProgress);
     }
@@ -1398,6 +1425,7 @@ void __fastcall TFTPFileSystem::Source(const UnicodeString FileName,
       UserData.Params = Params;
       UserData.AutoResume = FLAGSET(Flags, tfAutoResume);
       UserData.CopyParam = CopyParam;
+      UserData.Modification = Modification;
       FileTransfer(FileName, FileName, DestFileName,
         TargetDir, false, Size, TransferType, UserData, OperationProgress);
     }
@@ -1639,7 +1667,7 @@ void __fastcall TFTPFileSystem::DoStartup()
       {
         FFileZillaIntf->CustomCommand(Command.c_str());
 
-        GotReply(WaitForCommandReply(), REPLY_2XX_CODE);
+        GotReply(WaitForCommandReply(), REPLY_2XX_CODE | REPLY_3XX_CODE);
       }
     }
   }
@@ -2891,43 +2919,11 @@ TDateTime __fastcall TFTPFileSystem::ConvertLocalTimestamp(time_t Time)
   return UnixToDateTime(Timestamp, dstmUnix);
 }
 //---------------------------------------------------------------------------
-void __fastcall TFTPFileSystem::ConvertRemoteTimestamp(
-  time_t Time, bool HasTime, TDateTime & DateTime, TModificationFmt & ModificationFmt)
-{
-  tm * Tm = localtime(&Time);
-  if (Tm != NULL)
-  {
-    // should be the same as HandleListData
-    DateTime = EncodeDateVerbose(
-      static_cast<unsigned short>(Tm->tm_year + 1900),
-      static_cast<unsigned short>(Tm->tm_mon + 1),
-      static_cast<unsigned short>(Tm->tm_mday));
-    if (HasTime)
-    {
-      DateTime += EncodeTimeVerbose(
-        static_cast<unsigned short>(Tm->tm_hour),
-        static_cast<unsigned short>(Tm->tm_min),
-        static_cast<unsigned short>(Tm->tm_sec), 0);
-      ModificationFmt = (Tm->tm_sec != 0 ? mfFull : mfMDHM);
-    }
-    else
-    {
-      ModificationFmt = mfMDY;
-    }
-  }
-  else
-  {
-    // incorrect, but at least something
-    DateTime = UnixToDateTime(Time, dstmUnix);
-    ModificationFmt = (HasTime ? mfMDHM : mfMDY);
-  }
-}
-//---------------------------------------------------------------------------
 bool __fastcall TFTPFileSystem::HandleAsynchRequestOverwrite(
   wchar_t * FileName1, size_t FileName1Len, const wchar_t * /*FileName2*/,
   const wchar_t * /*Path1*/, const wchar_t * /*Path2*/,
-  __int64 Size1, __int64 Size2, time_t Time1, time_t Time2,
-  bool HasTime1, bool HasTime2, void * AUserData, int & RequestResult)
+  __int64 Size1, __int64 Size2, time_t LocalTime,
+  bool /*HasLocalTime*/, const TRemoteFileTime & RemoteTime, void * AUserData, int & RequestResult)
 {
   if (!FActive)
   {
@@ -2949,8 +2945,8 @@ bool __fastcall TFTPFileSystem::HandleAsynchRequestOverwrite(
       TOverwriteMode OverwriteMode = omOverwrite;
       TOverwriteFileParams FileParams;
       bool NoFileParams =
-        (Size1 < 0) || (Time1 == 0) ||
-        (Size2 < 0) || (Time2 == 0);
+        (Size1 < 0) || (LocalTime == 0) ||
+        (Size2 < 0) || !RemoteTime.HasDate;
       if (!NoFileParams)
       {
         FileParams.SourceSize = Size2;
@@ -2958,15 +2954,13 @@ bool __fastcall TFTPFileSystem::HandleAsynchRequestOverwrite(
 
         if (OperationProgress->Side == osLocal)
         {
-          FileParams.SourceTimestamp = ConvertLocalTimestamp(Time2);
-          ConvertRemoteTimestamp(Time1, HasTime1,
-            FileParams.DestTimestamp, FileParams.DestPrecision);
+          FileParams.SourceTimestamp = ConvertLocalTimestamp(LocalTime);
+          RemoteFileTimeToDateTimeAndPrecision(RemoteTime, FileParams.DestTimestamp, FileParams.DestPrecision);
         }
         else
         {
-          ConvertRemoteTimestamp(Time2, HasTime2,
-            FileParams.SourceTimestamp, FileParams.SourcePrecision);
-          FileParams.DestTimestamp = ConvertLocalTimestamp(Time1);
+          FileParams.DestTimestamp = ConvertLocalTimestamp(LocalTime);
+          RemoteFileTimeToDateTimeAndPrecision(RemoteTime, FileParams.SourceTimestamp, FileParams.SourcePrecision);
         }
       }
 
@@ -2994,6 +2988,11 @@ bool __fastcall TFTPFileSystem::HandleAsynchRequestOverwrite(
             RequestResult = TFileZillaIntf::FILEEXISTS_RESUME;
             break;
 
+          case omComplete:
+            FTerminal->LogEvent(L"File transfer was completed before disconnect");
+            RequestResult = TFileZillaIntf::FILEEXISTS_COMPLETE;
+            break;
+
           default:
             assert(false);
             RequestResult = TFileZillaIntf::FILEEXISTS_OVERWRITE;
@@ -3166,8 +3165,8 @@ bool __fastcall TFTPFileSystem::HandleAsynchRequestVerifyCertificate(
 
     FSessionInfo.Certificate =
       FMTLOAD(CERT_TEXT, (
-        FormatContact(Data.Subject),
         FormatContact(Data.Issuer),
+        FormatContact(Data.Subject),
         FormatValidityTime(Data.ValidFrom),
         FormatValidityTime(Data.ValidUntil),
         FSessionInfo.CertificateFingerprint,
@@ -3294,6 +3293,43 @@ bool __fastcall TFTPFileSystem::HandleAsynchRequestNeedPass(
   }
 }
 //---------------------------------------------------------------------------
+void __fastcall TFTPFileSystem::RemoteFileTimeToDateTimeAndPrecision(const TRemoteFileTime & Source, TDateTime & DateTime, TModificationFmt & ModificationFmt)
+{
+  // ModificationFmt must be set after Modification
+  if (Source.HasDate)
+  {
+    DateTime =
+      EncodeDateVerbose((unsigned short)Source.Year, (unsigned short)Source.Month,
+        (unsigned short)Source.Day);
+    if (Source.HasTime)
+    {
+      DateTime = DateTime +
+        EncodeTimeVerbose((unsigned short)Source.Hour, (unsigned short)Source.Minute,
+          (unsigned short)Source.Second, 0);
+      // not exact as we got year as well, but it is most probably
+      // guessed by FZAPI anyway
+      ModificationFmt = Source.HasSeconds ? mfFull : mfMDHM;
+    }
+    else
+    {
+      ModificationFmt = mfMDY;
+    }
+
+    if (Source.Utc)
+    {
+      DateTime = ConvertTimestampFromUTC(DateTime);
+    }
+
+  }
+  else
+  {
+    // With SCP we estimate date to be today, if we have at least time
+
+    DateTime = double(0);
+    ModificationFmt = mfNone;
+  }
+}
+//---------------------------------------------------------------------------
 bool __fastcall TFTPFileSystem::HandleListData(const wchar_t * Path,
   const TListDataEntry * Entries, unsigned int Count)
 {
@@ -3367,41 +3403,11 @@ bool __fastcall TFTPFileSystem::HandleListData(const wchar_t * Path,
           File->Type = L'-';
         }
 
-        // ModificationFmt must be set after Modification
-        if (Entry->HasDate)
-        {
-          // should be the same as ConvertRemoteTimestamp
-          TDateTime Modification =
-            EncodeDateVerbose((unsigned short)Entry->Year, (unsigned short)Entry->Month,
-              (unsigned short)Entry->Day);
-          if (Entry->HasTime)
-          {
-            File->Modification = Modification +
-              EncodeTimeVerbose((unsigned short)Entry->Hour, (unsigned short)Entry->Minute,
-                (unsigned short)Entry->Second, 0);
-            // not exact as we got year as well, but it is most probably
-            // guessed by FZAPI anyway
-            File->ModificationFmt = Entry->HasSeconds ? mfFull : mfMDHM;
-          }
-          else
-          {
-            File->Modification = Modification;
-            File->ModificationFmt = mfMDY;
-          }
-
-          if (Entry->Utc)
-          {
-            File->Modification = ConvertFileTimestampFromUTC(File->Modification);
-          }
-
-        }
-        else
-        {
-          // With SCP we estimate date to be today, if we have at least time
-
-          File->Modification = double(0);
-          File->ModificationFmt = mfNone;
-        }
+        TDateTime Modification;
+        TModificationFmt ModificationFmt;
+        RemoteFileTimeToDateTimeAndPrecision(Entry->Time, Modification, ModificationFmt);
+        File->Modification = Modification;
+        File->ModificationFmt = ModificationFmt;
         File->LastAccess = File->Modification;
 
         File->LinkTo = Entry->LinkTarget;
@@ -3414,9 +3420,9 @@ bool __fastcall TFTPFileSystem::HandleListData(const wchar_t * Path,
         UnicodeString EntryData =
           FORMAT(L"%s/%s/%s/%s/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d",
             (Entry->Name, Entry->Permissions, Entry->OwnerGroup, IntToStr(Entry->Size),
-             int(Entry->Dir), int(Entry->Link), Entry->Year, Entry->Month, Entry->Day,
-             Entry->Hour, Entry->Minute, int(Entry->HasTime),
-             int(Entry->HasSeconds), int(Entry->HasDate)));
+             int(Entry->Dir), int(Entry->Link), Entry->Time.Year, Entry->Time.Month, Entry->Time.Day,
+             Entry->Time.Hour, Entry->Time.Minute, int(Entry->Time.HasTime),
+             int(Entry->Time.HasSeconds), int(Entry->Time.HasDate)));
         throw ETerminal(&E, FMTLOAD(LIST_LINE_ERROR, (EntryData)));
       }
 
@@ -3581,4 +3587,64 @@ bool __fastcall TFTPFileSystem::Unquote(UnicodeString & Str)
   return (State == DONE);
 }
 //---------------------------------------------------------------------------
+void __fastcall TFTPFileSystem::PreserveDownloadFileTime(HANDLE Handle, void * UserData)
+{
+  TFileTransferData * Data = static_cast<TFileTransferData *>(UserData);
+  FILETIME WrTime = DateTimeToFileTime(Data->Modification, dstmUnix);
+  SetFileTime(Handle, NULL, NULL, &WrTime);
+}
+//---------------------------------------------------------------------------
+bool __fastcall TFTPFileSystem::GetFileModificationTimeInUtc(const wchar_t * FileName, struct tm & Time)
+{
+  bool Result;
+  try
+  {
+    // error-handling-free and DST-mode-inaware copy of TTerminal::OpenLocalFile
+    HANDLE Handle = CreateFile(FileName, GENERIC_READ,
+      FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
+    if (Handle == INVALID_HANDLE_VALUE)
+    {
+      Result = false;
+    }
+    else
+    {
+      FILETIME MTime;
+      if (!GetFileTime(Handle, NULL, NULL, &MTime))
+      {
+        Result = false;
+      }
+      else
+      {
+        TDateTime Modification = ConvertTimestampToUTC(FileTimeToDateTime(MTime));
+
+        unsigned short Year;
+        unsigned short Month;
+        unsigned short Day;
+        Modification.DecodeDate(&Year, &Month, &Day);
+        Time.tm_year = Year - 1900;
+        Time.tm_mon = Month - 1;
+        Time.tm_mday = Day;
+
+        unsigned short Hour;
+        unsigned short Min;
+        unsigned short Sec;
+        unsigned short MSec;
+        Modification.DecodeTime(&Hour, &Min, &Sec, &MSec);
+        Time.tm_hour = Hour;
+        Time.tm_min = Min;
+        Time.tm_sec = Sec;
+
+        Result = true;
+      }
+
+      CloseHandle(Handle);
+    }
+  }
+  catch (...)
+  {
+    Result = false;
+  }
+  return Result;
+}
+//---------------------------------------------------------------------------
 #endif NO_FILEZILLA

+ 8 - 4
core/FtpFileSystem.h

@@ -15,6 +15,7 @@ struct TOverwriteFileParams;
 struct TListDataEntry;
 struct TFileTransferData;
 struct TFtpsCertificateData;
+struct TRemoteFileTime;
 //---------------------------------------------------------------------------
 class TFTPFileSystem : public TCustomFileSystem
 {
@@ -81,7 +82,7 @@ public:
   virtual UnicodeString __fastcall GetUserName();
 
 protected:
-  enum TOverwriteMode { omOverwrite, omResume };
+  enum TOverwriteMode { omOverwrite, omResume, omComplete };
 
   virtual UnicodeString __fastcall GetCurrentDirectory();
 
@@ -118,8 +119,8 @@ protected:
   bool __fastcall HandleAsynchRequestOverwrite(
     wchar_t * FileName1, size_t FileName1Len, const wchar_t * FileName2,
     const wchar_t * Path1, const wchar_t * Path2,
-    __int64 Size1, __int64 Size2, time_t Time1, time_t Time2,
-    bool HasTime1, bool HasTime2, void * UserData, int & RequestResult);
+    __int64 Size1, __int64 Size2, time_t LocalTime,
+    bool HasLocalTime, const TRemoteFileTime & RemoteTime, void * UserData, int & RequestResult);
   bool __fastcall HandleAsynchRequestVerifyCertificate(
     const TFtpsCertificateData & Data, int & RequestResult);
   bool __fastcall HandleAsynchRequestNeedPass(
@@ -132,6 +133,8 @@ protected:
   bool __fastcall HandleReply(int Command, unsigned int Reply);
   bool __fastcall HandleCapabilities(TFTPServerCapabilities * ServerCapabilities);
   bool __fastcall CheckError(int ReturnCode, const wchar_t * Context);
+  void __fastcall PreserveDownloadFileTime(HANDLE Handle, void * UserData);
+  bool __fastcall GetFileModificationTimeInUtc(const wchar_t * FileName, struct tm & Time);
   void __fastcall EnsureLocation();
   UnicodeString __fastcall ActualCurrentDirectory();
   void __fastcall Discard();
@@ -173,7 +176,8 @@ protected:
     __int64 Size, int Type, TFileTransferData & UserData,
     TFileOperationProgressType * OperationProgress);
   TDateTime __fastcall ConvertLocalTimestamp(time_t Time);
-  void __fastcall ConvertRemoteTimestamp(time_t Time, bool HasTime, TDateTime & DateTime, TModificationFmt & ModificationFmt);
+  void __fastcall RemoteFileTimeToDateTimeAndPrecision(const TRemoteFileTime & Source,
+    TDateTime & DateTime, TModificationFmt & ModificationFmt);
   void __fastcall SetLastCode(int Code);
 
   static bool __fastcall Unquote(UnicodeString & Str);

+ 2 - 1
core/Queue.cpp

@@ -471,7 +471,7 @@ void __fastcall TTerminalQueue::TerminalFinished(TTerminalItem * TerminalItem)
       }
 
       // Index may be >= FTransfersLimit also when the transfer limit was
-      // recently decresed, then
+      // recently decreased, then
       // FTemporaryTerminals < FTerminals->Count - FTransfersLimit
       if ((FTransfersLimit >= 0) && (Index >= FTransfersLimit) && (FTemporaryTerminals > 0))
       {
@@ -784,6 +784,7 @@ bool __fastcall TTerminalQueue::ItemDelete(TQueueItem * Item)
         {
           FItems->Delete(Index);
           FForcedItems->Remove(Item);
+          delete Item;
           UpdateList = true;
         }
         else

+ 8 - 0
core/Script.cpp

@@ -2204,3 +2204,11 @@ void __fastcall TManagementScript::LLsProc(TScriptProcParams * Parameters)
   }
 }
 //---------------------------------------------------------------------------
+void __fastcall TManagementScript::ReflectSettings()
+{
+  for (int i = 0; i < FTerminalList->Count; i++)
+  {
+    FTerminalList->Terminals[i]->ReflectSettings();
+  }
+}
+//---------------------------------------------------------------------------

+ 1 - 0
core/Script.h

@@ -147,6 +147,7 @@ public:
   virtual __fastcall ~TManagementScript();
 
   void __fastcall Connect(const UnicodeString Session, TOptions * Options, bool CheckParams);
+  void __fastcall ReflectSettings();
 
   __property TScriptInputEvent OnInput = { read = FOnInput, write = FOnInput };
   __property TScriptQueryCancelEvent OnQueryCancel = { read = FOnQueryCancel, write = FOnQueryCancel };

+ 13 - 3
core/SessionInfo.cpp

@@ -1076,7 +1076,8 @@ void __fastcall TSessionLog::DoAddStartupInfo(TSessionData * Data)
     ADF(L"Cache directory changes: %s, Permanent: %s",
       (BooleanToEngStr(Data->CacheDirectoryChanges),
        BooleanToEngStr(Data->PreserveDirectoryChanges)));
-    ADF(L"DST mode: %d", (int(Data->DSTMode)));
+    int TimeDifferenceMin = TimeToMinutes(Data->TimeDifference);
+    ADF(L"DST mode: %d; Timezone offset: %dh %dm", (int(Data->DSTMode), (TimeDifferenceMin / MinsPerHour), (TimeDifferenceMin % MinsPerHour)));
 
     AddSeparator();
 
@@ -1236,7 +1237,11 @@ void __fastcall TActionLog::ReflectSettings()
     {
       EndGroup();
     }
-    Add(L"</session>");
+    // do not try to close the file, if it has not been opened, to avoid recursion
+    if (FFile != NULL)
+    {
+      Add(L"</session>");
+    }
     CloseLogFile();
     FLogging = false;
   }
@@ -1310,7 +1315,12 @@ void __fastcall TActionLog::EndGroup()
   FInGroup = false;
   assert(FIndent == L"    ");
   FIndent = L"  ";
-  AddIndented("</group>");
+  // this is called from ReflectSettings that in turn is called when logging fails,
+  // so do not try to close the group, if it has not been opened, to avoid recursion
+  if (FFile != NULL)
+  {
+    AddIndented("</group>");
+  }
 }
 //---------------------------------------------------------------------------
 void __fastcall TActionLog::SetEnabled(bool value)

+ 43 - 17
core/Terminal.cpp

@@ -660,8 +660,7 @@ void __fastcall TTerminal::ResetConnection()
 //---------------------------------------------------------------------------
 void __fastcall TTerminal::Open()
 {
-  FLog->ReflectSettings();
-  FActionLog->ReflectSettings();
+  ReflectSettings();
   try
   {
     DoInformation(L"", true, 1);
@@ -1994,14 +1993,27 @@ unsigned int __fastcall TTerminal::ConfirmFileOverwrite(const UnicodeString File
         break;
 
       case boOlder:
-        Result =
-          ((FileParams != NULL) &&
-           (CompareFileTime(
-             ReduceDateTimePrecision(FileParams->SourceTimestamp,
-               LessDateTimePrecision(FileParams->SourcePrecision, FileParams->DestPrecision)),
-             ReduceDateTimePrecision(FileParams->DestTimestamp,
-               LessDateTimePrecision(FileParams->SourcePrecision, FileParams->DestPrecision))) > 0)) ?
-          qaYes : qaNo;
+        if (FileParams == NULL)
+        {
+          Result = qaNo;
+        }
+        else
+        {
+          TModificationFmt Precision = LessDateTimePrecision(FileParams->SourcePrecision, FileParams->DestPrecision);
+          TDateTime ReducedSourceTimestamp =
+            ReduceDateTimePrecision(FileParams->SourceTimestamp, Precision);
+          TDateTime ReducedDestTimestamp =
+            ReduceDateTimePrecision(FileParams->DestTimestamp, Precision);
+
+          Result =
+            (CompareFileTime(ReducedSourceTimestamp, ReducedDestTimestamp) > 0) ?
+            qaYes : qaNo;
+
+          LogEvent(FORMAT(L"Source file timestamp is [%s], destination timestamp is [%s], will%s overwrite",
+            (StandardTimestamp(ReducedSourceTimestamp),
+             StandardTimestamp(ReducedDestTimestamp),
+             ((Result == qaYes) ? L"" : L" not"))));
+        }
         break;
 
       case boAlternateResume:
@@ -2311,6 +2323,14 @@ void __fastcall TTerminal::ReadDirectory(bool ReloadOnly, bool ForceCache)
   }
 }
 //---------------------------------------------------------------------------
+void __fastcall TTerminal::LogFile(TRemoteFile * File)
+{
+  LogEvent(FORMAT(L"%s;%s;%d;%s;%s;%s;%s;%d",
+    (File->FileName, File->Type, File->Size, StandardTimestamp(File->Modification),
+     File->Owner.LogText, File->Group.LogText, File->Rights->Text,
+     File->Attr)));
+}
+//---------------------------------------------------------------------------
 void __fastcall TTerminal::CustomReadDirectory(TRemoteFileList * FileList)
 {
   assert(FileList);
@@ -2321,11 +2341,7 @@ void __fastcall TTerminal::CustomReadDirectory(TRemoteFileList * FileList)
   {
     for (int Index = 0; Index < FileList->Count; Index++)
     {
-      TRemoteFile * File = FileList->Files[Index];
-      LogEvent(FORMAT(L"%s;%s;%d;%s;%s;%s;%s;%d",
-        (File->FileName, File->Type, File->Size, StandardTimestamp(File->Modification),
-         File->Owner.LogText, File->Group.LogText, File->Rights->Text,
-         File->Attr)));
+      LogFile(FileList->Files[Index]);
     }
   }
 
@@ -2544,6 +2560,7 @@ void __fastcall TTerminal::ReadFile(const UnicodeString FileName,
     LogEvent(FORMAT(L"Listing file \"%s\".", (FileName)));
     FFileSystem->ReadFile(FileName, File);
     ReactOnCommand(fsListFile);
+    LogFile(File);
   }
   catch (Exception &E)
   {
@@ -4663,9 +4680,9 @@ void __fastcall TTerminal::FileFind(UnicodeString FileName,
     MaskParams.Modification = File->Modification;
 
     UnicodeString FullFileName = UnixExcludeTrailingBackslash(File->FullFileName);
-    bool ImplicitMatch = false;
+    bool ImplicitMatch;
     if (AParams->FileMask.Matches(FullFileName, false,
-         File->IsDirectory, &MaskParams))
+         File->IsDirectory, &MaskParams, ImplicitMatch))
     {
       if (!ImplicitMatch)
       {
@@ -4974,6 +4991,15 @@ bool __fastcall TTerminal::CopyToLocal(TStrings * FilesToCopy,
   return Result;
 }
 //---------------------------------------------------------------------------
+void __fastcall TTerminal::ReflectSettings()
+{
+  assert(FLog != NULL);
+  FLog->ReflectSettings();
+  assert(FActionLog != NULL);
+  FActionLog->ReflectSettings();
+  // also FTunnelLog ?
+}
+//---------------------------------------------------------------------------
 __fastcall TSecondaryTerminal::TSecondaryTerminal(TTerminal * MainTerminal,
   TSessionData * ASessionData, TConfiguration * Configuration, const UnicodeString & Name) :
   TTerminal(ASessionData, Configuration),

+ 2 - 0
core/Terminal.h

@@ -344,6 +344,7 @@ protected:
   TRemoteFileList * __fastcall DoReadDirectoryListing(UnicodeString Directory, bool UseCache);
   RawByteString __fastcall EncryptPassword(const UnicodeString & Password);
   UnicodeString __fastcall DecryptPassword(const RawByteString & Password);
+  void __fastcall LogFile(TRemoteFile * File);
 
   __property TFileOperationProgressType * OperationProgress = { read=FOperationProgress };
 
@@ -438,6 +439,7 @@ public:
     TFileOperationProgressType * OperationProgress);
   UnicodeString __fastcall PeekCurrentDirectory();
   void __fastcall FatalAbort();
+  void __fastcall ReflectSettings();
 
   const TSessionInfo & __fastcall GetSessionInfo();
   const TFileSystemInfo & __fastcall GetFileSystemInfo(bool Retrieve = false);

+ 2 - 1
filezilla/ControlSocket.cpp

@@ -61,10 +61,11 @@ CCriticalSection CControlSocket::m_SpeedLimitSync;
 // Konstruktion/Destruktion
 //////////////////////////////////////////////////////////////////////
 
-CControlSocket::CControlSocket(CMainThread *pMainThread)
+CControlSocket::CControlSocket(CMainThread *pMainThread, CFileZillaTools * pTools)
 {
 	ASSERT(pMainThread);
 	m_pOwner=pMainThread;
+	m_pTools=pTools;
 
 	m_Operation.nOpMode=0;
 	m_Operation.nOpState=-1;

+ 3 - 1
filezilla/ControlSocket.h

@@ -69,13 +69,14 @@ class CAsyncSslSocketLayer;
 class CAsyncGssSocketLayer;
 #endif
 class CTransferSocket;
+class CFileZillaTools;
 
 #define BUFSIZE                             16384
 
 class CControlSocket : public CAsyncSocketEx, public CApiLog
 {
 public:
-	CControlSocket(CMainThread *pMainThread);
+	CControlSocket(CMainThread *pMainThread, CFileZillaTools * pTools);
 	virtual ~CControlSocket();
 
 	enum transferDirection
@@ -123,6 +124,7 @@ protected:
 	t_directory *m_pDirectoryListing;
 
 	CMainThread *m_pOwner;
+	CFileZillaTools * m_pTools;
 #ifndef MPEXT_NO_IDENT
 	CIdentServerControl *m_pIdentControl;
 #endif

+ 6 - 5
filezilla/FileZillaApi.cpp

@@ -59,7 +59,7 @@ CFileZillaApi::~CFileZillaApi()
 #ifndef MPEXT
 int CFileZillaApi::Init(HWND hOwnerWnd, int nReplyMessageID /*=0*/)
 #else
-int CFileZillaApi::Init(CApiLog * pParent)
+int CFileZillaApi::Init(CApiLog * pParent, CFileZillaTools * pTools)
 #endif
 {
 	//Check parameters
@@ -86,6 +86,8 @@ int CFileZillaApi::Init(CApiLog * pParent)
 	m_pMainThread->m_nInternalMessageID=m_nInternalMessageID;
 	m_pMainThread->m_nReplyMessageID=m_nReplyMessageID;
 	m_pMainThread->m_hOwnerWnd=m_hOwnerWnd;
+	m_pMainThread->m_hOwnerWnd=m_hOwnerWnd;
+	m_pMainThread->m_pTools=pTools;
 
 #ifndef MPEXT
 	m_pMainThread->InitLog(m_hOwnerWnd, m_nReplyMessageID);
@@ -863,16 +865,15 @@ COverwriteRequestData::COverwriteRequestData()
 	size1 = 0;
 	size2 = 0;
 	nRequestType=FZ_ASYNCREQUEST_OVERWRITE;
-	time1=0;
-	time2=0;
+	localtime=0;
+	remotetime.hasdate = false;
 	pTransferFile=0;
 }
 
 COverwriteRequestData::~COverwriteRequestData()
 {
 	delete pTransferFile;
-	delete time1;
-	delete time2;
+	delete localtime;
 }
 
 #ifndef MPEXT_NO_SSL

+ 5 - 3
filezilla/FileZillaApi.h

@@ -28,6 +28,7 @@
 #endif // _MSC_VER > 1000
 
 #include "FzApiStructures.h"
+#include "structures.h"
 #ifndef MPEXT_NO_SSL
 #include "AsyncSslSocketLayer.h"
 #endif
@@ -147,8 +148,8 @@ public:
 	CString path1,path2;
 	__int64 size1;
 	__int64 size2;
-	CTime *time1;
-	CTime *time2;
+	CTime *localtime;
+	t_directory::t_direntry::t_date remotetime;
 	const t_transferfile *pTransferFile;
 };
 
@@ -296,6 +297,7 @@ public:
 #define FZ_LOG_DEBUG 8
 
 class CMainThread;
+class CFileZillaTools;
 class CFileZillaApi  
 {
 public:
@@ -329,7 +331,7 @@ public:
 #ifndef MPEXT
 	int Init(HWND hOwnerWnd, int nReplyMessageID = 0);
 #else
-	int Init(CApiLog * pParent);
+	int Init(CApiLog * pParent, CFileZillaTools * pTools);
 #endif
 	unsigned int GetMessageID();
 

+ 21 - 15
filezilla/FileZillaIntf.cpp

@@ -55,7 +55,7 @@ bool __fastcall TFileZillaIntf::Init()
 
   FFileZillaApi = new CFileZillaApi();
 
-  bool Result = Check(FFileZillaApi->Init(FIntern), L"init");
+  bool Result = Check(FFileZillaApi->Init(FIntern, this), L"init");
 
   if (!Result)
   {
@@ -296,6 +296,20 @@ void __fastcall CopyValidityTime(TFtpsCertificateData::TValidityTime & Dest,
   Dest.Sec = Source.s;
 }
 //---------------------------------------------------------------------------
+void __fastcall CopyFileTime(TRemoteFileTime & Dest, const t_directory::t_direntry::t_date & Source)
+{
+  Dest.Year = Source.year;
+  Dest.Month = Source.month;
+  Dest.Day = Source.day;
+  Dest.Hour = Source.hour;
+  Dest.Minute = Source.minute;
+  Dest.Second = Source.second;
+  Dest.HasTime = Source.hastime;
+  Dest.HasDate = Source.hasdate;
+  Dest.HasSeconds = Source.hasseconds;
+  Dest.Utc = Source.utc;
+}
+//---------------------------------------------------------------------------
 bool __fastcall TFileZillaIntf::HandleMessage(WPARAM wParam, LPARAM lParam)
 {
   bool Result;
@@ -327,13 +341,14 @@ bool __fastcall TFileZillaIntf::HandleMessage(WPARAM wParam, LPARAM lParam)
           ASSERT(Data != NULL);
           wcsncpy(FileName1, Data->FileName1, LENOF(FileName1));
           FileName1[LENOF(FileName1) - 1] = L'\0';
+          TRemoteFileTime RemoteTime;
+          CopyFileTime(RemoteTime, Data->remotetime);
           Result = HandleAsynchRequestOverwrite(
             FileName1, LENOF(FileName1), Data->FileName2, Data->path1, Data->path2,
             Data->size1, Data->size2,
-            (Data->time1 != NULL) ? Data->time1->GetTime() : 0,
-            (Data->time2 != NULL) ? Data->time2->GetTime() : 0,
-            (Data->time1 != NULL) && ((Data->time1->GetHour() != 0) || (Data->time1->GetMinute() != 0)),
-            (Data->time2 != NULL) && ((Data->time2->GetHour() != 0) || (Data->time2->GetMinute() != 0)),
+            (Data->localtime != NULL) ? Data->localtime->GetTime() : 0,
+            (Data->localtime != NULL) && ((Data->localtime->GetHour() != 0) || (Data->localtime->GetMinute() != 0)),
+            RemoteTime,
             reinterpret_cast<void*>(Data->pTransferFile->nUserData), RequestResult);
         }
         catch(...)
@@ -436,16 +451,7 @@ bool __fastcall TFileZillaIntf::HandleMessage(WPARAM wParam, LPARAM lParam)
           Dest.Size = Source.size;
           Dest.Dir = Source.dir;
           Dest.Link = Source.bLink;
-          Dest.Year = Source.date.year;
-          Dest.Month = Source.date.month;
-          Dest.Day = Source.date.day;
-          Dest.Hour = Source.date.hour;
-          Dest.Minute = Source.date.minute;
-          Dest.Second = Source.date.second;
-          Dest.HasTime = Source.date.hastime;
-          Dest.HasDate = Source.date.hasdate;
-          Dest.HasSeconds = Source.date.hasseconds;
-          Dest.Utc = Source.date.utc;
+          CopyFileTime(Dest.Time, Source.date);
           Dest.LinkTarget = Source.linkTarget;
         }
 

+ 19 - 11
filezilla/FileZillaIntf.h

@@ -6,18 +6,13 @@
 
 #include <time.h>
 #include <FileZillaOpt.h>
+#include <FileZillaTools.h>
 //---------------------------------------------------------------------------
 class CFileZillaApi;
 class TFileZillaIntern;
 //---------------------------------------------------------------------------
-struct TListDataEntry
+struct TRemoteFileTime
 {
-  const wchar_t * Name;
-  const wchar_t * Permissions;
-  const wchar_t * OwnerGroup;
-  __int64 Size;
-  bool Dir;
-  bool Link;
   int Year;
   int Month;
   int Day;
@@ -28,6 +23,17 @@ struct TListDataEntry
   bool HasSeconds;
   bool HasDate;
   bool Utc;
+};
+//---------------------------------------------------------------------------
+struct TListDataEntry
+{
+  const wchar_t * Name;
+  const wchar_t * Permissions;
+  const wchar_t * OwnerGroup;
+  __int64 Size;
+  bool Dir;
+  bool Link;
+  TRemoteFileTime Time;
   const wchar_t * LinkTarget;
 };
 //---------------------------------------------------------------------------
@@ -76,7 +82,7 @@ struct TNeedPassRequestData
 class t_server;
 class TFTPServerCapabilities;
 //---------------------------------------------------------------------------
-class TFileZillaIntf
+class TFileZillaIntf : public CFileZillaTools
 {
 friend class TFileZillaIntern;
 
@@ -103,10 +109,12 @@ public:
   enum
   {
     FILEEXISTS_OVERWRITE = 0,
-    FILEEXISTS_OVERWRITEIFNEWER = 1,
+    // 1 is FILEEXISTS_OVERWRITEIFNEWER what we do not use
     FILEEXISTS_RESUME = 2,
     FILEEXISTS_RENAME = 3,
     FILEEXISTS_SKIP = 4,
+    // 5 is FILEEXISTS_RESUME_ASKONFAIL what we do not use
+    FILEEXISTS_COMPLETE = 6,
   };
 
   enum
@@ -190,8 +198,8 @@ protected:
   virtual bool __fastcall HandleAsynchRequestOverwrite(
     wchar_t * FileName1, size_t FileName1Len, const wchar_t * FileName2,
     const wchar_t * Path1, const wchar_t * Path2,
-    __int64 Size1, __int64 Size2, time_t Time1, time_t Time2,
-    bool HasTime1, bool HasTime2, void * UserData, int & RequestResult) = 0;
+    __int64 Size1, __int64 Size2, time_t LocalTime,
+    bool HasLocalTime1, const TRemoteFileTime & RemoteTime, void * UserData, int & RequestResult) = 0;
   virtual bool __fastcall HandleAsynchRequestVerifyCertificate(
     const TFtpsCertificateData & Data, int & RequestResult) = 0;
   virtual bool __fastcall HandleAsynchRequestNeedPass(

+ 14 - 0
filezilla/FilezillaTools.h

@@ -0,0 +1,14 @@
+//---------------------------------------------------------------------------
+#ifndef FileZillaToolsH
+#define FileZillaToolsH
+//---------------------------------------------------------------------------
+#include <ctime>
+//---------------------------------------------------------------------------
+class CFileZillaTools
+{
+public:
+  virtual void PreserveDownloadFileTime(HANDLE Handle, void * UserData) = 0;
+  virtual bool GetFileModificationTimeInUtc(const wchar_t * FileName, struct tm & Time) = 0;
+};
+//---------------------------------------------------------------------------
+#endif // FileZillaToolsH

+ 80 - 135
filezilla/FtpControlSocket.cpp

@@ -55,7 +55,7 @@ public:
 		nGotTransferEndReply=0;
 		nWaitNextOpState=0;
 		nMKDOpState=-1;
-		pFileTime=0;
+		hasRemoteDate = false;
 		pFileSize=0;
 		bUseAbsolutePaths = FALSE;
 		bTriedPortPasvOnce = FALSE;
@@ -67,7 +67,6 @@ public:
 			delete pDirectoryListing;
 		pDirectoryListing=0;
 		delete pFileSize;
-		delete pFileTime;
 	};
 	CString rawpwd;
 	t_transferfile transferfile;
@@ -82,7 +81,9 @@ public:
 	std::list<CString> MKDSegments;
 	int nMKDOpState;
 	CTime ListStartTime;
-	CTime *pFileTime; //Used when downloading and OPTION_PRESERVEDOWNLOADFILETIME is set or when LIST fails
+	bool hasRemoteDate;
+	t_directory::t_direntry::t_date remoteDate;
+	//CTime *pFileTime; //Used when downloading and OPTION_PRESERVEDOWNLOADFILETIME is set or when LIST fails
 	_int64 *pFileSize; //Used when LIST failes
 	BOOL bUseAbsolutePaths;
 	BOOL bTriedPortPasvOnce;
@@ -157,7 +158,7 @@ public:
 /////////////////////////////////////////////////////////////////////////////
 // CFtpControlSocket
 
-CFtpControlSocket::CFtpControlSocket(CMainThread *pMainThread) : CControlSocket(pMainThread)
+CFtpControlSocket::CFtpControlSocket(CMainThread *pMainThread, CFileZillaTools * pTools) : CControlSocket(pMainThread, pTools)
 {
 	ASSERT(pMainThread);
 	m_Operation.nOpMode=0;
@@ -3533,24 +3534,17 @@ void CFtpControlSocket::FileTransfer(t_transferfile *transferfile/*=0*/,BOOL bFi
 							}
 							if (M>0 && M<=12 && d>0 && d<=31 && h>=0 && h<24 && m>=0 && m<60)
 							{
-								if (pData->pFileTime)
-									delete pData->pFileTime;
-								TRY
-								{
-									pData->pFileTime = new CTime(y, M, d, h, m, 0);
-								}
-								CATCH_ALL(e)
-								{
-									TCHAR buffer[1024];
-									CString str =_T("Exception creating CTime object: ");
-									if (e->GetErrorMessage(buffer, 1024, NULL))
-										str += buffer;
-									else
-									str += _T("Unknown exception");
-									LogMessageRaw(__FILE__, __LINE__, this, FZ_LOG_WARNING, str);
-									pData->pFileTime = 0;
-								}
-								END_CATCH_ALL;
+							    pData->hasRemoteDate = true;
+							    pData->remoteDate.year = y;
+							    pData->remoteDate.month = M;
+							    pData->remoteDate.day = d;
+							    pData->remoteDate.hour = h;
+							    pData->remoteDate.minute = m;
+							    pData->remoteDate.second = 0;
+							    pData->remoteDate.hastime = true;
+							    pData->remoteDate.hasseconds = false;
+							    pData->remoteDate.hasdate = true;
+							    pData->remoteDate.utc = true;
 							}
 						}
 					}
@@ -3795,40 +3789,8 @@ void CFtpControlSocket::FileTransfer(t_transferfile *transferfile/*=0*/,BOOL bFi
 						{
 							if (m_pDirectoryListing->direntry[i].name==remotefile)
 							{
-								if (pData->pFileTime)
-								{
-									delete pData->pFileTime;
-									pData->pFileTime = 0;
-								}
-								t_directory::t_direntry::t_date *pDate=&m_pDirectoryListing->direntry[i].date;
-								if (pDate->hasdate)
-								{
-									TRY
-									{
-										if (pDate->hastime)
-											pData->pFileTime = new CTime(pDate->year, pDate->month, pDate->day, pDate->hour, pDate->minute, pDate->second);
-										else
-											pData->pFileTime = new CTime(pDate->year, pDate->month, pDate->day, 0, 0, 0);
-
-										TIME_ZONE_INFORMATION tzInfo = {0};
-										BOOL res = GetTimeZoneInformation(&tzInfo);
-										CTimeSpan span(0, 0, tzInfo.Bias + ((res == TIME_ZONE_ID_DAYLIGHT) ? tzInfo.DaylightBias : tzInfo.StandardBias), 0);
-										*pData->pFileTime += span;
-									}
-									CATCH_ALL(e)
-									{
-										TCHAR buffer[1024];
-										CString str =_T("Exception creating CTime object: ");
-										if (e->GetErrorMessage(buffer, 1024, NULL))
-											str += buffer;
-										else
-										str += _T("Unknown exception");
-										LogMessageRaw(__FILE__, __LINE__, this, FZ_LOG_WARNING, str);
-										pData->pFileTime = 0;
-									}
-									END_CATCH_ALL;
-								}
-
+							    pData->hasRemoteDate = true;
+							    pData->remoteDate = m_pDirectoryListing->direntry[i].date;
 								pData->transferdata.transfersize=m_pDirectoryListing->direntry[i].size;
 							}
 						}
@@ -3991,43 +3953,7 @@ void CFtpControlSocket::FileTransfer(t_transferfile *transferfile/*=0*/,BOOL bFi
 			}
 			if (pData->nGotTransferEndReply==3)
 			{
-				if (COptions::GetOptionVal(OPTION_PRESERVEDOWNLOADFILETIME) && m_pDataFile)
-				{
-					if (pData->pFileTime)
-					{
-						SYSTEMTIME stime;
-						FILETIME ftime;
-						if (pData->pFileTime->GetAsSystemTime(stime))
-							if (SystemTimeToFileTime(&stime, &ftime))
-								SetFileTime((HANDLE)m_pDataFile->m_hFile, &ftime, &ftime, &ftime);
-					}
-				}
-#ifdef MPEXT
-				if (!pData->transferfile.get &&
-						COptions::GetOptionVal(OPTION_MPEXT_PRESERVEUPLOADFILETIME) && m_pDataFile &&
-						m_hasMfmtCmd)
-				{
-					CString filename =
-						pData->transferfile.remotepath.FormatFilename(pData->transferfile.remotefile, !pData->bUseAbsolutePaths);
-					CFileStatus64 status;
-					if (GetStatus64(pData->transferfile.localfile, status) &&
-							status.m_has_mtime)
-					{
-						struct tm tm;
-						status.m_mtime.GetGmtTm(&tm);
-						CString timestr;
-						timestr.Format(L"%02d%02d%02d%02d%02d%02d",
-							1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
-						if (Send( _T("MFMT ") + timestr + _T(" ") + filename))
-						{
-							m_Operation.nOpState = FILETRANSFER_MFMT;
-							return;
-						}
-					}
-				}
-#endif
-				//Transfer successful
-				ResetOperation(FZ_REPLY_OK);
+			    TransferFinished();
 				return;
 			}
 			break;
@@ -4573,6 +4499,51 @@ void CFtpControlSocket::FileTransfer(t_transferfile *transferfile/*=0*/,BOOL bFi
 	}
 }
 
+void CFtpControlSocket::TransferFinished()
+{
+	CFileTransferData *pData=static_cast<CFileTransferData *>(m_Operation.pData);
+
+	if (COptions::GetOptionVal(OPTION_PRESERVEDOWNLOADFILETIME) && m_pDataFile)
+	{
+		#ifdef MPEXT
+		m_pTools->PreserveDownloadFileTime(
+			(HANDLE)m_pDataFile->m_hFile, reinterpret_cast<void *>(pData->transferfile.nUserData));
+		#else
+		if (pData->pFileTime)
+		{
+			SYSTEMTIME stime;
+			FILETIME ftime;
+			if (pData->pFileTime->GetAsSystemTime(stime))
+				if (SystemTimeToFileTime(&stime, &ftime))
+					SetFileTime((HANDLE)m_pDataFile->m_hFile, &ftime, &ftime, &ftime);
+		}
+		#endif
+	}
+#ifdef MPEXT
+	if (!pData->transferfile.get &&
+			COptions::GetOptionVal(OPTION_MPEXT_PRESERVEUPLOADFILETIME) && m_pDataFile &&
+			m_hasMfmtCmd)
+	{
+		CString filename =
+			pData->transferfile.remotepath.FormatFilename(pData->transferfile.remotefile, !pData->bUseAbsolutePaths);
+		struct tm tm;
+		if (m_pTools->GetFileModificationTimeInUtc((LPCTSTR)pData->transferfile.localfile, tm))
+		{
+			CString timestr;
+			timestr.Format(L"%02d%02d%02d%02d%02d%02d",
+				1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
+			if (Send( _T("MFMT ") + timestr + _T(" ") + filename))
+			{
+				m_Operation.nOpState = FILETRANSFER_MFMT;
+				return;
+			}
+		}
+	}
+#endif
+	//Transfer successful
+	ResetOperation(FZ_REPLY_OK);
+}
+
 void CFtpControlSocket::Cancel(BOOL bQuit/*=FALSE*/)
 {
 	LogMessage(__FILE__, __LINE__, this,FZ_LOG_DEBUG, _T("Cancel(%s)  OpMode=%d OpState=%d"), bQuit?_T("TRUE"):_T("FALSE"), m_Operation.nOpMode, m_Operation.nOpState);
@@ -5135,7 +5106,7 @@ int CFtpControlSocket::CheckOverwriteFile()
 			END_CATCH_ALL;
 			BOOL bRemoteFileExists = FALSE;
 			__int64 remotesize = -1;
-			CTime *remotetime = 0;
+			t_directory::t_direntry::t_date remotetime;
 			if (m_pDirectoryListing)
 			{
 				for (int i=0; i<m_pDirectoryListing->num; i++)
@@ -5144,45 +5115,20 @@ int CFtpControlSocket::CheckOverwriteFile()
 					if (m_pDirectoryListing->direntry[i].name == remotefile)
 					{
 						remotesize = m_pDirectoryListing->direntry[i].size;
-						if (m_pDirectoryListing->direntry[i].date.hasdate)
-						{
-							TRY
-							{
-								remotetime = new CTime(m_pDirectoryListing->direntry[i].date.year,
-									m_pDirectoryListing->direntry[i].date.month,
-									m_pDirectoryListing->direntry[i].date.day,
-									m_pDirectoryListing->direntry[i].date.hastime?m_pDirectoryListing->direntry[i].date.hour:0,
-									m_pDirectoryListing->direntry[i].date.hastime?m_pDirectoryListing->direntry[i].date.minute:0,
-									m_pDirectoryListing->direntry[i].date.hastime?m_pDirectoryListing->direntry[i].date.second:0,
-									-1);
-							}
-							CATCH_ALL(e)
-							{
-								TCHAR buffer[1024];
-								CString str =_T("Exception creating CTime object: ");
-								if (e->GetErrorMessage(buffer, 1024, NULL))
-									str += buffer;
-								else
-									str += _T("Unknown exception");
-								LogMessageRaw(__FILE__, __LINE__, this, FZ_LOG_WARNING, str);
-								remotetime = NULL;
-							}
-							END_CATCH_ALL;
-						}
+						remotetime = m_pDirectoryListing->direntry[i].date;
 						bRemoteFileExists = TRUE;
 						break;
 					}
 				}
 			}
-			if (remotesize == -1 && pData->pFileSize)
+			if (!bRemoteFileExists && pData->hasRemoteDate)
 			{
-				remotesize = *pData->pFileSize;
+				remotetime = pData->remoteDate;
 				bRemoteFileExists = TRUE;
 			}
-			if (!remotetime && pData->pFileTime)
+			if (remotesize == -1 && pData->pFileSize)
 			{
-				remotetime = new CTime;
-				*remotetime = *pData->pFileTime;
+				remotesize = *pData->pFileSize;
 				bRemoteFileExists = TRUE;
 			}
 
@@ -5202,8 +5148,6 @@ int CFtpControlSocket::CheckOverwriteFile()
 					pOverwriteData->path2 = pData->transferfile.remotepath.GetPath();
 					pOverwriteData->size1 = localsize;
 					pOverwriteData->size2 = remotesize;
-					pOverwriteData->time1 = localtime;
-					pOverwriteData->time2 = remotetime;
 				}
 				else
 				{
@@ -5215,9 +5159,9 @@ int CFtpControlSocket::CheckOverwriteFile()
 					pOverwriteData->path2 = pData->transferfile.localfile.Left(pos+1);
 					pOverwriteData->size1 = remotesize;
 					pOverwriteData->size2 = localsize;
-					pOverwriteData->time1 = remotetime;
-					pOverwriteData->time2 = localtime;
 				}
+				pOverwriteData->localtime = localtime;
+				pOverwriteData->remotetime = remotetime;
 				pOverwriteData->nRequestID = m_pOwner->GetNextAsyncRequestID();
 				if (!PostMessage(m_pOwner->m_hOwnerWnd, m_pOwner->m_nReplyMessageID, FZ_MSG_MAKEMSG(FZ_MSG_ASYNCREQUEST, FZ_ASYNCREQUEST_OVERWRITE), (LPARAM)pOverwriteData))
 				{
@@ -5234,7 +5178,6 @@ int CFtpControlSocket::CheckOverwriteFile()
 			{
 				m_Operation.nOpState = FILETRANSFER_TYPE;
 				delete localtime;
-				delete remotetime;
 			}
 		}
 	}
@@ -5267,12 +5210,9 @@ void CFtpControlSocket::SetFileExistsAction(int nAction, COverwriteRequestData *
 		pTransferData->nWaitNextOpState = FILETRANSFER_TYPE;
 		break;
 	case FILEEXISTS_OVERWRITEIFNEWER:
-		if ( !pData->time1 || !pData->time2 )
-			pTransferData->nWaitNextOpState = FILETRANSFER_TYPE;
-		else if (*pData->time2 <= *pData->time1)
-			nReplyError = FZ_REPLY_OK;
-		else
-			pTransferData->nWaitNextOpState = FILETRANSFER_TYPE;
+		// MPEXT
+		ASSERT(FALSE);
+		nReplyError = FZ_REPLY_OK;
 		break;
 	case FILEEXISTS_RENAME:
 		if (pTransferData->transferfile.get)
@@ -5324,7 +5264,12 @@ void CFtpControlSocket::SetFileExistsAction(int nAction, COverwriteRequestData *
 		}
 		pTransferData->nWaitNextOpState = FILETRANSFER_TYPE;
 		break;
+	#ifdef MPEXT
+	case FILEEXISTS_COMPLETE:
+		TransferFinished();
+		break;
 	}
+	#endif
 	if (nReplyError == FZ_REPLY_OK)
 		ResetOperation(FZ_REPLY_OK);
 	else if (nReplyError)

+ 2 - 1
filezilla/FtpControlSocket.h

@@ -45,7 +45,7 @@ public:
 
 // Operationen
 public:
-	CFtpControlSocket(CMainThread *pMainThread);
+	CFtpControlSocket(CMainThread *pMainThread, CFileZillaTools * pTools);
 	virtual ~CFtpControlSocket();
 
 // Überschreibungen
@@ -132,6 +132,7 @@ protected:
 #ifdef MPEXT
 	bool IsRoutableAddress(const CString & host);
 	bool CheckForcePasvIp(CString & host);
+	void TransferFinished();
 #endif
 
 	CFile *m_pDataFile;

+ 2 - 1
filezilla/MainThread.cpp

@@ -45,6 +45,7 @@ static char THIS_FILE[] = __FILE__;
 CMainThread::CMainThread()
 {
 	m_hOwnerWnd = 0;
+	m_pTools = NULL;
 	m_nReplyMessageID = 0;
 	m_nInternalMessageID = 0;
 	m_pPostKeepAliveCommand = 0;
@@ -97,7 +98,7 @@ BOOL CMainThread::InitInstance()
 		res=FALSE;
 	}
 	
-	m_pFtpControlSocket=new CFtpControlSocket(this);
+	m_pFtpControlSocket=new CFtpControlSocket(this, m_pTools);
 #ifndef MPEXT_NO_SFTP
 	m_pSFtpControlSocket=new CSFtpControlSocket(this);
 #endif

+ 1 - 0
filezilla/MainThread.h

@@ -84,6 +84,7 @@ public:
 	void Command(const t_command& command);
 	BOOL IsBusy();
 	HWND m_hOwnerWnd;
+	CFileZillaTools * m_pTools;
 	BOOL m_bBusy;
 	unsigned int m_nReplyMessageID;
 	unsigned int m_nInternalMessageID;

+ 1 - 0
filezilla/stdafx.h

@@ -57,6 +57,7 @@ const int FILEEXISTS_RESUME = 2;
 const int FILEEXISTS_RENAME = 3;
 const int FILEEXISTS_SKIP = 4;
 const int FILEEXISTS_RESUME_ASKONFAIL = 5; // Used by queue for automatic resuming. If APPE failes, ask what to do instead.
+const int FILEEXISTS_COMPLETE = 6;
 //---------------------------------------------------------------------------
 class t_ffam_statusmessage
 {

+ 29 - 15
forms/CustomScpExplorer.cpp

@@ -371,14 +371,17 @@ void __fastcall TCustomScpExplorerForm::TerminalChanged()
 {
   RemoteDirView->Terminal = Terminal;
   NonVisualDataModule->ResetQueueOnceEmptyOperation();
-  if (Terminal)
+
+  TManagedTerminal * ManagedTerminal = NULL;
+
+  if (Terminal != NULL)
   {
     if (Terminal->Active)
     {
       Terminal->RefreshDirectory();
     }
 
-    TManagedTerminal * ManagedTerminal = dynamic_cast<TManagedTerminal *>(Terminal);
+    ManagedTerminal = dynamic_cast<TManagedTerminal *>(Terminal);
     assert(ManagedTerminal != NULL);
 
     if (WinConfiguration->PreservePanelState)
@@ -393,11 +396,18 @@ void __fastcall TCustomScpExplorerForm::TerminalChanged()
       }
     }
 
-    SessionColor = ManagedTerminal->Color;
-
     InitStatusBar();
   }
+
   TerminalListChanged(NULL);
+
+  if (ManagedTerminal != NULL)
+  {
+    // this has to be set only after the tab is switched from TerminalListChanged,
+    // otherwise we are changing color of wrong tab
+    SessionColor = ManagedTerminal->Color;
+  }
+
   UpdateTransferList();
 }
 //---------------------------------------------------------------------------
@@ -442,7 +452,7 @@ void __fastcall TCustomScpExplorerForm::QueueView2Deletion(TObject * /*Sender*/,
   }
 }
 //---------------------------------------------------------------------------
-void __fastcall TCustomScpExplorerForm::UpdateQueueStatus(bool AppIdle, bool QueueChanging)
+void __fastcall TCustomScpExplorerForm::UpdateQueueStatus(bool QueueChanging)
 {
   {
     TGuard Guard(FQueueStatusSection);
@@ -478,7 +488,7 @@ void __fastcall TCustomScpExplorerForm::UpdateQueueStatus(bool AppIdle, bool Que
       FQueue->Enabled = false;
     }
 
-    if ((OnceDoneOperation != odoIdle) && AppIdle)
+    if ((OnceDoneOperation != odoIdle) && !NonVisualDataModule->Busy)
     {
       Terminal->CloseOnCompletion(OnceDoneOperation, LoadStr(CLOSED_ON_QUEUE_EMPTY));
     }
@@ -500,7 +510,7 @@ void __fastcall TCustomScpExplorerForm::QueueChanged()
     delete FQueueStatus;
     FQueueStatus = NULL;
   }
-  UpdateQueueStatus(false, true);
+  UpdateQueueStatus(true);
 }
 //---------------------------------------------------------------------------
 void __fastcall TCustomScpExplorerForm::QueueListUpdate(TTerminalQueue * Queue)
@@ -540,7 +550,7 @@ void __fastcall TCustomScpExplorerForm::QueueItemUpdate(TTerminalQueue * Queue,
   }
 }
 //---------------------------------------------------------------------------
-void __fastcall TCustomScpExplorerForm::RefreshQueueItems(bool AppIdle)
+void __fastcall TCustomScpExplorerForm::RefreshQueueItems()
 {
   if (FQueueStatus != NULL)
   {
@@ -559,7 +569,7 @@ void __fastcall TCustomScpExplorerForm::RefreshQueueItems(bool AppIdle)
       Update = false;
       QueueItem = FQueueStatus->Items[Index];
       WasUserAction = TQueueItem::IsUserActionStatus(QueueItem->Status);
-      if (AppIdle && QueueAutoPopup && WasUserAction &&
+      if (!NonVisualDataModule->Busy && QueueAutoPopup && WasUserAction &&
           (FPendingQueueActionItem == NULL))
       {
         FPendingQueueActionItem = QueueItem;
@@ -1249,7 +1259,7 @@ void __fastcall TCustomScpExplorerForm::CustomCommand(TStrings * FileList,
 
       UnicodeString Command = InteractiveCustomCommand.Complete(ACommand.Command, false);
 
-      Configuration->Usage->Inc(L"LocalCustomCommandRuns");
+      Configuration->Usage->Inc(L"RemoteCustomCommandRuns2");
 
       bool Capture = FLAGSET(ACommand.Params, ccShowResults) || FLAGSET(ACommand.Params, ccCopyResults);
       TCaptureOutputEvent OutputEvent = NULL;
@@ -1301,7 +1311,7 @@ void __fastcall TCustomScpExplorerForm::CustomCommand(TStrings * FileList,
 
     UnicodeString Command = InteractiveCustomCommand.Complete(ACommand.Command, false);
 
-    Configuration->Usage->Inc(L"RemoteCustomCommandRuns");
+    Configuration->Usage->Inc(L"LocalCustomCommandRuns2");
 
     if (!LocalCustomCommand.IsFileCommand(Command))
     {
@@ -1578,10 +1588,12 @@ void __fastcall TCustomScpExplorerForm::BatchStart(void *& /*Storage*/)
   {
     FErrorList = new TStringList();
   }
+  NonVisualDataModule->StartBusy();
 }
 //---------------------------------------------------------------------------
 void __fastcall TCustomScpExplorerForm::BatchEnd(void * /*Storage*/)
 {
+  NonVisualDataModule->EndBusy();
   if (FErrorList)
   {
     HandleErrorList(FErrorList);
@@ -3220,8 +3232,9 @@ void __fastcall TCustomScpExplorerForm::UpdateStatusPanelText(TTBXStatusPanel *
   Panel->Caption = L"";
 }
 //---------------------------------------------------------------------------
-void __fastcall TCustomScpExplorerForm::Idle(bool AppIdle)
+void __fastcall TCustomScpExplorerForm::Idle()
 {
+
   if (FShowing)
   {
     FEditorManager->Check();
@@ -3230,7 +3243,7 @@ void __fastcall TCustomScpExplorerForm::Idle(bool AppIdle)
     // that needs to know if queue view is visible (and it may be closed after queue update)
     TTerminalManager::Instance()->Idle();
 
-    if (AppIdle)
+    if (!NonVisualDataModule->Busy)
     {
       if (FRefreshRemoteDirectory)
       {
@@ -3261,15 +3274,16 @@ void __fastcall TCustomScpExplorerForm::Idle(bool AppIdle)
 
     if (FQueueStatusInvalidated)
     {
-      UpdateQueueStatus(AppIdle, false);
+      UpdateQueueStatus(false);
     }
 
-    RefreshQueueItems(AppIdle);
+    RefreshQueueItems();
 
     UpdateStatusBar();
   }
 
   FIgnoreNextSysCommand = false;
+
 }
 //---------------------------------------------------------------------------
 void __fastcall TCustomScpExplorerForm::UserActionTimer(TObject * /*Sender*/)

+ 3 - 3
forms/CustomScpExplorer.h

@@ -358,8 +358,8 @@ protected:
     TStringList * ExportData);
   void __fastcall QueueListUpdate(TTerminalQueue * Queue);
   void __fastcall QueueItemUpdate(TTerminalQueue * Queue, TQueueItem * Item);
-  void __fastcall UpdateQueueStatus(bool AppIdle, bool QueueChanging);
-  void __fastcall RefreshQueueItems(bool AppIdle);
+  void __fastcall UpdateQueueStatus(bool QueueChanging);
+  void __fastcall RefreshQueueItems();
   virtual int __fastcall GetStaticComponentsHeight();
   void __fastcall FillQueueViewItem(TListItem * Item,
     TQueueItemProxy * QueueItem, bool Detail);
@@ -495,7 +495,7 @@ public:
   void __fastcall OpenDirectory(TOperationSide Side);
   virtual void __fastcall HomeDirectory(TOperationSide Side);
   void __fastcall OpenStoredSession(TSessionData * Data);
-  void __fastcall Idle(bool AppIdle);
+  void __fastcall Idle();
   __fastcall TCustomScpExplorerForm(TComponent* Owner);
   void __fastcall SaveCurrentSession();
   virtual void __fastcall CompareDirectories();

+ 1 - 5
forms/Login.cpp

@@ -421,11 +421,7 @@ void __fastcall TLoginDialog::LoadSession(TSessionData * aSessionData)
         UtfCombo->ItemIndex = 0;
         break;
     }
-    int TimeDifferenceMin = DateTimeToTimeStamp(aSessionData->TimeDifference).Time / (SecsPerMin * MSecsPerSec);
-    if (double(aSessionData->TimeDifference) < 0)
-    {
-      TimeDifferenceMin = -TimeDifferenceMin;
-    }
+    int TimeDifferenceMin = TimeToMinutes(aSessionData->TimeDifference);
     TimeDifferenceEdit->AsInteger = TimeDifferenceMin / MinsPerHour;
     TimeDifferenceMinutesEdit->AsInteger = TimeDifferenceMin % MinsPerHour;
 

+ 16 - 16
forms/NonVisual.cpp

@@ -87,7 +87,7 @@ __fastcall TNonVisualDataModule::TNonVisualDataModule(TComponent* Owner)
 {
   FListColumn = NULL;
   FSessionIdleTimerExecuting = false;
-  FIdle = 0;
+  FBusy = 0;
 
   QueueSpeedComboBoxItem(QueuePopupSpeedComboBoxItem);
   InitMenus(this);
@@ -115,10 +115,10 @@ void __fastcall TNonVisualDataModule::LogActionsUpdate(
 void __fastcall TNonVisualDataModule::LogActionsExecute(
       TBasicAction *Action, bool &Handled)
 {
-  FIdle--;
 
-  try
   {
+    TAutoNestingCounter Counter(FBusy);
+
     TLogMemo * LogMemo = TTerminalManager::Instance()->LogMemo;
     assert(LogMemo && LogMemo->Parent);
     EXE(LogClearAction, LogMemo->SessionLog->Clear())
@@ -129,11 +129,6 @@ void __fastcall TNonVisualDataModule::LogActionsExecute(
     EXE(LogPreferencesAction, PreferencesDialog(pmLogging));
     ;
   }
-  __finally
-  {
-    assert(FIdle < 0);
-    FIdle++;
-  }
 
   DoIdle();
 }
@@ -465,9 +460,9 @@ void __fastcall TNonVisualDataModule::ExplorerActionsExecute(
     }
     ScpExplorer->BeforeAction();
 
-    FIdle--;
-    try
+
     {
+      TAutoNestingCounter Counter(FBusy);
       // focused operation
       EXE(CurrentCopyFocusedAction, ScpExplorer->ExecuteFileOperationCommand(foCopy, osCurrent, true))
       EXE(CurrentMoveFocusedAction, ScpExplorer->ExecuteFileOperationCommand(foMove, osCurrent, true))
@@ -724,11 +719,6 @@ void __fastcall TNonVisualDataModule::ExplorerActionsExecute(
       EXE(QueueItemSpeedAction, )
       ;
     }
-    __finally
-    {
-      assert(FIdle < 0);
-      FIdle++;
-    }
 
     DoIdle();
   }
@@ -877,7 +867,7 @@ void __fastcall TNonVisualDataModule::DoIdle()
     try
     {
       assert(ScpExplorer);
-      ScpExplorer->Idle(FIdle >= 0);
+      ScpExplorer->Idle();
     }
     __finally
     {
@@ -1525,3 +1515,13 @@ void __fastcall TNonVisualDataModule::SessionColorPaletteChange(
   assert(ColorPalette != NULL);
   ScpExplorer->SessionColor = (ColorPalette->Color != clNone ? ColorPalette->Color : (TColor)0);
 }
+//---------------------------------------------------------------------------
+void __fastcall TNonVisualDataModule::StartBusy()
+{
+  FBusy++;
+}
+//---------------------------------------------------------------------------
+void __fastcall TNonVisualDataModule::EndBusy()
+{
+  FBusy--;
+}

+ 6 - 1
forms/NonVisual.h

@@ -533,9 +533,11 @@ private:
   TListColumn * FListColumn;
   TCustomScpExplorerForm * FScpExplorer;
   bool FSessionIdleTimerExecuting;
-  int FIdle;
+  int FBusy;
 
   void __fastcall SetScpExplorer(TCustomScpExplorerForm * value);
+  bool __fastcall GetBusy() { return FBusy > 0; }
+
 protected:
   void __fastcall CreateSessionListMenu(TAction * Action);
   void __fastcall CreateSessionListMenuLevel(TTBCustomItem * Menu, int Index, int Level);
@@ -575,9 +577,12 @@ public:
   void __fastcall InitMenus(TComponent * Component);
   TOnceDoneOperation __fastcall CurrentQueueOnceEmptyOperation();
   void __fastcall ResetQueueOnceEmptyOperation();
+  void __fastcall StartBusy();
+  void __fastcall EndBusy();
 
   __property TListColumn * ListColumn = { read = FListColumn, write = FListColumn };
   __property TCustomScpExplorerForm * ScpExplorer = { read = FScpExplorer, write = SetScpExplorer };
+  __property bool Busy = { read = GetBusy };
 };
 //---------------------------------------------------------------------------
 extern PACKAGE TNonVisualDataModule *NonVisualDataModule;

+ 4 - 0
openssl/Makefile

@@ -130,6 +130,7 @@ SSLOBJ=$(OBJ_D)\s2_meth.obj \
     $(OBJ_D)\s2_enc.obj $(OBJ_D)\s2_pkt.obj $(OBJ_D)\s3_meth.obj \
     $(OBJ_D)\s3_srvr.obj $(OBJ_D)\s3_clnt.obj $(OBJ_D)\s3_lib.obj \
     $(OBJ_D)\s3_enc.obj $(OBJ_D)\s3_pkt.obj $(OBJ_D)\s3_both.obj \
+    $(OBJ_D)\s3_cbc.obj \
     $(OBJ_D)\s23_meth.obj $(OBJ_D)\s23_srvr.obj $(OBJ_D)\s23_clnt.obj \
     $(OBJ_D)\s23_lib.obj $(OBJ_D)\s23_pkt.obj $(OBJ_D)\t1_meth.obj \
     $(OBJ_D)\t1_srvr.obj $(OBJ_D)\t1_clnt.obj $(OBJ_D)\t1_lib.obj \
@@ -666,6 +667,9 @@ $(OBJ_D)\s3_pkt.obj: $(SRC_D)\ssl\s3_pkt.c
 $(OBJ_D)\s3_both.obj: $(SRC_D)\ssl\s3_both.c
     $(CC) -o$(OBJ_D)\s3_both.obj  $(LIB_CFLAGS) -c $(SRC_D)\ssl\s3_both.c
 
+$(OBJ_D)\s3_cbc.obj: $(SRC_D)\ssl\s3_cbc.c
+    $(CC) -o$(OBJ_D)\s3_cbc.obj  $(LIB_CFLAGS) -c $(SRC_D)\ssl\s3_cbc.c
+
 $(OBJ_D)\s23_meth.obj: $(SRC_D)\ssl\s23_meth.c
     $(CC) -o$(OBJ_D)\s23_meth.obj  $(LIB_CFLAGS) -c $(SRC_D)\ssl\s23_meth.c
 

+ 1 - 0
openssl/crypto/asn1/a_strex.c

@@ -567,6 +567,7 @@ int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in)
 	if(mbflag == -1) return -1;
 	mbflag |= MBSTRING_FLAG;
 	stmp.data = NULL;
+	stmp.length = 0;
 	ret = ASN1_mbstring_copy(&str, in->data, in->length, mbflag, B_ASN1_UTF8STRING);
 	if(ret < 0) return ret;
 	*out = stmp.data;

+ 6 - 0
openssl/crypto/asn1/a_verify.c

@@ -140,6 +140,12 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
 
 	int mdnid, pknid;
 
+	if (!pkey)
+		{
+		ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
+		return -1;
+		}
+
 	EVP_MD_CTX_init(&ctx);
 
 	/* Convert signature OID into digest and public key OIDs */

+ 4 - 1
openssl/crypto/asn1/x_pubkey.c

@@ -175,12 +175,15 @@ EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
 	CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY);
 	if (key->pkey)
 		{
+		CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
 		EVP_PKEY_free(ret);
 		ret = key->pkey;
 		}
 	else
+		{
 		key->pkey = ret;
-	CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
+		CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
+		}
 	CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY);
 
 	return ret;

+ 2 - 0
openssl/crypto/bn/bn_div.c

@@ -141,6 +141,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
     *
     *					<[email protected]>
     */
+#undef bn_div_words
 #  define bn_div_words(n0,n1,d0)		\
 	({  asm volatile (			\
 		"divl	%4"			\
@@ -155,6 +156,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
     * Same story here, but it's 128-bit by 64-bit division. Wow!
     *					<[email protected]>
     */
+#  undef bn_div_words
 #  define bn_div_words(n0,n1,d0)		\
 	({  asm volatile (			\
 		"divq	%4"			\

+ 1 - 0
openssl/crypto/bn/bn_gcd.c

@@ -205,6 +205,7 @@ err:
 /* solves ax == 1 (mod n) */
 static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in,
         const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx);
+
 BIGNUM *BN_mod_inverse(BIGNUM *in,
 	const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
 	{

+ 9 - 2
openssl/crypto/bn/bn_lcl.h

@@ -282,16 +282,23 @@ extern "C" {
 #  endif
 # elif defined(__mips) && (defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG))
 #  if defined(__GNUC__) && __GNUC__>=2
-#   define BN_UMULT_HIGH(a,b)	({	\
+#   if __GNUC__>=4 && __GNUC_MINOR__>=4 /* "h" constraint is no more since 4.4 */
+#     define BN_UMULT_HIGH(a,b)		 (((__uint128_t)(a)*(b))>>64)
+#     define BN_UMULT_LOHI(low,high,a,b) ({	\
+	__uint128_t ret=(__uint128_t)(a)*(b);	\
+	(high)=ret>>64; (low)=ret;	 })
+#   else
+#     define BN_UMULT_HIGH(a,b)	({	\
 	register BN_ULONG ret;		\
 	asm ("dmultu	%1,%2"		\
 	     : "=h"(ret)		\
 	     : "r"(a), "r"(b) : "l");	\
 	ret;			})
-#   define BN_UMULT_LOHI(low,high,a,b)	\
+#     define BN_UMULT_LOHI(low,high,a,b)\
 	asm ("dmultu	%2,%3"		\
 	     : "=l"(low),"=h"(high)	\
 	     : "r"(a), "r"(b));
+#    endif
 #  endif
 # endif		/* cpu */
 #endif		/* OPENSSL_NO_ASM */

+ 8 - 17
openssl/crypto/bn/bn_word.c

@@ -144,26 +144,17 @@ int BN_add_word(BIGNUM *a, BN_ULONG w)
 			a->neg=!(a->neg);
 		return(i);
 		}
-	/* Only expand (and risk failing) if it's possibly necessary */
-	if (((BN_ULONG)(a->d[a->top - 1] + 1) == 0) &&
-			(bn_wexpand(a,a->top+1) == NULL))
-		return(0);
-	i=0;
-	for (;;)
+	for (i=0;w!=0 && i<a->top;i++)
 		{
-		if (i >= a->top)
-			l=w;
-		else
-			l=(a->d[i]+w)&BN_MASK2;
-		a->d[i]=l;
-		if (w > l)
-			w=1;
-		else
-			break;
-		i++;
+		a->d[i] = l = (a->d[i]+w)&BN_MASK2;
+		w = (w>l)?1:0;
 		}
-	if (i >= a->top)
+	if (w && i==a->top)
+		{
+		if (bn_wexpand(a,a->top+1) == NULL) return 0;
 		a->top++;
+		a->d[i]=w;
+		}
 	bn_check_top(a);
 	return(1);
 	}

+ 2 - 2
openssl/crypto/buildinf.h

@@ -9,11 +9,11 @@
   /* auto-generated/updated by util/mk1mf.pl for crypto/cversion.c */
   #define CFLAGS "cl  /MD /Ox /O2 /Ob2 -DOPENSSL_THREADS  -DDSO_WIN32  -DOPENSSL_USE_APPLINK -I. -DOPENSSL_NO_RC5 -DOPENSSL_NO_MD2 -DOPENSSL_NO_KRB5 -DOPENSSL_NO_JPAKE -DOPENSSL_NO_STATIC_ENGINE    "
   #define PLATFORM "VC-WIN32"
-  #define DATE "Sat May 12 19:49:46 2012"
+  #define DATE "Tue Feb 12 22:48:05 2013"
 #endif
 #ifdef MK1MF_PLATFORM_BC_NT
   /* auto-generated/updated by util/mk1mf.pl for crypto/cversion.c */
   #define CFLAGS "bcc32 -DWIN32_LEAN_AND_MEAN -q -w-ccc -w-rch -w-pia -w-aus -w-par -w-inl  -c -tWC -tWM -DOPENSSL_SYSNAME_WIN32 -DL_ENDIAN -DDSO_WIN32 -D_stricmp=stricmp -D_strnicmp=strnicmp -O2 -ff -fp -DBN_ASM -DMD5_ASM -DSHA1_ASM -DRMD160_ASM -DOPENSSL_NO_RC5 -DOPENSSL_NO_MD2 -DOPENSSL_NO_KRB5 -DOPENSSL_NO_JPAKE -DOPENSSL_NO_DYNAMIC_ENGINE    "
   #define PLATFORM "BC-NT"
-  #define DATE "Sat May 12 19:49:46 2012"
+  #define DATE "Tue Feb 12 22:48:05 2013"
 #endif

+ 1 - 0
openssl/crypto/conf/conf_mall.c

@@ -76,5 +76,6 @@ void OPENSSL_load_builtin_modules(void)
 #ifndef OPENSSL_NO_ENGINE
 	ENGINE_add_conf_module();
 #endif
+	EVP_add_alg_module();
 	}
 

+ 15 - 1
openssl/crypto/cryptlib.c

@@ -504,7 +504,7 @@ void CRYPTO_THREADID_current(CRYPTO_THREADID *id)
 	CRYPTO_THREADID_set_numeric(id, (unsigned long)find_thread(NULL));
 #else
 	/* For everything else, default to using the address of 'errno' */
-	CRYPTO_THREADID_set_pointer(id, &errno);
+	CRYPTO_THREADID_set_pointer(id, (void*)&errno);
 #endif
 	}
 
@@ -704,6 +704,7 @@ void OPENSSL_cpuid_setup(void)
     }
     else
 	vec = OPENSSL_ia32_cpuid();
+
     /*
      * |(1<<10) sets a reserved bit to signal that variable
      * was initialized already... This is to avoid interference
@@ -924,3 +925,16 @@ void OpenSSLDie(const char *file,int line,const char *assertion)
 	}
 
 void *OPENSSL_stderr(void)	{ return stderr; }
+
+int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len)
+	{
+	size_t i;
+	const unsigned char *a = in_a;
+	const unsigned char *b = in_b;
+	unsigned char x = 0;
+
+	for (i = 0; i < len; i++)
+		x |= a[i] ^ b[i];
+
+	return x;
+	}

+ 1 - 1
openssl/crypto/cryptlib.h

@@ -100,7 +100,7 @@ extern "C" {
 
 void OPENSSL_cpuid_setup(void);
 extern unsigned int OPENSSL_ia32cap_P[];
-void OPENSSL_showfatal(const char *,...);
+void OPENSSL_showfatal(const char *fmta,...);
 void *OPENSSL_stderr(void);
 extern int OPENSSL_NONPIC_relocated;
 

+ 9 - 2
openssl/crypto/crypto.h

@@ -488,10 +488,10 @@ void CRYPTO_get_mem_debug_functions(void (**m)(void *,int,const char *,int,int),
 				    long (**go)(void));
 
 void *CRYPTO_malloc_locked(int num, const char *file, int line);
-void CRYPTO_free_locked(void *);
+void CRYPTO_free_locked(void *ptr);
 void *CRYPTO_malloc(int num, const char *file, int line);
 char *CRYPTO_strdup(const char *str, const char *file, int line);
-void CRYPTO_free(void *);
+void CRYPTO_free(void *ptr);
 void *CRYPTO_realloc(void *addr,int num, const char *file, int line);
 void *CRYPTO_realloc_clean(void *addr,int old_num,int num,const char *file,
 			   int line);
@@ -574,6 +574,13 @@ void OPENSSL_init(void);
 #define fips_cipher_abort(alg) while(0)
 #endif
 
+/* CRYPTO_memcmp returns zero iff the |len| bytes at |a| and |b| are equal. It
+ * takes an amount of time dependent on |len|, but independent of the contents
+ * of |a| and |b|. Unlike memcmp, it cannot be used to put elements into a
+ * defined order as the return value when a != b is undefined, other than to be
+ * non-zero. */
+int CRYPTO_memcmp(const void *a, const void *b, size_t len);
+
 /* BEGIN ERROR CODES */
 /* The following lines are auto generated by the script mkerr.pl. Any changes
  * made after this point may be overwritten when the script is next run.

+ 1 - 2
openssl/crypto/des/set_key.c

@@ -63,9 +63,8 @@
  * 1.1 added norm_expand_bits
  * 1.0 First working version
  */
-#include "des_locl.h"
-
 #include <openssl/crypto.h>
+#include "des_locl.h"
 
 OPENSSL_IMPLEMENT_GLOBAL(int,DES_check_key,0)	/* defaults to false */
 

+ 1 - 1
openssl/crypto/des/str2key.c

@@ -56,8 +56,8 @@
  * [including the GNU Public Licence.]
  */
 
-#include "des_locl.h"
 #include <openssl/crypto.h>
+#include "des_locl.h"
 
 void DES_string_to_key(const char *str, DES_cblock *key)
 	{

+ 10 - 9
openssl/crypto/err/err_all.c

@@ -64,7 +64,9 @@
 #endif
 #include <openssl/buffer.h>
 #include <openssl/bio.h>
+#ifndef OPENSSL_NO_COMP
 #include <openssl/comp.h>
+#endif
 #ifndef OPENSSL_NO_RSA
 #include <openssl/rsa.h>
 #endif
@@ -95,6 +97,9 @@
 #include <openssl/ui.h>
 #include <openssl/ocsp.h>
 #include <openssl/err.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
 #include <openssl/ts.h>
 #ifndef OPENSSL_NO_CMS
 #include <openssl/cms.h>
@@ -102,11 +107,6 @@
 #ifndef OPENSSL_NO_JPAKE
 #include <openssl/jpake.h>
 #endif
-#include <openssl/comp.h>
-
-#ifdef OPENSSL_FIPS
-#include <openssl/fips.h>
-#endif
 
 void ERR_load_crypto_strings(void)
 	{
@@ -130,7 +130,9 @@ void ERR_load_crypto_strings(void)
 	ERR_load_ASN1_strings();
 	ERR_load_CONF_strings();
 	ERR_load_CRYPTO_strings();
+#ifndef OPENSSL_NO_COMP
 	ERR_load_COMP_strings();
+#endif
 #ifndef OPENSSL_NO_EC
 	ERR_load_EC_strings();
 #endif
@@ -153,15 +155,14 @@ void ERR_load_crypto_strings(void)
 #endif
 	ERR_load_OCSP_strings();
 	ERR_load_UI_strings();
+#ifdef OPENSSL_FIPS
+	ERR_load_FIPS_strings();
+#endif
 #ifndef OPENSSL_NO_CMS
 	ERR_load_CMS_strings();
 #endif
 #ifndef OPENSSL_NO_JPAKE
 	ERR_load_JPAKE_strings();
 #endif
-	ERR_load_COMP_strings();
-#endif
-#ifdef OPENSSL_FIPS
-	ERR_load_FIPS_strings();
 #endif
 	}

+ 1 - 0
openssl/crypto/evp/digest.c

@@ -267,6 +267,7 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
 	return FIPS_digestfinal(ctx, md, size);
 #else
 	int ret;
+
 	OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
 	ret=ctx->digest->final(ctx,md);
 	if (size != NULL)

+ 3 - 2
openssl/crypto/evp/e_aes.c

@@ -969,8 +969,6 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
 
 	if (!gctx->iv_set)
 		return -1;
-	if (!ctx->encrypt && gctx->taglen < 0)
-		return -1;
 	if (in)
 		{
 		if (out == NULL)
@@ -1012,6 +1010,8 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
 		{
 		if (!ctx->encrypt)
 			{
+			if (gctx->taglen < 0)
+				return -1;
 			if (CRYPTO_gcm128_finish(&gctx->gcm,
 					ctx->buf, gctx->taglen) != 0)
 				return -1;
@@ -1217,6 +1217,7 @@ static int aes_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
 			vpaes_set_encrypt_key(key, ctx->key_len*8, &cctx->ks);
 			CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
 					&cctx->ks, (block128_f)vpaes_encrypt);
+			cctx->str = NULL;
 			cctx->key_set = 1;
 			break;
 			}

+ 195 - 21
openssl/crypto/evp/e_aes_cbc_hmac_sha1.c

@@ -1,5 +1,5 @@
 /* ====================================================================
- * Copyright (c) 2011 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 2011-2013 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -90,6 +90,10 @@ typedef struct
 	defined(_M_AMD64)	|| defined(_M_X64)	|| \
 	defined(__INTEL__)	)
 
+#if defined(__GNUC__) && __GNUC__>=2 && !defined(PEDANTIC)
+# define BSWAP(x) ({ unsigned int r=(x); asm ("bswapl %0":"=r"(r):"0"(r)); r; })
+#endif
+
 extern unsigned int OPENSSL_ia32cap_P[2];
 #define AESNI_CAPABLE   (1<<(57-32))
 
@@ -167,6 +171,9 @@ static void sha1_update(SHA_CTX *c,const void *data,size_t len)
 		SHA1_Update(c,ptr,res);
 }
 
+#ifdef SHA1_Update
+#undef SHA1_Update
+#endif
 #define SHA1_Update sha1_update
 
 static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
@@ -184,6 +191,8 @@ static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
 	sha_off = SHA_CBLOCK-key->md.num;
 #endif
 
+	key->payload_length = NO_PAYLOAD_LENGTH;
+
 	if (len%AES_BLOCK_SIZE) return 0;
 
 	if (ctx->encrypt) {
@@ -234,47 +243,210 @@ static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
 					&key->ks,ctx->iv,1);
 		}
 	} else {
-		unsigned char mac[SHA_DIGEST_LENGTH];
+		union { unsigned int  u[SHA_DIGEST_LENGTH/sizeof(unsigned int)];
+			unsigned char c[32+SHA_DIGEST_LENGTH]; } mac, *pmac;
+
+		/* arrange cache line alignment */
+		pmac = (void *)(((size_t)mac.c+31)&((size_t)0-32));
 
 		/* decrypt HMAC|padding at once */
 		aesni_cbc_encrypt(in,out,len,
 				&key->ks,ctx->iv,0);
 
 		if (plen) {	/* "TLS" mode of operation */
-			/* figure out payload length */
-			if (len<(size_t)(out[len-1]+1+SHA_DIGEST_LENGTH))
-				return 0;
-
-			len -= (out[len-1]+1+SHA_DIGEST_LENGTH);
+			size_t inp_len, mask, j, i;
+			unsigned int res, maxpad, pad, bitlen;
+			int ret = 1;
+			union {	unsigned int  u[SHA_LBLOCK];
+				unsigned char c[SHA_CBLOCK]; }
+				*data = (void *)key->md.data;
 
 			if ((key->aux.tls_aad[plen-4]<<8|key->aux.tls_aad[plen-3])
-			    >= TLS1_1_VERSION) {
-				len -= AES_BLOCK_SIZE;
+			    >= TLS1_1_VERSION)
 				iv = AES_BLOCK_SIZE;
-			}
 
-			key->aux.tls_aad[plen-2] = len>>8;
-			key->aux.tls_aad[plen-1] = len;
+			if (len<(iv+SHA_DIGEST_LENGTH+1))
+				return 0;
+
+			/* omit explicit iv */
+			out += iv;
+			len -= iv;
+
+			/* figure out payload length */
+			pad = out[len-1];
+			maxpad = len-(SHA_DIGEST_LENGTH+1);
+			maxpad |= (255-maxpad)>>(sizeof(maxpad)*8-8);
+			maxpad &= 255;
+
+			inp_len = len - (SHA_DIGEST_LENGTH+pad+1);
+			mask = (0-((inp_len-len)>>(sizeof(inp_len)*8-1)));
+			inp_len &= mask;
+			ret &= (int)mask;
+
+			key->aux.tls_aad[plen-2] = inp_len>>8;
+			key->aux.tls_aad[plen-1] = inp_len;
 
-			/* calculate HMAC and verify it */
+			/* calculate HMAC */
 			key->md = key->head;
 			SHA1_Update(&key->md,key->aux.tls_aad,plen);
-			SHA1_Update(&key->md,out+iv,len);
-			SHA1_Final(mac,&key->md);
 
+#if 1
+			len -= SHA_DIGEST_LENGTH;		/* amend mac */
+			if (len>=(256+SHA_CBLOCK)) {
+				j = (len-(256+SHA_CBLOCK))&(0-SHA_CBLOCK);
+				j += SHA_CBLOCK-key->md.num;
+				SHA1_Update(&key->md,out,j);
+				out += j;
+				len -= j;
+				inp_len -= j;
+			}
+
+			/* but pretend as if we hashed padded payload */
+			bitlen = key->md.Nl+(inp_len<<3);	/* at most 18 bits */
+#ifdef BSWAP
+			bitlen = BSWAP(bitlen);
+#else
+			mac.c[0] = 0;
+			mac.c[1] = (unsigned char)(bitlen>>16);
+			mac.c[2] = (unsigned char)(bitlen>>8);
+			mac.c[3] = (unsigned char)bitlen;
+			bitlen = mac.u[0];
+#endif
+
+			pmac->u[0]=0;
+			pmac->u[1]=0;
+			pmac->u[2]=0;
+			pmac->u[3]=0;
+			pmac->u[4]=0;
+
+			for (res=key->md.num, j=0;j<len;j++) {
+				size_t c = out[j];
+				mask = (j-inp_len)>>(sizeof(j)*8-8);
+				c &= mask;
+				c |= 0x80&~mask&~((inp_len-j)>>(sizeof(j)*8-8));
+				data->c[res++]=(unsigned char)c;
+
+				if (res!=SHA_CBLOCK) continue;
+
+				mask = 0-((inp_len+8-j)>>(sizeof(j)*8-1));
+				data->u[SHA_LBLOCK-1] |= bitlen&mask;
+				sha1_block_data_order(&key->md,data,1);
+				mask &= 0-((j-inp_len-73)>>(sizeof(j)*8-1));
+				pmac->u[0] |= key->md.h0 & mask;
+				pmac->u[1] |= key->md.h1 & mask;
+				pmac->u[2] |= key->md.h2 & mask;
+				pmac->u[3] |= key->md.h3 & mask;
+				pmac->u[4] |= key->md.h4 & mask;
+				res=0;
+			}
+
+			for(i=res;i<SHA_CBLOCK;i++,j++) data->c[i]=0;
+
+			if (res>SHA_CBLOCK-8) {
+				mask = 0-((inp_len+8-j)>>(sizeof(j)*8-1));
+				data->u[SHA_LBLOCK-1] |= bitlen&mask;
+				sha1_block_data_order(&key->md,data,1);
+				mask &= 0-((j-inp_len-73)>>(sizeof(j)*8-1));
+				pmac->u[0] |= key->md.h0 & mask;
+				pmac->u[1] |= key->md.h1 & mask;
+				pmac->u[2] |= key->md.h2 & mask;
+				pmac->u[3] |= key->md.h3 & mask;
+				pmac->u[4] |= key->md.h4 & mask;
+
+				memset(data,0,SHA_CBLOCK);
+				j+=64;
+			}
+			data->u[SHA_LBLOCK-1] = bitlen;
+			sha1_block_data_order(&key->md,data,1);
+			mask = 0-((j-inp_len-73)>>(sizeof(j)*8-1));
+			pmac->u[0] |= key->md.h0 & mask;
+			pmac->u[1] |= key->md.h1 & mask;
+			pmac->u[2] |= key->md.h2 & mask;
+			pmac->u[3] |= key->md.h3 & mask;
+			pmac->u[4] |= key->md.h4 & mask;
+
+#ifdef BSWAP
+			pmac->u[0] = BSWAP(pmac->u[0]);
+			pmac->u[1] = BSWAP(pmac->u[1]);
+			pmac->u[2] = BSWAP(pmac->u[2]);
+			pmac->u[3] = BSWAP(pmac->u[3]);
+			pmac->u[4] = BSWAP(pmac->u[4]);
+#else
+			for (i=0;i<5;i++) {
+				res = pmac->u[i];
+				pmac->c[4*i+0]=(unsigned char)(res>>24);
+				pmac->c[4*i+1]=(unsigned char)(res>>16);
+				pmac->c[4*i+2]=(unsigned char)(res>>8);
+				pmac->c[4*i+3]=(unsigned char)res;
+			}
+#endif
+			len += SHA_DIGEST_LENGTH;
+#else
+			SHA1_Update(&key->md,out,inp_len);
+			res = key->md.num;
+			SHA1_Final(pmac->c,&key->md);
+
+			{
+			unsigned int inp_blocks, pad_blocks;
+
+			/* but pretend as if we hashed padded payload */
+			inp_blocks = 1+((SHA_CBLOCK-9-res)>>(sizeof(res)*8-1));
+			res += (unsigned int)(len-inp_len);
+			pad_blocks = res / SHA_CBLOCK;
+			res %= SHA_CBLOCK;
+			pad_blocks += 1+((SHA_CBLOCK-9-res)>>(sizeof(res)*8-1));
+			for (;inp_blocks<pad_blocks;inp_blocks++)
+				sha1_block_data_order(&key->md,data,1);
+			}
+#endif
 			key->md = key->tail;
-			SHA1_Update(&key->md,mac,SHA_DIGEST_LENGTH);
-			SHA1_Final(mac,&key->md);
+			SHA1_Update(&key->md,pmac->c,SHA_DIGEST_LENGTH);
+			SHA1_Final(pmac->c,&key->md);
 
-			if (memcmp(out+iv+len,mac,SHA_DIGEST_LENGTH))
-				return 0;
+			/* verify HMAC */
+			out += inp_len;
+			len -= inp_len;
+#if 1
+			{
+			unsigned char *p = out+len-1-maxpad-SHA_DIGEST_LENGTH;
+			size_t off = out-p;
+			unsigned int c, cmask;
+
+			maxpad += SHA_DIGEST_LENGTH;
+			for (res=0,i=0,j=0;j<maxpad;j++) {
+				c = p[j];
+				cmask = ((int)(j-off-SHA_DIGEST_LENGTH))>>(sizeof(int)*8-1);
+				res |= (c^pad)&~cmask;	/* ... and padding */
+				cmask &= ((int)(off-1-j))>>(sizeof(int)*8-1);
+				res |= (c^pmac->c[i])&cmask;
+				i += 1&cmask;
+			}
+			maxpad -= SHA_DIGEST_LENGTH;
+
+			res = 0-((0-res)>>(sizeof(res)*8-1));
+			ret &= (int)~res;
+			}
+#else
+			for (res=0,i=0;i<SHA_DIGEST_LENGTH;i++)
+				res |= out[i]^pmac->c[i];
+			res = 0-((0-res)>>(sizeof(res)*8-1));
+			ret &= (int)~res;
+
+			/* verify padding */
+			pad = (pad&~res) | (maxpad&res);
+			out = out+len-1-pad;
+			for (res=0,i=0;i<pad;i++)
+				res |= out[i]^pad;
+
+			res = (0-res)>>(sizeof(res)*8-1);
+			ret &= (int)~res;
+#endif
+			return ret;
 		} else {
 			SHA1_Update(&key->md,out,len);
 		}
 	}
 
-	key->payload_length = NO_PAYLOAD_LENGTH;
-
 	return 1;
 	}
 
@@ -309,6 +481,8 @@ static int aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void
 		SHA1_Init(&key->tail);
 		SHA1_Update(&key->tail,hmac_key,sizeof(hmac_key));
 
+		OPENSSL_cleanse(hmac_key,sizeof(hmac_key));
+
 		return 1;
 		}
 	case EVP_CTRL_AEAD_TLS1_AAD:

+ 11 - 4
openssl/crypto/evp/evp.h

@@ -402,7 +402,6 @@ struct evp_cipher_st
 /* Length of tag for TLS */
 #define EVP_GCM_TLS_TAG_LEN				16
 
-
 typedef struct evp_cipher_info_st
 	{
 	const EVP_CIPHER *cipher;
@@ -789,8 +788,8 @@ const EVP_CIPHER *EVP_aes_128_cfb128(void);
 # define EVP_aes_128_cfb EVP_aes_128_cfb128
 const EVP_CIPHER *EVP_aes_128_ofb(void);
 const EVP_CIPHER *EVP_aes_128_ctr(void);
-const EVP_CIPHER *EVP_aes_128_gcm(void);
 const EVP_CIPHER *EVP_aes_128_ccm(void);
+const EVP_CIPHER *EVP_aes_128_gcm(void);
 const EVP_CIPHER *EVP_aes_128_xts(void);
 const EVP_CIPHER *EVP_aes_192_ecb(void);
 const EVP_CIPHER *EVP_aes_192_cbc(void);
@@ -800,8 +799,8 @@ const EVP_CIPHER *EVP_aes_192_cfb128(void);
 # define EVP_aes_192_cfb EVP_aes_192_cfb128
 const EVP_CIPHER *EVP_aes_192_ofb(void);
 const EVP_CIPHER *EVP_aes_192_ctr(void);
-const EVP_CIPHER *EVP_aes_192_gcm(void);
 const EVP_CIPHER *EVP_aes_192_ccm(void);
+const EVP_CIPHER *EVP_aes_192_gcm(void);
 const EVP_CIPHER *EVP_aes_256_ecb(void);
 const EVP_CIPHER *EVP_aes_256_cbc(void);
 const EVP_CIPHER *EVP_aes_256_cfb1(void);
@@ -810,8 +809,8 @@ const EVP_CIPHER *EVP_aes_256_cfb128(void);
 # define EVP_aes_256_cfb EVP_aes_256_cfb128
 const EVP_CIPHER *EVP_aes_256_ofb(void);
 const EVP_CIPHER *EVP_aes_256_ctr(void);
-const EVP_CIPHER *EVP_aes_256_gcm(void);
 const EVP_CIPHER *EVP_aes_256_ccm(void);
+const EVP_CIPHER *EVP_aes_256_gcm(void);
 const EVP_CIPHER *EVP_aes_256_xts(void);
 #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
 const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void);
@@ -1243,6 +1242,8 @@ void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
 	int (*ctrl_str)(EVP_PKEY_CTX *ctx,
 					const char *type, const char *value));
 
+void EVP_add_alg_module(void);
+
 /* BEGIN ERROR CODES */
 /* The following lines are auto generated by the script mkerr.pl. Any changes
  * made after this point may be overwritten when the script is next run.
@@ -1257,6 +1258,7 @@ void ERR_load_EVP_strings(void);
 #define EVP_F_AES_INIT_KEY				 133
 #define EVP_F_AES_XTS					 172
 #define EVP_F_AES_XTS_CIPHER				 175
+#define EVP_F_ALG_MODULE_INIT				 177
 #define EVP_F_CAMELLIA_INIT_KEY				 159
 #define EVP_F_CMAC_INIT					 173
 #define EVP_F_D2I_PKEY					 100
@@ -1350,15 +1352,19 @@ void ERR_load_EVP_strings(void);
 #define EVP_R_DIFFERENT_PARAMETERS			 153
 #define EVP_R_DISABLED_FOR_FIPS				 163
 #define EVP_R_ENCODE_ERROR				 115
+#define EVP_R_ERROR_LOADING_SECTION			 165
+#define EVP_R_ERROR_SETTING_FIPS_MODE			 166
 #define EVP_R_EVP_PBE_CIPHERINIT_ERROR			 119
 #define EVP_R_EXPECTING_AN_RSA_KEY			 127
 #define EVP_R_EXPECTING_A_DH_KEY			 128
 #define EVP_R_EXPECTING_A_DSA_KEY			 129
 #define EVP_R_EXPECTING_A_ECDSA_KEY			 141
 #define EVP_R_EXPECTING_A_EC_KEY			 142
+#define EVP_R_FIPS_MODE_NOT_SUPPORTED			 167
 #define EVP_R_INITIALIZATION_ERROR			 134
 #define EVP_R_INPUT_NOT_INITIALIZED			 111
 #define EVP_R_INVALID_DIGEST				 152
+#define EVP_R_INVALID_FIPS_MODE				 168
 #define EVP_R_INVALID_KEY_LENGTH			 130
 #define EVP_R_INVALID_OPERATION				 148
 #define EVP_R_IV_TOO_LARGE				 102
@@ -1383,6 +1389,7 @@ void ERR_load_EVP_strings(void);
 #define EVP_R_TOO_LARGE					 164
 #define EVP_R_UNKNOWN_CIPHER				 160
 #define EVP_R_UNKNOWN_DIGEST				 161
+#define EVP_R_UNKNOWN_OPTION				 169
 #define EVP_R_UNKNOWN_PBE_ALGORITHM			 121
 #define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS		 135
 #define EVP_R_UNSUPPORTED_ALGORITHM			 156

+ 125 - 0
openssl/crypto/evp/evp_cnf.c

@@ -0,0 +1,125 @@
+/* evp_cnf.c */
+/* Written by Stephen Henson ([email protected]) for the OpenSSL
+ * project 2007.
+ */
+/* ====================================================================
+ * Copyright (c) 2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    [email protected].
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/dso.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
+
+/* Algorithm configuration module. */
+
+static int alg_module_init(CONF_IMODULE *md, const CONF *cnf)
+	{
+	int i;
+	const char *oid_section;
+	STACK_OF(CONF_VALUE) *sktmp;
+	CONF_VALUE *oval;
+	oid_section = CONF_imodule_get_value(md);
+	if(!(sktmp = NCONF_get_section(cnf, oid_section)))
+		{
+		EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_LOADING_SECTION);
+		return 0;
+		}
+	for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++)
+		{
+		oval = sk_CONF_VALUE_value(sktmp, i);
+		if (!strcmp(oval->name, "fips_mode"))
+			{
+			int m;
+			if (!X509V3_get_value_bool(oval, &m))
+				{
+				EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_INVALID_FIPS_MODE);
+				return 0;
+				}
+			if (m > 0)
+				{
+#ifdef OPENSSL_FIPS
+				if (!FIPS_mode() && !FIPS_mode_set(1))
+					{
+					EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_SETTING_FIPS_MODE);
+					return 0;
+					}
+#else
+				EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_FIPS_MODE_NOT_SUPPORTED);
+				return 0;
+#endif
+				}
+			}
+		else
+			{
+			EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_UNKNOWN_OPTION);
+			ERR_add_error_data(4, "name=", oval->name,
+						", value=", oval->value);
+			}
+				
+		}
+	return 1;
+	}
+
+void EVP_add_alg_module(void)
+	{
+	CONF_module_add("alg_section", alg_module_init, 0);
+	}

+ 6 - 0
openssl/crypto/evp/evp_err.c

@@ -75,6 +75,7 @@ static ERR_STRING_DATA EVP_str_functs[]=
 {ERR_FUNC(EVP_F_AES_INIT_KEY),	"AES_INIT_KEY"},
 {ERR_FUNC(EVP_F_AES_XTS),	"AES_XTS"},
 {ERR_FUNC(EVP_F_AES_XTS_CIPHER),	"AES_XTS_CIPHER"},
+{ERR_FUNC(EVP_F_ALG_MODULE_INIT),	"ALG_MODULE_INIT"},
 {ERR_FUNC(EVP_F_CAMELLIA_INIT_KEY),	"CAMELLIA_INIT_KEY"},
 {ERR_FUNC(EVP_F_CMAC_INIT),	"CMAC_INIT"},
 {ERR_FUNC(EVP_F_D2I_PKEY),	"D2I_PKEY"},
@@ -171,15 +172,19 @@ static ERR_STRING_DATA EVP_str_reasons[]=
 {ERR_REASON(EVP_R_DIFFERENT_PARAMETERS)  ,"different parameters"},
 {ERR_REASON(EVP_R_DISABLED_FOR_FIPS)     ,"disabled for fips"},
 {ERR_REASON(EVP_R_ENCODE_ERROR)          ,"encode error"},
+{ERR_REASON(EVP_R_ERROR_LOADING_SECTION) ,"error loading section"},
+{ERR_REASON(EVP_R_ERROR_SETTING_FIPS_MODE),"error setting fips mode"},
 {ERR_REASON(EVP_R_EVP_PBE_CIPHERINIT_ERROR),"evp pbe cipherinit error"},
 {ERR_REASON(EVP_R_EXPECTING_AN_RSA_KEY)  ,"expecting an rsa key"},
 {ERR_REASON(EVP_R_EXPECTING_A_DH_KEY)    ,"expecting a dh key"},
 {ERR_REASON(EVP_R_EXPECTING_A_DSA_KEY)   ,"expecting a dsa key"},
 {ERR_REASON(EVP_R_EXPECTING_A_ECDSA_KEY) ,"expecting a ecdsa key"},
 {ERR_REASON(EVP_R_EXPECTING_A_EC_KEY)    ,"expecting a ec key"},
+{ERR_REASON(EVP_R_FIPS_MODE_NOT_SUPPORTED),"fips mode not supported"},
 {ERR_REASON(EVP_R_INITIALIZATION_ERROR)  ,"initialization error"},
 {ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED) ,"input not initialized"},
 {ERR_REASON(EVP_R_INVALID_DIGEST)        ,"invalid digest"},
+{ERR_REASON(EVP_R_INVALID_FIPS_MODE)     ,"invalid fips mode"},
 {ERR_REASON(EVP_R_INVALID_KEY_LENGTH)    ,"invalid key length"},
 {ERR_REASON(EVP_R_INVALID_OPERATION)     ,"invalid operation"},
 {ERR_REASON(EVP_R_IV_TOO_LARGE)          ,"iv too large"},
@@ -204,6 +209,7 @@ static ERR_STRING_DATA EVP_str_reasons[]=
 {ERR_REASON(EVP_R_TOO_LARGE)             ,"too large"},
 {ERR_REASON(EVP_R_UNKNOWN_CIPHER)        ,"unknown cipher"},
 {ERR_REASON(EVP_R_UNKNOWN_DIGEST)        ,"unknown digest"},
+{ERR_REASON(EVP_R_UNKNOWN_OPTION)        ,"unknown option"},
 {ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM) ,"unknown pbe algorithm"},
 {ERR_REASON(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS),"unsuported number of rounds"},
 {ERR_REASON(EVP_R_UNSUPPORTED_ALGORITHM) ,"unsupported algorithm"},

+ 1 - 1
openssl/crypto/evp/m_dss.c

@@ -60,7 +60,7 @@
 #include "cryptlib.h"
 #include <openssl/evp.h>
 #include <openssl/objects.h>
-#include <openssl/x509.h>
+#include <openssl/sha.h>
 #ifndef OPENSSL_NO_DSA
 #include <openssl/dsa.h>
 #endif

+ 1 - 1
openssl/crypto/evp/m_dss1.c

@@ -63,7 +63,7 @@
 
 #include <openssl/evp.h>
 #include <openssl/objects.h>
-#include <openssl/x509.h>
+#include <openssl/sha.h>
 #ifndef OPENSSL_NO_DSA
 #include <openssl/dsa.h>
 #endif

+ 1 - 1
openssl/crypto/evp/m_sha1.c

@@ -65,7 +65,7 @@
 
 #include <openssl/evp.h>
 #include <openssl/objects.h>
-#include <openssl/x509.h>
+#include <openssl/sha.h>
 #ifndef OPENSSL_NO_RSA
 #include <openssl/rsa.h>
 #endif

+ 1 - 1
openssl/crypto/evp/p_sign.c

@@ -80,7 +80,7 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen,
 	{
 	unsigned char m[EVP_MAX_MD_SIZE];
 	unsigned int m_len;
-	int i=0,ok=0,v;
+	int i = 0,ok = 0,v;
 	EVP_MD_CTX tmp_ctx;
 	EVP_PKEY_CTX *pkctx = NULL;
 

+ 1 - 1
openssl/crypto/evp/p_verify.c

@@ -67,7 +67,7 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
 	{
 	unsigned char m[EVP_MAX_MD_SIZE];
 	unsigned int m_len;
-	int i=-1,ok=0,v;
+	int i = 0,ok = 0,v;
 	EVP_MD_CTX tmp_ctx;
 	EVP_PKEY_CTX *pkctx = NULL;
 

+ 16 - 15
openssl/crypto/md4/md4_dgst.c

@@ -106,22 +106,23 @@ void md4_block_data_order (MD4_CTX *c, const void *data_, size_t num)
 
 	for (;num--;)
 		{
-	HOST_c2l(data,l); X( 0)=l;		HOST_c2l(data,l); X( 1)=l;
+	(void)HOST_c2l(data,l); X( 0)=l;
+	(void)HOST_c2l(data,l); X( 1)=l;
 	/* Round 0 */
-	R0(A,B,C,D,X( 0), 3,0);	HOST_c2l(data,l); X( 2)=l;
-	R0(D,A,B,C,X( 1), 7,0);	HOST_c2l(data,l); X( 3)=l;
-	R0(C,D,A,B,X( 2),11,0);	HOST_c2l(data,l); X( 4)=l;
-	R0(B,C,D,A,X( 3),19,0);	HOST_c2l(data,l); X( 5)=l;
-	R0(A,B,C,D,X( 4), 3,0);	HOST_c2l(data,l); X( 6)=l;
-	R0(D,A,B,C,X( 5), 7,0);	HOST_c2l(data,l); X( 7)=l;
-	R0(C,D,A,B,X( 6),11,0);	HOST_c2l(data,l); X( 8)=l;
-	R0(B,C,D,A,X( 7),19,0);	HOST_c2l(data,l); X( 9)=l;
-	R0(A,B,C,D,X( 8), 3,0);	HOST_c2l(data,l); X(10)=l;
-	R0(D,A,B,C,X( 9), 7,0);	HOST_c2l(data,l); X(11)=l;
-	R0(C,D,A,B,X(10),11,0);	HOST_c2l(data,l); X(12)=l;
-	R0(B,C,D,A,X(11),19,0);	HOST_c2l(data,l); X(13)=l;
-	R0(A,B,C,D,X(12), 3,0);	HOST_c2l(data,l); X(14)=l;
-	R0(D,A,B,C,X(13), 7,0);	HOST_c2l(data,l); X(15)=l;
+	R0(A,B,C,D,X( 0), 3,0);	(void)HOST_c2l(data,l); X( 2)=l;
+	R0(D,A,B,C,X( 1), 7,0);	(void)HOST_c2l(data,l); X( 3)=l;
+	R0(C,D,A,B,X( 2),11,0);	(void)HOST_c2l(data,l); X( 4)=l;
+	R0(B,C,D,A,X( 3),19,0);	(void)HOST_c2l(data,l); X( 5)=l;
+	R0(A,B,C,D,X( 4), 3,0);	(void)HOST_c2l(data,l); X( 6)=l;
+	R0(D,A,B,C,X( 5), 7,0);	(void)HOST_c2l(data,l); X( 7)=l;
+	R0(C,D,A,B,X( 6),11,0);	(void)HOST_c2l(data,l); X( 8)=l;
+	R0(B,C,D,A,X( 7),19,0);	(void)HOST_c2l(data,l); X( 9)=l;
+	R0(A,B,C,D,X( 8), 3,0);	(void)HOST_c2l(data,l); X(10)=l;
+	R0(D,A,B,C,X( 9), 7,0);	(void)HOST_c2l(data,l); X(11)=l;
+	R0(C,D,A,B,X(10),11,0);	(void)HOST_c2l(data,l); X(12)=l;
+	R0(B,C,D,A,X(11),19,0);	(void)HOST_c2l(data,l); X(13)=l;
+	R0(A,B,C,D,X(12), 3,0);	(void)HOST_c2l(data,l); X(14)=l;
+	R0(D,A,B,C,X(13), 7,0);	(void)HOST_c2l(data,l); X(15)=l;
 	R0(C,D,A,B,X(14),11,0);
 	R0(B,C,D,A,X(15),19,0);
 	/* Round 1 */

+ 4 - 4
openssl/crypto/md4/md4_locl.h

@@ -77,10 +77,10 @@ void md4_block_data_order (MD4_CTX *c, const void *p,size_t num);
 #define HASH_FINAL		MD4_Final
 #define	HASH_MAKE_STRING(c,s)	do {	\
 	unsigned long ll;		\
-	ll=(c)->A; HOST_l2c(ll,(s));	\
-	ll=(c)->B; HOST_l2c(ll,(s));	\
-	ll=(c)->C; HOST_l2c(ll,(s));	\
-	ll=(c)->D; HOST_l2c(ll,(s));	\
+	ll=(c)->A; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->B; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->C; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->D; (void)HOST_l2c(ll,(s));	\
 	} while (0)
 #define	HASH_BLOCK_DATA_ORDER	md4_block_data_order
 

+ 4 - 4
openssl/crypto/md5/md5_locl.h

@@ -86,10 +86,10 @@ void md5_block_data_order (MD5_CTX *c, const void *p,size_t num);
 #define HASH_FINAL		MD5_Final
 #define	HASH_MAKE_STRING(c,s)	do {	\
 	unsigned long ll;		\
-	ll=(c)->A; HOST_l2c(ll,(s));	\
-	ll=(c)->B; HOST_l2c(ll,(s));	\
-	ll=(c)->C; HOST_l2c(ll,(s));	\
-	ll=(c)->D; HOST_l2c(ll,(s));	\
+	ll=(c)->A; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->B; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->C; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->D; (void)HOST_l2c(ll,(s));	\
 	} while (0)
 #define	HASH_BLOCK_DATA_ORDER	md5_block_data_order
 

+ 1 - 1
openssl/crypto/mem.c

@@ -121,10 +121,10 @@ static void (*set_debug_options_func)(long) = NULL;
 static long (*get_debug_options_func)(void) = NULL;
 #endif
 
-
 int CRYPTO_set_mem_functions(void *(*m)(size_t), void *(*r)(void *, size_t),
 	void (*f)(void *))
 	{
+	/* Dummy call just to ensure OPENSSL_init() gets linked in */
 	OPENSSL_init();
 	if (!allow_customize)
 		return 0;

+ 2 - 2
openssl/crypto/modes/gcm128.c

@@ -723,7 +723,7 @@ void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx,void *key,block128_f block)
 #  endif
 	gcm_init_4bit(ctx->Htable,ctx->H.u);
 #  if	defined(GHASH_ASM_X86)			/* x86 only */
-#   if defined(OPENSSL_IA32_SSE2)
+#   if	defined(OPENSSL_IA32_SSE2)
 	if (OPENSSL_ia32cap_P[0]&(1<<25)) {	/* check SSE bit */
 #   else
 	if (OPENSSL_ia32cap_P[0]&(1<<23)) {	/* check MMX bit */
@@ -1398,7 +1398,7 @@ int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx,const unsigned char *tag,
 	void (*gcm_gmult_p)(u64 Xi[2],const u128 Htable[16])	= ctx->gmult;
 #endif
 
-	if (ctx->mres)
+	if (ctx->mres || ctx->ares)
 		GCM_MUL(ctx,Xi);
 
 	if (is_endian.little) {

+ 1 - 1
openssl/crypto/objects/o_names.c

@@ -73,7 +73,7 @@ int OBJ_NAME_new_index(unsigned long (*hash_func)(const char *),
 		name_funcs_stack=sk_NAME_FUNCS_new_null();
 		MemCheck_on();
 		}
-	if ((name_funcs_stack == NULL))
+	if (name_funcs_stack == NULL)
 		{
 		/* ERROR */
 		return(0);

+ 7 - 3
openssl/crypto/ocsp/ocsp_vfy.c

@@ -91,9 +91,12 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
 		{
 		EVP_PKEY *skey;
 		skey = X509_get_pubkey(signer);
-		ret = OCSP_BASICRESP_verify(bs, skey, 0);
-		EVP_PKEY_free(skey);
-		if(ret <= 0)
+		if (skey)
+			{
+			ret = OCSP_BASICRESP_verify(bs, skey, 0);
+			EVP_PKEY_free(skey);
+			}
+		if(!skey || ret <= 0)
 			{
 			OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNATURE_FAILURE);
 			goto end;
@@ -108,6 +111,7 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
 			init_res = X509_STORE_CTX_init(&ctx, st, signer, bs->certs);
 		if(!init_res)
 			{
+			ret = -1;
 			OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,ERR_R_X509_LIB);
 			goto end;
 			}

+ 3 - 3
openssl/crypto/opensslv.h

@@ -25,11 +25,11 @@
  * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
  *  major minor fix final patch/beta)
  */
-#define OPENSSL_VERSION_NUMBER	0x1000103fL
+#define OPENSSL_VERSION_NUMBER	0x1000105fL
 #ifdef OPENSSL_FIPS
-#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1c-fips 10 May 2012"
+#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1e-fips 11 Feb 2013"
 #else
-#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1c 10 May 2012"
+#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1e 11 Feb 2013"
 #endif
 #define OPENSSL_VERSION_PTEXT	" part of " OPENSSL_VERSION_TEXT
 

+ 161 - 0
openssl/crypto/pem/pem_all.c

@@ -193,7 +193,61 @@ RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb,
 
 #endif
 
+#ifdef OPENSSL_FIPS
+
+int PEM_write_bio_RSAPrivateKey(BIO *bp, RSA *x, const EVP_CIPHER *enc,
+                                               unsigned char *kstr, int klen,
+                                               pem_password_cb *cb, void *u)
+{
+	if (FIPS_mode())
+		{
+		EVP_PKEY *k;
+		int ret;
+		k = EVP_PKEY_new();
+		if (!k)
+			return 0;
+		EVP_PKEY_set1_RSA(k, x);
+
+		ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
+		EVP_PKEY_free(k);
+		return ret;
+		}
+	else
+		return PEM_ASN1_write_bio((i2d_of_void *)i2d_RSAPrivateKey,
+					PEM_STRING_RSA,bp,x,enc,kstr,klen,cb,u);
+}
+
+#ifndef OPENSSL_NO_FP_API
+int PEM_write_RSAPrivateKey(FILE *fp, RSA *x, const EVP_CIPHER *enc,
+                                               unsigned char *kstr, int klen,
+                                               pem_password_cb *cb, void *u)
+{
+	if (FIPS_mode())
+		{
+		EVP_PKEY *k;
+		int ret;
+		k = EVP_PKEY_new();
+		if (!k)
+			return 0;
+
+		EVP_PKEY_set1_RSA(k, x);
+
+		ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
+		EVP_PKEY_free(k);
+		return ret;
+		}
+	else
+		return PEM_ASN1_write((i2d_of_void *)i2d_RSAPrivateKey,
+					PEM_STRING_RSA,fp,x,enc,kstr,klen,cb,u);
+}
+#endif
+
+#else
+
 IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA, RSAPrivateKey)
+
+#endif
+
 IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, RSAPublicKey)
 IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, PEM_STRING_PUBLIC, RSA_PUBKEY)
 
@@ -223,7 +277,59 @@ DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb,
 	return pkey_get_dsa(pktmp, dsa);	/* will free pktmp */
 }
 
+#ifdef OPENSSL_FIPS
+
+int PEM_write_bio_DSAPrivateKey(BIO *bp, DSA *x, const EVP_CIPHER *enc,
+                                               unsigned char *kstr, int klen,
+                                               pem_password_cb *cb, void *u)
+{
+	if (FIPS_mode())
+		{
+		EVP_PKEY *k;
+		int ret;
+		k = EVP_PKEY_new();
+		if (!k)
+			return 0;
+		EVP_PKEY_set1_DSA(k, x);
+
+		ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
+		EVP_PKEY_free(k);
+		return ret;
+		}
+	else
+		return PEM_ASN1_write_bio((i2d_of_void *)i2d_DSAPrivateKey,
+					PEM_STRING_DSA,bp,x,enc,kstr,klen,cb,u);
+}
+
+#ifndef OPENSSL_NO_FP_API
+int PEM_write_DSAPrivateKey(FILE *fp, DSA *x, const EVP_CIPHER *enc,
+                                               unsigned char *kstr, int klen,
+                                               pem_password_cb *cb, void *u)
+{
+	if (FIPS_mode())
+		{
+		EVP_PKEY *k;
+		int ret;
+		k = EVP_PKEY_new();
+		if (!k)
+			return 0;
+		EVP_PKEY_set1_DSA(k, x);
+		ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
+		EVP_PKEY_free(k);
+		return ret;
+		}
+	else
+		return PEM_ASN1_write((i2d_of_void *)i2d_DSAPrivateKey,
+					PEM_STRING_DSA,fp,x,enc,kstr,klen,cb,u);
+}
+#endif
+
+#else
+
 IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA, DSAPrivateKey)
+
+#endif
+
 IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY)
 
 #ifndef OPENSSL_NO_FP_API
@@ -269,8 +375,63 @@ EC_KEY *PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb,
 
 IMPLEMENT_PEM_rw_const(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS, ECPKParameters)
 
+
+
+#ifdef OPENSSL_FIPS
+
+int PEM_write_bio_ECPrivateKey(BIO *bp, EC_KEY *x, const EVP_CIPHER *enc,
+                                               unsigned char *kstr, int klen,
+                                               pem_password_cb *cb, void *u)
+{
+	if (FIPS_mode())
+		{
+		EVP_PKEY *k;
+		int ret;
+		k = EVP_PKEY_new();
+		if (!k)
+			return 0;
+		EVP_PKEY_set1_EC_KEY(k, x);
+
+		ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
+		EVP_PKEY_free(k);
+		return ret;
+		}
+	else
+		return PEM_ASN1_write_bio((i2d_of_void *)i2d_ECPrivateKey,
+						PEM_STRING_ECPRIVATEKEY,
+						bp,x,enc,kstr,klen,cb,u);
+}
+
+#ifndef OPENSSL_NO_FP_API
+int PEM_write_ECPrivateKey(FILE *fp, EC_KEY *x, const EVP_CIPHER *enc,
+                                               unsigned char *kstr, int klen,
+                                               pem_password_cb *cb, void *u)
+{
+	if (FIPS_mode())
+		{
+		EVP_PKEY *k;
+		int ret;
+		k = EVP_PKEY_new();
+		if (!k)
+			return 0;
+		EVP_PKEY_set1_EC_KEY(k, x);
+		ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
+		EVP_PKEY_free(k);
+		return ret;
+		}
+	else
+		return PEM_ASN1_write((i2d_of_void *)i2d_ECPrivateKey,
+						PEM_STRING_ECPRIVATEKEY,
+						fp,x,enc,kstr,klen,cb,u);
+}
+#endif
+
+#else
+
 IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY, ECPrivateKey)
 
+#endif
+
 IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY)
 
 #ifndef OPENSSL_NO_FP_API

+ 17 - 10
openssl/crypto/pem/pem_lib.c

@@ -394,7 +394,8 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
 			goto err;
 		/* The 'iv' is used as the iv and as a salt.  It is
 		 * NOT taken from the BytesToKey function */
-		EVP_BytesToKey(enc,EVP_md5(),iv,kstr,klen,1,key,NULL);
+		if (!EVP_BytesToKey(enc,EVP_md5(),iv,kstr,klen,1,key,NULL))
+			goto err;
 
 		if (kstr == (unsigned char *)buf) OPENSSL_cleanse(buf,PEM_BUFSIZE);
 
@@ -406,12 +407,15 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
 		/* k=strlen(buf); */
 
 		EVP_CIPHER_CTX_init(&ctx);
-		EVP_EncryptInit_ex(&ctx,enc,NULL,key,iv);
-		EVP_EncryptUpdate(&ctx,data,&j,data,i);
-		EVP_EncryptFinal_ex(&ctx,&(data[j]),&i);
+		ret = 1;
+		if (!EVP_EncryptInit_ex(&ctx,enc,NULL,key,iv)
+			|| !EVP_EncryptUpdate(&ctx,data,&j,data,i)
+			|| !EVP_EncryptFinal_ex(&ctx,&(data[j]),&i))
+			ret = 0;
 		EVP_CIPHER_CTX_cleanup(&ctx);
+		if (ret == 0)
+			goto err;
 		i+=j;
-		ret=1;
 		}
 	else
 		{
@@ -459,14 +463,17 @@ int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen,
 	ebcdic2ascii(buf, buf, klen);
 #endif
 
-	EVP_BytesToKey(cipher->cipher,EVP_md5(),&(cipher->iv[0]),
-		(unsigned char *)buf,klen,1,key,NULL);
+	if (!EVP_BytesToKey(cipher->cipher,EVP_md5(),&(cipher->iv[0]),
+		(unsigned char *)buf,klen,1,key,NULL))
+		return 0;
 
 	j=(int)len;
 	EVP_CIPHER_CTX_init(&ctx);
-	EVP_DecryptInit_ex(&ctx,cipher->cipher,NULL, key,&(cipher->iv[0]));
-	EVP_DecryptUpdate(&ctx,data,&i,data,j);
-	o=EVP_DecryptFinal_ex(&ctx,&(data[i]),&j);
+	o = EVP_DecryptInit_ex(&ctx,cipher->cipher,NULL, key,&(cipher->iv[0]));
+	if (o)
+		o = EVP_DecryptUpdate(&ctx,data,&i,data,j);
+	if (o)
+		o = EVP_DecryptFinal_ex(&ctx,&(data[i]),&j);
 	EVP_CIPHER_CTX_cleanup(&ctx);
 	OPENSSL_cleanse((char *)buf,sizeof(buf));
 	OPENSSL_cleanse((char *)key,sizeof(key));

+ 4 - 2
openssl/crypto/pem/pem_seal.c

@@ -96,7 +96,8 @@ int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, EVP_MD *md_type,
 	EVP_EncodeInit(&ctx->encode);
 
 	EVP_MD_CTX_init(&ctx->md);
-	EVP_SignInit(&ctx->md,md_type);
+	if (!EVP_SignInit(&ctx->md,md_type))
+		goto err;
 
 	EVP_CIPHER_CTX_init(&ctx->cipher);
 	ret=EVP_SealInit(&ctx->cipher,type,ek,ekl,iv,pubk,npubk);
@@ -163,7 +164,8 @@ int PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig, int *sigl,
 		goto err;
 		}
 
-	EVP_EncryptFinal_ex(&ctx->cipher,s,(int *)&i);
+	if (!EVP_EncryptFinal_ex(&ctx->cipher,s,(int *)&i))
+		goto err;
 	EVP_EncodeUpdate(&ctx->encode,out,&j,s,i);
 	*outl=j;
 	out+=j;

+ 16 - 8
openssl/crypto/pkcs12/p12_key.c

@@ -176,24 +176,32 @@ int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
 		out += u;
 		for (j = 0; j < v; j++) B[j] = Ai[j % u];
 		/* Work out B + 1 first then can use B as tmp space */
-		if (!BN_bin2bn (B, v, Bpl1)) goto err;
-		if (!BN_add_word (Bpl1, 1)) goto err;
+		if (!BN_bin2bn (B, v, Bpl1))
+			goto err;
+		if (!BN_add_word (Bpl1, 1))
+			goto err;
 		for (j = 0; j < Ilen ; j+=v) {
-			if (!BN_bin2bn (I + j, v, Ij)) goto err;
-			if (!BN_add (Ij, Ij, Bpl1)) goto err;
-			BN_bn2bin (Ij, B);
+			if (!BN_bin2bn(I + j, v, Ij))
+				goto err;
+			if (!BN_add(Ij, Ij, Bpl1))
+				goto err;
+			if (!BN_bn2bin(Ij, B))
+				goto err;
 			Ijlen = BN_num_bytes (Ij);
 			/* If more than 2^(v*8) - 1 cut off MSB */
 			if (Ijlen > v) {
-				BN_bn2bin (Ij, B);
+				if (!BN_bn2bin (Ij, B))
+					goto err;
 				memcpy (I + j, B + 1, v);
 #ifndef PKCS12_BROKEN_KEYGEN
 			/* If less than v bytes pad with zeroes */
 			} else if (Ijlen < v) {
 				memset(I + j, 0, v - Ijlen);
-				BN_bn2bin(Ij, I + j + v - Ijlen); 
+				if (!BN_bn2bin(Ij, I + j + v - Ijlen))
+					goto err;
 #endif
-			} else BN_bn2bin (Ij, I + j);
+			} else if (!BN_bn2bin (Ij, I + j))
+				goto err;
 		}
 	}
 

+ 1 - 1
openssl/crypto/pkcs7/bio_pk7.c

@@ -56,7 +56,7 @@
 #include <openssl/pkcs7.h>
 #include <openssl/bio.h>
 
-#ifndef OPENSSL_SYSNAME_NETWARE
+#if !defined(OPENSSL_SYSNAME_NETWARE) && !defined(OPENSSL_SYSNAME_VXWORKS)
 #include <memory.h>
 #endif
 #include <stdio.h>

+ 11 - 0
openssl/crypto/ppccap.c

@@ -3,6 +3,7 @@
 #include <string.h>
 #include <setjmp.h>
 #include <signal.h>
+#include <unistd.h>
 #include <crypto.h>
 #include <openssl/bn.h>
 
@@ -53,6 +54,7 @@ static sigjmp_buf ill_jmp;
 static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); }
 
 void OPENSSL_ppc64_probe(void);
+void OPENSSL_altivec_probe(void);
 
 void OPENSSL_cpuid_setup(void)
 	{
@@ -82,6 +84,15 @@ void OPENSSL_cpuid_setup(void)
 
 	OPENSSL_ppccap_P = 0;
 
+#if defined(_AIX)
+	if (sizeof(size_t)==4
+# if defined(_SC_AIX_KERNEL_BITMODE)
+	    && sysconf(_SC_AIX_KERNEL_BITMODE)!=64
+# endif
+	   )
+		return;
+#endif
+
 	memset(&ill_act,0,sizeof(ill_act));
 	ill_act.sa_handler = ill_handler;
 	ill_act.sa_mask    = all_masked;

+ 1 - 1
openssl/crypto/rand/md_rand.c

@@ -123,10 +123,10 @@
 
 #include "e_os.h"
 
+#include <openssl/crypto.h>
 #include <openssl/rand.h>
 #include "rand_lcl.h"
 
-#include <openssl/crypto.h>
 #include <openssl/err.h>
 
 #ifdef BN_DEBUG

+ 5 - 2
openssl/crypto/rand/rand_lib.c

@@ -210,8 +210,11 @@ static size_t drbg_get_entropy(DRBG_CTX *ctx, unsigned char **pout,
 
 static void drbg_free_entropy(DRBG_CTX *ctx, unsigned char *out, size_t olen)
 	{
-	OPENSSL_cleanse(out, olen);
-	OPENSSL_free(out);
+	if (out)
+		{
+		OPENSSL_cleanse(out, olen);
+		OPENSSL_free(out);
+		}
 	}
 
 /* Set "additional input" when generating random data. This uses the

+ 15 - 15
openssl/crypto/ripemd/rmd_dgst.c

@@ -105,21 +105,21 @@ void ripemd160_block_data_order (RIPEMD160_CTX *ctx, const void *p, size_t num)
 
 	A=ctx->A; B=ctx->B; C=ctx->C; D=ctx->D; E=ctx->E;
 
-	HOST_c2l(data,l); X( 0)=l;	HOST_c2l(data,l); X( 1)=l;
-	RIP1(A,B,C,D,E,WL00,SL00);	HOST_c2l(data,l); X( 2)=l;
-	RIP1(E,A,B,C,D,WL01,SL01);	HOST_c2l(data,l); X( 3)=l;
-	RIP1(D,E,A,B,C,WL02,SL02);	HOST_c2l(data,l); X( 4)=l;
-	RIP1(C,D,E,A,B,WL03,SL03);	HOST_c2l(data,l); X( 5)=l;
-	RIP1(B,C,D,E,A,WL04,SL04);	HOST_c2l(data,l); X( 6)=l;
-	RIP1(A,B,C,D,E,WL05,SL05);	HOST_c2l(data,l); X( 7)=l;
-	RIP1(E,A,B,C,D,WL06,SL06);	HOST_c2l(data,l); X( 8)=l;
-	RIP1(D,E,A,B,C,WL07,SL07);	HOST_c2l(data,l); X( 9)=l;
-	RIP1(C,D,E,A,B,WL08,SL08);	HOST_c2l(data,l); X(10)=l;
-	RIP1(B,C,D,E,A,WL09,SL09);	HOST_c2l(data,l); X(11)=l;
-	RIP1(A,B,C,D,E,WL10,SL10);	HOST_c2l(data,l); X(12)=l;
-	RIP1(E,A,B,C,D,WL11,SL11);	HOST_c2l(data,l); X(13)=l;
-	RIP1(D,E,A,B,C,WL12,SL12);	HOST_c2l(data,l); X(14)=l;
-	RIP1(C,D,E,A,B,WL13,SL13);	HOST_c2l(data,l); X(15)=l;
+	(void)HOST_c2l(data,l); X( 0)=l;(void)HOST_c2l(data,l); X( 1)=l;
+	RIP1(A,B,C,D,E,WL00,SL00);	(void)HOST_c2l(data,l); X( 2)=l;
+	RIP1(E,A,B,C,D,WL01,SL01);	(void)HOST_c2l(data,l); X( 3)=l;
+	RIP1(D,E,A,B,C,WL02,SL02);	(void)HOST_c2l(data,l); X( 4)=l;
+	RIP1(C,D,E,A,B,WL03,SL03);	(void)HOST_c2l(data,l); X( 5)=l;
+	RIP1(B,C,D,E,A,WL04,SL04);	(void)HOST_c2l(data,l); X( 6)=l;
+	RIP1(A,B,C,D,E,WL05,SL05);	(void)HOST_c2l(data,l); X( 7)=l;
+	RIP1(E,A,B,C,D,WL06,SL06);	(void)HOST_c2l(data,l); X( 8)=l;
+	RIP1(D,E,A,B,C,WL07,SL07);	(void)HOST_c2l(data,l); X( 9)=l;
+	RIP1(C,D,E,A,B,WL08,SL08);	(void)HOST_c2l(data,l); X(10)=l;
+	RIP1(B,C,D,E,A,WL09,SL09);	(void)HOST_c2l(data,l); X(11)=l;
+	RIP1(A,B,C,D,E,WL10,SL10);	(void)HOST_c2l(data,l); X(12)=l;
+	RIP1(E,A,B,C,D,WL11,SL11);	(void)HOST_c2l(data,l); X(13)=l;
+	RIP1(D,E,A,B,C,WL12,SL12);	(void)HOST_c2l(data,l); X(14)=l;
+	RIP1(C,D,E,A,B,WL13,SL13);	(void)HOST_c2l(data,l); X(15)=l;
 	RIP1(B,C,D,E,A,WL14,SL14);
 	RIP1(A,B,C,D,E,WL15,SL15);
 

+ 5 - 5
openssl/crypto/ripemd/rmd_locl.h

@@ -88,11 +88,11 @@ void ripemd160_block_data_order (RIPEMD160_CTX *c, const void *p,size_t num);
 #define HASH_FINAL              RIPEMD160_Final
 #define	HASH_MAKE_STRING(c,s)	do {	\
 	unsigned long ll;		\
-	ll=(c)->A; HOST_l2c(ll,(s));	\
-	ll=(c)->B; HOST_l2c(ll,(s));	\
-	ll=(c)->C; HOST_l2c(ll,(s));	\
-	ll=(c)->D; HOST_l2c(ll,(s));	\
-	ll=(c)->E; HOST_l2c(ll,(s));	\
+	ll=(c)->A; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->B; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->C; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->D; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->E; (void)HOST_l2c(ll,(s));	\
 	} while (0)
 #define HASH_BLOCK_DATA_ORDER   ripemd160_block_data_order
 

+ 1 - 1
openssl/crypto/rsa/rsa.h

@@ -280,7 +280,7 @@ struct rsa_st
 
 RSA *	RSA_new(void);
 RSA *	RSA_new_method(ENGINE *engine);
-int	RSA_size(const RSA *);
+int	RSA_size(const RSA *rsa);
 
 /* Deprecated version */
 #ifndef OPENSSL_NO_DEPRECATED

+ 3 - 3
openssl/crypto/rsa/rsa_eay.c

@@ -847,12 +847,12 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
 	if (!BN_mod(r0,pr1,rsa->p,ctx)) goto err;
 
 	/* If p < q it is occasionally possible for the correction of
-         * adding 'p' if r0 is negative above to leave the result still
+	 * adding 'p' if r0 is negative above to leave the result still
 	 * negative. This can break the private key operations: the following
 	 * second correction should *always* correct this rare occurrence.
 	 * This will *never* happen with OpenSSL generated keys because
-         * they ensure p > q [steve]
-         */
+	 * they ensure p > q [steve]
+	 */
 	if (BN_is_negative(r0))
 		if (!BN_add(r0,r0,rsa->p)) goto err;
 	if (!BN_mul(r1,r0,rsa->q,ctx)) goto err;

+ 1 - 1
openssl/crypto/rsa/rsa_oaep.c

@@ -149,7 +149,7 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
 	if (!EVP_Digest((void *)param, plen, phash, NULL, EVP_sha1(), NULL))
 		return -1;
 
-	if (memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad)
+	if (CRYPTO_memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad)
 		goto decoding_err;
 	else
 		{

+ 1 - 1
openssl/crypto/sha/sha1_one.c

@@ -58,8 +58,8 @@
 
 #include <stdio.h>
 #include <string.h>
-#include <openssl/sha.h>
 #include <openssl/crypto.h>
+#include <openssl/sha.h>
 
 #ifndef OPENSSL_NO_SHA1
 unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md)

+ 1 - 1
openssl/crypto/sha/sha1dgst.c

@@ -56,8 +56,8 @@
  * [including the GNU Public Licence.]
  */
 
-#include <openssl/opensslconf.h>
 #include <openssl/crypto.h>
+#include <openssl/opensslconf.h>
 #if !defined(OPENSSL_NO_SHA1) && !defined(OPENSSL_NO_SHA)
 
 #undef  SHA_0

+ 3 - 3
openssl/crypto/sha/sha256.c

@@ -88,17 +88,17 @@ int SHA224_Final (unsigned char *md, SHA256_CTX *c)
 	switch ((c)->md_len)		\
 	{   case SHA224_DIGEST_LENGTH:	\
 		for (nn=0;nn<SHA224_DIGEST_LENGTH/4;nn++)	\
-		{   ll=(c)->h[nn]; HOST_l2c(ll,(s));   }	\
+		{   ll=(c)->h[nn]; (void)HOST_l2c(ll,(s));   }	\
 		break;			\
 	    case SHA256_DIGEST_LENGTH:	\
 		for (nn=0;nn<SHA256_DIGEST_LENGTH/4;nn++)	\
-		{   ll=(c)->h[nn]; HOST_l2c(ll,(s));   }	\
+		{   ll=(c)->h[nn]; (void)HOST_l2c(ll,(s));   }	\
 		break;			\
 	    default:			\
 		if ((c)->md_len > SHA256_DIGEST_LENGTH)	\
 		    return 0;				\
 		for (nn=0;nn<(c)->md_len/4;nn++)		\
-		{   ll=(c)->h[nn]; HOST_l2c(ll,(s));   }	\
+		{   ll=(c)->h[nn]; (void)HOST_l2c(ll,(s));   }	\
 		break;			\
 	}				\
 	} while (0)

+ 1 - 1
openssl/crypto/sha/sha_dgst.c

@@ -56,8 +56,8 @@
  * [including the GNU Public Licence.]
  */
 
-#include <openssl/opensslconf.h>
 #include <openssl/crypto.h>
+#include <openssl/opensslconf.h>
 #if !defined(OPENSSL_NO_SHA0) && !defined(OPENSSL_NO_SHA)
 
 #undef  SHA_1

+ 20 - 20
openssl/crypto/sha/sha_locl.h

@@ -69,11 +69,11 @@
 #define HASH_CBLOCK             SHA_CBLOCK
 #define HASH_MAKE_STRING(c,s)   do {	\
 	unsigned long ll;		\
-	ll=(c)->h0; HOST_l2c(ll,(s));	\
-	ll=(c)->h1; HOST_l2c(ll,(s));	\
-	ll=(c)->h2; HOST_l2c(ll,(s));	\
-	ll=(c)->h3; HOST_l2c(ll,(s));	\
-	ll=(c)->h4; HOST_l2c(ll,(s));	\
+	ll=(c)->h0; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->h1; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->h2; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->h3; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->h4; (void)HOST_l2c(ll,(s));	\
 	} while (0)
 
 #if defined(SHA_0)
@@ -256,21 +256,21 @@ static void HASH_BLOCK_DATA_ORDER (SHA_CTX *c, const void *p, size_t num)
 		}
 	else
 		{
-		HOST_c2l(data,l); X( 0)=l;		HOST_c2l(data,l); X( 1)=l;
-		BODY_00_15( 0,A,B,C,D,E,T,X( 0));	HOST_c2l(data,l); X( 2)=l;
-		BODY_00_15( 1,T,A,B,C,D,E,X( 1));	HOST_c2l(data,l); X( 3)=l;
-		BODY_00_15( 2,E,T,A,B,C,D,X( 2));	HOST_c2l(data,l); X( 4)=l;
-		BODY_00_15( 3,D,E,T,A,B,C,X( 3));	HOST_c2l(data,l); X( 5)=l;
-		BODY_00_15( 4,C,D,E,T,A,B,X( 4));	HOST_c2l(data,l); X( 6)=l;
-		BODY_00_15( 5,B,C,D,E,T,A,X( 5));	HOST_c2l(data,l); X( 7)=l;
-		BODY_00_15( 6,A,B,C,D,E,T,X( 6));	HOST_c2l(data,l); X( 8)=l;
-		BODY_00_15( 7,T,A,B,C,D,E,X( 7));	HOST_c2l(data,l); X( 9)=l;
-		BODY_00_15( 8,E,T,A,B,C,D,X( 8));	HOST_c2l(data,l); X(10)=l;
-		BODY_00_15( 9,D,E,T,A,B,C,X( 9));	HOST_c2l(data,l); X(11)=l;
-		BODY_00_15(10,C,D,E,T,A,B,X(10));	HOST_c2l(data,l); X(12)=l;
-		BODY_00_15(11,B,C,D,E,T,A,X(11));	HOST_c2l(data,l); X(13)=l;
-		BODY_00_15(12,A,B,C,D,E,T,X(12));	HOST_c2l(data,l); X(14)=l;
-		BODY_00_15(13,T,A,B,C,D,E,X(13));	HOST_c2l(data,l); X(15)=l;
+		(void)HOST_c2l(data,l); X( 0)=l;	(void)HOST_c2l(data,l); X( 1)=l;
+		BODY_00_15( 0,A,B,C,D,E,T,X( 0));	(void)HOST_c2l(data,l); X( 2)=l;
+		BODY_00_15( 1,T,A,B,C,D,E,X( 1));	(void)HOST_c2l(data,l); X( 3)=l;
+		BODY_00_15( 2,E,T,A,B,C,D,X( 2));	(void)HOST_c2l(data,l); X( 4)=l;
+		BODY_00_15( 3,D,E,T,A,B,C,X( 3));	(void)HOST_c2l(data,l); X( 5)=l;
+		BODY_00_15( 4,C,D,E,T,A,B,X( 4));	(void)HOST_c2l(data,l); X( 6)=l;
+		BODY_00_15( 5,B,C,D,E,T,A,X( 5));	(void)HOST_c2l(data,l); X( 7)=l;
+		BODY_00_15( 6,A,B,C,D,E,T,X( 6));	(void)HOST_c2l(data,l); X( 8)=l;
+		BODY_00_15( 7,T,A,B,C,D,E,X( 7));	(void)HOST_c2l(data,l); X( 9)=l;
+		BODY_00_15( 8,E,T,A,B,C,D,X( 8));	(void)HOST_c2l(data,l); X(10)=l;
+		BODY_00_15( 9,D,E,T,A,B,C,X( 9));	(void)HOST_c2l(data,l); X(11)=l;
+		BODY_00_15(10,C,D,E,T,A,B,X(10));	(void)HOST_c2l(data,l); X(12)=l;
+		BODY_00_15(11,B,C,D,E,T,A,X(11));	(void)HOST_c2l(data,l); X(13)=l;
+		BODY_00_15(12,A,B,C,D,E,T,X(12));	(void)HOST_c2l(data,l); X(14)=l;
+		BODY_00_15(13,T,A,B,C,D,E,X(13));	(void)HOST_c2l(data,l); X(15)=l;
 		BODY_00_15(14,E,T,A,B,C,D,X(14));
 		BODY_00_15(15,D,E,T,A,B,C,X(15));
 		}

+ 3 - 2
openssl/crypto/srp/srp_vfy.c

@@ -390,7 +390,7 @@ int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file)
 		}
 	for (i = 0; i < sk_OPENSSL_PSTRING_num(tmpdb->data); i++)
 		{
-		pp = (char **)sk_OPENSSL_PSTRING_value(tmpdb->data,i);
+		pp = sk_OPENSSL_PSTRING_value(tmpdb->data,i);
 		if (pp[DB_srptype][0] == DB_SRP_INDEX)
 			{
 			/*we add this couple in the internal Stack */
@@ -581,7 +581,8 @@ char *SRP_create_verifier(const char *user, const char *pass, char **salt,
 	if (*salt == NULL)
 		{
 		char *tmp_salt;
-		if ((tmp_salt = (char *)OPENSSL_malloc(SRP_RANDOM_SALT_LEN * 2)) == NULL)
+
+		if ((tmp_salt = OPENSSL_malloc(SRP_RANDOM_SALT_LEN * 2)) == NULL)
 			{
 			OPENSSL_free(vf);
 			goto err;

+ 6 - 8
openssl/crypto/symhacks.h

@@ -193,17 +193,17 @@
 #undef SSL_CTX_set_srp_username_callback
 #define SSL_CTX_set_srp_username_callback	SSL_CTX_set_srp_un_cb
 #undef ssl_add_clienthello_use_srtp_ext
-#define ssl_add_clienthello_use_srtp_ext ssl_add_clihello_use_srtp_ext
+#define ssl_add_clienthello_use_srtp_ext	ssl_add_clihello_use_srtp_ext
 #undef ssl_add_serverhello_use_srtp_ext
-#define ssl_add_serverhello_use_srtp_ext ssl_add_serhello_use_srtp_ext
+#define ssl_add_serverhello_use_srtp_ext	ssl_add_serhello_use_srtp_ext
 #undef ssl_parse_clienthello_use_srtp_ext
-#define ssl_parse_clienthello_use_srtp_ext ssl_parse_clihello_use_srtp_ext
+#define ssl_parse_clienthello_use_srtp_ext	ssl_parse_clihello_use_srtp_ext
 #undef ssl_parse_serverhello_use_srtp_ext
-#define ssl_parse_serverhello_use_srtp_ext ssl_parse_serhello_use_srtp_ext
+#define ssl_parse_serverhello_use_srtp_ext	ssl_parse_serhello_use_srtp_ext
 #undef SSL_CTX_set_next_protos_advertised_cb
-#define SSL_CTX_set_next_protos_advertised_cb SSL_CTX_set_next_protos_adv_cb
+#define SSL_CTX_set_next_protos_advertised_cb	SSL_CTX_set_next_protos_adv_cb
 #undef SSL_CTX_set_next_proto_select_cb
-#define SSL_CTX_set_next_proto_select_cb SSL_CTX_set_next_proto_sel_cb
+#define SSL_CTX_set_next_proto_select_cb	SSL_CTX_set_next_proto_sel_cb
 
 /* Hack some long ENGINE names */
 #undef ENGINE_get_default_BN_mod_exp_crt
@@ -316,8 +316,6 @@
 #define ec_GFp_simple_point_set_to_infinity     ec_GFp_simple_pt_set_to_inf
 #undef ec_GFp_simple_points_make_affine
 #define ec_GFp_simple_points_make_affine	ec_GFp_simple_pts_make_affine
-#undef ec_GFp_simple_group_get_curve_GFp
-#define ec_GFp_simple_group_get_curve_GFp       ec_GFp_simple_grp_get_curve_GFp
 #undef ec_GFp_simple_set_Jprojective_coordinates_GFp
 #define ec_GFp_simple_set_Jprojective_coordinates_GFp \
                                                 ec_GFp_smp_set_Jproj_coords_GFp

+ 6 - 0
openssl/crypto/ui/ui_openssl.c

@@ -122,9 +122,15 @@
  * sigaction and fileno included. -pedantic would be more appropriate for
  * the intended purposes, but we can't prevent users from adding -ansi.
  */
+#if defined(OPENSSL_SYSNAME_VXWORKS)
+#include <sys/types.h>
+#endif
+
 #if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS)
+#ifndef _POSIX_C_SOURCE
 #define _POSIX_C_SOURCE 2
 #endif
+#endif
 #include <signal.h>
 #include <stdio.h>
 #include <string.h>

+ 7 - 8
openssl/crypto/x509/x509_cmp.c

@@ -86,10 +86,9 @@ unsigned long X509_issuer_and_serial_hash(X509 *a)
 
 	EVP_MD_CTX_init(&ctx);
 	f=X509_NAME_oneline(a->cert_info->issuer,NULL,0);
-	ret=strlen(f);
 	if (!EVP_DigestInit_ex(&ctx, EVP_md5(), NULL))
 		goto err;
-	if (!EVP_DigestUpdate(&ctx,(unsigned char *)f,ret))
+	if (!EVP_DigestUpdate(&ctx,(unsigned char *)f,strlen(f)))
 		goto err;
 	OPENSSL_free(f);
 	if(!EVP_DigestUpdate(&ctx,(unsigned char *)a->cert_info->serialNumber->data,
@@ -249,14 +248,14 @@ unsigned long X509_NAME_hash_old(X509_NAME *x)
 	i2d_X509_NAME(x,NULL);
 	EVP_MD_CTX_init(&md_ctx);
 	EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
-	EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL);
-	EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length);
-	EVP_DigestFinal_ex(&md_ctx,md,NULL);
+	if (EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL)
+	    && EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length)
+	    && EVP_DigestFinal_ex(&md_ctx,md,NULL))
+		ret=(((unsigned long)md[0]     )|((unsigned long)md[1]<<8L)|
+		     ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
+		     )&0xffffffffL;
 	EVP_MD_CTX_cleanup(&md_ctx);
 
-	ret=(	((unsigned long)md[0]     )|((unsigned long)md[1]<<8L)|
-		((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
-		)&0xffffffffL;
 	return(ret);
 	}
 #endif

+ 2 - 2
openssl/crypto/x509/x509_vfy.c

@@ -872,7 +872,7 @@ static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid)
 	{
 	ASN1_OCTET_STRING *exta, *extb;
 	int i;
-	i = X509_CRL_get_ext_by_NID(a, nid, 0);
+	i = X509_CRL_get_ext_by_NID(a, nid, -1);
 	if (i >= 0)
 		{
 		/* Can't have multiple occurrences */
@@ -883,7 +883,7 @@ static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid)
 	else
 		exta = NULL;
 
-	i = X509_CRL_get_ext_by_NID(b, nid, 0);
+	i = X509_CRL_get_ext_by_NID(b, nid, -1);
 
 	if (i >= 0)
 		{

+ 2 - 2
openssl/crypto/x509v3/v3_purp.c

@@ -474,11 +474,11 @@ static void x509v3_cache_extensions(X509 *x)
 	for (i = 0; i < X509_get_ext_count(x); i++)
 		{
 		ex = X509_get_ext(x, i);
-		if (!X509_EXTENSION_get_critical(ex))
-			continue;
 		if (OBJ_obj2nid(X509_EXTENSION_get_object(ex))
 					== NID_freshest_crl)
 			x->ex_flags |= EXFLAG_FRESHEST;
+		if (!X509_EXTENSION_get_critical(ex))
+			continue;
 		if (!X509_supported_extension(ex))
 			{
 			x->ex_flags |= EXFLAG_CRITICAL;

+ 15 - 44
openssl/ssl/d1_enc.c

@@ -126,20 +126,28 @@
 #include <openssl/des.h>
 #endif
 
+/* dtls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively.
+ *
+ * Returns:
+ *   0: (in non-constant time) if the record is publically invalid (i.e. too
+ *       short etc).
+ *   1: if the record's padding is valid / the encryption was successful.
+ *   -1: if the record's padding/AEAD-authenticator is invalid or, if sending,
+ *       an internal error occured. */
 int dtls1_enc(SSL *s, int send)
 	{
 	SSL3_RECORD *rec;
 	EVP_CIPHER_CTX *ds;
 	unsigned long l;
-	int bs,i,ii,j,k,n=0;
+	int bs,i,j,k,mac_size=0;
 	const EVP_CIPHER *enc;
 
 	if (send)
 		{
 		if (EVP_MD_CTX_md(s->write_hash))
 			{
-			n=EVP_MD_CTX_size(s->write_hash);
-			if (n < 0)
+			mac_size=EVP_MD_CTX_size(s->write_hash);
+			if (mac_size < 0)
 				return -1;
 			}
 		ds=s->enc_write_ctx;
@@ -164,9 +172,8 @@ int dtls1_enc(SSL *s, int send)
 		{
 		if (EVP_MD_CTX_md(s->read_hash))
 			{
-			n=EVP_MD_CTX_size(s->read_hash);
-			if (n < 0)
-				return -1;
+			mac_size=EVP_MD_CTX_size(s->read_hash);
+			OPENSSL_assert(mac_size >= 0);
 			}
 		ds=s->enc_read_ctx;
 		rec= &(s->s3->rrec);
@@ -231,7 +238,7 @@ int dtls1_enc(SSL *s, int send)
 		if (!send)
 			{
 			if (l == 0 || l%bs != 0)
-				return -1;
+				return 0;
 			}
 		
 		EVP_Cipher(ds,rec->data,rec->input,l);
@@ -246,43 +253,7 @@ int dtls1_enc(SSL *s, int send)
 #endif	/* KSSL_DEBUG */
 
 		if ((bs != 1) && !send)
-			{
-			ii=i=rec->data[l-1]; /* padding_length */
-			i++;
-			if (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG)
-				{
-				/* First packet is even in size, so check */
-				if ((memcmp(s->s3->read_sequence,
-					"\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1))
-					s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG;
-				if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
-					i--;
-				}
-			/* TLS 1.0 does not bound the number of padding bytes by the block size.
-			 * All of them must have value 'padding_length'. */
-			if (i + bs > (int)rec->length)
-				{
-				/* Incorrect padding. SSLerr() and ssl3_alert are done
-				 * by caller: we don't want to reveal whether this is
-				 * a decryption error or a MAC verification failure
-				 * (see http://www.openssl.org/~bodo/tls-cbc.txt) 
-				 */
-				return -1;
-				}
-			for (j=(int)(l-i); j<(int)l; j++)
-				{
-				if (rec->data[j] != ii)
-					{
-					/* Incorrect padding */
-					return -1;
-					}
-				}
-			rec->length-=i;
-
-			rec->data += bs;    /* skip the implicit IV */
-			rec->input += bs;
-			rec->length -= bs;
-			}
+			return tls1_cbc_remove_padding(s, rec, bs, mac_size);
 		}
 	return(1);
 	}

+ 54 - 37
openssl/ssl/d1_pkt.c

@@ -376,15 +376,11 @@ static int
 dtls1_process_record(SSL *s)
 {
 	int i,al;
-	int clear=0;
 	int enc_err;
 	SSL_SESSION *sess;
 	SSL3_RECORD *rr;
-	unsigned int mac_size;
+	unsigned int mac_size, orig_len;
 	unsigned char md[EVP_MAX_MD_SIZE];
-	int decryption_failed_or_bad_record_mac = 0;
-	unsigned char *mac = NULL;
-
 
 	rr= &(s->s3->rrec);
 	sess = s->session;
@@ -416,12 +412,16 @@ dtls1_process_record(SSL *s)
 	rr->data=rr->input;
 
 	enc_err = s->method->ssl3_enc->enc(s,0);
-	if (enc_err <= 0)
+	/* enc_err is:
+	 *    0: (in non-constant time) if the record is publically invalid.
+	 *    1: if the padding is valid
+	 *    -1: if the padding is invalid */
+	if (enc_err == 0)
 		{
-		/* To minimize information leaked via timing, we will always
-		 * perform all computations before discarding the message.
-		 */
-		decryption_failed_or_bad_record_mac = 1;
+		/* For DTLS we simply ignore bad packets. */
+		rr->length = 0;
+		s->packet_length = 0;
+		goto err;
 		}
 
 #ifdef TLS_DEBUG
@@ -431,45 +431,62 @@ printf("\n");
 #endif
 
 	/* r->length is now the compressed data plus mac */
-	if (	(sess == NULL) ||
-		(s->enc_read_ctx == NULL) ||
-		(s->read_hash == NULL))
-		clear=1;
-
-	if (!clear)
+	if ((sess != NULL) &&
+	    (s->enc_read_ctx != NULL) &&
+	    (EVP_MD_CTX_md(s->read_hash) != NULL))
 		{
-		/* !clear => s->read_hash != NULL => mac_size != -1 */
-		int t;
-		t=EVP_MD_CTX_size(s->read_hash);
-		OPENSSL_assert(t >= 0);
-		mac_size=t;
-
-		if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size)
+		/* s->read_hash != NULL => mac_size != -1 */
+		unsigned char *mac = NULL;
+		unsigned char mac_tmp[EVP_MAX_MD_SIZE];
+		mac_size=EVP_MD_CTX_size(s->read_hash);
+		OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE);
+
+		/* kludge: *_cbc_remove_padding passes padding length in rr->type */
+		orig_len = rr->length+((unsigned int)rr->type>>8);
+
+		/* orig_len is the length of the record before any padding was
+		 * removed. This is public information, as is the MAC in use,
+		 * therefore we can safely process the record in a different
+		 * amount of time if it's too short to possibly contain a MAC.
+		 */
+		if (orig_len < mac_size ||
+		    /* CBC records must have a padding length byte too. */
+		    (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
+		     orig_len < mac_size+1))
 			{
-#if 0 /* OK only for stream ciphers (then rr->length is visible from ciphertext anyway) */
-			al=SSL_AD_RECORD_OVERFLOW;
-			SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG);
+			al=SSL_AD_DECODE_ERROR;
+			SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_LENGTH_TOO_SHORT);
 			goto f_err;
-#else
-			decryption_failed_or_bad_record_mac = 1;
-#endif			
 			}
-		/* check the MAC for rr->input (it's in mac_size bytes at the tail) */
-		if (rr->length >= mac_size)
+
+		if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE)
 			{
+			/* We update the length so that the TLS header bytes
+			 * can be constructed correctly but we need to extract
+			 * the MAC in constant time from within the record,
+			 * without leaking the contents of the padding bytes.
+			 * */
+			mac = mac_tmp;
+			ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len);
 			rr->length -= mac_size;
-			mac = &rr->data[rr->length];
 			}
 		else
-			rr->length = 0;
-		i=s->method->ssl3_enc->mac(s,md,0);
-		if (i < 0 || mac == NULL || memcmp(md, mac, mac_size) != 0)
 			{
-			decryption_failed_or_bad_record_mac = 1;
+			/* In this case there's no padding, so |orig_len|
+			 * equals |rec->length| and we checked that there's
+			 * enough bytes for |mac_size| above. */
+			rr->length -= mac_size;
+			mac = &rr->data[rr->length];
 			}
+
+		i=s->method->ssl3_enc->mac(s,md,0 /* not send */);
+		if (i < 0 || mac == NULL || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0)
+			enc_err = -1;
+		if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size)
+			enc_err = -1;
 		}
 
-	if (decryption_failed_or_bad_record_mac)
+	if (enc_err < 0)
 		{
 		/* decryption failed, silently discard message */
 		rr->length = 0;

+ 3 - 2
openssl/ssl/d1_srtp.c

@@ -115,11 +115,12 @@
   Copyright (C) 2011, RTFM, Inc.
 */
 
-#ifndef OPENSSL_NO_SRTP
-
 #include <stdio.h>
 #include <openssl/objects.h>
 #include "ssl_locl.h"
+
+#ifndef OPENSSL_NO_SRTP
+
 #include "srtp.h"
 
 

+ 6 - 2
openssl/ssl/dtls1.h

@@ -57,8 +57,8 @@
  *
  */
 
-#ifndef HEADER_DTLS1_H 
-#define HEADER_DTLS1_H 
+#ifndef HEADER_DTLS1_H
+#define HEADER_DTLS1_H
 
 #include <openssl/buffer.h>
 #include <openssl/pqueue.h>
@@ -72,8 +72,12 @@
 #elif defined(OPENSSL_SYS_NETWARE) && !defined(_WINSOCK2API_)
 #include <sys/timeval.h>
 #else
+#if defined(OPENSSL_SYS_VXWORKS)
+#include <sys/times.h>
+#else
 #include <sys/time.h>
 #endif
+#endif
 
 #ifdef  __cplusplus
 extern "C" {

+ 8 - 6
openssl/ssl/s2_clnt.c

@@ -359,12 +359,14 @@ static int get_server_hello(SSL *s)
 					SSL_R_PEER_ERROR);
 			return(-1);
 			}
-#ifdef __APPLE_CC__
-		/* The Rhapsody 5.5 (a.k.a. MacOS X) compiler bug
-		 * workaround. <[email protected]> */
-		s->hit=(i=*(p++))?1:0;
-#else
+#if 0
 		s->hit=(*(p++))?1:0;
+		/* Some [PPC?] compilers fail to increment p in above
+		   statement, e.g. one provided with Rhapsody 5.5, but
+		   most recent example XL C 11.1 for AIX, even without
+		   optimization flag... */
+#else
+		s->hit=(*p)?1:0; p++;
 #endif
 		s->s2->tmp.cert_type= *(p++);
 		n2s(p,i);
@@ -937,7 +939,7 @@ static int get_server_verify(SSL *s)
 		s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* SERVER-VERIFY */
 	p += 1;
 
-	if (memcmp(p,s->s2->challenge,s->s2->challenge_length) != 0)
+	if (CRYPTO_memcmp(p,s->s2->challenge,s->s2->challenge_length) != 0)
 		{
 		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
 		SSLerr(SSL_F_GET_SERVER_VERIFY,SSL_R_CHALLENGE_IS_DIFFERENT);

+ 1 - 2
openssl/ssl/s2_pkt.c

@@ -269,8 +269,7 @@ static int ssl2_read_internal(SSL *s, void *buf, int len, int peek)
 			s->s2->ract_data_length-=mac_size;
 			ssl2_mac(s,mac,0);
 			s->s2->ract_data_length-=s->s2->padding;
-			if (	(memcmp(mac,s->s2->mac_data,
-				(unsigned int)mac_size) != 0) ||
+			if (	(CRYPTO_memcmp(mac,s->s2->mac_data,mac_size) != 0) ||
 				(s->s2->rlength%EVP_CIPHER_CTX_block_size(s->enc_read_ctx) != 0))
 				{
 				SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_BAD_MAC_DECODE);

+ 11 - 5
openssl/ssl/s2_srvr.c

@@ -1059,10 +1059,12 @@ static int request_certificate(SSL *s)
 		EVP_PKEY *pkey=NULL;
 
 		EVP_MD_CTX_init(&ctx);
-		EVP_VerifyInit_ex(&ctx,s->ctx->rsa_md5, NULL);
-		EVP_VerifyUpdate(&ctx,s->s2->key_material,
-				 s->s2->key_material_length);
-		EVP_VerifyUpdate(&ctx,ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH);
+		if (!EVP_VerifyInit_ex(&ctx,s->ctx->rsa_md5, NULL)
+		    || !EVP_VerifyUpdate(&ctx,s->s2->key_material,
+					 s->s2->key_material_length)
+		    || !EVP_VerifyUpdate(&ctx,ccd,
+					 SSL2_MIN_CERT_CHALLENGE_LENGTH))
+			goto msg_end;
 
 		i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,NULL);
 		buf2=OPENSSL_malloc((unsigned int)i);
@@ -1073,7 +1075,11 @@ static int request_certificate(SSL *s)
 			}
 		p2=buf2;
 		i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,&p2);
-		EVP_VerifyUpdate(&ctx,buf2,(unsigned int)i);
+		if (!EVP_VerifyUpdate(&ctx,buf2,(unsigned int)i))
+			{
+			OPENSSL_free(buf2);
+			goto msg_end;
+			}
 		OPENSSL_free(buf2);
 
 		pkey=X509_get_pubkey(x509);

+ 9 - 5
openssl/ssl/s3_both.c

@@ -204,7 +204,8 @@ int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
 
 #ifndef OPENSSL_NO_NEXTPROTONEG
 /* ssl3_take_mac calculates the Finished MAC for the handshakes messages seen to far. */
-static void ssl3_take_mac(SSL *s) {
+static void ssl3_take_mac(SSL *s)
+	{
 	const char *sender;
 	int slen;
 
@@ -221,7 +222,7 @@ static void ssl3_take_mac(SSL *s) {
 
 	s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
 		sender,slen,s->s3->tmp.peer_finish_md);
-}
+	}
 #endif
 
 int ssl3_get_finished(SSL *s, int a, int b)
@@ -231,8 +232,9 @@ int ssl3_get_finished(SSL *s, int a, int b)
 	unsigned char *p;
 
 #ifdef OPENSSL_NO_NEXTPROTONEG
-	/* the mac has already been generated when we received the change
-	 * cipher spec message and is in s->s3->tmp.peer_finish_md. */
+	/* the mac has already been generated when we received the
+	 * change cipher spec message and is in s->s3->tmp.peer_finish_md.
+	 */ 
 #endif
 
 	n=s->method->ssl_get_message(s,
@@ -263,7 +265,7 @@ int ssl3_get_finished(SSL *s, int a, int b)
 		goto f_err;
 		}
 
-	if (memcmp(p, s->s3->tmp.peer_finish_md, i) != 0)
+	if (CRYPTO_memcmp(p, s->s3->tmp.peer_finish_md, i) != 0)
 		{
 		al=SSL_AD_DECRYPT_ERROR;
 		SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_DIGEST_CHECK_FAILED);
@@ -537,12 +539,14 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
 		s->init_num += i;
 		n -= i;
 		}
+
 #ifndef OPENSSL_NO_NEXTPROTONEG
 	/* If receiving Finished, record MAC of prior handshake messages for
 	 * Finished verification. */
 	if (*s->init_buf->data == SSL3_MT_FINISHED)
 		ssl3_take_mac(s);
 #endif
+
 	/* Feed this message into MAC computation. */
 	ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num + 4);
 	if (s->msg_callback)

+ 790 - 0
openssl/ssl/s3_cbc.c

@@ -0,0 +1,790 @@
+/* ssl/s3_cbc.c */
+/* ====================================================================
+ * Copyright (c) 2012 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    [email protected].
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+
+#include "ssl_locl.h"
+
+#include <openssl/md5.h>
+#include <openssl/sha.h>
+
+/* MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's length
+ * field. (SHA-384/512 have 128-bit length.) */
+#define MAX_HASH_BIT_COUNT_BYTES 16
+
+/* MAX_HASH_BLOCK_SIZE is the maximum hash block size that we'll support.
+ * Currently SHA-384/512 has a 128-byte block size and that's the largest
+ * supported by TLS.) */
+#define MAX_HASH_BLOCK_SIZE 128
+
+/* Some utility functions are needed:
+ *
+ * These macros return the given value with the MSB copied to all the other
+ * bits. They use the fact that arithmetic shift shifts-in the sign bit.
+ * However, this is not ensured by the C standard so you may need to replace
+ * them with something else on odd CPUs. */
+#define DUPLICATE_MSB_TO_ALL(x) ( (unsigned)( (int)(x) >> (sizeof(int)*8-1) ) )
+#define DUPLICATE_MSB_TO_ALL_8(x) ((unsigned char)(DUPLICATE_MSB_TO_ALL(x)))
+
+/* constant_time_lt returns 0xff if a<b and 0x00 otherwise. */
+static unsigned constant_time_lt(unsigned a, unsigned b)
+	{
+	a -= b;
+	return DUPLICATE_MSB_TO_ALL(a);
+	}
+
+/* constant_time_ge returns 0xff if a>=b and 0x00 otherwise. */
+static unsigned constant_time_ge(unsigned a, unsigned b)
+	{
+	a -= b;
+	return DUPLICATE_MSB_TO_ALL(~a);
+	}
+
+/* constant_time_eq_8 returns 0xff if a==b and 0x00 otherwise. */
+static unsigned char constant_time_eq_8(unsigned a, unsigned b)
+	{
+	unsigned c = a ^ b;
+	c--;
+	return DUPLICATE_MSB_TO_ALL_8(c);
+	}
+
+/* ssl3_cbc_remove_padding removes padding from the decrypted, SSLv3, CBC
+ * record in |rec| by updating |rec->length| in constant time.
+ *
+ * block_size: the block size of the cipher used to encrypt the record.
+ * returns:
+ *   0: (in non-constant time) if the record is publicly invalid.
+ *   1: if the padding was valid
+ *  -1: otherwise. */
+int ssl3_cbc_remove_padding(const SSL* s,
+			    SSL3_RECORD *rec,
+			    unsigned block_size,
+			    unsigned mac_size)
+	{
+	unsigned padding_length, good;
+	const unsigned overhead = 1 /* padding length byte */ + mac_size;
+
+	/* These lengths are all public so we can test them in non-constant
+	 * time. */
+	if (overhead > rec->length)
+		return 0;
+
+	padding_length = rec->data[rec->length-1];
+	good = constant_time_ge(rec->length, padding_length+overhead);
+	/* SSLv3 requires that the padding is minimal. */
+	good &= constant_time_ge(block_size, padding_length+1);
+	padding_length = good & (padding_length+1);
+	rec->length -= padding_length;
+	rec->type |= padding_length<<8;	/* kludge: pass padding length */
+	return (int)((good & 1) | (~good & -1));
+}
+
+/* tls1_cbc_remove_padding removes the CBC padding from the decrypted, TLS, CBC
+ * record in |rec| in constant time and returns 1 if the padding is valid and
+ * -1 otherwise. It also removes any explicit IV from the start of the record
+ * without leaking any timing about whether there was enough space after the
+ * padding was removed.
+ *
+ * block_size: the block size of the cipher used to encrypt the record.
+ * returns:
+ *   0: (in non-constant time) if the record is publicly invalid.
+ *   1: if the padding was valid
+ *  -1: otherwise. */
+int tls1_cbc_remove_padding(const SSL* s,
+			    SSL3_RECORD *rec,
+			    unsigned block_size,
+			    unsigned mac_size)
+	{
+	unsigned padding_length, good, to_check, i;
+	const unsigned overhead = 1 /* padding length byte */ + mac_size;
+	/* Check if version requires explicit IV */
+	if (s->version >= TLS1_1_VERSION || s->version == DTLS1_VERSION)
+		{
+		/* These lengths are all public so we can test them in
+		 * non-constant time.
+		 */
+		if (overhead + block_size > rec->length)
+			return 0;
+		/* We can now safely skip explicit IV */
+		rec->data += block_size;
+		rec->input += block_size;
+		rec->length -= block_size;
+		}
+	else if (overhead > rec->length)
+		return 0;
+
+	padding_length = rec->data[rec->length-1];
+
+	/* NB: if compression is in operation the first packet may not be of
+	 * even length so the padding bug check cannot be performed. This bug
+	 * workaround has been around since SSLeay so hopefully it is either
+	 * fixed now or no buggy implementation supports compression [steve]
+	 */
+	if ( (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG) && !s->expand)
+		{
+		/* First packet is even in size, so check */
+		if ((memcmp(s->s3->read_sequence, "\0\0\0\0\0\0\0\0",8) == 0) &&
+		    !(padding_length & 1))
+			{
+			s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG;
+			}
+		if ((s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) &&
+		    padding_length > 0)
+			{
+			padding_length--;
+			}
+		}
+
+	if (EVP_CIPHER_flags(s->enc_read_ctx->cipher)&EVP_CIPH_FLAG_AEAD_CIPHER)
+		{
+		/* padding is already verified */
+		rec->length -= padding_length + 1;
+		return 1;
+		}
+
+	good = constant_time_ge(rec->length, overhead+padding_length);
+	/* The padding consists of a length byte at the end of the record and
+	 * then that many bytes of padding, all with the same value as the
+	 * length byte. Thus, with the length byte included, there are i+1
+	 * bytes of padding.
+	 *
+	 * We can't check just |padding_length+1| bytes because that leaks
+	 * decrypted information. Therefore we always have to check the maximum
+	 * amount of padding possible. (Again, the length of the record is
+	 * public information so we can use it.) */
+	to_check = 255; /* maximum amount of padding. */
+	if (to_check > rec->length-1)
+		to_check = rec->length-1;
+
+	for (i = 0; i < to_check; i++)
+		{
+		unsigned char mask = constant_time_ge(padding_length, i);
+		unsigned char b = rec->data[rec->length-1-i];
+		/* The final |padding_length+1| bytes should all have the value
+		 * |padding_length|. Therefore the XOR should be zero. */
+		good &= ~(mask&(padding_length ^ b));
+		}
+
+	/* If any of the final |padding_length+1| bytes had the wrong value,
+	 * one or more of the lower eight bits of |good| will be cleared. We
+	 * AND the bottom 8 bits together and duplicate the result to all the
+	 * bits. */
+	good &= good >> 4;
+	good &= good >> 2;
+	good &= good >> 1;
+	good <<= sizeof(good)*8-1;
+	good = DUPLICATE_MSB_TO_ALL(good);
+
+	padding_length = good & (padding_length+1);
+	rec->length -= padding_length;
+	rec->type |= padding_length<<8;	/* kludge: pass padding length */
+
+	return (int)((good & 1) | (~good & -1));
+	}
+
+/* ssl3_cbc_copy_mac copies |md_size| bytes from the end of |rec| to |out| in
+ * constant time (independent of the concrete value of rec->length, which may
+ * vary within a 256-byte window).
+ *
+ * ssl3_cbc_remove_padding or tls1_cbc_remove_padding must be called prior to
+ * this function.
+ *
+ * On entry:
+ *   rec->orig_len >= md_size
+ *   md_size <= EVP_MAX_MD_SIZE
+ *
+ * If CBC_MAC_ROTATE_IN_PLACE is defined then the rotation is performed with
+ * variable accesses in a 64-byte-aligned buffer. Assuming that this fits into
+ * a single or pair of cache-lines, then the variable memory accesses don't
+ * actually affect the timing. CPUs with smaller cache-lines [if any] are
+ * not multi-core and are not considered vulnerable to cache-timing attacks.
+ */
+#define CBC_MAC_ROTATE_IN_PLACE
+
+void ssl3_cbc_copy_mac(unsigned char* out,
+		       const SSL3_RECORD *rec,
+		       unsigned md_size,unsigned orig_len)
+	{
+#if defined(CBC_MAC_ROTATE_IN_PLACE)
+	unsigned char rotated_mac_buf[64+EVP_MAX_MD_SIZE];
+	unsigned char *rotated_mac;
+#else
+	unsigned char rotated_mac[EVP_MAX_MD_SIZE];
+#endif
+
+	/* mac_end is the index of |rec->data| just after the end of the MAC. */
+	unsigned mac_end = rec->length;
+	unsigned mac_start = mac_end - md_size;
+	/* scan_start contains the number of bytes that we can ignore because
+	 * the MAC's position can only vary by 255 bytes. */
+	unsigned scan_start = 0;
+	unsigned i, j;
+	unsigned div_spoiler;
+	unsigned rotate_offset;
+
+	OPENSSL_assert(orig_len >= md_size);
+	OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE);
+
+#if defined(CBC_MAC_ROTATE_IN_PLACE)
+	rotated_mac = rotated_mac_buf + ((0-(size_t)rotated_mac_buf)&63);
+#endif
+
+	/* This information is public so it's safe to branch based on it. */
+	if (orig_len > md_size + 255 + 1)
+		scan_start = orig_len - (md_size + 255 + 1);
+	/* div_spoiler contains a multiple of md_size that is used to cause the
+	 * modulo operation to be constant time. Without this, the time varies
+	 * based on the amount of padding when running on Intel chips at least.
+	 *
+	 * The aim of right-shifting md_size is so that the compiler doesn't
+	 * figure out that it can remove div_spoiler as that would require it
+	 * to prove that md_size is always even, which I hope is beyond it. */
+	div_spoiler = md_size >> 1;
+	div_spoiler <<= (sizeof(div_spoiler)-1)*8;
+	rotate_offset = (div_spoiler + mac_start - scan_start) % md_size;
+
+	memset(rotated_mac, 0, md_size);
+	for (i = scan_start, j = 0; i < orig_len; i++)
+		{
+		unsigned char mac_started = constant_time_ge(i, mac_start);
+		unsigned char mac_ended = constant_time_ge(i, mac_end);
+		unsigned char b = rec->data[i];
+		rotated_mac[j++] |= b & mac_started & ~mac_ended;
+		j &= constant_time_lt(j,md_size);
+		}
+
+	/* Now rotate the MAC */
+#if defined(CBC_MAC_ROTATE_IN_PLACE)
+	j = 0;
+	for (i = 0; i < md_size; i++)
+		{
+		/* in case cache-line is 32 bytes, touch second line */
+		((volatile unsigned char *)rotated_mac)[rotate_offset^32];
+		out[j++] = rotated_mac[rotate_offset++];
+		rotate_offset &= constant_time_lt(rotate_offset,md_size);
+		}
+#else
+	memset(out, 0, md_size);
+	rotate_offset = md_size - rotate_offset;
+	rotate_offset &= constant_time_lt(rotate_offset,md_size);
+	for (i = 0; i < md_size; i++)
+		{
+		for (j = 0; j < md_size; j++)
+			out[j] |= rotated_mac[i] & constant_time_eq_8(j, rotate_offset);
+		rotate_offset++;
+		rotate_offset &= constant_time_lt(rotate_offset,md_size);
+		}
+#endif
+	}
+
+/* u32toLE serialises an unsigned, 32-bit number (n) as four bytes at (p) in
+ * little-endian order. The value of p is advanced by four. */
+#define u32toLE(n, p) \
+	(*((p)++)=(unsigned char)(n), \
+	 *((p)++)=(unsigned char)(n>>8), \
+	 *((p)++)=(unsigned char)(n>>16), \
+	 *((p)++)=(unsigned char)(n>>24))
+
+/* These functions serialize the state of a hash and thus perform the standard
+ * "final" operation without adding the padding and length that such a function
+ * typically does. */
+static void tls1_md5_final_raw(void* ctx, unsigned char *md_out)
+	{
+	MD5_CTX *md5 = ctx;
+	u32toLE(md5->A, md_out);
+	u32toLE(md5->B, md_out);
+	u32toLE(md5->C, md_out);
+	u32toLE(md5->D, md_out);
+	}
+
+static void tls1_sha1_final_raw(void* ctx, unsigned char *md_out)
+	{
+	SHA_CTX *sha1 = ctx;
+	l2n(sha1->h0, md_out);
+	l2n(sha1->h1, md_out);
+	l2n(sha1->h2, md_out);
+	l2n(sha1->h3, md_out);
+	l2n(sha1->h4, md_out);
+	}
+#define LARGEST_DIGEST_CTX SHA_CTX
+
+#ifndef OPENSSL_NO_SHA256
+static void tls1_sha256_final_raw(void* ctx, unsigned char *md_out)
+	{
+	SHA256_CTX *sha256 = ctx;
+	unsigned i;
+
+	for (i = 0; i < 8; i++)
+		{
+		l2n(sha256->h[i], md_out);
+		}
+	}
+#undef  LARGEST_DIGEST_CTX
+#define LARGEST_DIGEST_CTX SHA256_CTX
+#endif
+
+#ifndef OPENSSL_NO_SHA512
+static void tls1_sha512_final_raw(void* ctx, unsigned char *md_out)
+	{
+	SHA512_CTX *sha512 = ctx;
+	unsigned i;
+
+	for (i = 0; i < 8; i++)
+		{
+		l2n8(sha512->h[i], md_out);
+		}
+	}
+#undef  LARGEST_DIGEST_CTX
+#define LARGEST_DIGEST_CTX SHA512_CTX
+#endif
+
+/* ssl3_cbc_record_digest_supported returns 1 iff |ctx| uses a hash function
+ * which ssl3_cbc_digest_record supports. */
+char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx)
+	{
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode())
+		return 0;
+#endif
+	switch (EVP_MD_CTX_type(ctx))
+		{
+		case NID_md5:
+		case NID_sha1:
+#ifndef OPENSSL_NO_SHA256
+		case NID_sha224:
+		case NID_sha256:
+#endif
+#ifndef OPENSSL_NO_SHA512
+		case NID_sha384:
+		case NID_sha512:
+#endif
+			return 1;
+		default:
+			return 0;
+		}
+	}
+
+/* ssl3_cbc_digest_record computes the MAC of a decrypted, padded SSLv3/TLS
+ * record.
+ *
+ *   ctx: the EVP_MD_CTX from which we take the hash function.
+ *     ssl3_cbc_record_digest_supported must return true for this EVP_MD_CTX.
+ *   md_out: the digest output. At most EVP_MAX_MD_SIZE bytes will be written.
+ *   md_out_size: if non-NULL, the number of output bytes is written here.
+ *   header: the 13-byte, TLS record header.
+ *   data: the record data itself, less any preceeding explicit IV.
+ *   data_plus_mac_size: the secret, reported length of the data and MAC
+ *     once the padding has been removed.
+ *   data_plus_mac_plus_padding_size: the public length of the whole
+ *     record, including padding.
+ *   is_sslv3: non-zero if we are to use SSLv3. Otherwise, TLS.
+ *
+ * On entry: by virtue of having been through one of the remove_padding
+ * functions, above, we know that data_plus_mac_size is large enough to contain
+ * a padding byte and MAC. (If the padding was invalid, it might contain the
+ * padding too. ) */
+void ssl3_cbc_digest_record(
+	const EVP_MD_CTX *ctx,
+	unsigned char* md_out,
+	size_t* md_out_size,
+	const unsigned char header[13],
+	const unsigned char *data,
+	size_t data_plus_mac_size,
+	size_t data_plus_mac_plus_padding_size,
+	const unsigned char *mac_secret,
+	unsigned mac_secret_length,
+	char is_sslv3)
+	{
+	union {	double align;
+		unsigned char c[sizeof(LARGEST_DIGEST_CTX)]; } md_state;
+	void (*md_final_raw)(void *ctx, unsigned char *md_out);
+	void (*md_transform)(void *ctx, const unsigned char *block);
+	unsigned md_size, md_block_size = 64;
+	unsigned sslv3_pad_length = 40, header_length, variance_blocks,
+		 len, max_mac_bytes, num_blocks,
+		 num_starting_blocks, k, mac_end_offset, c, index_a, index_b;
+	unsigned int bits;	/* at most 18 bits */
+	unsigned char length_bytes[MAX_HASH_BIT_COUNT_BYTES];
+	/* hmac_pad is the masked HMAC key. */
+	unsigned char hmac_pad[MAX_HASH_BLOCK_SIZE];
+	unsigned char first_block[MAX_HASH_BLOCK_SIZE];
+	unsigned char mac_out[EVP_MAX_MD_SIZE];
+	unsigned i, j, md_out_size_u;
+	EVP_MD_CTX md_ctx;
+	/* mdLengthSize is the number of bytes in the length field that terminates
+	* the hash. */
+	unsigned md_length_size = 8;
+	char length_is_big_endian = 1;
+
+	/* This is a, hopefully redundant, check that allows us to forget about
+	 * many possible overflows later in this function. */
+	OPENSSL_assert(data_plus_mac_plus_padding_size < 1024*1024);
+
+	switch (EVP_MD_CTX_type(ctx))
+		{
+		case NID_md5:
+			MD5_Init((MD5_CTX*)md_state.c);
+			md_final_raw = tls1_md5_final_raw;
+			md_transform = (void(*)(void *ctx, const unsigned char *block)) MD5_Transform;
+			md_size = 16;
+			sslv3_pad_length = 48;
+			length_is_big_endian = 0;
+			break;
+		case NID_sha1:
+			SHA1_Init((SHA_CTX*)md_state.c);
+			md_final_raw = tls1_sha1_final_raw;
+			md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA1_Transform;
+			md_size = 20;
+			break;
+#ifndef OPENSSL_NO_SHA256
+		case NID_sha224:
+			SHA224_Init((SHA256_CTX*)md_state.c);
+			md_final_raw = tls1_sha256_final_raw;
+			md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA256_Transform;
+			md_size = 224/8;
+			break;
+		case NID_sha256:
+			SHA256_Init((SHA256_CTX*)md_state.c);
+			md_final_raw = tls1_sha256_final_raw;
+			md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA256_Transform;
+			md_size = 32;
+			break;
+#endif
+#ifndef OPENSSL_NO_SHA512
+		case NID_sha384:
+			SHA384_Init((SHA512_CTX*)md_state.c);
+			md_final_raw = tls1_sha512_final_raw;
+			md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA512_Transform;
+			md_size = 384/8;
+			md_block_size = 128;
+			md_length_size = 16;
+			break;
+		case NID_sha512:
+			SHA512_Init((SHA512_CTX*)md_state.c);
+			md_final_raw = tls1_sha512_final_raw;
+			md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA512_Transform;
+			md_size = 64;
+			md_block_size = 128;
+			md_length_size = 16;
+			break;
+#endif
+		default:
+			/* ssl3_cbc_record_digest_supported should have been
+			 * called first to check that the hash function is
+			 * supported. */
+			OPENSSL_assert(0);
+			if (md_out_size)
+				*md_out_size = -1;
+			return;
+		}
+
+	OPENSSL_assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES);
+	OPENSSL_assert(md_block_size <= MAX_HASH_BLOCK_SIZE);
+	OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE);
+
+	header_length = 13;
+	if (is_sslv3)
+		{
+		header_length =
+			mac_secret_length +
+			sslv3_pad_length +
+			8 /* sequence number */ +
+			1 /* record type */ +
+			2 /* record length */;
+		}
+
+	/* variance_blocks is the number of blocks of the hash that we have to
+	 * calculate in constant time because they could be altered by the
+	 * padding value.
+	 *
+	 * In SSLv3, the padding must be minimal so the end of the plaintext
+	 * varies by, at most, 15+20 = 35 bytes. (We conservatively assume that
+	 * the MAC size varies from 0..20 bytes.) In case the 9 bytes of hash
+	 * termination (0x80 + 64-bit length) don't fit in the final block, we
+	 * say that the final two blocks can vary based on the padding.
+	 *
+	 * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not
+	 * required to be minimal. Therefore we say that the final six blocks
+	 * can vary based on the padding.
+	 *
+	 * Later in the function, if the message is short and there obviously
+	 * cannot be this many blocks then variance_blocks can be reduced. */
+	variance_blocks = is_sslv3 ? 2 : 6;
+	/* From now on we're dealing with the MAC, which conceptually has 13
+	 * bytes of `header' before the start of the data (TLS) or 71/75 bytes
+	 * (SSLv3) */
+	len = data_plus_mac_plus_padding_size + header_length;
+	/* max_mac_bytes contains the maximum bytes of bytes in the MAC, including
+	* |header|, assuming that there's no padding. */
+	max_mac_bytes = len - md_size - 1;
+	/* num_blocks is the maximum number of hash blocks. */
+	num_blocks = (max_mac_bytes + 1 + md_length_size + md_block_size - 1) / md_block_size;
+	/* In order to calculate the MAC in constant time we have to handle
+	 * the final blocks specially because the padding value could cause the
+	 * end to appear somewhere in the final |variance_blocks| blocks and we
+	 * can't leak where. However, |num_starting_blocks| worth of data can
+	 * be hashed right away because no padding value can affect whether
+	 * they are plaintext. */
+	num_starting_blocks = 0;
+	/* k is the starting byte offset into the conceptual header||data where
+	 * we start processing. */
+	k = 0;
+	/* mac_end_offset is the index just past the end of the data to be
+	 * MACed. */
+	mac_end_offset = data_plus_mac_size + header_length - md_size;
+	/* c is the index of the 0x80 byte in the final hash block that
+	 * contains application data. */
+	c = mac_end_offset % md_block_size;
+	/* index_a is the hash block number that contains the 0x80 terminating
+	 * value. */
+	index_a = mac_end_offset / md_block_size;
+	/* index_b is the hash block number that contains the 64-bit hash
+	 * length, in bits. */
+	index_b = (mac_end_offset + md_length_size) / md_block_size;
+	/* bits is the hash-length in bits. It includes the additional hash
+	 * block for the masked HMAC key, or whole of |header| in the case of
+	 * SSLv3. */
+
+	/* For SSLv3, if we're going to have any starting blocks then we need
+	 * at least two because the header is larger than a single block. */
+	if (num_blocks > variance_blocks + (is_sslv3 ? 1 : 0))
+		{
+		num_starting_blocks = num_blocks - variance_blocks;
+		k = md_block_size*num_starting_blocks;
+		}
+
+	bits = 8*mac_end_offset;
+	if (!is_sslv3)
+		{
+		/* Compute the initial HMAC block. For SSLv3, the padding and
+		 * secret bytes are included in |header| because they take more
+		 * than a single block. */
+		bits += 8*md_block_size;
+		memset(hmac_pad, 0, md_block_size);
+		OPENSSL_assert(mac_secret_length <= sizeof(hmac_pad));
+		memcpy(hmac_pad, mac_secret, mac_secret_length);
+		for (i = 0; i < md_block_size; i++)
+			hmac_pad[i] ^= 0x36;
+
+		md_transform(md_state.c, hmac_pad);
+		}
+
+	if (length_is_big_endian)
+		{
+		memset(length_bytes,0,md_length_size-4);
+		length_bytes[md_length_size-4] = (unsigned char)(bits>>24);
+		length_bytes[md_length_size-3] = (unsigned char)(bits>>16);
+		length_bytes[md_length_size-2] = (unsigned char)(bits>>8);
+		length_bytes[md_length_size-1] = (unsigned char)bits;
+		}
+	else
+		{
+		memset(length_bytes,0,md_length_size);
+		length_bytes[md_length_size-5] = (unsigned char)(bits>>24);
+		length_bytes[md_length_size-6] = (unsigned char)(bits>>16);
+		length_bytes[md_length_size-7] = (unsigned char)(bits>>8);
+		length_bytes[md_length_size-8] = (unsigned char)bits;
+		}
+
+	if (k > 0)
+		{
+		if (is_sslv3)
+			{
+			/* The SSLv3 header is larger than a single block.
+			 * overhang is the number of bytes beyond a single
+			 * block that the header consumes: either 7 bytes
+			 * (SHA1) or 11 bytes (MD5). */
+			unsigned overhang = header_length-md_block_size;
+			md_transform(md_state.c, header);
+			memcpy(first_block, header + md_block_size, overhang);
+			memcpy(first_block + overhang, data, md_block_size-overhang);
+			md_transform(md_state.c, first_block);
+			for (i = 1; i < k/md_block_size - 1; i++)
+				md_transform(md_state.c, data + md_block_size*i - overhang);
+			}
+		else
+			{
+			/* k is a multiple of md_block_size. */
+			memcpy(first_block, header, 13);
+			memcpy(first_block+13, data, md_block_size-13);
+			md_transform(md_state.c, first_block);
+			for (i = 1; i < k/md_block_size; i++)
+				md_transform(md_state.c, data + md_block_size*i - 13);
+			}
+		}
+
+	memset(mac_out, 0, sizeof(mac_out));
+
+	/* We now process the final hash blocks. For each block, we construct
+	 * it in constant time. If the |i==index_a| then we'll include the 0x80
+	 * bytes and zero pad etc. For each block we selectively copy it, in
+	 * constant time, to |mac_out|. */
+	for (i = num_starting_blocks; i <= num_starting_blocks+variance_blocks; i++)
+		{
+		unsigned char block[MAX_HASH_BLOCK_SIZE];
+		unsigned char is_block_a = constant_time_eq_8(i, index_a);
+		unsigned char is_block_b = constant_time_eq_8(i, index_b);
+		for (j = 0; j < md_block_size; j++)
+			{
+			unsigned char b = 0, is_past_c, is_past_cp1;
+			if (k < header_length)
+				b = header[k];
+			else if (k < data_plus_mac_plus_padding_size + header_length)
+				b = data[k-header_length];
+			k++;
+
+			is_past_c = is_block_a & constant_time_ge(j, c);
+			is_past_cp1 = is_block_a & constant_time_ge(j, c+1);
+			/* If this is the block containing the end of the
+			 * application data, and we are at the offset for the
+			 * 0x80 value, then overwrite b with 0x80. */
+			b = (b&~is_past_c) | (0x80&is_past_c);
+			/* If this the the block containing the end of the
+			 * application data and we're past the 0x80 value then
+			 * just write zero. */
+			b = b&~is_past_cp1;
+			/* If this is index_b (the final block), but not
+			 * index_a (the end of the data), then the 64-bit
+			 * length didn't fit into index_a and we're having to
+			 * add an extra block of zeros. */
+			b &= ~is_block_b | is_block_a;
+
+			/* The final bytes of one of the blocks contains the
+			 * length. */
+			if (j >= md_block_size - md_length_size)
+				{
+				/* If this is index_b, write a length byte. */
+				b = (b&~is_block_b) | (is_block_b&length_bytes[j-(md_block_size-md_length_size)]);
+				}
+			block[j] = b;
+			}
+
+		md_transform(md_state.c, block);
+		md_final_raw(md_state.c, block);
+		/* If this is index_b, copy the hash value to |mac_out|. */
+		for (j = 0; j < md_size; j++)
+			mac_out[j] |= block[j]&is_block_b;
+		}
+
+	EVP_MD_CTX_init(&md_ctx);
+	EVP_DigestInit_ex(&md_ctx, ctx->digest, NULL /* engine */);
+	if (is_sslv3)
+		{
+		/* We repurpose |hmac_pad| to contain the SSLv3 pad2 block. */
+		memset(hmac_pad, 0x5c, sslv3_pad_length);
+
+		EVP_DigestUpdate(&md_ctx, mac_secret, mac_secret_length);
+		EVP_DigestUpdate(&md_ctx, hmac_pad, sslv3_pad_length);
+		EVP_DigestUpdate(&md_ctx, mac_out, md_size);
+		}
+	else
+		{
+		/* Complete the HMAC in the standard manner. */
+		for (i = 0; i < md_block_size; i++)
+			hmac_pad[i] ^= 0x6a;
+
+		EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size);
+		EVP_DigestUpdate(&md_ctx, mac_out, md_size);
+		}
+	EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u);
+	if (md_out_size)
+		*md_out_size = md_out_size_u;
+	EVP_MD_CTX_cleanup(&md_ctx);
+	}
+
+#ifdef OPENSSL_FIPS
+
+/* Due to the need to use EVP in FIPS mode we can't reimplement digests but
+ * we can ensure the number of blocks processed is equal for all cases
+ * by digesting additional data.
+ */
+
+void tls_fips_digest_extra(
+	const EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *mac_ctx,
+	const unsigned char *data, size_t data_len, size_t orig_len)
+	{
+	size_t block_size, digest_pad, blocks_data, blocks_orig;
+	if (EVP_CIPHER_CTX_mode(cipher_ctx) != EVP_CIPH_CBC_MODE)
+		return;
+	block_size = EVP_MD_CTX_block_size(mac_ctx);
+	/* We are in FIPS mode if we get this far so we know we have only SHA*
+	 * digests and TLS to deal with.
+	 * Minimum digest padding length is 17 for SHA384/SHA512 and 9
+	 * otherwise.
+	 * Additional header is 13 bytes. To get the number of digest blocks
+	 * processed round up the amount of data plus padding to the nearest
+	 * block length. Block length is 128 for SHA384/SHA512 and 64 otherwise.
+	 * So we have:
+	 * blocks = (payload_len + digest_pad + 13 + block_size - 1)/block_size
+	 * equivalently:
+	 * blocks = (payload_len + digest_pad + 12)/block_size + 1
+	 * HMAC adds a constant overhead.
+	 * We're ultimately only interested in differences so this becomes
+	 * blocks = (payload_len + 29)/128
+	 * for SHA384/SHA512 and
+	 * blocks = (payload_len + 21)/64
+	 * otherwise.
+	 */
+	digest_pad = block_size == 64 ? 21 : 29;
+	blocks_orig = (orig_len + digest_pad)/block_size;
+	blocks_data = (data_len + digest_pad)/block_size;
+	/* MAC enough blocks to make up the difference between the original
+	 * and actual lengths plus one extra block to ensure this is never a
+	 * no op. The "data" pointer should always have enough space to
+	 * perform this operation as it is large enough for a maximum
+	 * length TLS buffer. 
+	 */
+	EVP_DigestSignUpdate(mac_ctx, data,
+				(blocks_orig - blocks_data + 1) * block_size);
+	}
+#endif

+ 3 - 1
openssl/ssl/s3_clnt.c

@@ -459,7 +459,6 @@ int ssl3_connect(SSL *s)
 				SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B);
 			if (ret <= 0) goto end;
 
-
 #if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
 			s->state=SSL3_ST_CW_FINISHED_A;
 #else
@@ -987,7 +986,10 @@ int ssl3_get_server_hello(SSL *s)
 	 * client authentication.
 	 */
 	if (TLS1_get_version(s) < TLS1_2_VERSION && !ssl3_digest_cached_records(s))
+		{
+		al = SSL_AD_INTERNAL_ERROR;
 		goto f_err;
+		}
 	/* lets get the compression algorithm */
 	/* COMPRESSION */
 #ifdef OPENSSL_NO_COMP

Some files were not shown because too many files changed in this diff