Martin Prikryl 11 年之前
父节点
当前提交
b8e0750e5a
共有 100 个文件被更改,包括 1022 次插入653 次删除
  1. 1 1
      deployment/WinSCPnet.nuspec
  2. 2 1
      deployment/winscpsetup.iss
  3. 18 4
      dotnet/Session.cs
  4. 3 3
      dotnet/properties/AssemblyInfo.cs
  5. 1 1
      libs/openssl/crypto/LPdir_win.c
  6. 6 1
      libs/openssl/crypto/asn1/a_bitstr.c
  7. 1 1
      libs/openssl/crypto/asn1/a_type.c
  8. 12 0
      libs/openssl/crypto/asn1/a_verify.c
  9. 3 1
      libs/openssl/crypto/asn1/asn1.h
  10. 3 1
      libs/openssl/crypto/asn1/asn1_err.c
  11. 8 0
      libs/openssl/crypto/asn1/tasn_dec.c
  12. 11 0
      libs/openssl/crypto/asn1/x_algor.c
  13. 2 0
      libs/openssl/crypto/asn1/x_name.c
  14. 4 0
      libs/openssl/crypto/bio/bio.h
  15. 3 1
      libs/openssl/crypto/bn/bn.h
  16. 10 6
      libs/openssl/crypto/bn/bn_asm.c
  17. 1 1
      libs/openssl/crypto/bn/bn_ctx.c
  18. 5 3
      libs/openssl/crypto/bn/bn_div.c
  19. 2 2
      libs/openssl/crypto/buildinf.h
  20. 4 14
      libs/openssl/crypto/constant_time_locl.h
  21. 3 12
      libs/openssl/crypto/cversion.c
  22. 13 1
      libs/openssl/crypto/dsa/dsa_asn1.c
  23. 2 4
      libs/openssl/crypto/dso/dso_dlfcn.c
  24. 1 1
      libs/openssl/crypto/ec/ec.h
  25. 5 4
      libs/openssl/crypto/ec/ec2_smpl.c
  26. 8 6
      libs/openssl/crypto/ec/ec_ameth.c
  27. 29 11
      libs/openssl/crypto/ec/ec_asn1.c
  28. 1 1
      libs/openssl/crypto/ec/ec_lib.c
  29. 4 3
      libs/openssl/crypto/ec/ec_mult.c
  30. 6 0
      libs/openssl/crypto/ec/ec_pmeth.c
  31. 5 4
      libs/openssl/crypto/ec/ecp_mont.c
  32. 5 4
      libs/openssl/crypto/ec/ecp_nist.c
  33. 0 1
      libs/openssl/crypto/ec/ecp_nistp256.c
  34. 7 6
      libs/openssl/crypto/ec/ecp_smpl.c
  35. 14 1
      libs/openssl/crypto/ecdsa/ecs_vrf.c
  36. 12 10
      libs/openssl/crypto/evp/e_des3.c
  37. 28 30
      libs/openssl/crypto/evp/evp_enc.c
  38. 2 4
      libs/openssl/crypto/md32_common.h
  39. 8 4
      libs/openssl/crypto/mem.c
  40. 0 3
      libs/openssl/crypto/objects/obj_xref.h
  41. 3 3
      libs/openssl/crypto/opensslv.h
  42. 1 1
      libs/openssl/crypto/ts/ts_rsp_sign.c
  43. 1 0
      libs/openssl/crypto/x509/x509.h
  44. 2 0
      libs/openssl/crypto/x509/x509_vpm.c
  45. 2 0
      libs/openssl/crypto/x509/x_all.c
  46. 17 10
      libs/openssl/e_os.h
  47. 94 68
      libs/openssl/ssl/d1_both.c
  48. 9 16
      libs/openssl/ssl/d1_clnt.c
  49. 2 1
      libs/openssl/ssl/d1_enc.c
  50. 31 7
      libs/openssl/ssl/d1_lib.c
  51. 24 13
      libs/openssl/ssl/d1_pkt.c
  52. 35 18
      libs/openssl/ssl/d1_srvr.c
  53. 8 0
      libs/openssl/ssl/dtls1.h
  54. 36 36
      libs/openssl/ssl/kssl.c
  55. 5 2
      libs/openssl/ssl/s23_srvr.c
  56. 8 4
      libs/openssl/ssl/s2_enc.c
  57. 7 2
      libs/openssl/ssl/s2_pkt.c
  58. 15 7
      libs/openssl/ssl/s2_srvr.c
  59. 1 0
      libs/openssl/ssl/s3_both.c
  60. 48 83
      libs/openssl/ssl/s3_clnt.c
  61. 2 1
      libs/openssl/ssl/s3_enc.c
  62. 9 7
      libs/openssl/ssl/s3_lib.c
  63. 2 3
      libs/openssl/ssl/s3_meth.c
  64. 3 2
      libs/openssl/ssl/s3_pkt.c
  65. 102 41
      libs/openssl/ssl/s3_srvr.c
  66. 3 1
      libs/openssl/ssl/srtp.h
  67. 20 8
      libs/openssl/ssl/ssl.h
  68. 10 3
      libs/openssl/ssl/ssl3.h
  69. 0 29
      libs/openssl/ssl/ssl_cert.c
  70. 6 6
      libs/openssl/ssl/ssl_ciph.c
  71. 25 21
      libs/openssl/ssl/ssl_lib.c
  72. 4 3
      libs/openssl/ssl/ssl_locl.h
  73. 15 1
      libs/openssl/ssl/ssl_sess.c
  74. 35 35
      libs/openssl/ssl/t1_enc.c
  75. 29 9
      libs/openssl/ssl/t1_lib.c
  76. 1 1
      source/Console.cbproj
  77. 1 1
      source/DragExt.cbproj
  78. 3 3
      source/DragExt64.rc
  79. 2 2
      source/WinSCP.cbproj
  80. 14 1
      source/core/Common.cpp
  81. 2 0
      source/core/Common.h
  82. 21 1
      source/core/Configuration.cpp
  83. 2 1
      source/core/Configuration.h
  84. 6 1
      source/core/FileMasks.cpp
  85. 1 0
      source/core/FileMasks.h
  86. 0 7
      source/core/FileOperationProgress.cpp
  87. 0 3
      source/core/FileOperationProgress.h
  88. 7 3
      source/core/FtpFileSystem.cpp
  89. 12 2
      source/core/RemoteFiles.cpp
  90. 1 0
      source/core/RemoteFiles.h
  91. 12 14
      source/core/SecureShell.cpp
  92. 1 1
      source/core/SecureShell.h
  93. 2 0
      source/core/SessionInfo.cpp
  94. 1 0
      source/core/SessionInfo.h
  95. 24 16
      source/core/SftpFileSystem.cpp
  96. 20 0
      source/core/Terminal.cpp
  97. 2 0
      source/core/Terminal.h
  98. 2 0
      source/filezilla/AsyncProxySocketLayer.cpp
  99. 8 0
      source/filezilla/AsyncSocketExLayer.cpp
  100. 10 4
      source/filezilla/FtpControlSocket.cpp

+ 1 - 1
deployment/WinSCPnet.nuspec

@@ -18,7 +18,7 @@ The library is primarily intended for advanced automation tasks that require con
 For documentation and examples of use, see project website.
 
 The NuGet package includes the assembly itself and a required WinSCP executable. When installed, it adds the assembly as reference to your project and sets up WinSCP executable to be copied to project output directory, so that it can be found on run-time.</description>
-    <copyright>Copyright © 2012-2014 Martin Prikryl</copyright>
+    <copyright>Copyright © 2012-2015 Martin Prikryl</copyright>
     <tags>winscp sftp ftp ftps scp transfer</tags>
   </metadata>
   <files>

+ 2 - 1
deployment/winscpsetup.iss

@@ -7,7 +7,7 @@
 #define WebDocumentation WebRoot+"eng/docs/"
 #define WebReport WebRoot+"install.php"
 #define WebPuTTY "http://www.chiark.greenend.org.uk/~sgtatham/putty/"
-#define Year 2014
+#define Year 2015
 #define EnglishLang "English"
 #define SetupTypeData "SetupType"
 #define InnoSetupReg "Software\Microsoft\Windows\CurrentVersion\Uninstall\" + AppId + "_is1"
@@ -341,6 +341,7 @@ Root: HKCU; SubKey: "{#RegistryKey}\Configuration\Interface"; \
 #for {LangI = 0; LangI < LanguageCount; LangI++} EmitLang
 
 [UninstallRun]
+; Make sure no later uninstall task recreate the configuration
 Filename: "{app}\WinSCP.exe"; Parameters: "/UninstallCleanup"; \
   RunOnceId: "UninstallCleanup"
 Filename: "{app}\WinSCP.exe"; Parameters: "/RemoveSearchPath"; \

+ 18 - 4
dotnet/Session.cs

@@ -680,13 +680,13 @@ namespace WinSCP
             }
         }
 
-        public string CalculateFileChecksum(string algorithm, string path)
+        public byte[] CalculateFileChecksum(string algorithm, string path)
         {
             using (Logger.CreateCallstack())
             {
                 WriteCommand(string.Format(CultureInfo.InvariantCulture, "checksum -- \"{0}\" \"{1}\"", Tools.ArgumentEscape(algorithm), Tools.ArgumentEscape(path)));
 
-                string result = null;
+                string hex = null;
 
                 using (ElementLogReader groupReader = _reader.WaitForGroupAndCreateLogReader())
                 using (ElementLogReader checksumReader = groupReader.WaitForNonEmptyElementAndCreateLogReader("checksum", LogReadFlags.ThrowFailures))
@@ -696,14 +696,28 @@ namespace WinSCP
                         string value;
                         if (checksumReader.GetEmptyElementValue("checksum", out value))
                         {
-                            result = value;
+                            hex = value;
                         }
                     }
 
                     groupReader.ReadToEnd(LogReadFlags.ThrowFailures);
                 }
 
-                return result;
+                int len = hex.Length;
+
+                if ((len % 2) != 0)
+                {
+                    string error = string.Format(CultureInfo.CurrentCulture, "Invalid string representation of checksum - {0}", hex);
+                    throw new SessionLocalException(this, error);
+                }
+
+                int count = len / 2;
+                byte[] bytes = new byte[count];
+                for (int i = 0; i < count; i++)
+                {
+                    bytes[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);
+                }
+                return bytes;
             }
         }
 

+ 3 - 3
dotnet/properties/AssemblyInfo.cs

@@ -19,9 +19,9 @@ using System.Runtime.InteropServices;
 // The following GUID is for the ID of the typelib if this project is exposed to COM
 [assembly: Guid("a0b93468-d98a-4845-a234-8076229ad93f")]
 
-[assembly: AssemblyVersion("1.2.4.0")]
-[assembly: AssemblyFileVersion("1.2.4.0")]
-[assembly: AssemblyInformationalVersionAttribute("5.6.4.0")]
+[assembly: AssemblyVersion("1.2.5.0")]
+[assembly: AssemblyFileVersion("1.2.5.0")]
+[assembly: AssemblyInformationalVersionAttribute("5.6.5.0")]
 
 [assembly: CLSCompliant(true)]
 

+ 1 - 1
libs/openssl/crypto/LPdir_win.c

@@ -36,7 +36,7 @@
 #if defined(LP_SYS_WINCE) && !defined(FindFirstFile)
 # define FindFirstFile FindFirstFileW
 #endif
-#if defined(LP_SYS_WINCE) && !defined(FindFirstFile)
+#if defined(LP_SYS_WINCE) && !defined(FindNextFile)
 # define FindNextFile FindNextFileW
 #endif
 

+ 6 - 1
libs/openssl/crypto/asn1/a_bitstr.c

@@ -136,11 +136,16 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
 
 	p= *pp;
 	i= *(p++);
+	if (i > 7)
+		{
+		i=ASN1_R_INVALID_BIT_STRING_BITS_LEFT;
+		goto err;
+		}
 	/* We do this to preserve the settings.  If we modify
 	 * the settings, via the _set_bit function, we will recalculate
 	 * on output */
 	ret->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
-	ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|(i&0x07)); /* set */
+	ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|i); /* set */
 
 	if (len-- > 1) /* using one because of the bits left byte */
 		{

+ 1 - 1
libs/openssl/crypto/asn1/a_type.c

@@ -113,7 +113,7 @@ IMPLEMENT_STACK_OF(ASN1_TYPE)
 IMPLEMENT_ASN1_SET_OF(ASN1_TYPE)
 
 /* Returns 0 if they are equal, != 0 otherwise. */
-int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b)
+int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b)
 	{
 	int result = -1;
 

+ 12 - 0
libs/openssl/crypto/asn1/a_verify.c

@@ -90,6 +90,12 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature,
 		ASN1err(ASN1_F_ASN1_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
 		goto err;
 		}
+
+	if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7)
+		{
+		ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
+		goto err;
+		}
 	
 	inl=i2d(data,NULL);
 	buf_in=OPENSSL_malloc((unsigned int)inl);
@@ -146,6 +152,12 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
 		return -1;
 		}
 
+	if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7)
+		{
+		ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
+		return -1;
+		}
+
 	EVP_MD_CTX_init(&ctx);
 
 	/* Convert signature OID into digest and public key OIDs */

+ 3 - 1
libs/openssl/crypto/asn1/asn1.h

@@ -776,7 +776,7 @@ DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE)
 int ASN1_TYPE_get(ASN1_TYPE *a);
 void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value);
 int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value);
-int            ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b);
+int            ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b);
 
 ASN1_OBJECT *	ASN1_OBJECT_new(void );
 void		ASN1_OBJECT_free(ASN1_OBJECT *a);
@@ -1329,6 +1329,7 @@ void ERR_load_ASN1_strings(void);
 #define ASN1_R_ILLEGAL_TIME_VALUE			 184
 #define ASN1_R_INTEGER_NOT_ASCII_FORMAT			 185
 #define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG		 128
+#define ASN1_R_INVALID_BIT_STRING_BITS_LEFT		 220
 #define ASN1_R_INVALID_BMPSTRING_LENGTH			 129
 #define ASN1_R_INVALID_DIGIT				 130
 #define ASN1_R_INVALID_MIME_TYPE			 205
@@ -1378,6 +1379,7 @@ void ERR_load_ASN1_strings(void);
 #define ASN1_R_TIME_NOT_ASCII_FORMAT			 193
 #define ASN1_R_TOO_LONG					 155
 #define ASN1_R_TYPE_NOT_CONSTRUCTED			 156
+#define ASN1_R_TYPE_NOT_PRIMITIVE			 218
 #define ASN1_R_UNABLE_TO_DECODE_RSA_KEY			 157
 #define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY		 158
 #define ASN1_R_UNEXPECTED_EOC				 159

+ 3 - 1
libs/openssl/crypto/asn1/asn1_err.c

@@ -1,6 +1,6 @@
 /* crypto/asn1/asn1_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2011 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2014 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
@@ -246,6 +246,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
 {ERR_REASON(ASN1_R_ILLEGAL_TIME_VALUE)   ,"illegal time value"},
 {ERR_REASON(ASN1_R_INTEGER_NOT_ASCII_FORMAT),"integer not ascii format"},
 {ERR_REASON(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG),"integer too large for long"},
+{ERR_REASON(ASN1_R_INVALID_BIT_STRING_BITS_LEFT),"invalid bit string bits left"},
 {ERR_REASON(ASN1_R_INVALID_BMPSTRING_LENGTH),"invalid bmpstring length"},
 {ERR_REASON(ASN1_R_INVALID_DIGIT)        ,"invalid digit"},
 {ERR_REASON(ASN1_R_INVALID_MIME_TYPE)    ,"invalid mime type"},
@@ -295,6 +296,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
 {ERR_REASON(ASN1_R_TIME_NOT_ASCII_FORMAT),"time not ascii format"},
 {ERR_REASON(ASN1_R_TOO_LONG)             ,"too long"},
 {ERR_REASON(ASN1_R_TYPE_NOT_CONSTRUCTED) ,"type not constructed"},
+{ERR_REASON(ASN1_R_TYPE_NOT_PRIMITIVE)   ,"type not primitive"},
 {ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_KEY),"unable to decode rsa key"},
 {ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY),"unable to decode rsa private key"},
 {ERR_REASON(ASN1_R_UNEXPECTED_EOC)       ,"unexpected eoc"},

+ 8 - 0
libs/openssl/crypto/asn1/tasn_dec.c

@@ -870,6 +870,14 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
 		}
 	else if (cst)
 		{
+		if (utype == V_ASN1_NULL || utype == V_ASN1_BOOLEAN
+			|| utype == V_ASN1_OBJECT || utype == V_ASN1_INTEGER
+			|| utype == V_ASN1_ENUMERATED)
+			{
+			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
+				ASN1_R_TYPE_NOT_PRIMITIVE);
+			return 0;
+			}
 		buf.length = 0;
 		buf.max = 0;
 		buf.data = NULL;

+ 11 - 0
libs/openssl/crypto/asn1/x_algor.c

@@ -142,3 +142,14 @@ void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md)
 	X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
 
 	}
+
+int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b)
+	{
+	int rv;
+	rv = OBJ_cmp(a->algorithm, b->algorithm);
+	if (rv)
+		return rv;
+	if (!a->parameter && !b->parameter)
+		return 0;
+	return ASN1_TYPE_cmp(a->parameter, b->parameter);
+	}

+ 2 - 0
libs/openssl/crypto/asn1/x_name.c

@@ -350,6 +350,8 @@ static int x509_name_canon(X509_NAME *a)
 			set = entry->set;
 			}
 		tmpentry = X509_NAME_ENTRY_new();
+		if (!tmpentry)
+			goto err;
 		tmpentry->object = OBJ_dup(entry->object);
 		if (!asn1_string_canon(tmpentry->value, entry->value))
 			goto err;

+ 4 - 0
libs/openssl/crypto/bio/bio.h

@@ -175,6 +175,8 @@ extern "C" {
 #define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT   45 /* Next DTLS handshake timeout to
                                               * adjust socket timeouts */
 
+#define BIO_CTRL_DGRAM_GET_MTU_OVERHEAD   49
+
 #ifndef OPENSSL_NO_SCTP
 /* SCTP stuff */
 #define BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE	50
@@ -607,6 +609,8 @@ int BIO_ctrl_reset_read_request(BIO *b);
          (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)peer)
 #define BIO_dgram_set_peer(b,peer) \
          (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)peer)
+#define BIO_dgram_get_mtu_overhead(b) \
+         (unsigned int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_MTU_OVERHEAD, 0, NULL)
 
 /* These two aren't currently implemented */
 /* int BIO_get_ex_num(BIO *bio); */

+ 3 - 1
libs/openssl/crypto/bn/bn.h

@@ -780,7 +780,9 @@ int RAND_pseudo_bytes(unsigned char *buf,int num);
 #define bn_wcheck_size(bn, words) \
 	do { \
 		const BIGNUM *_bnum2 = (bn); \
-		assert(words <= (_bnum2)->dmax && words >= (_bnum2)->top); \
+		assert((words) <= (_bnum2)->dmax && (words) >= (_bnum2)->top); \
+		/* avoid unused variable warning with NDEBUG */ \
+		(void)(_bnum2); \
 	} while(0)
 
 #else /* !BN_DEBUG */

+ 10 - 6
libs/openssl/crypto/bn/bn_asm.c

@@ -438,6 +438,10 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
 /* sqr_add_c(a,i,c0,c1,c2)  -- c+=a[i]^2 for three word number c=(c2,c1,c0) */
 /* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */
 
+/*
+ * Keep in mind that carrying into high part of multiplication result
+ * can not overflow, because it cannot be all-ones.
+ */
 #ifdef BN_LLONG
 #define mul_add_c(a,b,c0,c1,c2) \
 	t=(BN_ULLONG)a*b; \
@@ -478,10 +482,10 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
 #define mul_add_c2(a,b,c0,c1,c2) {	\
 	BN_ULONG ta=(a),tb=(b),t0;	\
 	BN_UMULT_LOHI(t0,t1,ta,tb);	\
-	t2 = t1+t1; c2 += (t2<t1)?1:0;	\
-	t1 = t0+t0; t2 += (t1<t0)?1:0;	\
-	c0 += t1; t2 += (c0<t1)?1:0;	\
+	c0 += t0; t2 = t1+((c0<t0)?1:0);\
 	c1 += t2; c2 += (c1<t2)?1:0;	\
+	c0 += t0; t1 += (c0<t0)?1:0;	\
+	c1 += t1; c2 += (c1<t1)?1:0;	\
 	}
 
 #define sqr_add_c(a,i,c0,c1,c2)	{	\
@@ -508,10 +512,10 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
 	BN_ULONG ta=(a),tb=(b),t0;	\
 	t1 = BN_UMULT_HIGH(ta,tb);	\
 	t0 = ta * tb;			\
-	t2 = t1+t1; c2 += (t2<t1)?1:0;	\
-	t1 = t0+t0; t2 += (t1<t0)?1:0;	\
-	c0 += t1; t2 += (c0<t1)?1:0;	\
+	c0 += t0; t2 = t1+((c0<t0)?1:0);\
 	c1 += t2; c2 += (c1<t2)?1:0;	\
+	c0 += t0; t1 += (c0<t0)?1:0;	\
+	c1 += t1; c2 += (c1<t1)?1:0;	\
 	}
 
 #define sqr_add_c(a,i,c0,c1,c2)	{	\

+ 1 - 1
libs/openssl/crypto/bn/bn_ctx.c

@@ -158,7 +158,7 @@ static void ctxdbg(BN_CTX *ctx)
 	unsigned int bnidx = 0, fpidx = 0;
 	BN_POOL_ITEM *item = ctx->pool.head;
 	BN_STACK *stack = &ctx->stack;
-	fprintf(stderr,"(%08x): ", (unsigned int)ctx);
+	fprintf(stderr,"(%16p): ", ctx);
 	while(bnidx < ctx->used)
 		{
 		fprintf(stderr,"%03x ", item->vals[bnidx++ % BN_CTX_POOL_SIZE].dmax);

+ 5 - 3
libs/openssl/crypto/bn/bn_div.c

@@ -189,15 +189,17 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
 	int no_branch=0;
 
 	/* Invalid zero-padding would have particularly bad consequences
-	 * in the case of 'num', so don't just rely on bn_check_top() for this one
+	 * so don't just rely on bn_check_top() here
 	 * (bn_check_top() works only for BN_DEBUG builds) */
-	if (num->top > 0 && num->d[num->top - 1] == 0)
+	if ((num->top > 0 && num->d[num->top - 1] == 0) ||
+		(divisor->top > 0 && divisor->d[divisor->top - 1] == 0))
 		{
 		BNerr(BN_F_BN_DIV,BN_R_NOT_INITIALIZED);
 		return 0;
 		}
 
 	bn_check_top(num);
+	bn_check_top(divisor);
 
 	if ((BN_get_flags(num, BN_FLG_CONSTTIME) != 0) || (BN_get_flags(divisor, BN_FLG_CONSTTIME) != 0))
 		{
@@ -207,7 +209,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
 	bn_check_top(dv);
 	bn_check_top(rm);
 	/* bn_check_top(num); */ /* 'num' has been checked already */
-	bn_check_top(divisor);
+	/* bn_check_top(divisor); */ /* 'divisor' has been checked already */
 
 	if (BN_is_zero(divisor))
 		{

+ 2 - 2
libs/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 "Thu Oct 16 10:19:54 2014"
+  #define DATE "Fri Jan  9 11:28:31 2015"
 #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 -D_timeb=timeb -D_ftime=ftime -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 "Thu Oct 16 10:19:54 2014"
+  #define DATE "Fri Jan  9 11:28:31 2015"
 #endif

+ 4 - 14
libs/openssl/crypto/constant_time_locl.h

@@ -129,17 +129,12 @@ static inline int constant_time_select_int(unsigned int mask, int a, int b);
 
 static inline unsigned int constant_time_msb(unsigned int a)
 	{
-	return (unsigned int)((int)(a) >> (sizeof(int) * 8 - 1));
+	return 0-(a >> (sizeof(a) * 8 - 1));
 	}
 
 static inline unsigned int constant_time_lt(unsigned int a, unsigned int b)
 	{
-	unsigned int lt;
-	/* Case 1: msb(a) == msb(b). a < b iff the MSB of a - b is set.*/
-	lt = ~(a ^ b) & (a - b);
-	/* Case 2: msb(a) != msb(b). a < b iff the MSB of b is set. */
-	lt |= ~a & b;
-	return constant_time_msb(lt);
+	return constant_time_msb(a^((a^b)|((a-b)^b)));
 	}
 
 static inline unsigned char constant_time_lt_8(unsigned int a, unsigned int b)
@@ -149,12 +144,7 @@ static inline unsigned char constant_time_lt_8(unsigned int a, unsigned int b)
 
 static inline unsigned int constant_time_ge(unsigned int a, unsigned int b)
 	{
-	unsigned int ge;
-	/* Case 1: msb(a) == msb(b). a >= b iff the MSB of a - b is not set.*/
-	ge = ~((a ^ b) | (a - b));
-	/* Case 2: msb(a) != msb(b). a >= b iff the MSB of a is set. */
-	ge |= a & ~b;
-	return constant_time_msb(ge);
+	return ~constant_time_lt(a, b);
 	}
 
 static inline unsigned char constant_time_ge_8(unsigned int a, unsigned int b)
@@ -204,7 +194,7 @@ static inline unsigned char constant_time_select_8(unsigned char mask,
 	return (unsigned char)(constant_time_select(mask, a, b));
 	}
 
-inline int constant_time_select_int(unsigned int mask, int a, int b)
+static inline int constant_time_select_int(unsigned int mask, int a, int b)
 	{
 	return (int)(constant_time_select(mask, (unsigned)(a), (unsigned)(b)));
 	}

+ 3 - 12
libs/openssl/crypto/cversion.c

@@ -69,10 +69,7 @@ const char *SSLeay_version(int t)
 	if (t == SSLEAY_BUILT_ON)
 		{
 #ifdef DATE
-		static char buf[sizeof(DATE)+11];
-
-		BIO_snprintf(buf,sizeof buf,"built on: %s",DATE);
-		return(buf);
+		return(DATE);
 #else
 		return("built on: date not available");
 #endif
@@ -80,10 +77,7 @@ const char *SSLeay_version(int t)
 	if (t == SSLEAY_CFLAGS)
 		{
 #ifdef CFLAGS
-		static char buf[sizeof(CFLAGS)+11];
-
-		BIO_snprintf(buf,sizeof buf,"compiler: %s",CFLAGS);
-		return(buf);
+		return(CFLAGS); // MPEXT
 #else
 		return("compiler: information not available");
 #endif
@@ -91,10 +85,7 @@ const char *SSLeay_version(int t)
 	if (t == SSLEAY_PLATFORM)
 		{
 #ifdef PLATFORM
-		static char buf[sizeof(PLATFORM)+11];
-
-		BIO_snprintf(buf,sizeof buf,"platform: %s", PLATFORM);
-		return(buf);
+		return(PLATFORM);
 #else
 		return("platform: information not available");
 #endif

+ 13 - 1
libs/openssl/crypto/dsa/dsa_asn1.c

@@ -176,13 +176,25 @@ int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
 	     const unsigned char *sigbuf, int siglen, DSA *dsa)
 	{
 	DSA_SIG *s;
+	const unsigned char *p = sigbuf;
+	unsigned char *der = NULL;
+	int derlen = -1;
 	int ret=-1;
 
 	s = DSA_SIG_new();
 	if (s == NULL) return(ret);
-	if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err;
+	if (d2i_DSA_SIG(&s,&p,siglen) == NULL) goto err;
+	/* Ensure signature uses DER and doesn't have trailing garbage */
+	derlen = i2d_DSA_SIG(s, &der);
+	if (derlen != siglen || memcmp(sigbuf, der, derlen))
+		goto err;
 	ret=DSA_do_verify(dgst,dgst_len,s,dsa);
 err:
+	if (derlen > 0)
+		{
+		OPENSSL_cleanse(der, derlen);
+		OPENSSL_free(der);
+		}
 	DSA_SIG_free(s);
 	return(ret);
 	}

+ 2 - 4
libs/openssl/crypto/dso/dso_dlfcn.c

@@ -60,10 +60,8 @@
    that handle _GNU_SOURCE and other similar macros.  Defining it later
    is simply too late, because those headers are protected from re-
    inclusion.  */
-#ifdef __linux
-# ifndef _GNU_SOURCE
-#  define _GNU_SOURCE	/* make sure dladdr is declared */
-# endif
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE	/* make sure dladdr is declared */
 #endif
 
 #include <stdio.h>

+ 1 - 1
libs/openssl/crypto/ec/ec.h

@@ -629,7 +629,7 @@ int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN
 int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx);
 int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx);
 
-/** Computes r = generator * n sum_{i=0}^num p[i] * m[i]
+/** Computes r = generator * n sum_{i=0}^{num-1} p[i] * m[i]
  *  \param  group  underlying EC_GROUP object
  *  \param  r      EC_POINT object for the result
  *  \param  n      BIGNUM with the multiplier for the group generator (optional)

+ 5 - 4
libs/openssl/crypto/ec/ec2_smpl.c

@@ -80,9 +80,6 @@
 
 const EC_METHOD *EC_GF2m_simple_method(void)
 	{
-#ifdef OPENSSL_FIPS
-	return fips_ec_gf2m_simple_method();
-#else
 	static const EC_METHOD ret = {
 		EC_FLAGS_DEFAULT_OCT,
 		NID_X9_62_characteristic_two_field,
@@ -125,8 +122,12 @@ const EC_METHOD *EC_GF2m_simple_method(void)
 		0 /* field_decode */,
 		0 /* field_set_to_one */ };
 
-	return &ret;
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode())
+		return fips_ec_gf2m_simple_method();
 #endif
+
+	return &ret;
 	}
 
 

+ 8 - 6
libs/openssl/crypto/ec/ec_ameth.c

@@ -453,14 +453,16 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype)
 	if (ktype > 0)
 		{
 		public_key = EC_KEY_get0_public_key(x);
-		if ((pub_key = EC_POINT_point2bn(group, public_key,
-			EC_KEY_get_conv_form(x), NULL, ctx)) == NULL)
+		if (public_key != NULL)
 			{
-			reason = ERR_R_EC_LIB;
-			goto err;
-			}
-		if (pub_key)
+			if ((pub_key = EC_POINT_point2bn(group, public_key,
+				EC_KEY_get_conv_form(x), NULL, ctx)) == NULL)
+				{
+				reason = ERR_R_EC_LIB;
+				goto err;
+				}
 			buf_len = (size_t)BN_num_bytes(pub_key);
+			}
 		}
 
 	if (ktype == 2)

+ 29 - 11
libs/openssl/crypto/ec/ec_asn1.c

@@ -1183,29 +1183,46 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
 		goto err;
 		}
 
+	if (ret->pub_key)
+		EC_POINT_clear_free(ret->pub_key);
+	ret->pub_key = EC_POINT_new(ret->group);
+	if (ret->pub_key == NULL)
+		{
+		ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+		goto err;
+		}
+
 	if (priv_key->publicKey)
 		{
 		const unsigned char *pub_oct;
-		size_t pub_oct_len;
+		int pub_oct_len;
 
-		if (ret->pub_key)
-			EC_POINT_clear_free(ret->pub_key);
-		ret->pub_key = EC_POINT_new(ret->group);
-		if (ret->pub_key == NULL)
+		pub_oct     = M_ASN1_STRING_data(priv_key->publicKey);
+		pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey);
+		/* The first byte - point conversion form - must be present. */
+                if (pub_oct_len <= 0)
 			{
-			ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+			ECerr(EC_F_D2I_ECPRIVATEKEY, EC_R_BUFFER_TOO_SMALL);
 			goto err;
 			}
-		pub_oct     = M_ASN1_STRING_data(priv_key->publicKey);
-		pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey);
-		/* save the point conversion form */
+		/* Save the point conversion form. */
 		ret->conv_form = (point_conversion_form_t)(pub_oct[0] & ~0x01);
 		if (!EC_POINT_oct2point(ret->group, ret->pub_key,
-			pub_oct, pub_oct_len, NULL))
+					pub_oct, (size_t)(pub_oct_len), NULL))
+			{
+			ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+			goto err;
+			}
+		}
+	else
+		{
+		if (!EC_POINT_mul(ret->group, ret->pub_key, ret->priv_key, NULL, NULL, NULL))
 			{
 			ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
 			goto err;
 			}
+		/* Remember the original private-key-only encoding. */
+		ret->enc_flag |= EC_PKEY_NO_PUBKEY;
 		}
 
 	ok = 1;
@@ -1230,7 +1247,8 @@ int	i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
 	size_t          buf_len=0, tmp_len;
 	EC_PRIVATEKEY   *priv_key=NULL;
 
-	if (a == NULL || a->group == NULL || a->priv_key == NULL)
+	if (a == NULL || a->group == NULL || a->priv_key == NULL ||
+	    (!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key == NULL))
 		{
 		ECerr(EC_F_I2D_ECPRIVATEKEY,
                       ERR_R_PASSED_NULL_PARAMETER);

+ 1 - 1
libs/openssl/crypto/ec/ec_lib.c

@@ -68,7 +68,7 @@
 
 #include "ec_lcl.h"
 
-static const char EC_version[] = "EC" OPENSSL_VERSION_PTEXT;
+const char EC_version[] = "EC" OPENSSL_VERSION_PTEXT;
 
 
 /* functions for EC_GROUP objects */

+ 4 - 3
libs/openssl/crypto/ec/ec_mult.c

@@ -445,15 +445,16 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
 	wNAF_len = OPENSSL_malloc(totalnum * sizeof wNAF_len[0]);
 	wNAF     = OPENSSL_malloc((totalnum + 1) * sizeof wNAF[0]); /* includes space for pivot */
 	val_sub  = OPENSSL_malloc(totalnum * sizeof val_sub[0]);
-		 
+
+	/* Ensure wNAF is initialised in case we end up going to err */
+	if (wNAF) wNAF[0] = NULL;	/* preliminary pivot */
+
 	if (!wsize || !wNAF_len || !wNAF || !val_sub)
 		{
 		ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
 		goto err;
 		}
 
-	wNAF[0] = NULL;	/* preliminary pivot */
-
 	/* num_val will be the total number of temporarily precomputed points */
 	num_val = 0;
 

+ 6 - 0
libs/openssl/crypto/ec/ec_pmeth.c

@@ -167,6 +167,7 @@ static int pkey_ec_verify(EVP_PKEY_CTX *ctx,
 	return ret;
 	}
 
+#ifndef OPENSSL_NO_ECDH
 static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
 	{
 	int ret;
@@ -200,6 +201,7 @@ static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
 	*keylen = ret;
 	return 1;
 	}
+#endif
 
 static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
 	{
@@ -333,7 +335,11 @@ const EVP_PKEY_METHOD ec_pkey_meth =
 	0,0,
 
 	0,
+#ifndef OPENSSL_NO_ECDH
 	pkey_ec_derive,
+#else
+	0,
+#endif
 
 	pkey_ec_ctrl,
 	pkey_ec_ctrl_str

+ 5 - 4
libs/openssl/crypto/ec/ecp_mont.c

@@ -72,9 +72,6 @@
 
 const EC_METHOD *EC_GFp_mont_method(void)
 	{
-#ifdef OPENSSL_FIPS
-	return fips_ec_gfp_mont_method();
-#else
 	static const EC_METHOD ret = {
 		EC_FLAGS_DEFAULT_OCT,
 		NID_X9_62_prime_field,
@@ -114,8 +111,12 @@ const EC_METHOD *EC_GFp_mont_method(void)
 		ec_GFp_mont_field_decode,
 		ec_GFp_mont_field_set_to_one };
 
-	return &ret;
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode())
+		return fips_ec_gfp_mont_method();
 #endif
+
+	return &ret;
 	}
 
 

+ 5 - 4
libs/openssl/crypto/ec/ecp_nist.c

@@ -73,9 +73,6 @@
 
 const EC_METHOD *EC_GFp_nist_method(void)
 	{
-#ifdef OPENSSL_FIPS
-	return fips_ec_gfp_nist_method();
-#else
 	static const EC_METHOD ret = {
 		EC_FLAGS_DEFAULT_OCT,
 		NID_X9_62_prime_field,
@@ -115,8 +112,12 @@ const EC_METHOD *EC_GFp_nist_method(void)
 		0 /* field_decode */,
 		0 /* field_set_to_one */ };
 
-	return &ret;
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode())
+		return fips_ec_gfp_nist_method();
 #endif
+
+	return &ret;
 	}
 
 int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src)

+ 0 - 1
libs/openssl/crypto/ec/ecp_nistp256.c

@@ -113,7 +113,6 @@ typedef u64 smallfelem[NLIMBS];
 
 /* This is the value of the prime as four 64-bit words, little-endian. */
 static const u64 kPrime[4] = { 0xfffffffffffffffful, 0xffffffff, 0, 0xffffffff00000001ul };
-static const limb bottom32bits = 0xffffffff;
 static const u64 bottom63bits = 0x7ffffffffffffffful;
 
 /* bin32_to_felem takes a little-endian byte array and converts it into felem

+ 7 - 6
libs/openssl/crypto/ec/ecp_smpl.c

@@ -73,9 +73,6 @@
 
 const EC_METHOD *EC_GFp_simple_method(void)
 	{
-#ifdef OPENSSL_FIPS
-	return fips_ec_gfp_simple_method();
-#else
 	static const EC_METHOD ret = {
 		EC_FLAGS_DEFAULT_OCT,
 		NID_X9_62_prime_field,
@@ -115,8 +112,12 @@ const EC_METHOD *EC_GFp_simple_method(void)
 		0 /* field_decode */,
 		0 /* field_set_to_one */ };
 
-	return &ret;
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode())
+		return fips_ec_gfp_simple_method();
 #endif
+
+	return &ret;
 	}
 
 
@@ -1317,8 +1318,8 @@ int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT
 		{
 		for (i = 0; i < num; i++)
 			{
-			if (prod_Z[i] != NULL)
-				BN_clear_free(prod_Z[i]);
+			if (prod_Z[i] == NULL) break;
+			BN_clear_free(prod_Z[i]);
 			}
 		OPENSSL_free(prod_Z);
 		}

+ 14 - 1
libs/openssl/crypto/ecdsa/ecs_vrf.c

@@ -57,6 +57,7 @@
  */
 
 #include "ecs_locl.h"
+#include "cryptlib.h"
 #ifndef OPENSSL_NO_ENGINE
 #include <openssl/engine.h>
 #endif
@@ -84,13 +85,25 @@ int ECDSA_verify(int type, const unsigned char *dgst, int dgst_len,
 		const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
  	{
 	ECDSA_SIG *s;
+	const unsigned char *p = sigbuf;
+	unsigned char *der = NULL;
+	int derlen = -1;
 	int ret=-1;
 
 	s = ECDSA_SIG_new();
 	if (s == NULL) return(ret);
-	if (d2i_ECDSA_SIG(&s, &sigbuf, sig_len) == NULL) goto err;
+	if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL) goto err;
+	/* Ensure signature uses DER and doesn't have trailing garbage */
+	derlen = i2d_ECDSA_SIG(s, &der);
+	if (derlen != sig_len || memcmp(sigbuf, der, derlen))
+		goto err;
 	ret=ECDSA_do_verify(dgst, dgst_len, s, eckey);
 err:
+	if (derlen > 0)
+		{
+		OPENSSL_cleanse(der, derlen);
+		OPENSSL_free(der);
+		}
 	ECDSA_SIG_free(s);
 	return(ret);
 	}

+ 12 - 10
libs/openssl/crypto/evp/e_des3.c

@@ -124,12 +124,11 @@ static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
 #ifdef KSSL_DEBUG
 	{
         int i;
-        char *cp;
-	printf("des_ede_cbc_cipher(ctx=%lx, buflen=%d)\n", ctx, ctx->buf_len);
-	printf("\t iv= ");
+	fprintf(stderr,"des_ede_cbc_cipher(ctx=%p, buflen=%d)\n", ctx, ctx->buf_len);
+	fprintf(stderr,"\t iv= ");
         for(i=0;i<8;i++)
-                printf("%02X",ctx->iv[i]);
-	printf("\n");
+                fprintf(stderr,"%02X",ctx->iv[i]);
+	fprintf(stderr,"\n");
 	}
 #endif    /* KSSL_DEBUG */
 	while (inl>=EVP_MAXCHUNK)
@@ -260,11 +259,14 @@ static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
 #ifdef KSSL_DEBUG
 	{
         int i;
-        printf("des_ede3_init_key(ctx=%lx)\n", ctx);
-	printf("\tKEY= ");
-        for(i=0;i<24;i++) printf("%02X",key[i]); printf("\n");
-	printf("\t IV= ");
-        for(i=0;i<8;i++) printf("%02X",iv[i]); printf("\n");
+        fprintf(stderr,"des_ede3_init_key(ctx=%p)\n", ctx);
+	fprintf(stderr,"\tKEY= ");
+        for(i=0;i<24;i++) fprintf(stderr,"%02X",key[i]); fprintf(stderr,"\n");
+	if (iv) 
+		{
+		fprintf(stderr,"\t IV= ");
+		for(i=0;i<8;i++) fprintf(stderr,"%02X",iv[i]); fprintf(stderr,"\n");
+		}
 	}
 #endif	/* KSSL_DEBUG */
 

+ 28 - 30
libs/openssl/crypto/evp/evp_enc.c

@@ -67,7 +67,6 @@
 #ifdef OPENSSL_FIPS
 #include <openssl/fips.h>
 #endif
-#include "constant_time_locl.h"
 #include "evp_locl.h"
 
 #ifdef OPENSSL_FIPS
@@ -501,21 +500,21 @@ int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
 
 int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
 	{
-	unsigned int i, b;
-        unsigned char pad, padding_good;
+	int i,n;
+	unsigned int b;
 	*outl=0;
 
 	if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER)
 		{
-		int ret = M_do_cipher(ctx, out, NULL, 0);
-		if (ret < 0)
+		i = M_do_cipher(ctx, out, NULL, 0);
+		if (i < 0)
 			return 0;
 		else
-			*outl = ret;
+			*outl = i;
 		return 1;
 		}
 
-	b=(unsigned int)(ctx->cipher->block_size);
+	b=ctx->cipher->block_size;
 	if (ctx->flags & EVP_CIPH_NO_PADDING)
 		{
 		if(ctx->buf_len)
@@ -534,34 +533,33 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
 			return(0);
 			}
 		OPENSSL_assert(b <= sizeof ctx->final);
-		pad=ctx->final[b-1];
-
-		padding_good = (unsigned char)(~constant_time_is_zero_8(pad));
-		padding_good &= constant_time_ge_8(b, pad);
-
-                for (i = 1; i < b; ++i)
-			{
-			unsigned char is_pad_index = constant_time_lt_8(i, pad);
-			unsigned char pad_byte_good = constant_time_eq_8(ctx->final[b-i-1], pad);
-			padding_good &= constant_time_select_8(is_pad_index, pad_byte_good, 0xff);
-			}
 
 		/*
-		 * At least 1 byte is always padding, so we always write b - 1
-		 * bytes to avoid a timing leak. The caller is required to have |b|
-		 * bytes space in |out| by the API contract.
+		 * The following assumes that the ciphertext has been authenticated.
+		 * Otherwise it provides a padding oracle.
 		 */
-		for (i = 0; i < b - 1; ++i)
-			out[i] = ctx->final[i] & padding_good;
-		/* Safe cast: for a good padding, EVP_MAX_IV_LENGTH >= b >= pad */
-		*outl = padding_good & ((unsigned char)(b - pad));
-		return padding_good & 1;
+		n=ctx->final[b-1];
+		if (n == 0 || n > (int)b)
+			{
+			EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT);
+			return(0);
+			}
+		for (i=0; i<n; i++)
+			{
+			if (ctx->final[--b] != n)
+				{
+				EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT);
+				return(0);
+				}
+			}
+		n=ctx->cipher->block_size-n;
+		for (i=0; i<n; i++)
+			out[i]=ctx->final[i];
+		*outl=n;
 		}
 	else
-		{
-		*outl = 0;
-		return 1;
-		}
+		*outl=0;
+	return(1);
 	}
 
 void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)

+ 2 - 4
libs/openssl/crypto/md32_common.h

@@ -225,8 +225,7 @@
 #define HOST_c2l(c,l)	(l =(((unsigned long)(*((c)++)))<<24),		\
 			 l|=(((unsigned long)(*((c)++)))<<16),		\
 			 l|=(((unsigned long)(*((c)++)))<< 8),		\
-			 l|=(((unsigned long)(*((c)++)))    ),		\
-			 l)
+			 l|=(((unsigned long)(*((c)++)))    )		)
 #endif
 #ifndef HOST_l2c
 #define HOST_l2c(l,c)	(*((c)++)=(unsigned char)(((l)>>24)&0xff),	\
@@ -262,8 +261,7 @@
 #define HOST_c2l(c,l)	(l =(((unsigned long)(*((c)++)))    ),		\
 			 l|=(((unsigned long)(*((c)++)))<< 8),		\
 			 l|=(((unsigned long)(*((c)++)))<<16),		\
-			 l|=(((unsigned long)(*((c)++)))<<24),		\
-			 l)
+			 l|=(((unsigned long)(*((c)++)))<<24)		)
 #endif
 #ifndef HOST_l2c
 #define HOST_l2c(l,c)	(*((c)++)=(unsigned char)(((l)    )&0xff),	\

+ 8 - 4
libs/openssl/crypto/mem.c

@@ -255,10 +255,12 @@ void *CRYPTO_malloc_locked(int num, const char *file, int line)
 
 	if (num <= 0) return NULL;
 
-	allow_customize = 0;
+	if(allow_customize)
+		allow_customize = 0;
 	if (malloc_debug_func != NULL)
 		{
-		allow_customize_debug = 0;
+		if(allow_customize_debug)
+			allow_customize_debug = 0;
 		malloc_debug_func(NULL, num, file, line, 0);
 		}
 	ret = malloc_locked_ex_func(num,file,line);
@@ -299,10 +301,12 @@ void *CRYPTO_malloc(int num, const char *file, int line)
 
 	if (num <= 0) return NULL;
 
-	allow_customize = 0;
+	if(allow_customize)
+		allow_customize = 0;
 	if (malloc_debug_func != NULL)
 		{
-		allow_customize_debug = 0;
+		if(allow_customize_debug)
+			allow_customize_debug = 0;
 		malloc_debug_func(NULL, num, file, line, 0);
 		}
 	ret = malloc_ex_func(num,file,line);

+ 0 - 3
libs/openssl/crypto/objects/obj_xref.h

@@ -43,9 +43,6 @@ static const nid_triple sigoid_srt[] =
 
 static const nid_triple * const sigoid_srt_xref[] =
 	{
-	&sigoid_srt[29],
-	&sigoid_srt[17],
-	&sigoid_srt[18],
 	&sigoid_srt[0],
 	&sigoid_srt[1],
 	&sigoid_srt[7],

+ 3 - 3
libs/openssl/crypto/opensslv.h

@@ -29,11 +29,11 @@ extern "C" {
  * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
  *  major minor fix final patch/beta)
  */
-#define OPENSSL_VERSION_NUMBER	0x100010afL
+#define OPENSSL_VERSION_NUMBER	0x100010bfL
 #ifdef OPENSSL_FIPS
-#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1j-fips 15 Oct 2014"
+#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1k-fips 8 Jan 2015"
 #else
-#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1j 15 Oct 2014"
+#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1k 8 Jan 2015"
 #endif
 #define OPENSSL_VERSION_PTEXT	" part of " OPENSSL_VERSION_TEXT
 

+ 1 - 1
libs/openssl/crypto/ts/ts_rsp_sign.c

@@ -977,7 +977,7 @@ TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *asn1_time,
 	if (precision > 0)
 	{
 		/* Add fraction of seconds (leave space for dot and null). */
-		BIO_snprintf(p, 2 + precision, ".%ld", usec);
+		BIO_snprintf(p, 2 + precision, ".%06ld", usec);
 		/* We cannot use the snprintf return value, 
 		   because it might have been truncated. */
 		p += strlen(p);

+ 1 - 0
libs/openssl/crypto/x509/x509.h

@@ -768,6 +768,7 @@ int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval);
 void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
 						X509_ALGOR *algor);
 void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md);
+int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b);
 
 X509_NAME *X509_NAME_dup(X509_NAME *xn);
 X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);

+ 2 - 0
libs/openssl/crypto/x509/x509_vpm.c

@@ -89,6 +89,8 @@ X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void)
 	{
 	X509_VERIFY_PARAM *param;
 	param = OPENSSL_malloc(sizeof(X509_VERIFY_PARAM));
+	if (!param)
+		return NULL;
 	memset(param, 0, sizeof(X509_VERIFY_PARAM));
 	x509_verify_param_zero(param);
 	return param;

+ 2 - 0
libs/openssl/crypto/x509/x_all.c

@@ -72,6 +72,8 @@
 
 int X509_verify(X509 *a, EVP_PKEY *r)
 	{
+	if (X509_ALGOR_cmp(a->sig_alg, a->cert_info->signature))
+		return 0;
 	return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF),a->sig_alg,
 		a->signature,a->cert_info,r));
 	}

+ 17 - 10
libs/openssl/e_os.h

@@ -290,7 +290,7 @@ extern "C" {
 #    ifdef _WIN64
 #      define strlen(s) _strlen31(s)
 /* cut strings to 2GB */
-static unsigned int _strlen31(const char *str)
+static __inline unsigned int _strlen31(const char *str)
 	{
 	unsigned int len=0;
 	while (*str && len<0x80000000U) str++, len++;
@@ -375,15 +375,6 @@ static unsigned int _strlen31(const char *str)
 #  define check_winnt() (GetVersion() < 0x80000000)
 #endif
 
-/*
- * Visual Studio: inline is available in C++ only, however
- * __inline is available for C, see
- * http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx
- */
-#if defined(_MSC_VER) && !defined(__cplusplus) && !defined(inline)
-#  define inline __inline
-#endif
-
 #else /* The non-microsoft world */
 
 #  ifdef OPENSSL_SYS_VMS
@@ -741,6 +732,22 @@ struct servent *getservbyname(const char *name, const char *proto);
 #include <OS.h>
 #endif
 
+#if !defined(inline) && !defined(__cplusplus)
+# if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L
+   /* do nothing, inline works */
+# elif defined(__GNUC__) && __GNUC__>=2
+#  define inline __inline__
+# elif defined(_MSC_VER)
+  /*
+   * Visual Studio: inline is available in C++ only, however
+   * __inline is available for C, see
+   * http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx
+   */
+#  define inline __inline
+# else
+#  define inline
+# endif
+#endif
 
 #ifdef  __cplusplus
 }

+ 94 - 68
libs/openssl/ssl/d1_both.c

@@ -156,9 +156,8 @@ static unsigned char bitmask_start_values[] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe
 static unsigned char bitmask_end_values[]   = {0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f};
 
 /* XDTLS:  figure out the right values */
-static unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28};
+static const unsigned int g_probable_mtu[] = {1500, 512, 256};
 
-static unsigned int dtls1_guess_mtu(unsigned int curr_mtu);
 static void dtls1_fix_message_header(SSL *s, unsigned long frag_off, 
 	unsigned long frag_len);
 static unsigned char *dtls1_write_message_header(SSL *s,
@@ -211,8 +210,7 @@ dtls1_hm_fragment_new(unsigned long frag_len, int reassembly)
 	return frag;
 	}
 
-static void
-dtls1_hm_fragment_free(hm_fragment *frag)
+void dtls1_hm_fragment_free(hm_fragment *frag)
 	{
 
 	if (frag->msg_header.is_ccs)
@@ -225,53 +223,50 @@ dtls1_hm_fragment_free(hm_fragment *frag)
 	OPENSSL_free(frag);
 	}
 
-/* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC) */
-int dtls1_do_write(SSL *s, int type)
-	{
-	int ret;
-	int curr_mtu;
-	unsigned int len, frag_off, mac_size, blocksize;
+static int dtls1_query_mtu(SSL *s)
+{
+	if(s->d1->link_mtu)
+		{
+		s->d1->mtu = s->d1->link_mtu-BIO_dgram_get_mtu_overhead(SSL_get_wbio(s));
+		s->d1->link_mtu = 0;
+		}
 
 	/* AHA!  Figure out the MTU, and stick to the right size */
-	if (s->d1->mtu < dtls1_min_mtu() && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
+	if (s->d1->mtu < dtls1_min_mtu(s))
 		{
-		s->d1->mtu = 
-			BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
-
-		/* I've seen the kernel return bogus numbers when it doesn't know
-		 * (initial write), so just make sure we have a reasonable number */
-		if (s->d1->mtu < dtls1_min_mtu())
+		if(!(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
 			{
-			s->d1->mtu = 0;
-			s->d1->mtu = dtls1_guess_mtu(s->d1->mtu);
-			BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU, 
-				s->d1->mtu, NULL);
+			s->d1->mtu =
+				BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
+
+			/* I've seen the kernel return bogus numbers when it doesn't know
+			 * (initial write), so just make sure we have a reasonable number */
+			if (s->d1->mtu < dtls1_min_mtu(s))
+				{
+				/* Set to min mtu */
+				s->d1->mtu = dtls1_min_mtu(s);
+				BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU,
+					s->d1->mtu, NULL);
+				}
 			}
+		else
+			return 0;
 		}
-#if 0 
-	mtu = s->d1->mtu;
-
-	fprintf(stderr, "using MTU = %d\n", mtu);
-
-	mtu -= (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LENGTH);
-
-	curr_mtu = mtu - BIO_wpending(SSL_get_wbio(s));
+	return 1;
+}
 
-	if ( curr_mtu > 0)
-		mtu = curr_mtu;
-	else if ( ( ret = BIO_flush(SSL_get_wbio(s))) <= 0)
-		return ret;
+/* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC) */
+int dtls1_do_write(SSL *s, int type)
+	{
+	int ret;
+	unsigned int curr_mtu;
+	int retry = 1;
+	unsigned int len, frag_off, mac_size, blocksize, used_len;
 
-	if ( BIO_wpending(SSL_get_wbio(s)) + s->init_num >= mtu)
-		{
-		ret = BIO_flush(SSL_get_wbio(s));
-		if ( ret <= 0)
-			return ret;
-		mtu = s->d1->mtu - (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LENGTH);
-		}
-#endif
+	if(!dtls1_query_mtu(s))
+		return -1;
 
-	OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu());  /* should have something reasonable now */
+	OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu(s));  /* should have something reasonable now */
 
 	if ( s->init_off == 0  && type == SSL3_RT_HANDSHAKE)
 		OPENSSL_assert(s->init_num == 
@@ -289,10 +284,15 @@ int dtls1_do_write(SSL *s, int type)
 		blocksize = 0;
 
 	frag_off = 0;
-	while( s->init_num)
+	/* s->init_num shouldn't ever be < 0...but just in case */
+	while(s->init_num > 0)
 		{
-		curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) - 
-			DTLS1_RT_HEADER_LENGTH - mac_size - blocksize;
+		used_len = BIO_wpending(SSL_get_wbio(s)) +  DTLS1_RT_HEADER_LENGTH
+			+ mac_size + blocksize;
+		if(s->d1->mtu > used_len)
+			curr_mtu = s->d1->mtu - used_len;
+		else
+			curr_mtu = 0;
 
 		if ( curr_mtu <= DTLS1_HM_HEADER_LENGTH)
 			{
@@ -300,15 +300,27 @@ int dtls1_do_write(SSL *s, int type)
 			ret = BIO_flush(SSL_get_wbio(s));
 			if ( ret <= 0)
 				return ret;
-			curr_mtu = s->d1->mtu - DTLS1_RT_HEADER_LENGTH -
-				mac_size - blocksize;
+			used_len = DTLS1_RT_HEADER_LENGTH + mac_size + blocksize;
+			if(s->d1->mtu > used_len + DTLS1_HM_HEADER_LENGTH)
+				{
+				curr_mtu = s->d1->mtu - used_len;
+				}
+			else
+				{
+				/* Shouldn't happen */
+				return -1;
+				}
 			}
 
-		if ( s->init_num > curr_mtu)
+		/* We just checked that s->init_num > 0 so this cast should be safe */
+		if (((unsigned int)s->init_num) > curr_mtu)
 			len = curr_mtu;
 		else
 			len = s->init_num;
 
+		/* Shouldn't ever happen */
+		if(len > INT_MAX)
+			len = INT_MAX;
 
 		/* XDTLS: this function is too long.  split out the CCS part */
 		if ( type == SSL3_RT_HANDSHAKE)
@@ -319,18 +331,29 @@ int dtls1_do_write(SSL *s, int type)
 				s->init_off -= DTLS1_HM_HEADER_LENGTH;
 				s->init_num += DTLS1_HM_HEADER_LENGTH;
 
-				if ( s->init_num > curr_mtu)
+				/* We just checked that s->init_num > 0 so this cast should be safe */
+				if (((unsigned int)s->init_num) > curr_mtu)
 					len = curr_mtu;
 				else
 					len = s->init_num;
 				}
 
+			/* Shouldn't ever happen */
+			if(len > INT_MAX)
+				len = INT_MAX;
+
+			if ( len < DTLS1_HM_HEADER_LENGTH )
+				{
+				/*
+				 * len is so small that we really can't do anything sensible
+				 * so fail
+				 */
+				return -1;
+				}
 			dtls1_fix_message_header(s, frag_off, 
 				len - DTLS1_HM_HEADER_LENGTH);
 
 			dtls1_write_message_header(s, (unsigned char *)&s->init_buf->data[s->init_off]);
-
-			OPENSSL_assert(len >= DTLS1_HM_HEADER_LENGTH);
 			}
 
 		ret=dtls1_write_bytes(s,type,&s->init_buf->data[s->init_off],
@@ -343,12 +366,23 @@ int dtls1_do_write(SSL *s, int type)
 			 * is fine and wait for an alert to handle the
 			 * retransmit 
 			 */
-			if ( BIO_ctrl(SSL_get_wbio(s),
+			if ( retry && BIO_ctrl(SSL_get_wbio(s),
 				BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0 )
-				s->d1->mtu = BIO_ctrl(SSL_get_wbio(s),
-					BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
+				{
+				if(!(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
+					{
+					if(!dtls1_query_mtu(s))
+						return -1;
+					/* Have one more go */
+					retry = 0;
+					}
+				else
+					return -1;
+				}
 			else
+				{
 				return(-1);
+				}
 			}
 		else
 			{
@@ -1412,28 +1446,20 @@ dtls1_write_message_header(SSL *s, unsigned char *p)
 	return p;
 	}
 
-unsigned int 
-dtls1_min_mtu(void)
+unsigned int
+dtls1_link_min_mtu(void)
 	{
 	return (g_probable_mtu[(sizeof(g_probable_mtu) / 
 		sizeof(g_probable_mtu[0])) - 1]);
 	}
 
-static unsigned int 
-dtls1_guess_mtu(unsigned int curr_mtu)
+unsigned int
+dtls1_min_mtu(SSL *s)
 	{
-	unsigned int i;
-
-	if ( curr_mtu == 0 )
-		return g_probable_mtu[0] ;
-
-	for ( i = 0; i < sizeof(g_probable_mtu)/sizeof(g_probable_mtu[0]); i++)
-		if ( curr_mtu > g_probable_mtu[i])
-			return g_probable_mtu[i];
-
-	return curr_mtu;
+	return dtls1_link_min_mtu()-BIO_dgram_get_mtu_overhead(SSL_get_wbio(s));
 	}
 
+
 void
 dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr)
 	{

+ 9 - 16
libs/openssl/ssl/d1_clnt.c

@@ -249,6 +249,9 @@ int dtls1_connect(SSL *s)
 			memset(s->s3->client_random,0,sizeof(s->s3->client_random));
 			s->d1->send_cookie = 0;
 			s->hit = 0;
+			s->d1->change_cipher_spec_ok = 0;
+			/* Should have been reset by ssl3_get_finished, too. */
+			s->s3->change_cipher_spec = 0;
 			break;
 
 #ifndef OPENSSL_NO_SCTP
@@ -370,20 +373,6 @@ int dtls1_connect(SSL *s)
 
 		case SSL3_ST_CR_CERT_A:
 		case SSL3_ST_CR_CERT_B:
-#ifndef OPENSSL_NO_TLSEXT
-			ret=ssl3_check_finished(s);
-			if (ret <= 0) goto end;
-			if (ret == 2)
-				{
-				s->hit = 1;
-				if (s->tlsext_ticket_expected)
-					s->state=SSL3_ST_CR_SESSION_TICKET_A;
-				else
-					s->state=SSL3_ST_CR_FINISHED_A;
-				s->init_num=0;
-				break;
-				}
-#endif
 			/* Check if it is anon DH or PSK */
 			if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
 			    !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
@@ -506,7 +495,6 @@ int dtls1_connect(SSL *s)
 				else
 #endif
 					s->state=SSL3_ST_CW_CHANGE_A;
-				s->s3->change_cipher_spec=0;
 				}
 
 			s->init_num=0;
@@ -527,7 +515,6 @@ int dtls1_connect(SSL *s)
 #endif
 				s->state=SSL3_ST_CW_CHANGE_A;
 			s->init_num=0;
-			s->s3->change_cipher_spec=0;
 			break;
 
 		case SSL3_ST_CW_CHANGE_A:
@@ -1730,6 +1717,12 @@ int dtls1_send_client_certificate(SSL *s)
 		s->state=SSL3_ST_CW_CERT_D;
 		l=dtls1_output_cert_chain(s,
 			(s->s3->tmp.cert_req == 2)?NULL:s->cert->key->x509);
+		if (!l)
+			{
+			SSLerr(SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR);
+			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INTERNAL_ERROR);
+			return 0;
+			}
 		s->init_num=(int)l;
 		s->init_off=0;
 

+ 2 - 1
libs/openssl/ssl/d1_enc.c

@@ -241,7 +241,8 @@ int dtls1_enc(SSL *s, int send)
 				return 0;
 			}
 		
-		EVP_Cipher(ds,rec->data,rec->input,l);
+		if(EVP_Cipher(ds,rec->data,rec->input,l) < 1)
+			return -1;
 
 #ifdef KSSL_DEBUG
 		{

+ 31 - 7
libs/openssl/ssl/d1_lib.c

@@ -113,6 +113,9 @@ int dtls1_new(SSL *s)
 		d1->cookie_len = sizeof(s->d1->cookie);
 		}
 
+	d1->link_mtu = 0;
+	d1->mtu = 0;
+
 	if( ! d1->unprocessed_rcds.q || ! d1->processed_rcds.q 
         || ! d1->buffered_messages || ! d1->sent_messages || ! d1->buffered_app_data.q)
 		{
@@ -161,16 +164,14 @@ static void dtls1_clear_queues(SSL *s)
     while( (item = pqueue_pop(s->d1->buffered_messages)) != NULL)
         {
         frag = (hm_fragment *)item->data;
-        OPENSSL_free(frag->fragment);
-        OPENSSL_free(frag);
+        dtls1_hm_fragment_free(frag);
         pitem_free(item);
         }
 
     while ( (item = pqueue_pop(s->d1->sent_messages)) != NULL)
         {
         frag = (hm_fragment *)item->data;
-        OPENSSL_free(frag->fragment);
-        OPENSSL_free(frag);
+        dtls1_hm_fragment_free(frag);
         pitem_free(item);
         }
 
@@ -210,6 +211,7 @@ void dtls1_clear(SSL *s)
 	pqueue sent_messages;
 	pqueue buffered_app_data;
 	unsigned int mtu;
+	unsigned int link_mtu;
 
 	if (s->d1)
 		{
@@ -219,6 +221,7 @@ void dtls1_clear(SSL *s)
 		sent_messages = s->d1->sent_messages;
 		buffered_app_data = s->d1->buffered_app_data.q;
 		mtu = s->d1->mtu;
+		link_mtu = s->d1->link_mtu;
 
 		dtls1_clear_queues(s);
 
@@ -232,6 +235,7 @@ void dtls1_clear(SSL *s)
 		if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)
 			{
 			s->d1->mtu = mtu;
+			s->d1->link_mtu = link_mtu;
 			}
 
 		s->d1->unprocessed_rcds.q = unprocessed_rcds;
@@ -276,7 +280,22 @@ long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg)
 		/* Just one protocol version is supported so far;
 		 * fail closed if the version is not as expected. */
 		return s->version == DTLS_MAX_VERSION;
-
+	case DTLS_CTRL_SET_LINK_MTU:
+		if (larg < (long)dtls1_link_min_mtu())
+			return 0;
+		s->d1->link_mtu = larg;
+		return 1;
+	case DTLS_CTRL_GET_LINK_MIN_MTU:
+		return (long)dtls1_link_min_mtu();
+	case SSL_CTRL_SET_MTU:
+		/*
+		 *  We may not have a BIO set yet so can't call dtls1_min_mtu()
+		 *  We'll have to make do with dtls1_link_min_mtu() and max overhead
+		 */
+		if (larg < (long)dtls1_link_min_mtu() - DTLS1_MAX_MTU_OVERHEAD)
+			return 0;
+		s->d1->mtu = larg;
+		return larg;
 	default:
 		ret = ssl3_ctrl(s, cmd, larg, parg);
 		break;
@@ -415,12 +434,17 @@ void dtls1_stop_timer(SSL *s)
 
 int dtls1_check_timeout_num(SSL *s)
 	{
+	unsigned int mtu;
+
 	s->d1->timeout.num_alerts++;
 
 	/* Reduce MTU after 2 unsuccessful retransmissions */
-	if (s->d1->timeout.num_alerts > 2)
+	if (s->d1->timeout.num_alerts > 2
+			&& !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
 		{
-		s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL);		
+		mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL);
+		if(mtu < s->d1->mtu)
+			s->d1->mtu = mtu;
 		}
 
 	if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT)

+ 24 - 13
libs/openssl/ssl/d1_pkt.c

@@ -212,7 +212,7 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority)
 	/* Limit the size of the queue to prevent DOS attacks */
 	if (pqueue_size(queue->q) >= 100)
 		return 0;
-		
+
 	rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA));
 	item = pitem_new(priority, rdata);
 	if (rdata == NULL || item == NULL)
@@ -247,18 +247,22 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority)
 	if (!ssl3_setup_buffers(s))
 		{
 		SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
+		if (rdata->rbuf.buf != NULL)
+			OPENSSL_free(rdata->rbuf.buf);
 		OPENSSL_free(rdata);
 		pitem_free(item);
-		return(0);
+		return(-1);
 		}
 
 	/* insert should not fail, since duplicates are dropped */
 	if (pqueue_insert(queue->q, item) == NULL)
 		{
 		SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
+		if (rdata->rbuf.buf != NULL)
+			OPENSSL_free(rdata->rbuf.buf);
 		OPENSSL_free(rdata);
 		pitem_free(item);
-		return(0);
+		return(-1);
 		}
 
 	return(1);
@@ -314,8 +318,9 @@ dtls1_process_buffered_records(SSL *s)
             dtls1_get_unprocessed_record(s);
             if ( ! dtls1_process_record(s))
                 return(0);
-            dtls1_buffer_record(s, &(s->d1->processed_rcds), 
-                s->s3->rrec.seq_num);
+            if(dtls1_buffer_record(s, &(s->d1->processed_rcds),
+                s->s3->rrec.seq_num)<0)
+                return -1;
             }
         }
 
@@ -530,7 +535,6 @@ printf("\n");
 
 	/* we have pulled in a full packet so zero things */
 	s->packet_length=0;
-	dtls1_record_bitmap_update(s, &(s->d1->bitmap));/* Mark receipt of record. */
 	return(1);
 
 f_err:
@@ -563,7 +567,8 @@ int dtls1_get_record(SSL *s)
 
 	/* The epoch may have changed.  If so, process all the
 	 * pending records.  This is a non-blocking operation. */
-	dtls1_process_buffered_records(s);
+	if(dtls1_process_buffered_records(s)<0)
+		return -1;
 
 	/* if we're renegotiating, then there may be buffered records */
 	if (dtls1_get_processed_record(s))
@@ -642,8 +647,6 @@ again:
 		/* now s->packet_length == DTLS1_RT_HEADER_LENGTH */
 		i=rr->length;
 		n=ssl3_read_n(s,i,i,1);
-		if (n <= 0) return(n); /* error or non-blocking io */
-
 		/* this packet contained a partial record, dump it */
 		if ( n != i)
 			{
@@ -678,7 +681,8 @@ again:
 		 * would be dropped unnecessarily.
 		 */
 		if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE &&
-		    *p == SSL3_MT_CLIENT_HELLO) &&
+		    s->packet_length > DTLS1_RT_HEADER_LENGTH &&
+		    s->packet[DTLS1_RT_HEADER_LENGTH] == SSL3_MT_CLIENT_HELLO) &&
 		    !dtls1_record_replay_check(s, bitmap))
 			{
 			rr->length = 0;
@@ -701,7 +705,9 @@ again:
 		{
 		if ((SSL_in_init(s) || s->in_handshake) && !s->d1->listen)
 			{
-			dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num);
+			if(dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num)<0)
+				return -1;
+			dtls1_record_bitmap_update(s, bitmap);/* Mark receipt of record. */
 			}
 		rr->length = 0;
 		s->packet_length = 0;
@@ -714,6 +720,7 @@ again:
 		s->packet_length = 0;  /* dump this record */
 		goto again;   /* get another record */
 		}
+	dtls1_record_bitmap_update(s, bitmap);/* Mark receipt of record. */
 
 	return(1);
 
@@ -865,7 +872,11 @@ start:
 		 * buffer the application data for later processing rather
 		 * than dropping the connection.
 		 */
-		dtls1_buffer_record(s, &(s->d1->buffered_app_data), rr->seq_num);
+		if(dtls1_buffer_record(s, &(s->d1->buffered_app_data), rr->seq_num)<0)
+			{
+			SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR);
+			return -1;
+			}
 		rr->length = 0;
 		goto start;
 		}
@@ -1619,7 +1630,7 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len,
 		wr->length += bs;
 		}
 
-	s->method->ssl3_enc->enc(s,1);
+	if(s->method->ssl3_enc->enc(s,1) < 1) goto err;
 
 	/* record length after mac and block padding */
 /*	if (type == SSL3_RT_APPLICATION_DATA ||

+ 35 - 18
libs/openssl/ssl/d1_srvr.c

@@ -233,6 +233,7 @@ int dtls1_accept(SSL *s)
 					}
 				if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
 					{
+					BUF_MEM_free(buf);
 					ret= -1;
 					goto end;
 					}
@@ -246,6 +247,9 @@ int dtls1_accept(SSL *s)
 				}
 
 			s->init_num=0;
+			s->d1->change_cipher_spec_ok = 0;
+			/* Should have been reset by ssl3_get_finished, too. */
+			s->s3->change_cipher_spec = 0;
 
 			if (s->state != SSL_ST_RENEGOTIATE)
 				{
@@ -450,24 +454,15 @@ int dtls1_accept(SSL *s)
 		case SSL3_ST_SW_KEY_EXCH_B:
 			alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
 
-			/* clear this, it may get reset by
-			 * send_server_key_exchange */
-			if ((s->options & SSL_OP_EPHEMERAL_RSA)
-#ifndef OPENSSL_NO_KRB5
-				&& !(alg_k & SSL_kKRB5)
-#endif /* OPENSSL_NO_KRB5 */
-				)
-				/* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
-				 * even when forbidden by protocol specs
-				 * (handshake may fail as clients are not required to
-				 * be able to handle this) */
-				s->s3->tmp.use_rsa_tmp=1;
-			else
-				s->s3->tmp.use_rsa_tmp=0;
+			/*
+			 * clear this, it may get reset by
+			 * send_server_key_exchange
+			 */
+			s->s3->tmp.use_rsa_tmp=0;
 
 			/* only send if a DH key exchange or
 			 * RSA but we have a sign only certificate */
-			if (s->s3->tmp.use_rsa_tmp
+			if (0
 			/* PSK: send ServerKeyExchange if PSK identity
 			 * hint if provided */
 #ifndef OPENSSL_NO_PSK
@@ -658,8 +653,14 @@ int dtls1_accept(SSL *s)
 
 		case SSL3_ST_SR_CERT_VRFY_A:
 		case SSL3_ST_SR_CERT_VRFY_B:
-
-			s->d1->change_cipher_spec_ok = 1;
+			/*
+			 * This *should* be the first time we enable CCS, but be
+			 * extra careful about surrounding code changes. We need
+			 * to set this here because we don't know if we're
+			 * expecting a CertificateVerify or not.
+			 */
+			if (!s->s3->change_cipher_spec)
+				s->d1->change_cipher_spec_ok = 1;
 			/* we should decide if we expected this one */
 			ret=ssl3_get_cert_verify(s);
 			if (ret <= 0) goto end;
@@ -675,7 +676,18 @@ int dtls1_accept(SSL *s)
 
 		case SSL3_ST_SR_FINISHED_A:
 		case SSL3_ST_SR_FINISHED_B:
-			s->d1->change_cipher_spec_ok = 1;
+			/*
+			 * Enable CCS for resumed handshakes.
+			 * In a full handshake, we end up here through
+			 * SSL3_ST_SR_CERT_VRFY_B, so change_cipher_spec_ok was
+			 * already set. Receiving a CCS clears the flag, so make
+			 * sure not to re-enable it to ban duplicates.
+			 * s->s3->change_cipher_spec is set when a CCS is
+			 * processed in d1_pkt.c, and remains set until
+			 * the client's Finished message is read.
+			 */
+			if (!s->s3->change_cipher_spec)
+				s->d1->change_cipher_spec_ok = 1;
 			ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
 				SSL3_ST_SR_FINISHED_B);
 			if (ret <= 0) goto end;
@@ -1604,6 +1616,11 @@ int dtls1_send_server_certificate(SSL *s)
 			}
 
 		l=dtls1_output_cert_chain(s,x);
+		if (!l)
+			{
+			SSLerr(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR);
+			return(0);
+			}
 		s->state=SSL3_ST_SW_CERT_B;
 		s->init_num=(int)l;
 		s->init_off=0;

+ 8 - 0
libs/openssl/ssl/dtls1.h

@@ -117,6 +117,9 @@ extern "C" {
 #define DTLS1_SCTP_AUTH_LABEL	"EXPORTER_DTLS_OVER_SCTP"
 #endif
 
+/* Max MTU overhead we know about so far is 40 for IPv6 + 8 for UDP */
+#define DTLS1_MAX_MTU_OVERHEAD                   48
+
 typedef struct dtls1_bitmap_st
 	{
 	unsigned long map;		/* track 32 packets on 32-bit systems
@@ -231,6 +234,7 @@ typedef struct dtls1_state_st
 	/* Is set when listening for new connections with dtls1_listen() */
 	unsigned int listen;
 
+	unsigned int link_mtu; /* max on-the-wire DTLS packet size */
 	unsigned int mtu; /* max DTLS packet size */
 
 	struct hm_header_st w_msg_hdr;
@@ -252,6 +256,10 @@ typedef struct dtls1_state_st
 	unsigned int handshake_fragment_len;
 
 	unsigned int retransmitting;
+	/*
+	 * Set when the handshake is ready to process peer's ChangeCipherSpec message.
+	 * Cleared after the message has been processed.
+	 */
 	unsigned int change_cipher_spec_ok;
 
 #ifndef OPENSSL_NO_SCTP

+ 36 - 36
libs/openssl/ssl/kssl.c

@@ -954,15 +954,15 @@ print_krb5_data(char *label, krb5_data *kdata)
         {
 	int i;
 
-	printf("%s[%d] ", label, kdata->length);
+	fprintf(stderr,"%s[%d] ", label, kdata->length);
 	for (i=0; i < (int)kdata->length; i++)
                 {
 		if (0 &&  isprint((int) kdata->data[i]))
-                        printf(	"%c ",  kdata->data[i]);
+                        fprintf(stderr,	"%c ",  kdata->data[i]);
 		else
-                        printf(	"%02x ", (unsigned char) kdata->data[i]);
+                        fprintf(stderr,	"%02x ", (unsigned char) kdata->data[i]);
 		}
-	printf("\n");
+	fprintf(stderr,"\n");
         }
 
 
@@ -973,20 +973,20 @@ print_krb5_authdata(char *label, krb5_authdata **adata)
         {
 	if (adata == NULL)
                 {
-		printf("%s, authdata==0\n", label);
+		fprintf(stderr,"%s, authdata==0\n", label);
 		return;
 		}
-	printf("%s [%p]\n", label, (void *)adata);
+	fprintf(stderr,"%s [%p]\n", label, (void *)adata);
 #if 0
 	{
         int 	i;
-	printf("%s[at%d:%d] ", label, adata->ad_type, adata->length);
+	fprintf(stderr,"%s[at%d:%d] ", label, adata->ad_type, adata->length);
 	for (i=0; i < adata->length; i++)
                 {
-                printf((isprint(adata->contents[i]))? "%c ": "%02x",
+                fprintf(stderr,(isprint(adata->contents[i]))? "%c ": "%02x",
                         adata->contents[i]);
 		}
-	printf("\n");
+	fprintf(stderr,"\n");
 	}
 #endif
 	}
@@ -1001,24 +1001,24 @@ print_krb5_keyblock(char *label, krb5_keyblock *keyblk)
 
 	if (keyblk == NULL)
                 {
-		printf("%s, keyblk==0\n", label);
+		fprintf(stderr,"%s, keyblk==0\n", label);
 		return;
 		}
 #ifdef KRB5_HEIMDAL
-	printf("%s\n\t[et%d:%d]: ", label, keyblk->keytype,
+	fprintf(stderr,"%s\n\t[et%d:%d]: ", label, keyblk->keytype,
 					   keyblk->keyvalue->length);
 	for (i=0; i < (int)keyblk->keyvalue->length; i++)
                 {
-		printf("%02x",(unsigned char *)(keyblk->keyvalue->contents)[i]);
+		fprintf(stderr,"%02x",(unsigned char *)(keyblk->keyvalue->contents)[i]);
 		}
-	printf("\n");
+	fprintf(stderr,"\n");
 #else
-	printf("%s\n\t[et%d:%d]: ", label, keyblk->enctype, keyblk->length);
+	fprintf(stderr,"%s\n\t[et%d:%d]: ", label, keyblk->enctype, keyblk->length);
 	for (i=0; i < (int)keyblk->length; i++)
                 {
-		printf("%02x",keyblk->contents[i]);
+		fprintf(stderr,"%02x",keyblk->contents[i]);
 		}
-	printf("\n");
+	fprintf(stderr,"\n");
 #endif
         }
 
@@ -1031,17 +1031,17 @@ print_krb5_princ(char *label, krb5_principal_data *princ)
         {
 	int i, ui, uj;
 
-	printf("%s principal Realm: ", label);
+	fprintf(stderr,"%s principal Realm: ", label);
 	if (princ == NULL)  return;
 	for (ui=0; ui < (int)princ->realm.length; ui++)  putchar(princ->realm.data[ui]);
-	printf(" (nametype %d) has %d strings:\n", princ->type,princ->length);
+	fprintf(stderr," (nametype %d) has %d strings:\n", princ->type,princ->length);
 	for (i=0; i < (int)princ->length; i++)
                 {
-		printf("\t%d [%d]: ", i, princ->data[i].length);
+		fprintf(stderr,"\t%d [%d]: ", i, princ->data[i].length);
 		for (uj=0; uj < (int)princ->data[i].length; uj++)  {
 			putchar(princ->data[i].data[uj]);
 			}
-		printf("\n");
+		fprintf(stderr,"\n");
 		}
 	return;
         }
@@ -1332,7 +1332,7 @@ kssl_sget_tkt(	/* UPDATE */	KSSL_CTX		*kssl_ctx,
 		}
 
 #ifdef KSSL_DEBUG
-	printf("in kssl_sget_tkt(%s)\n", kstring(kssl_ctx->service_name));
+	fprintf(stderr,"in kssl_sget_tkt(%s)\n", kstring(kssl_ctx->service_name));
 #endif	/* KSSL_DEBUG */
 
 	if (!krb5context  &&  (krb5rc = krb5_init_context(&krb5context)))
@@ -1481,18 +1481,18 @@ kssl_sget_tkt(	/* UPDATE */	KSSL_CTX		*kssl_ctx,
 #ifdef KSSL_DEBUG
 		{
 		int i; krb5_address **paddr = krb5ticket->enc_part2->caddrs;
-		printf("Decrypted ticket fields:\n");
-		printf("\tflags: %X, transit-type: %X",
+		fprintf(stderr,"Decrypted ticket fields:\n");
+		fprintf(stderr,"\tflags: %X, transit-type: %X",
 			krb5ticket->enc_part2->flags,
 			krb5ticket->enc_part2->transited.tr_type);
 		print_krb5_data("\ttransit-data: ",
 			&(krb5ticket->enc_part2->transited.tr_contents));
-		printf("\tcaddrs: %p, authdata: %p\n",
+		fprintf(stderr,"\tcaddrs: %p, authdata: %p\n",
 			krb5ticket->enc_part2->caddrs,
 			krb5ticket->enc_part2->authorization_data);
 		if (paddr)
 			{
-			printf("\tcaddrs:\n");
+			fprintf(stderr,"\tcaddrs:\n");
 			for (i=0; paddr[i] != NULL; i++)
 				{
 				krb5_data d;
@@ -1501,7 +1501,7 @@ kssl_sget_tkt(	/* UPDATE */	KSSL_CTX		*kssl_ctx,
 				print_krb5_data("\t\tIP: ", &d);
 				}
 			}
-		printf("\tstart/auth/end times: %d / %d / %d\n",
+		fprintf(stderr,"\tstart/auth/end times: %d / %d / %d\n",
 			krb5ticket->enc_part2->times.starttime,
 			krb5ticket->enc_part2->times.authtime,
 			krb5ticket->enc_part2->times.endtime);
@@ -1976,7 +1976,7 @@ krb5_error_code  kssl_validate_times(	krb5_timestamp atime,
 	if ((now - ttimes->endtime) > skew)  return SSL_R_KRB5_S_TKT_EXPIRED;
 
 #ifdef KSSL_DEBUG
-	printf("kssl_validate_times: %d |<-  | %d - %d | < %d  ->| %d\n",
+	fprintf(stderr,"kssl_validate_times: %d |<-  | %d - %d | < %d  ->| %d\n",
 		start, atime, now, skew, ttimes->endtime);
 #endif	/* KSSL_DEBUG */
 
@@ -2027,10 +2027,10 @@ krb5_error_code  kssl_check_authent(
 #ifdef KSSL_DEBUG
         {
         unsigned int ui;
-	printf("kssl_check_authent: authenticator[%d]:\n",authentp->length);
+	fprintf(stderr,"kssl_check_authent: authenticator[%d]:\n",authentp->length);
 	p = authentp->data; 
-	for (ui=0; ui < authentp->length; ui++)  printf("%02x ",p[ui]);
-	printf("\n");
+	for (ui=0; ui < authentp->length; ui++)  fprintf(stderr,"%02x ",p[ui]);
+	fprintf(stderr,"\n");
         }
 #endif	/* KSSL_DEBUG */
 
@@ -2095,9 +2095,9 @@ krb5_error_code  kssl_check_authent(
 #ifdef KSSL_DEBUG
 	{
 	int padl;
-	printf("kssl_check_authent: decrypted authenticator[%d] =\n", outl);
-	for (padl=0; padl < outl; padl++) printf("%02x ",unenc_authent[padl]);
-	printf("\n");
+	fprintf(stderr,"kssl_check_authent: decrypted authenticator[%d] =\n", outl);
+	for (padl=0; padl < outl; padl++) fprintf(stderr,"%02x ",unenc_authent[padl]);
+	fprintf(stderr,"\n");
 	}
 #endif	/* KSSL_DEBUG */
 
@@ -2132,10 +2132,10 @@ krb5_error_code  kssl_check_authent(
  		}
 
 #ifdef KSSL_DEBUG
-	printf("kssl_check_authent: returns %d for client time ", *atimep);
+	fprintf(stderr,"kssl_check_authent: returns %d for client time ", *atimep);
 	if (auth && auth->ctime && auth->ctime->length && auth->ctime->data)
-		printf("%.*s\n", auth->ctime->length, auth->ctime->data);
-	else	printf("NULL\n");
+		fprintf(stderr,"%.*s\n", auth->ctime->length, auth->ctime->data);
+	else	fprintf(stderr,"NULL\n");
 #endif	/* KSSL_DEBUG */
 
  err:

+ 5 - 2
libs/openssl/ssl/s23_srvr.c

@@ -192,6 +192,7 @@ int ssl23_accept(SSL *s)
 					}
 				if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
 					{
+					BUF_MEM_free(buf);
 					ret= -1;
 					goto end;
 					}
@@ -602,12 +603,14 @@ int ssl23_get_client_hello(SSL *s)
 	if ((type == 2) || (type == 3))
 		{
 		/* we have SSLv3/TLSv1 (type 2: SSL2 style, type 3: SSL3/TLS style) */
-                s->method = ssl23_get_server_method(s->version);
-		if (s->method == NULL)
+		const SSL_METHOD *new_method;
+		new_method = ssl23_get_server_method(s->version);
+		if (new_method == NULL)
 			{
 			SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
 			goto err;
 			}
+		s->method = new_method;
 
 		if (!ssl_init_wbio_buffer(s,1)) goto err;
 

+ 8 - 4
libs/openssl/ssl/s2_enc.c

@@ -117,8 +117,9 @@ err:
 
 /* read/writes from s->s2->mac_data using length for encrypt and 
  * decrypt.  It sets s->s2->padding and s->[rw]length
- * if we are encrypting */
-void ssl2_enc(SSL *s, int send)
+ * if we are encrypting
+ * Returns 0 on error and 1 on success */
+int ssl2_enc(SSL *s, int send)
 	{
 	EVP_CIPHER_CTX *ds;
 	unsigned long l;
@@ -136,7 +137,7 @@ void ssl2_enc(SSL *s, int send)
 		}
 
 	/* check for NULL cipher */
-	if (ds == NULL) return;
+	if (ds == NULL) return 1;
 
 
 	bs=ds->cipher->block_size;
@@ -145,7 +146,10 @@ void ssl2_enc(SSL *s, int send)
 	if (bs == 8)
 		l=(l+7)/8*8;
 
-	EVP_Cipher(ds,s->s2->mac_data,s->s2->mac_data,l);
+	if(EVP_Cipher(ds,s->s2->mac_data,s->s2->mac_data,l) < 1)
+		return 0;
+
+	return 1;
 	}
 
 void ssl2_mac(SSL *s, unsigned char *md, int send)

+ 7 - 2
libs/openssl/ssl/s2_pkt.c

@@ -265,7 +265,11 @@ static int ssl2_read_internal(SSL *s, void *buf, int len, int peek)
 		if ((!s->s2->clear_text) &&
 			(s->s2->rlength >= (unsigned int)mac_size))
 			{
-			ssl2_enc(s,0);
+			if(!ssl2_enc(s,0))
+				{
+				SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_DECRYPTION_FAILED);
+				return(-1);
+				}
 			s->s2->ract_data_length-=mac_size;
 			ssl2_mac(s,mac,0);
 			s->s2->ract_data_length-=s->s2->padding;
@@ -616,7 +620,8 @@ static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len)
 		s->s2->wact_data_length=len+p;
 		ssl2_mac(s,s->s2->mac_data,1);
 		s->s2->wlength+=p+mac_size;
-		ssl2_enc(s,1);
+		if(ssl2_enc(s,1) < 1)
+			return -1;
 		}
 
 	/* package up the header */

+ 15 - 7
libs/openssl/ssl/s2_srvr.c

@@ -188,13 +188,21 @@ int ssl2_accept(SSL *s)
 			s->version=SSL2_VERSION;
 			s->type=SSL_ST_ACCEPT;
 
-			buf=s->init_buf;
-			if ((buf == NULL) && ((buf=BUF_MEM_new()) == NULL))
-				{ ret= -1; goto end; }
-			if (!BUF_MEM_grow(buf,(int)
-				SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER))
-				{ ret= -1; goto end; }
-			s->init_buf=buf;
+			if(s->init_buf == NULL)
+				{
+				if ((buf=BUF_MEM_new()) == NULL)
+					{
+					ret= -1;
+					goto end;
+					}
+				if (!BUF_MEM_grow(buf,(int) SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER))
+					{
+					BUF_MEM_free(buf);
+					ret= -1;
+					goto end;
+					}
+				s->init_buf=buf;
+				}
 			s->init_num=0;
 			s->ctx->stats.sess_accept++;
 			s->handshake_func=ssl2_accept;

+ 1 - 0
libs/openssl/ssl/s3_both.c

@@ -439,6 +439,7 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
 			goto f_err;
 			}
 		*ok=1;
+		s->state = stn;
 		s->init_msg = s->init_buf->data + 4;
 		s->init_num = (int)s->s3->tmp.message_size;
 		return s->init_num;

+ 48 - 83
libs/openssl/ssl/s3_clnt.c

@@ -167,9 +167,9 @@
 #include <openssl/engine.h>
 #endif
 
-static const SSL_METHOD *ssl3_get_client_method(int ver);
 static int ca_dn_cmp(const X509_NAME * const *a,const X509_NAME * const *b);
 
+#ifndef OPENSSL_NO_SSL3_METHOD
 static const SSL_METHOD *ssl3_get_client_method(int ver)
 	{
 	if (ver == SSL3_VERSION)
@@ -182,6 +182,7 @@ IMPLEMENT_ssl3_meth_func(SSLv3_client_method,
 			ssl_undefined_function,
 			ssl3_connect,
 			ssl3_get_client_method)
+#endif
 
 int ssl3_connect(SSL *s)
 	{
@@ -272,6 +273,9 @@ int ssl3_connect(SSL *s)
 			s->state=SSL3_ST_CW_CLNT_HELLO_A;
 			s->ctx->stats.sess_connect++;
 			s->init_num=0;
+			s->s3->flags &= ~SSL3_FLAGS_CCS_OK;
+			/* Should have been reset by ssl3_get_finished, too. */
+			s->s3->change_cipher_spec = 0;
 			break;
 
 		case SSL3_ST_CW_CLNT_HELLO_A:
@@ -312,20 +316,6 @@ int ssl3_connect(SSL *s)
 
 		case SSL3_ST_CR_CERT_A:
 		case SSL3_ST_CR_CERT_B:
-#ifndef OPENSSL_NO_TLSEXT
-			ret=ssl3_check_finished(s);
-			if (ret <= 0) goto end;
-			if (ret == 2)
-				{
-				s->hit = 1;
-				if (s->tlsext_ticket_expected)
-					s->state=SSL3_ST_CR_SESSION_TICKET_A;
-				else
-					s->state=SSL3_ST_CR_FINISHED_A;
-				s->init_num=0;
-				break;
-				}
-#endif
 			/* Check if it is anon DH/ECDH, SRP auth */
 			/* or PSK */
 			if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL|SSL_aSRP)) &&
@@ -433,12 +423,10 @@ int ssl3_connect(SSL *s)
 			else
 				{
 				s->state=SSL3_ST_CW_CHANGE_A;
-				s->s3->change_cipher_spec=0;
 				}
 			if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY)
 				{
 				s->state=SSL3_ST_CW_CHANGE_A;
-				s->s3->change_cipher_spec=0;
 				}
 
 			s->init_num=0;
@@ -450,7 +438,6 @@ int ssl3_connect(SSL *s)
 			if (ret <= 0) goto end;
 			s->state=SSL3_ST_CW_CHANGE_A;
 			s->init_num=0;
-			s->s3->change_cipher_spec=0;
 			break;
 
 		case SSL3_ST_CW_CHANGE_A:
@@ -510,7 +497,6 @@ int ssl3_connect(SSL *s)
 				s->method->ssl3_enc->client_finished_label,
 				s->method->ssl3_enc->client_finished_label_len);
 			if (ret <= 0) goto end;
-			s->s3->flags |= SSL3_FLAGS_CCS_OK;
 			s->state=SSL3_ST_CW_FLUSH;
 
 			/* clear flags */
@@ -559,7 +545,6 @@ int ssl3_connect(SSL *s)
 
 		case SSL3_ST_CR_FINISHED_A:
 		case SSL3_ST_CR_FINISHED_B:
-
 			s->s3->flags |= SSL3_FLAGS_CCS_OK;
 			ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A,
 				SSL3_ST_CR_FINISHED_B);
@@ -669,11 +654,7 @@ int ssl3_client_hello(SSL *s)
 		SSL_SESSION *sess = s->session;
 		if ((sess == NULL) ||
 			(sess->ssl_version != s->version) ||
-#ifdef OPENSSL_NO_TLSEXT
 			!sess->session_id_length ||
-#else
-			(!sess->session_id_length && !sess->tlsext_tick) ||
-#endif
 			(sess->not_resumable))
 			{
 			if (!ssl_get_new_session(s,0))
@@ -879,6 +860,8 @@ int ssl3_get_server_hello(SSL *s)
 	memcpy(s->s3->server_random,p,SSL3_RANDOM_SIZE);
 	p+=SSL3_RANDOM_SIZE;
 
+	s->hit = 0;
+
 	/* get the session-id */
 	j= *(p++);
 
@@ -902,12 +885,12 @@ int ssl3_get_server_hello(SSL *s)
 			{
 			s->session->cipher = pref_cipher ?
 				pref_cipher : ssl_get_cipher_by_char(s, p+j);
-	    		s->s3->flags |= SSL3_FLAGS_CCS_OK;
+			s->hit = 1;
 			}
 		}
 #endif /* OPENSSL_NO_TLSEXT */
 
-	if (j != 0 && j == s->session->session_id_length
+	if (!s->hit && j != 0 && j == s->session->session_id_length
 	    && memcmp(p,s->session->session_id,j) == 0)
 	    {
 	    if(s->sid_ctx_length != s->session->sid_ctx_length
@@ -918,14 +901,13 @@ int ssl3_get_server_hello(SSL *s)
 		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
 		goto f_err;
 		}
-	    s->s3->flags |= SSL3_FLAGS_CCS_OK;
 	    s->hit=1;
 	    }
-	else	/* a miss or crap from the other end */
+	/* a miss or crap from the other end */
+	if (!s->hit)
 		{
 		/* If we were trying for session-id reuse, make a new
 		 * SSL_SESSION so we don't stuff up other people */
-		s->hit=0;
 		if (s->session->session_id_length > 0)
 			{
 			if (!ssl_get_new_session(s,0))
@@ -1203,9 +1185,9 @@ int ssl3_get_server_certificate(SSL *s)
 	            ? 0 : 1;
 
 #ifdef KSSL_DEBUG
-	printf("pkey,x = %p, %p\n", pkey,x);
-	printf("ssl_cert_type(x,pkey) = %d\n", ssl_cert_type(x,pkey));
-	printf("cipher, alg, nc = %s, %lx, %lx, %d\n", s->s3->tmp.new_cipher->name,
+	fprintf(stderr,"pkey,x = %p, %p\n", pkey,x);
+	fprintf(stderr,"ssl_cert_type(x,pkey) = %d\n", ssl_cert_type(x,pkey));
+	fprintf(stderr,"cipher, alg, nc = %s, %lx, %lx, %d\n", s->s3->tmp.new_cipher->name,
 		s->s3->tmp.new_cipher->algorithm_mkey, s->s3->tmp.new_cipher->algorithm_auth, need_cert);
 #endif    /* KSSL_DEBUG */
 
@@ -1295,6 +1277,8 @@ int ssl3_get_key_exchange(SSL *s)
 	int encoded_pt_len = 0;
 #endif
 
+	EVP_MD_CTX_init(&md_ctx);
+
 	/* use same message size as in ssl3_get_certificate_request()
 	 * as ServerKeyExchange message may be skipped */
 	n=s->method->ssl_get_message(s,
@@ -1305,14 +1289,26 @@ int ssl3_get_key_exchange(SSL *s)
 		&ok);
 	if (!ok) return((int)n);
 
+	alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
+
 	if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE)
 		{
+		/*
+		 * Can't skip server key exchange if this is an ephemeral
+		 * ciphersuite.
+		 */
+		if (alg_k & (SSL_kEDH|SSL_kEECDH))
+			{
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE);
+			al = SSL_AD_UNEXPECTED_MESSAGE;
+			goto f_err;
+			}
 #ifndef OPENSSL_NO_PSK
 		/* In plain PSK ciphersuite, ServerKeyExchange can be
 		   omitted if no identity hint is sent. Set
 		   session->sess_cert anyway to avoid problems
 		   later.*/
-		if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)
+		if (alg_k & SSL_kPSK)
 			{
 			s->session->sess_cert=ssl_sess_cert_new();
 			if (s->ctx->psk_identity_hint)
@@ -1357,9 +1353,7 @@ int ssl3_get_key_exchange(SSL *s)
 	/* Total length of the parameters including the length prefix */
 	param_len=0;
 
-	alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
 	alg_a=s->s3->tmp.new_cipher->algorithm_auth;
-	EVP_MD_CTX_init(&md_ctx);
 
 	al=SSL_AD_DECODE_ERROR;
 
@@ -1543,6 +1537,13 @@ int ssl3_get_key_exchange(SSL *s)
 #ifndef OPENSSL_NO_RSA
 	if (alg_k & SSL_kRSA)
 		{
+		/* Temporary RSA keys only allowed in export ciphersuites */
+		if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher))
+			{
+			al=SSL_AD_UNEXPECTED_MESSAGE;
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE);
+			goto f_err;
+			}
 		if ((rsa=RSA_new()) == NULL)
 			{
 			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
@@ -2174,24 +2175,13 @@ int ssl3_get_new_session_ticket(SSL *s)
 	n=s->method->ssl_get_message(s,
 		SSL3_ST_CR_SESSION_TICKET_A,
 		SSL3_ST_CR_SESSION_TICKET_B,
-		-1,
+		SSL3_MT_NEWSESSION_TICKET,
 		16384,
 		&ok);
 
 	if (!ok)
 		return((int)n);
 
-	if (s->s3->tmp.message_type == SSL3_MT_FINISHED)
-		{
-		s->s3->tmp.reuse_message=1;
-		return(1);
-		}
-	if (s->s3->tmp.message_type != SSL3_MT_NEWSESSION_TICKET)
-		{
-		al=SSL_AD_UNEXPECTED_MESSAGE;
-		SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_BAD_MESSAGE_TYPE);
-		goto f_err;
-		}
 	if (n < 6)
 		{
 		/* need at least ticket_lifetime_hint + ticket length */
@@ -2223,7 +2213,7 @@ int ssl3_get_new_session_ticket(SSL *s)
 		}
 	memcpy(s->session->tlsext_tick, p, ticklen);
 	s->session->tlsext_ticklen = ticklen;
-	/* There are two ways to detect a resumed ticket sesion.
+	/* There are two ways to detect a resumed ticket session.
 	 * One is to set an appropriate session ID and then the server
 	 * must return a match in ServerHello. This allows the normal
 	 * client session ID matching to work and we know much 
@@ -2462,7 +2452,7 @@ int ssl3_send_client_key_exchange(SSL *s)
 			EVP_CIPHER_CTX_init(&ciph_ctx);
 
 #ifdef KSSL_DEBUG
-			printf("ssl3_send_client_key_exchange(%lx & %lx)\n",
+			fprintf(stderr,"ssl3_send_client_key_exchange(%lx & %lx)\n",
 				alg_k, SSL_kKRB5);
 #endif	/* KSSL_DEBUG */
 
@@ -2478,9 +2468,9 @@ int ssl3_send_client_key_exchange(SSL *s)
 			    goto err;
 #ifdef KSSL_DEBUG
 			{
-			printf("kssl_cget_tkt rtn %d\n", krb5rc);
+			fprintf(stderr,"kssl_cget_tkt rtn %d\n", krb5rc);
 			if (krb5rc && kssl_err.text)
-			  printf("kssl_cget_tkt kssl_err=%s\n", kssl_err.text);
+			  fprintf(stderr,"kssl_cget_tkt kssl_err=%s\n", kssl_err.text);
 			}
 #endif	/* KSSL_DEBUG */
 
@@ -3309,6 +3299,12 @@ int ssl3_send_client_certificate(SSL *s)
 		s->state=SSL3_ST_CW_CERT_D;
 		l=ssl3_output_cert_chain(s,
 			(s->s3->tmp.cert_req == 2)?NULL:s->cert->key->x509);
+		if (!l)
+			{
+			SSLerr(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR);
+			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INTERNAL_ERROR);
+			return 0;
+			}
 		s->init_num=(int)l;
 		s->init_off=0;
 		}
@@ -3478,40 +3474,9 @@ int ssl3_send_next_proto(SSL *s)
 		}
 
 	return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
-}
+        }
 #endif  /* !OPENSSL_NO_TLSEXT && !OPENSSL_NO_NEXTPROTONEG */
 
-/* Check to see if handshake is full or resumed. Usually this is just a
- * case of checking to see if a cache hit has occurred. In the case of
- * session tickets we have to check the next message to be sure.
- */
-
-#ifndef OPENSSL_NO_TLSEXT
-int ssl3_check_finished(SSL *s)
-	{
-	int ok;
-	long n;
-	/* If we have no ticket it cannot be a resumed session. */
-	if (!s->session->tlsext_tick)
-		return 1;
-	/* this function is called when we really expect a Certificate
-	 * message, so permit appropriate message length */
-	n=s->method->ssl_get_message(s,
-		SSL3_ST_CR_CERT_A,
-		SSL3_ST_CR_CERT_B,
-		-1,
-		s->max_cert_list,
-		&ok);
-	if (!ok) return((int)n);
-	s->s3->tmp.reuse_message = 1;
-	if ((s->s3->tmp.message_type == SSL3_MT_FINISHED)
-		|| (s->s3->tmp.message_type == SSL3_MT_NEWSESSION_TICKET))
-		return 2;
-
-	return 1;
-	}
-#endif
-
 int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey)
 	{
 	int i = 0;

+ 2 - 1
libs/openssl/ssl/s3_enc.c

@@ -535,7 +535,8 @@ int ssl3_enc(SSL *s, int send)
 			/* otherwise, rec->length >= bs */
 			}
 		
-		EVP_Cipher(ds,rec->data,rec->input,l);
+		if(EVP_Cipher(ds,rec->data,rec->input,l) < 1)
+			return -1;
 
 		if (EVP_MD_CTX_md(s->read_hash) != NULL)
 			mac_size = EVP_MD_CTX_size(s->read_hash);

+ 9 - 7
libs/openssl/ssl/s3_lib.c

@@ -3810,17 +3810,17 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
 #endif
 
 #ifdef CIPHER_DEBUG
-	printf("Server has %d from %p:\n", sk_SSL_CIPHER_num(srvr), (void *)srvr);
+	fprintf(stderr, "Server has %d from %p:\n", sk_SSL_CIPHER_num(srvr), (void *)srvr);
 	for(i=0 ; i < sk_SSL_CIPHER_num(srvr) ; ++i)
 		{
 		c=sk_SSL_CIPHER_value(srvr,i);
-		printf("%p:%s\n",(void *)c,c->name);
+		fprintf(stderr, "%p:%s\n",(void *)c,c->name);
 		}
-	printf("Client sent %d from %p:\n", sk_SSL_CIPHER_num(clnt), (void *)clnt);
+	fprintf(stderr, "Client sent %d from %p:\n", sk_SSL_CIPHER_num(clnt), (void *)clnt);
 	for(i=0 ; i < sk_SSL_CIPHER_num(clnt) ; ++i)
 	    {
 	    c=sk_SSL_CIPHER_value(clnt,i);
-	    printf("%p:%s\n",(void *)c,c->name);
+	    fprintf(stderr, "%p:%s\n",(void *)c,c->name);
 	    }
 #endif
 
@@ -3860,7 +3860,7 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
 #endif
 
 #ifdef KSSL_DEBUG
-/*		printf("ssl3_choose_cipher %d alg= %lx\n", i,c->algorithms);*/
+/*		fprintf(stderr,"ssl3_choose_cipher %d alg= %lx\n", i,c->algorithms);*/
 #endif    /* KSSL_DEBUG */
 
 		alg_k=c->algorithm_mkey;
@@ -3883,7 +3883,7 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
 			{
 			ok = (alg_k & emask_k) && (alg_a & emask_a);
 #ifdef CIPHER_DEBUG
-			printf("%d:[%08lX:%08lX:%08lX:%08lX]%p:%s (export)\n",ok,alg_k,alg_a,emask_k,emask_a,
+			fprintf(stderr, "%d:[%08lX:%08lX:%08lX:%08lX]%p:%s (export)\n",ok,alg_k,alg_a,emask_k,emask_a,
 			       (void *)c,c->name);
 #endif
 			}
@@ -3891,7 +3891,7 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
 			{
 			ok = (alg_k & mask_k) && (alg_a & mask_a);
 #ifdef CIPHER_DEBUG
-			printf("%d:[%08lX:%08lX:%08lX:%08lX]%p:%s\n",ok,alg_k,alg_a,mask_k,mask_a,(void *)c,
+			fprintf(stderr, "%d:[%08lX:%08lX:%08lX:%08lX]%p:%s\n",ok,alg_k,alg_a,mask_k,mask_a,(void *)c,
 			       c->name);
 #endif
 			}
@@ -4000,6 +4000,7 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
 				}
 			ok = ok && ec_ok;
 			}
+#ifndef OPENSSL_NO_ECDH
 		if (
 			/* if we are considering an ECC cipher suite that uses an ephemeral EC key */
 			(alg_k & SSL_kEECDH)
@@ -4047,6 +4048,7 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
 				}
 			ok = ok && ec_ok;
 			}
+#endif /* OPENSSL_NO_ECDH */
 #endif /* OPENSSL_NO_EC */
 #endif /* OPENSSL_NO_TLSEXT */
 

+ 2 - 3
libs/openssl/ssl/s3_meth.c

@@ -60,7 +60,7 @@
 #include <openssl/objects.h>
 #include "ssl_locl.h"
 
-static const SSL_METHOD *ssl3_get_method(int ver);
+#ifndef OPENSSL_NO_SSL3_METHOD
 static const SSL_METHOD *ssl3_get_method(int ver)
 	{
 	if (ver == SSL3_VERSION)
@@ -73,5 +73,4 @@ IMPLEMENT_ssl3_meth_func(SSLv3_method,
 			 ssl3_accept,
 			 ssl3_connect,
 			 ssl3_get_method)
-
-
+#endif

+ 3 - 2
libs/openssl/ssl/s3_pkt.c

@@ -183,6 +183,8 @@ int ssl3_read_n(SSL *s, int n, int max, int extend)
 	 * at once (as long as it fits into the buffer). */
 	if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
 		{
+		if (left == 0 && extend)
+			return 0;
 		if (left > 0 && n > left)
 			n = left;
 		}
@@ -856,8 +858,7 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
 		wr->length += eivlen;
 		}
 
-	/* ssl3_enc can only have an error on read */
-	s->method->ssl3_enc->enc(s,1);
+	if(s->method->ssl3_enc->enc(s,1)<1) goto err;
 
 	/* record length after mac and block padding */
 	s2n(wr->length,plen);

+ 102 - 41
libs/openssl/ssl/s3_srvr.c

@@ -170,6 +170,7 @@
 #endif
 #include <openssl/md5.h>
 
+#ifndef OPENSSL_NO_SSL3_METHOD
 static const SSL_METHOD *ssl3_get_server_method(int ver);
 
 static const SSL_METHOD *ssl3_get_server_method(int ver)
@@ -180,6 +181,12 @@ static const SSL_METHOD *ssl3_get_server_method(int ver)
 		return(NULL);
 	}
 
+IMPLEMENT_ssl3_meth_func(SSLv3_server_method,
+			ssl3_accept,
+			ssl_undefined_function,
+			ssl3_get_server_method)
+#endif
+
 #ifndef OPENSSL_NO_SRP
 static int ssl_check_srp_ext_ClientHello(SSL *s, int *al)
 	{
@@ -206,11 +213,6 @@ static int ssl_check_srp_ext_ClientHello(SSL *s, int *al)
 	}
 #endif
 
-IMPLEMENT_ssl3_meth_func(SSLv3_server_method,
-			ssl3_accept,
-			ssl_undefined_function,
-			ssl3_get_server_method)
-
 int ssl3_accept(SSL *s)
 	{
 	BUF_MEM *buf;
@@ -284,6 +286,7 @@ int ssl3_accept(SSL *s)
 					}
 				if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
 					{
+					BUF_MEM_free(buf);
 					ret= -1;
 					goto end;
 					}
@@ -298,6 +301,9 @@ int ssl3_accept(SSL *s)
 
 			s->init_num=0;
 			s->s3->flags &= ~SSL3_FLAGS_SGC_RESTART_DONE;
+			s->s3->flags &= ~SSL3_FLAGS_CCS_OK;
+			/* Should have been reset by ssl3_get_finished, too. */
+			s->s3->change_cipher_spec = 0;
 
 			if (s->state != SSL_ST_RENEGOTIATE)
 				{
@@ -441,20 +447,11 @@ int ssl3_accept(SSL *s)
 		case SSL3_ST_SW_KEY_EXCH_B:
 			alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
 
-			/* clear this, it may get reset by
-			 * send_server_key_exchange */
-			if ((s->options & SSL_OP_EPHEMERAL_RSA)
-#ifndef OPENSSL_NO_KRB5
-				&& !(alg_k & SSL_kKRB5)
-#endif /* OPENSSL_NO_KRB5 */
-				)
-				/* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
-				 * even when forbidden by protocol specs
-				 * (handshake may fail as clients are not required to
-				 * be able to handle this) */
-				s->s3->tmp.use_rsa_tmp=1;
-			else
-				s->s3->tmp.use_rsa_tmp=0;
+			/*
+			 * clear this, it may get reset by
+			 * send_server_key_exchange
+			 */
+			s->s3->tmp.use_rsa_tmp=0;
 
 
 			/* only send if a DH key exchange, fortezza or
@@ -468,7 +465,7 @@ int ssl3_accept(SSL *s)
 			 * server certificate contains the server's
 			 * public key for key exchange.
 			 */
-			if (s->s3->tmp.use_rsa_tmp
+			if (0
 			/* PSK: send ServerKeyExchange if PSK identity
 			 * hint if provided */
 #ifndef OPENSSL_NO_PSK
@@ -674,8 +671,14 @@ int ssl3_accept(SSL *s)
 
 		case SSL3_ST_SR_CERT_VRFY_A:
 		case SSL3_ST_SR_CERT_VRFY_B:
-
-			s->s3->flags |= SSL3_FLAGS_CCS_OK;
+			/*
+			 * This *should* be the first time we enable CCS, but be
+			 * extra careful about surrounding code changes. We need
+			 * to set this here because we don't know if we're
+			 * expecting a CertificateVerify or not.
+			 */
+			if (!s->s3->change_cipher_spec)
+				s->s3->flags |= SSL3_FLAGS_CCS_OK;
 			/* we should decide if we expected this one */
 			ret=ssl3_get_cert_verify(s);
 			if (ret <= 0) goto end;
@@ -694,6 +697,19 @@ int ssl3_accept(SSL *s)
 #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
 		case SSL3_ST_SR_NEXT_PROTO_A:
 		case SSL3_ST_SR_NEXT_PROTO_B:
+			/*
+			 * Enable CCS for resumed handshakes with NPN.
+			 * In a full handshake with NPN, we end up here through
+			 * SSL3_ST_SR_CERT_VRFY_B, where SSL3_FLAGS_CCS_OK was
+			 * already set. Receiving a CCS clears the flag, so make
+			 * sure not to re-enable it to ban duplicates.
+			 * s->s3->change_cipher_spec is set when a CCS is
+			 * processed in s3_pkt.c, and remains set until
+			 * the client's Finished message is read.
+			 */
+			if (!s->s3->change_cipher_spec)
+				s->s3->flags |= SSL3_FLAGS_CCS_OK;
+
 			ret=ssl3_get_next_proto(s);
 			if (ret <= 0) goto end;
 			s->init_num = 0;
@@ -703,7 +719,18 @@ int ssl3_accept(SSL *s)
 
 		case SSL3_ST_SR_FINISHED_A:
 		case SSL3_ST_SR_FINISHED_B:
-			s->s3->flags |= SSL3_FLAGS_CCS_OK;
+			/*
+			 * Enable CCS for resumed handshakes without NPN.
+			 * In a full handshake, we end up here through
+			 * SSL3_ST_SR_CERT_VRFY_B, where SSL3_FLAGS_CCS_OK was
+			 * already set. Receiving a CCS clears the flag, so make
+			 * sure not to re-enable it to ban duplicates.
+			 * s->s3->change_cipher_spec is set when a CCS is
+			 * processed in s3_pkt.c, and remains set until
+			 * the client's Finished message is read.
+			 */
+			if (!s->s3->change_cipher_spec)
+				s->s3->flags |= SSL3_FLAGS_CCS_OK;
 			ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
 				SSL3_ST_SR_FINISHED_B);
 			if (ret <= 0) goto end;
@@ -775,7 +802,6 @@ int ssl3_accept(SSL *s)
 #else
 				if (s->s3->next_proto_neg_seen)
 					{
-					s->s3->flags |= SSL3_FLAGS_CCS_OK;
 					s->s3->tmp.next_state=SSL3_ST_SR_NEXT_PROTO_A;
 					}
 				else
@@ -1017,7 +1043,16 @@ int ssl3_get_client_hello(SSL *s)
 	else
 		{
 		i=ssl_get_prev_session(s, p, j, d + n);
-		if (i == 1)
+		/*
+		 * Only resume if the session's version matches the negotiated
+		 * version.
+		 * RFC 5246 does not provide much useful advice on resumption
+		 * with a different protocol version. It doesn't forbid it but
+		 * the sanity of such behaviour would be questionable.
+		 * In practice, clients do not accept a version mismatch and
+		 * will abort the handshake with an error.
+		 */
+		if (i == 1 && s->version == s->session->ssl_version)
 			{ /* previous session */
 			s->hit=1;
 			}
@@ -1112,14 +1147,15 @@ int ssl3_get_client_hello(SSL *s)
 		id=s->session->cipher->id;
 
 #ifdef CIPHER_DEBUG
-		printf("client sent %d ciphers\n",sk_num(ciphers));
+		fprintf(stderr,"client sent %d ciphers\n",sk_SSL_CIPHER_num(ciphers));
 #endif
 		for (i=0; i<sk_SSL_CIPHER_num(ciphers); i++)
 			{
 			c=sk_SSL_CIPHER_value(ciphers,i);
 #ifdef CIPHER_DEBUG
-			printf("client [%2d of %2d]:%s\n",
-				i,sk_num(ciphers),SSL_CIPHER_get_name(c));
+			fprintf(stderr,"client [%2d of %2d]:%s\n",
+				i,sk_SSL_CIPHER_num(ciphers),
+				SSL_CIPHER_get_name(c));
 #endif
 			if (c->id == id)
 				{
@@ -2171,6 +2207,7 @@ int ssl3_get_client_key_exchange(SSL *s)
 		unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH];
 		int decrypt_len;
 		unsigned char decrypt_good, version_good;
+		size_t j;
 
 		/* FIX THIS UP EAY EAY EAY EAY */
 		if (s->s3->tmp.use_rsa_tmp)
@@ -2209,8 +2246,9 @@ int ssl3_get_client_key_exchange(SSL *s)
 				{
 				if (!(s->options & SSL_OP_TLS_D5_BUG))
 					{
+					al = SSL_AD_DECODE_ERROR;
 					SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
-					goto err;
+					goto f_err;
 					}
 				else
 					p-=2;
@@ -2219,6 +2257,20 @@ int ssl3_get_client_key_exchange(SSL *s)
 				n=i;
 			}
 
+		/*
+		 * Reject overly short RSA ciphertext because we want to be sure
+		 * that the buffer size makes it safe to iterate over the entire
+		 * size of a premaster secret (SSL_MAX_MASTER_KEY_LENGTH). The
+		 * actual expected size is larger due to RSA padding, but the
+		 * bound is sufficient to be safe.
+		 */
+		if (n < SSL_MAX_MASTER_KEY_LENGTH)
+			{
+			al = SSL_AD_DECRYPT_ERROR;
+			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
+			goto f_err;
+			}
+
 		/* We must not leak whether a decryption failure occurs because
 		 * of Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see
 		 * RFC 2246, section 7.4.7.1). The code follows that advice of
@@ -2266,19 +2318,23 @@ int ssl3_get_client_key_exchange(SSL *s)
 		 * to remain non-zero (0xff). */
 		decrypt_good &= version_good;
 
-		/* Now copy rand_premaster_secret over p using
-		 * decrypt_good_mask. */
-		for (i = 0; i < (int) sizeof(rand_premaster_secret); i++)
+		/*
+		 * Now copy rand_premaster_secret over from p using
+		 * decrypt_good_mask. If decryption failed, then p does not
+		 * contain valid plaintext, however, a check above guarantees
+		 * it is still sufficiently large to read from.
+		 */
+		for (j = 0; j < sizeof(rand_premaster_secret); j++)
 			{
-			p[i] = constant_time_select_8(decrypt_good, p[i],
-						      rand_premaster_secret[i]);
+			p[j] = constant_time_select_8(decrypt_good, p[j],
+						      rand_premaster_secret[j]);
 			}
 
 		s->session->master_key_length=
 			s->method->ssl3_enc->generate_master_secret(s,
 				s->session->master_key,
-				p,i);
-		OPENSSL_cleanse(p,i);
+				p,sizeof(rand_premaster_secret));
+		OPENSSL_cleanse(p,sizeof(rand_premaster_secret));
 		}
 	else
 #endif
@@ -2420,10 +2476,10 @@ int ssl3_get_client_key_exchange(SSL *s)
 					&kssl_err)) != 0)
 			{
 #ifdef KSSL_DEBUG
-			printf("kssl_sget_tkt rtn %d [%d]\n",
+			fprintf(stderr,"kssl_sget_tkt rtn %d [%d]\n",
 				krb5rc, kssl_err.reason);
 			if (kssl_err.text)
-				printf("kssl_err text= %s\n", kssl_err.text);
+				fprintf(stderr,"kssl_err text= %s\n", kssl_err.text);
 #endif	/* KSSL_DEBUG */
 			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
 				kssl_err.reason);
@@ -2437,10 +2493,10 @@ int ssl3_get_client_key_exchange(SSL *s)
 					&authtime, &kssl_err)) != 0)
 			{
 #ifdef KSSL_DEBUG
-			printf("kssl_check_authent rtn %d [%d]\n",
+			fprintf(stderr,"kssl_check_authent rtn %d [%d]\n",
 				krb5rc, kssl_err.reason);
 			if (kssl_err.text)
-				printf("kssl_err text= %s\n", kssl_err.text);
+				fprintf(stderr,"kssl_err text= %s\n", kssl_err.text);
 #endif	/* KSSL_DEBUG */
 			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
 				kssl_err.reason);
@@ -2958,7 +3014,7 @@ int ssl3_get_cert_verify(SSL *s)
 	if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_VERIFY)
 		{
 		s->s3->tmp.reuse_message=1;
-		if ((peer != NULL) && (type & EVP_PKT_SIGN))
+		if (peer != NULL)
 			{
 			al=SSL_AD_UNEXPECTED_MESSAGE;
 			SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_MISSING_VERIFY_MESSAGE);
@@ -3362,6 +3418,11 @@ int ssl3_send_server_certificate(SSL *s)
 			}
 
 		l=ssl3_output_cert_chain(s,x);
+		if (!l)
+			{
+			SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR);
+			return(0);
+			}
 		s->state=SSL3_ST_SW_CERT_B;
 		s->init_num=(int)l;
 		s->init_off=0;

+ 3 - 1
libs/openssl/ssl/srtp.h

@@ -1,4 +1,4 @@
-/* ssl/tls1.h */
+/* ssl/srtp.h */
 /* Copyright (C) 1995-1998 Eric Young ([email protected])
  * All rights reserved.
  *
@@ -118,6 +118,8 @@
 #ifndef HEADER_D1_SRTP_H
 #define HEADER_D1_SRTP_H
 
+#include <openssl/ssl.h>
+
 #ifdef  __cplusplus
 extern "C" {
 #endif

+ 20 - 8
libs/openssl/ssl/ssl.h

@@ -596,9 +596,8 @@ struct ssl_session_st
 #define SSL_OP_SINGLE_ECDH_USE				0x00080000L
 /* If set, always create a new key when using tmp_dh parameters */
 #define SSL_OP_SINGLE_DH_USE				0x00100000L
-/* Set to always use the tmp_rsa key when doing RSA operations,
- * even when this violates protocol specs */
-#define SSL_OP_EPHEMERAL_RSA				0x00200000L
+/* Does nothing: retained for compatibiity */
+#define SSL_OP_EPHEMERAL_RSA				0x0
 /* Set on servers to choose the cipher according to the server's
  * preferences */
 #define SSL_OP_CIPHER_SERVER_PREFERENCE			0x00400000L
@@ -654,8 +653,13 @@ struct ssl_session_st
 #define SSL_MODE_SEND_CLIENTHELLO_TIME 0x00000020L
 #define SSL_MODE_SEND_SERVERHELLO_TIME 0x00000040L
 /* Send TLS_FALLBACK_SCSV in the ClientHello.
- * To be set by applications that reconnect with a downgraded protocol
- * version; see draft-ietf-tls-downgrade-scsv-00 for details. */
+ * To be set only by applications that reconnect with a downgraded protocol
+ * version; see draft-ietf-tls-downgrade-scsv-00 for details.
+ *
+ * DO NOT ENABLE THIS if your application attempts a normal handshake.
+ * Only use this in explicit fallback retries, following the guidance
+ * in draft-ietf-tls-downgrade-scsv-00.
+ */
 #define SSL_MODE_SEND_FALLBACK_SCSV 0x00000080L
 
 /* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
@@ -688,6 +692,10 @@ struct ssl_session_st
         SSL_ctrl((ssl),SSL_CTRL_MODE,0,NULL)
 #define SSL_set_mtu(ssl, mtu) \
         SSL_ctrl((ssl),SSL_CTRL_SET_MTU,(mtu),NULL)
+#define DTLS_set_link_mtu(ssl, mtu) \
+        SSL_ctrl((ssl),DTLS_CTRL_SET_LINK_MTU,(mtu),NULL)
+#define DTLS_get_link_min_mtu(ssl) \
+        SSL_ctrl((ssl),DTLS_CTRL_GET_LINK_MIN_MTU,0,NULL)
 
 #define SSL_get_secure_renegotiation_support(ssl) \
 	SSL_ctrl((ssl), SSL_CTRL_GET_RI_SUPPORT, 0, NULL)
@@ -1627,6 +1635,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
 #define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS	83
 
 #define SSL_CTRL_CHECK_PROTO_VERSION		119
+#define DTLS_CTRL_SET_LINK_MTU			120
+#define DTLS_CTRL_GET_LINK_MIN_MTU		121
 
 #define DTLSv1_get_timeout(ssl, arg) \
 	SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg)
@@ -1878,13 +1888,15 @@ const SSL_METHOD *SSLv2_server_method(void);	/* SSLv2 */
 const SSL_METHOD *SSLv2_client_method(void);	/* SSLv2 */
 #endif
 
+#ifndef OPENSSL_NO_SSL3_METHOD
 const SSL_METHOD *SSLv3_method(void);		/* SSLv3 */
 const SSL_METHOD *SSLv3_server_method(void);	/* SSLv3 */
 const SSL_METHOD *SSLv3_client_method(void);	/* SSLv3 */
+#endif
 
-const SSL_METHOD *SSLv23_method(void);	/* SSLv3 but can rollback to v2 */
-const SSL_METHOD *SSLv23_server_method(void);	/* SSLv3 but can rollback to v2 */
-const SSL_METHOD *SSLv23_client_method(void);	/* SSLv3 but can rollback to v2 */
+const SSL_METHOD *SSLv23_method(void);	/* Negotiate highest available SSL/TLS version */
+const SSL_METHOD *SSLv23_server_method(void);	/* Negotiate highest available SSL/TLS version */
+const SSL_METHOD *SSLv23_client_method(void);	/* Negotiate highest available SSL/TLS version */
 
 const SSL_METHOD *TLSv1_method(void);		/* TLSv1.0 */
 const SSL_METHOD *TLSv1_server_method(void);	/* TLSv1.0 */

+ 10 - 3
libs/openssl/ssl/ssl3.h

@@ -393,8 +393,12 @@ typedef struct ssl3_buffer_st
 #define TLS1_FLAGS_TLS_PADDING_BUG		0x0008
 #define TLS1_FLAGS_SKIP_CERT_VERIFY		0x0010
 #define TLS1_FLAGS_KEEP_HANDSHAKE		0x0020
+/*
+ * Set when the handshake is ready to process peer's ChangeCipherSpec message.
+ * Cleared after the message has been processed.
+ */
 #define SSL3_FLAGS_CCS_OK			0x0080
- 
+
 /* SSL3_FLAGS_SGC_RESTART_DONE is set when we
  * restart a handshake because of MS SGC and so prevents us
  * from restarting the handshake in a loop. It's reset on a
@@ -456,8 +460,11 @@ typedef struct ssl3_state_st
 	 * and freed and MD_CTX-es for all required digests are stored in
 	 * this array */
 	EVP_MD_CTX **handshake_dgst;
-	/* this is set whenerver we see a change_cipher_spec message
-	 * come in when we are not looking for one */
+	/*
+	 * Set whenever an expected ChangeCipherSpec message is processed.
+	 * Unset when the peer's Finished message is received.
+	 * Unexpected ChangeCipherSpec messages trigger a fatal alert.
+	 */
 	int change_cipher_spec;
 
 	int warn_alert;

+ 0 - 29
libs/openssl/ssl/ssl_cert.c

@@ -286,35 +286,6 @@ CERT *ssl_cert_dup(CERT *cert)
 			ret->pkeys[i].privatekey = cert->pkeys[i].privatekey;
 			CRYPTO_add(&ret->pkeys[i].privatekey->references, 1,
 				CRYPTO_LOCK_EVP_PKEY);
-
-			switch(i) 
-				{
-				/* If there was anything special to do for
-				 * certain types of keys, we'd do it here.
-				 * (Nothing at the moment, I think.) */
-
-			case SSL_PKEY_RSA_ENC:
-			case SSL_PKEY_RSA_SIGN:
-				/* We have an RSA key. */
-				break;
-				
-			case SSL_PKEY_DSA_SIGN:
-				/* We have a DSA key. */
-				break;
-				
-			case SSL_PKEY_DH_RSA:
-			case SSL_PKEY_DH_DSA:
-				/* We have a DH key. */
-				break;
-
-			case SSL_PKEY_ECC:
-				/* We have an ECC key */
-				break;
-
-			default:
-				/* Can't happen. */
-				SSLerr(SSL_F_SSL_CERT_DUP, SSL_R_LIBRARY_BUG);
-				}
 			}
 		}
 	

+ 6 - 6
libs/openssl/ssl/ssl_ciph.c

@@ -814,7 +814,7 @@ static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method,
 			co_list[co_list_num].active = 0;
 			co_list_num++;
 #ifdef KSSL_DEBUG
-			printf("\t%d: %s %lx %lx %lx\n",i,c->name,c->id,c->algorithm_mkey,c->algorithm_auth);
+			fprintf(stderr,"\t%d: %s %lx %lx %lx\n",i,c->name,c->id,c->algorithm_mkey,c->algorithm_auth);
 #endif	/* KSSL_DEBUG */
 			/*
 			if (!sk_push(ca_list,(char *)c)) goto err;
@@ -931,7 +931,7 @@ static void ssl_cipher_apply_rule(unsigned long cipher_id,
 	int reverse = 0;
 
 #ifdef CIPHER_DEBUG
-	printf("Applying rule %d with %08lx/%08lx/%08lx/%08lx/%08lx %08lx (%d)\n",
+	fprintf(stderr, "Applying rule %d with %08lx/%08lx/%08lx/%08lx/%08lx %08lx (%d)\n",
 		rule, alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, algo_strength, strength_bits);
 #endif
 
@@ -977,7 +977,7 @@ static void ssl_cipher_apply_rule(unsigned long cipher_id,
 		else
 			{
 #ifdef CIPHER_DEBUG
-			printf("\nName: %s:\nAlgo = %08lx/%08lx/%08lx/%08lx/%08lx Algo_strength = %08lx\n", cp->name, cp->algorithm_mkey, cp->algorithm_auth, cp->algorithm_enc, cp->algorithm_mac, cp->algorithm_ssl, cp->algo_strength);
+			fprintf(stderr, "\nName: %s:\nAlgo = %08lx/%08lx/%08lx/%08lx/%08lx Algo_strength = %08lx\n", cp->name, cp->algorithm_mkey, cp->algorithm_auth, cp->algorithm_enc, cp->algorithm_mac, cp->algorithm_ssl, cp->algo_strength);
 #endif
 
 			if (alg_mkey && !(alg_mkey & cp->algorithm_mkey))
@@ -997,7 +997,7 @@ static void ssl_cipher_apply_rule(unsigned long cipher_id,
 			}
 
 #ifdef CIPHER_DEBUG
-		printf("Action = %d\n", rule);
+		fprintf(stderr, "Action = %d\n", rule);
 #endif
 
 		/* add the cipher if it has not been added yet. */
@@ -1386,7 +1386,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
 	 */
 	num_of_ciphers = ssl_method->num_ciphers();
 #ifdef KSSL_DEBUG
-	printf("ssl_create_cipher_list() for %d ciphers\n", num_of_ciphers);
+	fprintf(stderr,"ssl_create_cipher_list() for %d ciphers\n", num_of_ciphers);
 #endif    /* KSSL_DEBUG */
 	co_list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * num_of_ciphers);
 	if (co_list == NULL)
@@ -1513,7 +1513,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
 			{
 			sk_SSL_CIPHER_push(cipherstack, curr->cipher);
 #ifdef CIPHER_DEBUG
-			printf("<%s>\n",curr->cipher->name);
+			fprintf(stderr, "<%s>\n",curr->cipher->name);
 #endif
 			}
 		}

+ 25 - 21
libs/openssl/ssl/ssl_lib.c

@@ -383,13 +383,7 @@ SSL *SSL_new(SSL_CTX *ctx)
 	return(s);
 err:
 	if (s != NULL)
-		{
-		if (s->cert != NULL)
-			ssl_cert_free(s->cert);
-		if (s->ctx != NULL)
-			SSL_CTX_free(s->ctx); /* decrement reference count */
-		OPENSSL_free(s);
-		}
+		SSL_free(s);
 	SSLerr(SSL_F_SSL_NEW,ERR_R_MALLOC_FAILURE);
 	return(NULL);
 	}
@@ -1080,19 +1074,6 @@ long SSL_ctrl(SSL *s,int cmd,long larg,void *parg)
 		l=s->max_cert_list;
 		s->max_cert_list=larg;
 		return(l);
-	case SSL_CTRL_SET_MTU:
-#ifndef OPENSSL_NO_DTLS1
-		if (larg < (long)dtls1_min_mtu())
-			return 0;
-#endif
-
-		if (SSL_version(s) == DTLS1_VERSION ||
-		    SSL_version(s) == DTLS1_BAD_VER)
-			{
-			s->d1->mtu = larg;
-			return larg;
-			}
-		return 0;
 	case SSL_CTRL_SET_MAX_SEND_FRAGMENT:
 		if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH)
 			return 0;
@@ -1507,6 +1488,7 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
 					ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INAPPROPRIATE_FALLBACK);
 				goto err;
 				}
+			p += n;
 			continue;
 			}
 
@@ -2112,7 +2094,7 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher)
 	
 
 #ifdef CIPHER_DEBUG
-	printf("rt=%d rte=%d dht=%d ecdht=%d re=%d ree=%d rs=%d ds=%d dhr=%d dhd=%d\n",
+	fprintf(stderr,"rt=%d rte=%d dht=%d ecdht=%d re=%d ree=%d rs=%d ds=%d dhr=%d dhd=%d\n",
 	        rsa_tmp,rsa_tmp_export,dh_tmp,have_ecdh_tmp,
 		rsa_enc,rsa_enc_export,rsa_sign,dsa_sign,dh_rsa,dh_dsa);
 #endif
@@ -2996,10 +2978,32 @@ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx)
 			}
 		ssl_cert_free(ocert);
 		}
+
+	/*
+	 * Program invariant: |sid_ctx| has fixed size (SSL_MAX_SID_CTX_LENGTH),
+	 * so setter APIs must prevent invalid lengths from entering the system.
+	 */
+	OPENSSL_assert(ssl->sid_ctx_length <= sizeof(ssl->sid_ctx));
+
+	/*
+	 * If the session ID context matches that of the parent SSL_CTX,
+	 * inherit it from the new SSL_CTX as well. If however the context does
+	 * not match (i.e., it was set per-ssl with SSL_set_session_id_context),
+	 * leave it unchanged.
+	 */
+	if ((ssl->ctx != NULL) &&
+		(ssl->sid_ctx_length == ssl->ctx->sid_ctx_length) &&
+		(memcmp(ssl->sid_ctx, ssl->ctx->sid_ctx, ssl->sid_ctx_length) == 0))
+		{
+		ssl->sid_ctx_length = ctx->sid_ctx_length;
+		memcpy(&ssl->sid_ctx, &ctx->sid_ctx, sizeof(ssl->sid_ctx));
+		}
+
 	CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
 	if (ssl->ctx != NULL)
 		SSL_CTX_free(ssl->ctx); /* decrement reference count */
 	ssl->ctx = ctx;
+
 	return(ssl->ctx);
 	}
 

+ 4 - 3
libs/openssl/ssl/ssl_locl.h

@@ -864,7 +864,7 @@ int ssl_fill_hello_random(SSL *s, int server, unsigned char *field, int len);
 
 int ssl2_enc_init(SSL *s, int client);
 int ssl2_generate_key_material(SSL *s);
-void ssl2_enc(SSL *s,int send_data);
+int ssl2_enc(SSL *s,int send_data);
 void ssl2_mac(SSL *s,unsigned char *mac,int send_data);
 const SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p);
 int ssl2_put_cipher_by_char(const SSL_CIPHER *c,unsigned char *p);
@@ -997,7 +997,9 @@ void dtls1_stop_timer(SSL *s);
 int dtls1_is_timer_expired(SSL *s);
 void dtls1_double_timeout(SSL *s);
 int dtls1_send_newsession_ticket(SSL *s);
-unsigned int dtls1_min_mtu(void);
+unsigned int dtls1_min_mtu(SSL *s);
+unsigned int dtls1_link_min_mtu(void);
+void dtls1_hm_fragment_free(hm_fragment *frag);
 
 /* some client-only functions */
 int ssl3_client_hello(SSL *s);
@@ -1014,7 +1016,6 @@ int ssl3_get_key_exchange(SSL *s);
 int ssl3_get_server_certificate(SSL *s);
 int ssl3_check_cert_and_algorithm(SSL *s);
 #ifndef OPENSSL_NO_TLSEXT
-int ssl3_check_finished(SSL *s);
 # ifndef OPENSSL_NO_NEXTPROTONEG
 int ssl3_send_next_proto(SSL *s);
 # endif

+ 15 - 1
libs/openssl/ssl/ssl_sess.c

@@ -335,7 +335,21 @@ int ssl_get_new_session(SSL *s, int session)
 			return(0);
 			}
 #ifndef OPENSSL_NO_TLSEXT
-		/* If RFC4507 ticket use empty session ID */
+		/*
+		 * If RFC5077 ticket, use empty session ID (as server).
+		 * Note that:
+		 * (a) ssl_get_prev_session() does lookahead into the
+		 *     ClientHello extensions to find the session ticket.
+		 *     When ssl_get_prev_session() fails, s3_srvr.c calls
+		 *     ssl_get_new_session() in ssl3_get_client_hello().
+		 *     At that point, it has not yet parsed the extensions,
+		 *     however, because of the lookahead, it already knows
+		 *     whether a ticket is expected or not.
+		 *
+		 * (b) s3_clnt.c calls ssl_get_new_session() before parsing
+		 *     ServerHello extensions, and before recording the session
+		 *     ID received from the server, so this block is a noop.
+		 */
 		if (s->tlsext_ticket_expected)
 			{
 			ss->session_id_length = 0;

+ 35 - 35
libs/openssl/ssl/t1_enc.c

@@ -303,15 +303,15 @@ static int tls1_generate_key_block(SSL *s, unsigned char *km,
 		 s->session->master_key,s->session->master_key_length,
 		 km,tmp,num);
 #ifdef KSSL_DEBUG
-	printf("tls1_generate_key_block() ==> %d byte master_key =\n\t",
+	fprintf(stderr,"tls1_generate_key_block() ==> %d byte master_key =\n\t",
                 s->session->master_key_length);
 	{
         int i;
         for (i=0; i < s->session->master_key_length; i++)
                 {
-                printf("%02X", s->session->master_key[i]);
+                fprintf(stderr,"%02X", s->session->master_key[i]);
                 }
-        printf("\n");  }
+        fprintf(stderr,"\n");  }
 #endif    /* KSSL_DEBUG */
 	return ret;
 	}
@@ -349,19 +349,19 @@ int tls1_change_cipher_state(SSL *s, int which)
 #endif
 
 #ifdef KSSL_DEBUG
-	printf("tls1_change_cipher_state(which= %d) w/\n", which);
-	printf("\talg= %ld/%ld, comp= %p\n",
+	fprintf(stderr,"tls1_change_cipher_state(which= %d) w/\n", which);
+	fprintf(stderr,"\talg= %ld/%ld, comp= %p\n",
 	       s->s3->tmp.new_cipher->algorithm_mkey,
 	       s->s3->tmp.new_cipher->algorithm_auth,
 	       comp);
-	printf("\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", c);
-	printf("\tevp_cipher: nid, blksz= %d, %d, keylen=%d, ivlen=%d\n",
+	fprintf(stderr,"\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", c);
+	fprintf(stderr,"\tevp_cipher: nid, blksz= %d, %d, keylen=%d, ivlen=%d\n",
                 c->nid,c->block_size,c->key_len,c->iv_len);
-	printf("\tkey_block: len= %d, data= ", s->s3->tmp.key_block_length);
+	fprintf(stderr,"\tkey_block: len= %d, data= ", s->s3->tmp.key_block_length);
 	{
         int i;
         for (i=0; i<s->s3->tmp.key_block_length; i++)
-		printf("%02x", s->s3->tmp.key_block[i]);  printf("\n");
+		fprintf(stderr,"%02x", s->s3->tmp.key_block[i]);  fprintf(stderr,"\n");
         }
 #endif	/* KSSL_DEBUG */
 
@@ -540,11 +540,11 @@ printf("which = %04X\nmac key=",which);
 #ifdef KSSL_DEBUG
 	{
         int i;
-	printf("EVP_CipherInit_ex(dd,c,key=,iv=,which)\n");
-	printf("\tkey= "); for (i=0; i<c->key_len; i++) printf("%02x", key[i]);
-	printf("\n");
-	printf("\t iv= "); for (i=0; i<c->iv_len; i++) printf("%02x", iv[i]);
-	printf("\n");
+	fprintf(stderr,"EVP_CipherInit_ex(dd,c,key=,iv=,which)\n");
+	fprintf(stderr,"\tkey= "); for (i=0; i<c->key_len; i++) fprintf(stderr,"%02x", key[i]);
+	fprintf(stderr,"\n");
+	fprintf(stderr,"\t iv= "); for (i=0; i<c->iv_len; i++) fprintf(stderr,"%02x", iv[i]);
+	fprintf(stderr,"\n");
 	}
 #endif	/* KSSL_DEBUG */
 
@@ -591,7 +591,7 @@ int tls1_setup_key_block(SSL *s)
 	int ret=0;
 
 #ifdef KSSL_DEBUG
-	printf ("tls1_setup_key_block()\n");
+	fprintf(stderr,"tls1_setup_key_block()\n");
 #endif	/* KSSL_DEBUG */
 
 	if (s->s3->tmp.key_block_length != 0)
@@ -740,7 +740,7 @@ int tls1_enc(SSL *s, int send)
 		}
 
 #ifdef KSSL_DEBUG
-	printf("tls1_enc(%d)\n", send);
+	fprintf(stderr,"tls1_enc(%d)\n", send);
 #endif    /* KSSL_DEBUG */
 
 	if ((s->session == NULL) || (ds == NULL) || (enc == NULL))
@@ -812,18 +812,18 @@ int tls1_enc(SSL *s, int send)
 #ifdef KSSL_DEBUG
 		{
 		unsigned long ui;
-		printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
+		fprintf(stderr,"EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
 			ds,rec->data,rec->input,l);
-		printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n",
+		fprintf(stderr,"\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%lu %lu], %d iv_len\n",
 			ds->buf_len, ds->cipher->key_len,
 			DES_KEY_SZ, DES_SCHEDULE_SZ,
 			ds->cipher->iv_len);
-		printf("\t\tIV: ");
-		for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]);
-		printf("\n");
-		printf("\trec->input=");
-		for (ui=0; ui<l; ui++) printf(" %02x", rec->input[ui]);
-		printf("\n");
+		fprintf(stderr,"\t\tIV: ");
+		for (i=0; i<ds->cipher->iv_len; i++) fprintf(stderr,"%02X", ds->iv[i]);
+		fprintf(stderr,"\n");
+		fprintf(stderr,"\trec->input=");
+		for (ui=0; ui<l; ui++) fprintf(stderr," %02x", rec->input[ui]);
+		fprintf(stderr,"\n");
 		}
 #endif	/* KSSL_DEBUG */
 
@@ -848,9 +848,9 @@ int tls1_enc(SSL *s, int send)
 #ifdef KSSL_DEBUG
 		{
 		unsigned long i;
-		printf("\trec->data=");
+		fprintf(stderr,"\trec->data=");
 		for (i=0; i<l; i++)
-			printf(" %02x", rec->data[i]);  printf("\n");
+			fprintf(stderr," %02x", rec->data[i]);  fprintf(stderr,"\n");
 		}
 #endif	/* KSSL_DEBUG */
 
@@ -1048,10 +1048,10 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send)
 	if (!stream_mac)
 		EVP_MD_CTX_cleanup(&hmac);
 #ifdef TLS_DEBUG
-printf("seq=");
-{int z; for (z=0; z<8; z++) printf("%02X ",seq[z]); printf("\n"); }
-printf("rec=");
-{unsigned int z; for (z=0; z<rec->length; z++) printf("%02X ",rec->data[z]); printf("\n"); }
+fprintf(stderr,"seq=");
+{int z; for (z=0; z<8; z++) fprintf(stderr,"%02X ",seq[z]); fprintf(stderr,"\n"); }
+fprintf(stderr,"rec=");
+{unsigned int z; for (z=0; z<rec->length; z++) fprintf(stderr,"%02X ",rec->data[z]); fprintf(stderr,"\n"); }
 #endif
 
 	if (ssl->version != DTLS1_VERSION && ssl->version != DTLS1_BAD_VER)
@@ -1064,7 +1064,7 @@ printf("rec=");
 		}
 
 #ifdef TLS_DEBUG
-{unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",md[z]); printf("\n"); }
+{unsigned int z; for (z=0; z<md_size; z++) fprintf(stderr,"%02X ",md[z]); fprintf(stderr,"\n"); }
 #endif
 	return(md_size);
 	}
@@ -1078,7 +1078,7 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
 
 
 #ifdef KSSL_DEBUG
-	printf ("tls1_generate_master_secret(%p,%p, %p, %d)\n", s,out, p,len);
+	fprintf(stderr,"tls1_generate_master_secret(%p,%p, %p, %d)\n", s,out, p,len);
 #endif	/* KSSL_DEBUG */
 
 #ifdef TLSEXT_TYPE_opaque_prf_input
@@ -1113,7 +1113,7 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
 #endif
 
 #ifdef KSSL_DEBUG
-	printf ("tls1_generate_master_secret() complete\n");
+	fprintf(stderr,"tls1_generate_master_secret() complete\n");
 #endif	/* KSSL_DEBUG */
 	return(SSL3_MASTER_SECRET_SIZE);
 	}
@@ -1128,7 +1128,7 @@ int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
 	int rv;
 
 #ifdef KSSL_DEBUG
-	printf ("tls1_export_keying_material(%p,%p,%d,%s,%d,%p,%d)\n", s, out, olen, label, llen, context, contextlen);
+	fprintf(stderr,"tls1_export_keying_material(%p,%p,%lu,%s,%lu,%p,%lu)\n", s, out, olen, label, llen, context, contextlen);
 #endif	/* KSSL_DEBUG */
 
 	buff = OPENSSL_malloc(olen);
@@ -1191,7 +1191,7 @@ int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
 		      out,buff,olen);
 
 #ifdef KSSL_DEBUG
-	printf ("tls1_export_keying_material() complete\n");
+	fprintf(stderr,"tls1_export_keying_material() complete\n");
 #endif	/* KSSL_DEBUG */
 	goto ret;
 err1:

+ 29 - 9
libs/openssl/ssl/t1_lib.c

@@ -204,28 +204,40 @@ static int nid_list[] =
 
 static int pref_list[] =
 	{
+#ifndef OPENSSL_NO_EC2M
 		NID_sect571r1, /* sect571r1 (14) */ 
 		NID_sect571k1, /* sect571k1 (13) */ 
+#endif
 		NID_secp521r1, /* secp521r1 (25) */	
+#ifndef OPENSSL_NO_EC2M
 		NID_sect409k1, /* sect409k1 (11) */ 
 		NID_sect409r1, /* sect409r1 (12) */
+#endif
 		NID_secp384r1, /* secp384r1 (24) */
+#ifndef OPENSSL_NO_EC2M
 		NID_sect283k1, /* sect283k1 (9) */
 		NID_sect283r1, /* sect283r1 (10) */ 
+#endif
 		NID_secp256k1, /* secp256k1 (22) */ 
 		NID_X9_62_prime256v1, /* secp256r1 (23) */ 
+#ifndef OPENSSL_NO_EC2M
 		NID_sect239k1, /* sect239k1 (8) */ 
 		NID_sect233k1, /* sect233k1 (6) */
 		NID_sect233r1, /* sect233r1 (7) */ 
+#endif
 		NID_secp224k1, /* secp224k1 (20) */ 
 		NID_secp224r1, /* secp224r1 (21) */
+#ifndef OPENSSL_NO_EC2M
 		NID_sect193r1, /* sect193r1 (4) */ 
 		NID_sect193r2, /* sect193r2 (5) */ 
+#endif
 		NID_secp192k1, /* secp192k1 (18) */
 		NID_X9_62_prime192v1, /* secp192r1 (19) */ 
+#ifndef OPENSSL_NO_EC2M
 		NID_sect163k1, /* sect163k1 (1) */
 		NID_sect163r1, /* sect163r1 (2) */
 		NID_sect163r2, /* sect163r2 (3) */
+#endif
 		NID_secp160k1, /* secp160k1 (15) */
 		NID_secp160r1, /* secp160r1 (16) */ 
 		NID_secp160r2, /* secp160r2 (17) */ 
@@ -233,7 +245,7 @@ static int pref_list[] =
 
 int tls1_ec_curve_id2nid(int curve_id)
 	{
-	/* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
+	/* ECC curves from RFC 4492 */
 	if ((curve_id < 1) || ((unsigned int)curve_id >
 				sizeof(nid_list)/sizeof(nid_list[0])))
 		return 0;
@@ -242,7 +254,7 @@ int tls1_ec_curve_id2nid(int curve_id)
 
 int tls1_ec_nid2curve_id(int nid)
 	{
-	/* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
+	/* ECC curves from RFC 4492 */
 	switch (nid)
 		{
 	case NID_sect163k1: /* sect163k1 (1) */
@@ -488,11 +500,6 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned c
 		s2n(TLSEXT_TYPE_elliptic_curves,ret);
 		s2n(s->tlsext_ellipticcurvelist_length + 2, ret);
 
-		/* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for
-		 * elliptic_curve_list, but the examples use two bytes.
-		 * http://www1.ietf.org/mail-archive/web/tls/current/msg00538.html
-		 * resolves this to two bytes.
-		 */
 		s2n(s->tlsext_ellipticcurvelist_length, ret);
 		memcpy(ret, s->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist_length);
 		ret+=s->tlsext_ellipticcurvelist_length;
@@ -998,6 +1005,16 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
 		ssl_check_for_safari(s, data, d, n);
 #endif /* !OPENSSL_NO_EC */
 
+#ifndef OPENSSL_NO_SRP
+	if (s->srp_ctx.login != NULL)
+		{
+		OPENSSL_free(s->srp_ctx.login);
+		s->srp_ctx.login = NULL;
+		}
+#endif
+
+	s->srtp_profile = NULL;
+
 	if (data >= (d+n-2))
 		goto ri_check;
 	n2s(data,len);
@@ -1192,7 +1209,9 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
 			ellipticcurvelist_length += (*(sdata++));
 
 			if (ellipticcurvelist_length != size - 2 ||
-				ellipticcurvelist_length < 1)
+				ellipticcurvelist_length < 1 ||
+				/* Each NamedCurve is 2 bytes. */
+				ellipticcurvelist_length & 1)
 				{
 				*al = TLS1_AD_DECODE_ERROR;
 				return 0;
@@ -1506,6 +1525,7 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
 #ifndef OPENSSL_NO_NEXTPROTONEG
 	s->s3->next_proto_neg_seen = 0;
 #endif
+	s->tlsext_ticket_expected = 0;
 
 #ifndef OPENSSL_NO_HEARTBEATS
 	s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED |
@@ -1800,7 +1820,7 @@ int ssl_prepare_clienthello_tlsext(SSL *s)
 		s->tlsext_ecpointformatlist[1] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
 		s->tlsext_ecpointformatlist[2] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;
 
-		/* we support all named elliptic curves in draft-ietf-tls-ecc-12 */
+		/* we support all named elliptic curves in RFC 4492 */
 		if (s->tlsext_ellipticcurvelist != NULL) OPENSSL_free(s->tlsext_ellipticcurvelist);
 		s->tlsext_ellipticcurvelist_length = sizeof(pref_list)/sizeof(pref_list[0]) * 2;
 		if ((s->tlsext_ellipticcurvelist = OPENSSL_malloc(s->tlsext_ellipticcurvelist_length)) == NULL)

+ 1 - 1
source/Console.cbproj

@@ -65,7 +65,7 @@
 			<ProjectType>CppConsoleApplication</ProjectType>
 			<SanitizedProjectName>Console</SanitizedProjectName>
 			<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
-			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=Console interface for WinSCP;FileVersion=4.1.0.0;InternalName=console;LegalCopyright=(c) 2000-2014 Martin Prikryl;LegalTrademarks=;OriginalFilename=winscp.com;ProductName=WinSCP;ProductVersion=5.6.4.0;ReleaseType=RC;WWW=http://winscp.net/</VerInfo_Keys>
+			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=Console interface for WinSCP;FileVersion=4.1.0.0;InternalName=console;LegalCopyright=(c) 2000-2015 Martin Prikryl;LegalTrademarks=;OriginalFilename=winscp.com;ProductName=WinSCP;ProductVersion=5.6.5.0;ReleaseType=RC;WWW=http://winscp.net/</VerInfo_Keys>
 			<VerInfo_Locale>1033</VerInfo_Locale>
 			<VerInfo_MajorVer>4</VerInfo_MajorVer>
 			<VerInfo_MinorVer>1</VerInfo_MinorVer>

+ 1 - 1
source/DragExt.cbproj

@@ -66,7 +66,7 @@
 			<SanitizedProjectName>DragExt</SanitizedProjectName>
 			<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-2014 Martin Prikryl;LegalTrademarks=;OriginalFilename=dragext.dll;ProductName=WinSCP;ProductVersion=5.6.4.0;ReleaseType=RC;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-2015 Martin Prikryl;LegalTrademarks=;OriginalFilename=dragext.dll;ProductName=WinSCP;ProductVersion=5.6.5.0;ReleaseType=RC;WWW=http://winscp.net/</VerInfo_Keys>
 			<VerInfo_Locale>1033</VerInfo_Locale>
 			<VerInfo_MinorVer>2</VerInfo_MinorVer>
 			<VerInfo_Release>1</VerInfo_Release>

+ 3 - 3
source/DragExt64.rc

@@ -1,6 +1,6 @@
 1 VERSIONINFO
 FILEVERSION 1,2,1,0
-PRODUCTVERSION 5,6,4,0
+PRODUCTVERSION 5,6,5,0
 FILEOS 0x4
 FILETYPE 0x2
 {
@@ -12,11 +12,11 @@ FILETYPE 0x2
             VALUE "FileDescription", "Drag&Drop shell extension for WinSCP (64-bit)\0"
             VALUE "FileVersion", "1.2.1.0\0"
             VALUE "InternalName", "dragext64\0"
-            VALUE "LegalCopyright", "(c) 2000-2014 Martin Prikryl\0"
+            VALUE "LegalCopyright", "(c) 2000-2015 Martin Prikryl\0"
             VALUE "LegalTrademarks", "\0"
             VALUE "OriginalFilename", "dragext64.dll\0"
             VALUE "ProductName", "WinSCP\0"
-            VALUE "ProductVersion", "5.6.4.0\0"
+            VALUE "ProductVersion", "5.6.5.0\0"
             VALUE "ReleaseType", "RC\0"
             VALUE "WWW", "http://winscp.net/\0"
         }

+ 2 - 2
source/WinSCP.cbproj

@@ -83,11 +83,11 @@
 			<SanitizedProjectName>WinSCP</SanitizedProjectName>
 			<UsingDelphiRTL>true</UsingDelphiRTL>
 			<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
-			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=WinSCP: SFTP, FTP and SCP client;FileVersion=5.6.4.0;InternalName=winscp;LegalCopyright=(c) 2000-2014 Martin Prikryl;LegalTrademarks=;OriginalFilename=winscp.exe;ProductName=WinSCP;ProductVersion=5.6.4.0;ReleaseType=RC;WWW=http://winscp.net/</VerInfo_Keys>
+			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=WinSCP: SFTP, FTP and SCP client;FileVersion=5.6.5.0;InternalName=winscp;LegalCopyright=(c) 2000-2015 Martin Prikryl;LegalTrademarks=;OriginalFilename=winscp.exe;ProductName=WinSCP;ProductVersion=5.6.5.0;ReleaseType=RC;WWW=http://winscp.net/</VerInfo_Keys>
 			<VerInfo_Locale>1033</VerInfo_Locale>
 			<VerInfo_MajorVer>5</VerInfo_MajorVer>
 			<VerInfo_MinorVer>6</VerInfo_MinorVer>
-			<VerInfo_Release>4</VerInfo_Release>
+			<VerInfo_Release>5</VerInfo_Release>
 		</PropertyGroup>
 	<PropertyGroup Condition="'$(Base_Win32)'!=''">
 			<Defines>IDE;STRICT;$(Defines)</Defines>

+ 14 - 1
source/core/Common.cpp

@@ -238,6 +238,12 @@ UnicodeString CopyToChars(const UnicodeString & Str, int & From, UnicodeString C
   return Result;
 }
 //---------------------------------------------------------------------------
+UnicodeString CopyToChar(const UnicodeString & Str, wchar_t Ch, bool Trim)
+{
+  int From = 1;
+  return CopyToChars(Str, From, UnicodeString(Ch), Trim);
+}
+//---------------------------------------------------------------------------
 UnicodeString DelimitStr(UnicodeString Str, UnicodeString Chars)
 {
   for (int i = 1; i <= Str.Length(); i++)
@@ -351,13 +357,19 @@ static int FindInteractiveMsgStart(const UnicodeString & S)
   return Result;
 }
 //---------------------------------------------------------------------------
-UnicodeString UnformatMessage(UnicodeString S)
+UnicodeString RemoveMainInstructionsTag(UnicodeString S)
 {
   UnicodeString MainInstruction;
   if (ExtractMainInstructions(S, MainInstruction))
   {
     S = MainInstruction + S;
   }
+  return S;
+}
+//---------------------------------------------------------------------------
+UnicodeString UnformatMessage(UnicodeString S)
+{
+  S = RemoveMainInstructionsTag(S);
 
   int InteractiveMsgStart = FindInteractiveMsgStart(S);
   if (InteractiveMsgStart > 0)
@@ -2469,6 +2481,7 @@ TStringList * __fastcall CreateSortedStringList(bool CaseSensitive, System::Type
 {
   TStringList * Result = new TStringList();
   Result->CaseSensitive = CaseSensitive;
+  Result->Sorted = true;
   Result->Duplicates = Duplicates;
   return Result;
 }

+ 2 - 0
source/core/Common.h

@@ -43,12 +43,14 @@ UnicodeString DefaultStr(const UnicodeString & Str, const UnicodeString & Defaul
 UnicodeString CutToChar(UnicodeString &Str, wchar_t Ch, bool Trim);
 UnicodeString CopyToChars(const UnicodeString & Str, int & From, UnicodeString Chs, bool Trim,
   wchar_t * Delimiter = NULL, bool DoubleDelimiterEscapes = false);
+UnicodeString CopyToChar(const UnicodeString & Str, wchar_t Ch, bool Trim);
 UnicodeString DelimitStr(UnicodeString Str, UnicodeString Chars);
 UnicodeString ShellDelimitStr(UnicodeString Str, wchar_t Quote);
 UnicodeString ExceptionLogString(Exception *E);
 UnicodeString __fastcall MainInstructions(const UnicodeString & S);
 UnicodeString __fastcall MainInstructionsFirstParagraph(const UnicodeString & S);
 bool ExtractMainInstructions(UnicodeString & S, UnicodeString & MainInstructions);
+UnicodeString RemoveMainInstructionsTag(UnicodeString S);
 UnicodeString UnformatMessage(UnicodeString S);
 UnicodeString RemoveInteractiveMsgTag(UnicodeString S);
 bool IsNumber(const UnicodeString Str);

+ 21 - 1
source/core/Configuration.cpp

@@ -676,6 +676,11 @@ void __fastcall TConfiguration::CleanupIniFile()
   }
 }
 //---------------------------------------------------------------------------
+void __fastcall TConfiguration::DontSave()
+{
+  FDontSave = true;
+}
+//---------------------------------------------------------------------------
 RawByteString __fastcall TConfiguration::EncryptPassword(UnicodeString Password, UnicodeString Key)
 {
   if (Password.IsEmpty())
@@ -805,6 +810,11 @@ UnicodeString __fastcall TConfiguration::GetProductVersion()
   return GetFileProductVersion(L"");
 }
 //---------------------------------------------------------------------------
+UnicodeString __fastcall TConfiguration::GetReleaseType()
+{
+  return GetFileInfoString(L"ReleaseType");
+}
+//---------------------------------------------------------------------------
 bool __fastcall TConfiguration::GetIsUnofficial()
 {
   #ifdef BUILD_OFFICIAL
@@ -849,7 +859,17 @@ UnicodeString __fastcall TConfiguration::GetVersionStr()
     AddToList(BuildStr, DateStr, L" ");
     #endif
 
-    UnicodeString Result = FMTLOAD(VERSION2, (Version, BuildStr));
+    UnicodeString FullVersion = Version;
+
+    UnicodeString AReleaseType = GetReleaseType();
+    if (ALWAYS_TRUE(!AReleaseType.IsEmpty()) &&
+        !SameText(AReleaseType, L"stable") &&
+        !SameText(AReleaseType, L"development"))
+    {
+      FullVersion += L" " + AReleaseType;
+    }
+
+    UnicodeString Result = FMTLOAD(VERSION2, (FullVersion, BuildStr));
 
     #ifndef BUILD_OFFICIAL
     Result += L" " + LoadStr(VERSION_DONT_DISTRIBUTE);

+ 2 - 1
source/core/Configuration.h

@@ -145,6 +145,7 @@ protected:
   bool __fastcall GetAutoReadDirectoryAfterOp();
   void __fastcall SetAutoReadDirectoryAfterOp(bool value);
   virtual bool __fastcall GetRememberPassword();
+  UnicodeString __fastcall GetReleaseType();
 
   virtual UnicodeString __fastcall ModuleFileName();
 
@@ -178,6 +179,7 @@ public:
   void __fastcall CleanupRandomSeedFile();
   void __fastcall BeginUpdate();
   void __fastcall EndUpdate();
+  void __fastcall DontSave();
   void __fastcall LoadDirectoryChangesCache(const UnicodeString SessionKey,
     TRemoteDirectoryChangesCache * DirectoryChangesCache);
   void __fastcall SaveDirectoryChangesCache(const UnicodeString SessionKey,
@@ -212,7 +214,6 @@ public:
   __property UnicodeString ProductVersion = { read=GetProductVersion };
   __property UnicodeString ProductName = { read=GetProductName };
   __property UnicodeString CompanyName = { read=GetCompanyName };
-  __property UnicodeString FileInfoString[UnicodeString Key] = { read = GetFileInfoString };
   __property UnicodeString OSVersionStr = { read = GetOSVersionStr };
   __property bool IsUnofficial = { read = GetIsUnofficial };
   __property bool Logging  = { read=FLogging, write=SetLogging };

+ 6 - 1
source/core/FileMasks.cpp

@@ -1207,11 +1207,16 @@ bool __fastcall TFileCustomCommand::IsFileListCommand(const UnicodeString & Comm
   return FindPattern(Command, L'&');
 }
 //---------------------------------------------------------------------------
-bool __fastcall TFileCustomCommand::IsFileCommand(const UnicodeString & Command)
+bool __fastcall TFileCustomCommand::IsRemoteFileCommand(const UnicodeString & Command)
 {
   return FindPattern(Command, L'!') || FindPattern(Command, L'&');
 }
 //---------------------------------------------------------------------------
+bool __fastcall TFileCustomCommand::IsFileCommand(const UnicodeString & Command)
+{
+  return IsRemoteFileCommand(Command);
+}
+//---------------------------------------------------------------------------
 bool __fastcall TFileCustomCommand::IsSiteCommand(const UnicodeString & Command)
 {
   return FindPattern(Command, L'@');

+ 1 - 0
source/core/FileMasks.h

@@ -209,6 +209,7 @@ public:
 
   bool __fastcall IsFileListCommand(const UnicodeString & Command);
   virtual bool __fastcall IsFileCommand(const UnicodeString & Command);
+  bool __fastcall IsRemoteFileCommand(const UnicodeString & Command);
   bool __fastcall IsSiteCommand(const UnicodeString & Command);
   bool __fastcall IsPasswordCommand(const UnicodeString & Command);
 

+ 0 - 7
source/core/FileOperationProgress.cpp

@@ -42,7 +42,6 @@ void __fastcall TFileOperationProgressType::Clear()
 {
   FileName = L"";
   AsciiTransfer = false;
-  ResumeStatus = rsNotAvailable;
   Count = 0;
   FFilesFinished = 0;
   StartTime = Now();
@@ -455,12 +454,6 @@ void __fastcall TFileOperationProgressType::SetAsciiTransfer(bool AAsciiTransfer
   DoProgress();
 }
 //---------------------------------------------------------------------------
-void __fastcall TFileOperationProgressType::SetResumeStatus(TResumeStatus AResumeStatus)
-{
-  ResumeStatus = AResumeStatus;
-  DoProgress();
-}
-//---------------------------------------------------------------------------
 TDateTime __fastcall TFileOperationProgressType::TimeElapsed()
 {
   return Now() - StartTime;

+ 0 - 3
source/core/FileOperationProgress.h

@@ -13,7 +13,6 @@ enum TFileOperation { foNone, foCopy, foMove, foDelete, foSetProperties,
   foGetProperties, foCalculateChecksum };
 // csCancelTransfer and csRemoteAbort are used with SCP only
 enum TCancelStatus { csContinue = 0, csCancel, csCancelTransfer, csRemoteAbort };
-enum TResumeStatus { rsNotAvailable, rsEnabled, rsDisabled };
 enum TBatchOverwrite { boNo, boAll, boNone, boOlder, boAlternateResume, boAppend, boResume };
 typedef void __fastcall (__closure *TFileOperationProgressEvent)
   (TFileOperationProgressType & ProgressData);
@@ -61,7 +60,6 @@ public:
   __int64 TransferSize;
   __int64 TransferedSize;
   __int64 SkippedSize;
-  TResumeStatus ResumeStatus;
   bool InProgress;
   bool FileInProgress;
   TCancelStatus Cancel;
@@ -109,7 +107,6 @@ public:
   void __fastcall Resume();
   void __fastcall SetLocalSize(__int64 ASize);
   void __fastcall SetAsciiTransfer(bool AAsciiTransfer);
-  void __fastcall SetResumeStatus(TResumeStatus AResumeStatus);
   void __fastcall SetTransferSize(__int64 ASize);
   void __fastcall ChangeTransferSize(__int64 ASize);
   void __fastcall RollbackTransfer();

+ 7 - 3
source/core/FtpFileSystem.cpp

@@ -3011,7 +3011,7 @@ void __fastcall TFTPFileSystem::WaitForMessages()
   do
   {
     Result = WaitForSingleObject(FQueueEvent, GUIUpdateInterval);
-    ProcessGUI();
+    FTerminal->ProcessGUI();
   } while (Result == WAIT_TIMEOUT);
 
   if (Result != WAIT_OBJECT_0)
@@ -3271,6 +3271,11 @@ UnicodeString __fastcall TFTPFileSystem::GotReply(unsigned int Reply, unsigned i
           HelpKeyword = HELP_ERRORMSG_TIMEOUT;
         }
 
+        if (FLastCode == DummyDisconnectCode)
+        {
+          HelpKeyword = HELP_STATUSMSG_DISCONNECTED;
+        }
+
         MoreMessages->AddStrings(FLastError);
         // already cleared from WaitForReply, but GotReply can be also called
         // from Closed. then make sure that error from previous command not
@@ -3355,8 +3360,7 @@ UnicodeString __fastcall TFTPFileSystem::GotReply(unsigned int Reply, unsigned i
 void __fastcall TFTPFileSystem::SendCommand(const UnicodeString & Command)
 {
   FFileZillaIntf->CustomCommand(Command.c_str());
-  int From = 1;
-  FLastCommandSent = CopyToChars(Command, From, L" ", false);
+  FLastCommandSent = CopyToChar(Command, L' ', false);
 }
 //---------------------------------------------------------------------------
 void __fastcall TFTPFileSystem::SetLastCode(int Code)

+ 12 - 2
source/core/RemoteFiles.cpp

@@ -498,6 +498,15 @@ int __fastcall FakeFileImageIndex(UnicodeString FileName, unsigned long Attrs,
   return Icon;
 }
 //---------------------------------------------------------------------------
+bool __fastcall SameUserName(const UnicodeString & UserName1, const UnicodeString & UserName2)
+{
+  // Bitvise reports file owner as "user@host", but we login with "user" only.
+  UnicodeString AUserName1 = CopyToChar(UserName1, L'@', true);
+  UnicodeString AUserName2 = CopyToChar(UserName2, L'@', true);
+  return SameText(AUserName1, AUserName2);
+}
+//---------------------------------------------------------------------------
+//---------------------------------------------------------------------------
 __fastcall TRemoteToken::TRemoteToken() :
   FID(0),
   FIDValid(false)
@@ -706,6 +715,7 @@ void __fastcall TRemoteTokenList::AddUnique(const TRemoteToken & Token)
 //---------------------------------------------------------------------------
 bool __fastcall TRemoteTokenList::Exists(const UnicodeString & Name) const
 {
+  // We should make use of SameUserName
   return (FNameMap.find(Name) != FNameMap.end());
 }
 //---------------------------------------------------------------------------
@@ -914,12 +924,12 @@ Boolean __fastcall TRemoteFile::GetIsInaccesibleDirectory() const
   {
     assert(Terminal);
     Result = !
-       (SameText(Terminal->UserName, L"root") ||
+       (SameUserName(Terminal->UserName, L"root") ||
         ((Rights->RightUndef[TRights::rrOtherExec] != TRights::rsNo)) ||
         ((Rights->Right[TRights::rrGroupExec] != TRights::rsNo) &&
          Terminal->Membership->Exists(Group.Name)) ||
         ((Rights->Right[TRights::rrUserExec] != TRights::rsNo) &&
-         SameText(Terminal->UserName, Owner.Name)));
+         SameUserName(Terminal->UserName, Owner.Name)));
   }
     else Result = False;
   return Result;

+ 1 - 0
source/core/RemoteFiles.h

@@ -460,5 +460,6 @@ UnicodeString __fastcall ModificationStr(TDateTime DateTime,
   TModificationFmt Precision);
 int __fastcall FakeFileImageIndex(UnicodeString FileName, unsigned long Attrs = 0,
   UnicodeString * TypeName = NULL);
+bool __fastcall SameUserName(const UnicodeString & UserName1, const UnicodeString & UserName2);
 //---------------------------------------------------------------------------
 #endif

+ 12 - 14
source/core/SecureShell.cpp

@@ -1167,7 +1167,7 @@ void __fastcall TSecureShell::DispatchSendBuffer(int BufSize)
         "need to send at least another %u bytes",
         (BufSize, BufSize - MAX_BUFSIZE)));
     }
-    EventSelectLoop(100, false, true, NULL);
+    EventSelectLoop(100, false, NULL);
     BufSize = FBackend->sendbuffer(FBackendHandle);
     if (Configuration->ActualLogProtocol >= 1)
     {
@@ -1212,7 +1212,7 @@ void __fastcall TSecureShell::Send(const unsigned char * Buf, Integer Len)
   }
   FLastDataSent = Now();
   // among other forces receive of pending data to free the servers's send buffer
-  EventSelectLoop(0, false, true, NULL);
+  EventSelectLoop(0, false, NULL);
 
   if (BufSize > MAX_BUFSIZE)
   {
@@ -1609,7 +1609,7 @@ void __fastcall TSecureShell::PoolForData(WSANETWORKEVENTS & Events, unsigned in
       // in extreme condition it may happen that send buffer is full, but there
       // will be no data coming and we may not empty the send buffer because we
       // do not process FD_WRITE until we receive any FD_READ
-      if (EventSelectLoop(0, false, true, &Events))
+      if (EventSelectLoop(0, false, &Events))
       {
         LogEvent(L"Data has arrived, closing query to user.");
         Result = qaOK;
@@ -1659,7 +1659,7 @@ void __fastcall TSecureShell::WaitForData()
       LogEvent(L"Looking for incoming data");
     }
 
-    IncomingData = EventSelectLoop(FSessionData->Timeout * MSecsPerSec, true, true, NULL);
+    IncomingData = EventSelectLoop(FSessionData->Timeout * MSecsPerSec, true, NULL);
     if (!IncomingData)
     {
       assert(FWaitingForData == 0);
@@ -1790,7 +1790,7 @@ bool __fastcall TSecureShell::ProcessNetworkEvents(SOCKET Socket)
 }
 //---------------------------------------------------------------------------
 bool __fastcall TSecureShell::EventSelectLoop(unsigned int MSec, bool ReadEventRequired,
-  bool DoProcessGUI, WSANETWORKEVENTS * Events)
+  WSANETWORKEVENTS * Events)
 {
   CheckConnection();
 
@@ -1822,10 +1822,7 @@ bool __fastcall TSecureShell::EventSelectLoop(unsigned int MSec, bool ReadEventR
         unsigned int TimeoutStep = std::min(GUIUpdateInterval, Timeout);
         Timeout -= TimeoutStep;
         WaitResult = WaitForMultipleObjects(HandleCount + 1, Handles, FALSE, TimeoutStep);
-        if (DoProcessGUI)
-        {
-          ProcessGUI();
-        }
+        FUI->ProcessGUI();
       } while ((WaitResult == WAIT_TIMEOUT) && (Timeout > 0));
 
       if (WaitResult < WAIT_OBJECT_0 + HandleCount)
@@ -1922,9 +1919,7 @@ void __fastcall TSecureShell::Idle(unsigned int MSec)
   // do not read here, otherwise we swallow read event and never wake
   if (FWaitingForData <= 0)
   {
-    // do not process GUI here, as we are called from GUI loop and may
-    // recurse for good
-    EventSelectLoop(MSec, false, false, NULL);
+    EventSelectLoop(MSec, false, NULL);
   }
 }
 //---------------------------------------------------------------------------
@@ -2078,7 +2073,7 @@ void __fastcall TSecureShell::VerifyHostKey(UnicodeString Host, int Port,
     {
       UnicodeString StoredKey = CutToChar(Buf, Delimiter, false);
       bool Fingerprint = (StoredKey.SubString(1, 2) != L"0x");
-      // its probably a fingerprint (stored by TSessionData::CacheHostKey)
+      // it's probably a fingerprint (stored by TSessionData::CacheHostKey)
       UnicodeString NormalizedExpectedKey;
       if (Fingerprint)
       {
@@ -2220,9 +2215,11 @@ void __fastcall TSecureShell::AskAlg(const UnicodeString AlgType,
   const UnicodeString AlgName)
 {
   UnicodeString Msg;
+  UnicodeString Error;
   if (AlgType == L"key-exchange algorithm")
   {
     Msg = FMTLOAD(KEX_BELOW_TRESHOLD, (AlgName));
+    Error = FMTLOAD(KEX_NOT_VERIFIED, (AlgName));
   }
   else
   {
@@ -2245,11 +2242,12 @@ void __fastcall TSecureShell::AskAlg(const UnicodeString AlgType,
     }
 
     Msg = FMTLOAD(CIPHER_BELOW_TRESHOLD, (LoadStr(CipherType), AlgName));
+    Error = FMTLOAD(CIPHER_NOT_VERIFIED, (AlgName));
   }
 
   if (FUI->QueryUser(Msg, NULL, qaYes | qaNo, NULL, qtWarning) == qaNo)
   {
-    Abort();
+    FUI->FatalError(NULL, Error);
   }
 }
 //---------------------------------------------------------------------------

+ 1 - 1
source/core/SecureShell.h

@@ -87,7 +87,7 @@ private:
   void __fastcall HandleNetworkEvents(SOCKET Socket, WSANETWORKEVENTS & Events);
   bool __fastcall ProcessNetworkEvents(SOCKET Socket);
   bool __fastcall EventSelectLoop(unsigned int MSec, bool ReadEventRequired,
-    bool DoProcessGUI, WSANETWORKEVENTS * Events);
+    WSANETWORKEVENTS * Events);
   void __fastcall UpdateSessionInfo();
   bool __fastcall GetReady();
   void __fastcall DispatchSendBuffer(int BufSize);

+ 2 - 0
source/core/SessionInfo.cpp

@@ -1035,6 +1035,8 @@ void __fastcall TSessionLog::DoAddStartupInfo(TSessionData * Data)
         }
         ADF(L"Ping type: %s, Ping interval: %d sec; Timeout: %d sec",
           (UnicodeString(PingTypes[PingType]), PingInterval, Data->Timeout));
+        ADF(L"Disable Nagle: %s",
+          (BooleanToEngStr(Data->TcpNoDelay)));
       }
       ADF(L"Proxy: %s",
         ((Data->FtpProxyLogonType != 0) ?

+ 1 - 0
source/core/SessionInfo.h

@@ -71,6 +71,7 @@ public:
   virtual void __fastcall FatalError(Exception * E, UnicodeString Msg, UnicodeString HelpKeyword = L"") = 0;
   virtual void __fastcall HandleExtendedException(Exception * E) = 0;
   virtual void __fastcall Closed() = 0;
+  virtual void __fastcall ProcessGUI() = 0;
 };
 //---------------------------------------------------------------------------
 // Duplicated in LogMemo.h for design-time-only purposes

+ 24 - 16
source/core/SftpFileSystem.cpp

@@ -1662,11 +1662,14 @@ protected:
       FIndex++;
 
       bool MissingRights =
-        (FLAGSET(FFileSystem->FSupport->AttributeMask, SSH_FILEXFER_ATTR_PERMISSIONS) &&
-           File->Rights->Unknown);
+        (FFileSystem->FSupport->Loaded &&
+         FLAGSET(FFileSystem->FSupport->AttributeMask, SSH_FILEXFER_ATTR_PERMISSIONS) &&
+         File->Rights->Unknown);
       bool MissingOwnerGroup =
-        (FLAGSET(FFileSystem->FSupport->AttributeMask, SSH_FILEXFER_ATTR_OWNERGROUP) &&
-           !File->Owner.IsSet || !File->Group.IsSet);
+        (FFileSystem->FSecureShell->SshImplementation == sshiBitvise) ||
+        (FFileSystem->FSupport->Loaded &&
+         FLAGSET(FFileSystem->FSupport->AttributeMask, SSH_FILEXFER_ATTR_OWNERGROUP) &&
+         !File->Owner.IsSet || !File->Group.IsSet);
 
       Result = (MissingRights || MissingOwnerGroup);
       if (Result)
@@ -2088,11 +2091,14 @@ bool __fastcall TSFTPFileSystem::IsCapable(int Capability) const
       // (no other attributes are loaded).
       // This is here only because of VShell
       // (it supports owner/group, but does not include them into response to
-      // SSH_FXP_READDIR).
-      // No other use is know.
-      return FSupport->Loaded &&
-        ((FSupport->AttributeMask &
-          (SSH_FILEXFER_ATTR_PERMISSIONS | SSH_FILEXFER_ATTR_OWNERGROUP)) != 0);
+      // SSH_FXP_READDIR)
+      // and Bitwise (the same as VShell, but it does not even bother to provide "supported" extension)
+      // No other use is known.
+      return
+        (FSupport->Loaded &&
+         ((FSupport->AttributeMask &
+           (SSH_FILEXFER_ATTR_PERMISSIONS | SSH_FILEXFER_ATTR_OWNERGROUP)) != 0)) ||
+        (FSecureShell->SshImplementation == sshiBitvise);
 
     case fcCheckingSpaceAvailable:
       return
@@ -3803,7 +3809,7 @@ bool __fastcall TSFTPFileSystem::LoadFilesProperties(TStrings * FileList)
 {
   bool Result = false;
   // without knowledge of server's capabilities, this all make no sense
-  if (FSupport->Loaded)
+  if (FSupport->Loaded || (FSecureShell->SshImplementation == sshiBitvise))
   {
     TFileOperationProgressType Progress(&FTerminal->DoProgress, &FTerminal->DoFinished);
     Progress.Start(foGetProperties, osRemote, FileList->Count);
@@ -4518,7 +4524,6 @@ void __fastcall TSFTPFileSystem::SFTPSource(const UnicodeString FileName,
       ResumeAllowed = !OperationProgress->AsciiTransfer &&
         CopyParam->AllowResume(OperationProgress->LocalSize) &&
         IsCapable(fcRename);
-      OperationProgress->SetResumeStatus(ResumeAllowed ? rsEnabled : rsDisabled);
 
       TOverwriteFileParams FileParams;
       FileParams.SourceSize = OperationProgress->LocalSize;
@@ -4542,20 +4547,24 @@ void __fastcall TSFTPFileSystem::SFTPSource(const UnicodeString FileName,
             FileParams.DestSize = OpenParams.DestFileSize;
             FileParams.DestTimestamp = File->Modification;
             DestRights = *File->Rights;
-            // if destination file is symlink, never do resumable transfer,
+            // - If destination file is symlink, never do resumable transfer,
             // as it would delete the symlink.
-            // also bit of heuristics to detect symlink on SFTP-3 and older
+            // - Also bit of heuristics to detect symlink on SFTP-3 and older
             // (which does not indicate symlink in SSH_FXP_ATTRS).
             // if file has all permissions and is small, then it is likely symlink.
             // also it is not likely that such a small file (if it is not symlink)
             // gets overwritten by large file (that would trigger resumable transfer).
+            // - Also never do resumable transfer for file owner by other user
+            // as deleting and recreating the file would change ownership.
+            // This won't for work for SFT-3 (OpenSSH) as it does not provide
+            // owner name (only UID) and we know only logged in user name (not UID)
             if (File->IsSymLink ||
                 ((FVersion < 4) &&
                  ((*File->Rights & TRights::rfAll) == TRights::rfAll) &&
-                 (File->Size < 100)))
+                 (File->Size < 100)) ||
+                (!File->Owner.Name.IsEmpty() && !SameUserName(File->Owner.Name, FTerminal->UserName)))
             {
               ResumeAllowed = false;
-              OperationProgress->SetResumeStatus(rsDisabled);
             }
 
             delete File;
@@ -5482,7 +5491,6 @@ void __fastcall TSFTPFileSystem::SFTPSink(const UnicodeString FileName,
     ResumeAllowed = ((Params & cpTemporary) == 0) &&
       !OperationProgress->AsciiTransfer &&
       CopyParam->AllowResume(OperationProgress->TransferSize);
-    OperationProgress->SetResumeStatus(ResumeAllowed ? rsEnabled : rsDisabled);
 
     int Attrs;
     FILE_OPERATION_LOOP_BEGIN

+ 20 - 0
source/core/Terminal.cpp

@@ -369,6 +369,7 @@ public:
   virtual void __fastcall FatalError(Exception * E, UnicodeString Msg, UnicodeString HelpContext);
   virtual void __fastcall HandleExtendedException(Exception * E);
   virtual void __fastcall Closed();
+  virtual void __fastcall ProcessGUI();
 
 private:
   TTerminal * FTerminal;
@@ -469,6 +470,11 @@ void __fastcall TTunnelUI::Closed()
   // noop
 }
 //---------------------------------------------------------------------------
+void __fastcall TTunnelUI::ProcessGUI()
+{
+  // noop
+}
+//---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
 class TCallbackGuard
 {
@@ -623,6 +629,7 @@ __fastcall TTerminal::TTerminal(TSessionData * SessionData,
   FTunnelUI = NULL;
   FTunnelOpening = false;
   FCallbackGuard = NULL;
+  FIdle = 0;
 }
 //---------------------------------------------------------------------------
 __fastcall TTerminal::~TTerminal()
@@ -663,6 +670,8 @@ void __fastcall TTerminal::Idle()
   // "receives the information"
   if (Active)
   {
+    TAutoNestingCounter IdleCounter(FIdle);
+
     if (Configuration->ActualLogProtocol >= 1)
     {
       LogEvent(L"Session upkeep");
@@ -1070,6 +1079,17 @@ void __fastcall TTerminal::Closed()
   FStatus = ssClosed;
 }
 //---------------------------------------------------------------------------
+void __fastcall TTerminal::ProcessGUI()
+{
+  // Do not process GUI here, as we are called directly from a GUI loop and may
+  // recurse for good.
+  // Alternatively we may check for (FOperationProgress == NULL)
+  if (FIdle == 0)
+  {
+    ::ProcessGUI();
+  }
+}
+//---------------------------------------------------------------------------
 void __fastcall TTerminal::Reopen(int Params)
 {
   TFSProtocol OrigFSProtocol = SessionData->FSProtocol;

+ 2 - 0
source/core/Terminal.h

@@ -203,6 +203,7 @@ private:
   bool FCollectFileSystemUsage;
   bool FRememberedPasswordTried;
   bool FRememberedTunnelPasswordTried;
+  int FIdle;
 
   void __fastcall CommandError(Exception * E, const UnicodeString Msg);
   unsigned int __fastcall CommandError(Exception * E, const UnicodeString Msg,
@@ -348,6 +349,7 @@ protected:
     UnicodeString Name, UnicodeString Instructions, TStrings * Prompts, TStrings * Results);
   virtual void __fastcall DisplayBanner(const UnicodeString & Banner);
   virtual void __fastcall Closed();
+  virtual void __fastcall ProcessGUI();
   virtual void __fastcall HandleExtendedException(Exception * E);
   bool __fastcall IsListenerFree(unsigned int PortNumber);
   void __fastcall DoProgress(TFileOperationProgressType & ProgressData);

+ 2 - 0
source/filezilla/AsyncProxySocketLayer.cpp

@@ -1160,7 +1160,9 @@ BOOL CAsyncProxySocketLayer::GetPeerName(CString &rPeerAddress, UINT &rPeerPort)
 BOOL CAsyncProxySocketLayer::GetPeerName( SOCKADDR* lpSockAddr, int* lpSockAddrLen )
 {
 	if (m_ProxyData.nProxyType==PROXYTYPE_NOPROXY)
+	{
 		return GetPeerNameNext(lpSockAddr, lpSockAddrLen);
+	}
 
 	if (GetLayerState()==notsock)
 	{

+ 8 - 0
source/filezilla/AsyncSocketExLayer.cpp

@@ -506,7 +506,9 @@ BOOL CAsyncSocketExLayer::GetPeerName( CString& rPeerAddress, UINT& rPeerPort )
 BOOL CAsyncSocketExLayer::GetPeerNameNext( CString& rPeerAddress, UINT& rPeerPort )
 {
 	if (m_pNextLayer)
+	{
 		return m_pNextLayer->GetPeerName(rPeerAddress, rPeerPort);
+	}
 	else
 	{
 		SOCKADDR* sockAddr;
@@ -563,14 +565,20 @@ BOOL CAsyncSocketExLayer::GetPeerName( SOCKADDR* lpSockAddr, int* lpSockAddrLen
 BOOL CAsyncSocketExLayer::GetPeerNameNext( SOCKADDR* lpSockAddr, int* lpSockAddrLen )
 {
 	if (m_pNextLayer)
+	{
 		return m_pNextLayer->GetPeerName(lpSockAddr, lpSockAddrLen);
+	}
 	else
 	{
 		ASSERT(m_pOwnerSocket);
 		if ( !getpeername(m_pOwnerSocket->GetSocketHandle(), lpSockAddr, lpSockAddrLen) )
+		{
 			return TRUE;
+		}
 		else
+		{
 			return FALSE;
+		}
 	}
 }
 

+ 10 - 4
source/filezilla/FtpControlSocket.cpp

@@ -6551,10 +6551,17 @@ bool CFtpControlSocket::CheckForcePasvIp(CString & host)
 		case 0: // on
 			if (!GetPeerName(ahost, tmpPort))
 			{
-				LogMessage(__FILE__, __LINE__, this, FZ_LOG_WARNING, _T("Error retrieving server address"));
-				result = false;
+				// this should happen with proxy server only
+				int logontype = COptions::GetOptionVal(OPTION_LOGONTYPE);
+				// do not know what to do, if there's FTP proxy
+				if (!logontype)
+				{
+					// this is a host name, not an IP, but it should not be a problem
+					ahost = m_CurrentServer.host;
+				}
 			}
-			else if (ahost != host)
+			
+			if (ahost != host)
 			{
 				LogMessage(__FILE__, __LINE__, this, FZ_LOG_WARNING, _T("Using host address %s instead of the one suggested by the server: %s"), ahost, host);
 				host = ahost;
@@ -6568,7 +6575,6 @@ bool CFtpControlSocket::CheckForcePasvIp(CString & host)
 		default: // auto
 			if (!GetPeerName(ahost, tmpPort))
 			{
-				// this is not failure in "auto" mode
 				LogMessage(__FILE__, __LINE__, this, FZ_LOG_INFO, _T("Error retrieving server address, cannot test if address is routable"));
 			}
 			else if (!IsRoutableAddress(host) && IsRoutableAddress(ahost))

部分文件因为文件数量过多而无法显示