Module Name:    src
Committed By:   spz
Date:           Fri Jan 27 23:16:21 UTC 2017

Modified Files:
        src/crypto/external/bsd/openssl/dist: CHANGES Configure Makefile NEWS
            README openssl.spec
        src/crypto/external/bsd/openssl/dist/apps: ca.c s_client.c s_server.c
            speed.c
        src/crypto/external/bsd/openssl/dist/crypto: opensslv.h
        src/crypto/external/bsd/openssl/dist/crypto/bn: bn_exp.c
        src/crypto/external/bsd/openssl/dist/crypto/ec: ec2_mult.c
        src/crypto/external/bsd/openssl/dist/crypto/evp: e_aes.c
        src/crypto/external/bsd/openssl/dist/crypto/rsa: rsa_oaep.c
        src/crypto/external/bsd/openssl/dist/crypto/ui: ui_lib.c ui_openssl.c
        src/crypto/external/bsd/openssl/dist/doc/crypto:
            EVP_DigestVerifyInit.pod
        src/crypto/external/bsd/openssl/dist/ssl: s2_lib.c s3_clnt.c s3_pkt.c
            s3_srvr.c ssl_err.c ssl_lib.c ssl_locl.h ssl_sess.c t1_lib.c

Log Message:
merge for OpenSSL 1.0.2k


To generate a diff of this commit:
cvs rdiff -u -r1.12 -r1.13 src/crypto/external/bsd/openssl/dist/CHANGES \
    src/crypto/external/bsd/openssl/dist/NEWS \
    src/crypto/external/bsd/openssl/dist/README \
    src/crypto/external/bsd/openssl/dist/openssl.spec
cvs rdiff -u -r1.16 -r1.17 src/crypto/external/bsd/openssl/dist/Configure
cvs rdiff -u -r1.13 -r1.14 src/crypto/external/bsd/openssl/dist/Makefile
cvs rdiff -u -r1.12 -r1.13 src/crypto/external/bsd/openssl/dist/apps/ca.c \
    src/crypto/external/bsd/openssl/dist/apps/s_client.c \
    src/crypto/external/bsd/openssl/dist/apps/s_server.c
cvs rdiff -u -r1.10 -r1.11 src/crypto/external/bsd/openssl/dist/apps/speed.c
cvs rdiff -u -r1.21 -r1.22 \
    src/crypto/external/bsd/openssl/dist/crypto/opensslv.h
cvs rdiff -u -r1.12 -r1.13 \
    src/crypto/external/bsd/openssl/dist/crypto/bn/bn_exp.c
cvs rdiff -u -r1.3 -r1.4 \
    src/crypto/external/bsd/openssl/dist/crypto/ec/ec2_mult.c
cvs rdiff -u -r1.10 -r1.11 \
    src/crypto/external/bsd/openssl/dist/crypto/evp/e_aes.c
cvs rdiff -u -r1.4 -r1.5 \
    src/crypto/external/bsd/openssl/dist/crypto/rsa/rsa_oaep.c
cvs rdiff -u -r1.2 -r1.3 \
    src/crypto/external/bsd/openssl/dist/crypto/ui/ui_lib.c
cvs rdiff -u -r1.8 -r1.9 \
    src/crypto/external/bsd/openssl/dist/crypto/ui/ui_openssl.c
cvs rdiff -u -r1.4 -r1.5 \
    src/crypto/external/bsd/openssl/dist/doc/crypto/EVP_DigestVerifyInit.pod
cvs rdiff -u -r1.7 -r1.8 src/crypto/external/bsd/openssl/dist/ssl/s2_lib.c
cvs rdiff -u -r1.19 -r1.20 src/crypto/external/bsd/openssl/dist/ssl/s3_clnt.c
cvs rdiff -u -r1.22 -r1.23 src/crypto/external/bsd/openssl/dist/ssl/s3_pkt.c \
    src/crypto/external/bsd/openssl/dist/ssl/t1_lib.c
cvs rdiff -u -r1.25 -r1.26 src/crypto/external/bsd/openssl/dist/ssl/s3_srvr.c
cvs rdiff -u -r1.11 -r1.12 src/crypto/external/bsd/openssl/dist/ssl/ssl_err.c
cvs rdiff -u -r1.8 -r1.9 src/crypto/external/bsd/openssl/dist/ssl/ssl_lib.c
cvs rdiff -u -r1.14 -r1.15 \
    src/crypto/external/bsd/openssl/dist/ssl/ssl_locl.h
cvs rdiff -u -r1.2 -r1.3 src/crypto/external/bsd/openssl/dist/ssl/ssl_sess.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/crypto/external/bsd/openssl/dist/CHANGES
diff -u src/crypto/external/bsd/openssl/dist/CHANGES:1.12 src/crypto/external/bsd/openssl/dist/CHANGES:1.13
--- src/crypto/external/bsd/openssl/dist/CHANGES:1.12	Fri Oct 14 16:23:17 2016
+++ src/crypto/external/bsd/openssl/dist/CHANGES	Fri Jan 27 23:16:20 2017
@@ -2,6 +2,67 @@
  OpenSSL CHANGES
  _______________
 
+ Changes between 1.0.2j and 1.0.2k [26 Jan 2017]
+
+  *) Truncated packet could crash via OOB read
+
+     If one side of an SSL/TLS path is running on a 32-bit host and a specific
+     cipher is being used, then a truncated packet can cause that host to
+     perform an out-of-bounds read, usually resulting in a crash.
+
+     This issue was reported to OpenSSL by Robert Święcki of Google.
+     (CVE-2017-3731)
+     [Andy Polyakov]
+
+  *) BN_mod_exp may produce incorrect results on x86_64
+
+     There is a carry propagating bug in the x86_64 Montgomery squaring
+     procedure. No EC algorithms are affected. Analysis suggests that attacks
+     against RSA and DSA as a result of this defect would be very difficult to
+     perform and are not believed likely. Attacks against DH are considered just
+     feasible (although very difficult) because most of the work necessary to
+     deduce information about a private key may be performed offline. The amount
+     of resources required for such an attack would be very significant and
+     likely only accessible to a limited number of attackers. An attacker would
+     additionally need online access to an unpatched system using the target
+     private key in a scenario with persistent DH parameters and a private
+     key that is shared between multiple clients. For example this can occur by
+     default in OpenSSL DHE based SSL/TLS ciphersuites. Note: This issue is very
+     similar to CVE-2015-3193 but must be treated as a separate problem.
+
+     This issue was reported to OpenSSL by the OSS-Fuzz project.
+     (CVE-2017-3732)
+     [Andy Polyakov]
+
+  *) Montgomery multiplication may produce incorrect results
+
+     There is a carry propagating bug in the Broadwell-specific Montgomery
+     multiplication procedure that handles input lengths divisible by, but
+     longer than 256 bits. Analysis suggests that attacks against RSA, DSA
+     and DH private keys are impossible. This is because the subroutine in
+     question is not used in operations with the private key itself and an input
+     of the attacker's direct choice. Otherwise the bug can manifest itself as
+     transient authentication and key negotiation failures or reproducible
+     erroneous outcome of public-key operations with specially crafted input.
+     Among EC algorithms only Brainpool P-512 curves are affected and one
+     presumably can attack ECDH key negotiation. Impact was not analyzed in
+     detail, because pre-requisites for attack are considered unlikely. Namely
+     multiple clients have to choose the curve in question and the server has to
+     share the private key among them, neither of which is default behaviour.
+     Even then only clients that chose the curve will be affected.
+
+     This issue was publicly reported as transient failures and was not
+     initially recognized as a security issue. Thanks to Richard Morgan for
+     providing reproducible case.
+     (CVE-2016-7055)
+     [Andy Polyakov]
+
+  *) OpenSSL now fails if it receives an unrecognised record type in TLS1.0
+     or TLS1.1. Previously this only happened in SSLv3 and TLS1.2. This is to
+     prevent issues where no progress is being made and the peer continually
+     sends unrecognised record types, using up resources processing them.
+     [Matt Caswell]
+
  Changes between 1.0.2i and 1.0.2j [26 Sep 2016]
 
   *) Missing CRL sanity check
Index: src/crypto/external/bsd/openssl/dist/NEWS
diff -u src/crypto/external/bsd/openssl/dist/NEWS:1.12 src/crypto/external/bsd/openssl/dist/NEWS:1.13
--- src/crypto/external/bsd/openssl/dist/NEWS:1.12	Fri Oct 14 16:23:17 2016
+++ src/crypto/external/bsd/openssl/dist/NEWS	Fri Jan 27 23:16:20 2017
@@ -5,9 +5,15 @@
   This file gives a brief overview of the major changes between each OpenSSL
   release. For more details please read the CHANGES file.
 
+  Major changes between OpenSSL 1.0.2j and OpenSSL 1.0.2k [26 Jan 2017]
+
+      o Truncated packet could crash via OOB read (CVE-2017-3731)
+      o BN_mod_exp may produce incorrect results on x86_64 (CVE-2017-3732)
+      o Montgomery multiplication may produce incorrect results (CVE-2016-7055)
+
   Major changes between OpenSSL 1.0.2i and OpenSSL 1.0.2j [26 Sep 2016]
 
-      o Fix Use After Free for large message sizes (CVE-2016-6309)
+      o Missing CRL sanity check (CVE-2016-7052)
 
   Major changes between OpenSSL 1.0.2h and OpenSSL 1.0.2i [22 Sep 2016]
 
Index: src/crypto/external/bsd/openssl/dist/README
diff -u src/crypto/external/bsd/openssl/dist/README:1.12 src/crypto/external/bsd/openssl/dist/README:1.13
--- src/crypto/external/bsd/openssl/dist/README:1.12	Fri Oct 14 16:23:17 2016
+++ src/crypto/external/bsd/openssl/dist/README	Fri Jan 27 23:16:20 2017
@@ -1,5 +1,5 @@
 
- OpenSSL 1.0.2j 26 Sep 2016
+ OpenSSL 1.0.2k 26 Jan 2017
 
  Copyright (c) 1998-2015 The OpenSSL Project
  Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
@@ -66,13 +66,13 @@
  If you have any problems with OpenSSL then please take the following steps
  first:
 
-    - Download the current snapshot from ftp://ftp.openssl.org/snapshot/
+    - Download the latest version from the repository
       to see if the problem has already been addressed
-    - Remove ASM versions of libraries
+    - Configure with no-asm
     - Remove compiler optimisation flags
 
- If you wish to report a bug then please include the following information in
- any bug report:
+ If you wish to report a bug then please include the following information
+ and create an issue on GitHub:
 
     - On Unix systems:
         Self-test report generated by 'make report'
@@ -84,27 +84,9 @@
     - Problem Description (steps that will reproduce the problem, if known)
     - Stack Traceback (if the application dumps core)
 
- Email the report to:
-
-    r...@openssl.org
-
- In order to avoid spam, this is a moderated mailing list, and it might
- take a day for the ticket to show up.  (We also scan posts to make sure
- that security disclosures aren't publically posted by mistake.) Mail
- to this address is recorded in the public RT (request tracker) database
- (see https://www.openssl.org/community/index.html#bugs for details) and
- also forwarded the public openssl-dev mailing list.  Confidential mail
- may be sent to openssl-secur...@openssl.org (PGP key available from the
- key servers).
-
- Please do NOT use this for general assistance or support queries.
  Just because something doesn't work the way you expect does not mean it
  is necessarily a bug in OpenSSL.
 
- You can also make GitHub pull requests. If you do this, please also send
- mail to r...@openssl.org with a link to the PR so that we can more easily
- keep track of it.
-
  HOW TO CONTRIBUTE TO OpenSSL
  ----------------------------
 
@@ -113,7 +95,7 @@
  LEGALITIES
  ----------
 
- A number of nations, in particular the U.S., restrict the use or export
- of cryptography. If you are potentially subject to such restrictions
- you should seek competent professional legal advice before attempting to
- develop or distribute cryptographic code.
+ A number of nations restrict the use or export of cryptography. If you
+ are potentially subject to such restrictions you should seek competent
+ professional legal advice before attempting to develop or distribute
+ cryptographic code.
Index: src/crypto/external/bsd/openssl/dist/openssl.spec
diff -u src/crypto/external/bsd/openssl/dist/openssl.spec:1.12 src/crypto/external/bsd/openssl/dist/openssl.spec:1.13
--- src/crypto/external/bsd/openssl/dist/openssl.spec:1.12	Fri Oct 14 16:23:17 2016
+++ src/crypto/external/bsd/openssl/dist/openssl.spec	Fri Jan 27 23:16:20 2017
@@ -7,7 +7,7 @@ Release: 1
 
 Summary: Secure Sockets Layer and cryptography libraries and tools
 Name: openssl
-Version: 1.0.2j
+Version: 1.0.2k
 Source0: ftp://ftp.openssl.org/source/%{name}-%{version}.tar.gz
 License: OpenSSL
 Group: System Environment/Libraries

Index: src/crypto/external/bsd/openssl/dist/Configure
diff -u src/crypto/external/bsd/openssl/dist/Configure:1.16 src/crypto/external/bsd/openssl/dist/Configure:1.17
--- src/crypto/external/bsd/openssl/dist/Configure:1.16	Fri Oct 14 16:23:17 2016
+++ src/crypto/external/bsd/openssl/dist/Configure	Fri Jan 27 23:16:20 2017
@@ -7,6 +7,7 @@ eval 'exec perl -S $0 ${1+"$@"}'
 
 require 5.000;
 use strict;
+use File::Compare;
 
 # see INSTALL for instructions.
 
@@ -57,12 +58,13 @@ my $usage="Usage: Configure [no-<cipher>
 # zlib-dynamic	Like "zlib", but the zlib library is expected to be a shared
 #		library and will be loaded in run-time by the OpenSSL library.
 # sctp          include SCTP support
-# 386           generate 80386 code
 # enable-weak-ssl-ciphers
 #		Enable EXPORT and LOW SSLv3 ciphers that are disabled by
 #		default.  Note, weak SSLv2 ciphers are unconditionally
 #		disabled.
-# no-sse2	disables IA-32 SSE2 code, above option implies no-sse2
+# 386		generate 80386 code in assembly modules
+# no-sse2	disables IA-32 SSE2 code in assembly modules, the above
+#		mentioned '386' option implies this one
 # no-<cipher>   build without specified algorithm (rsa, idea, rc5, ...)
 # -<xxx> +<xxx> compiler options are passed through 
 #
@@ -1792,8 +1794,16 @@ while (<IN>)
 	}
 close(IN);
 close(OUT);
-rename($Makefile,"$Makefile.bak") || die "unable to rename $Makefile\n" if -e $Makefile;
-rename("$Makefile.new",$Makefile) || die "unable to rename $Makefile.new\n";
+if ((compare($Makefile, "$Makefile.new"))
+	or file_newer('Configure', $Makefile)
+	or file_newer('config', $Makefile)
+	or file_newer('Makefile.org', $Makefile))
+	{
+	rename($Makefile,"$Makefile.bak") || die "unable to rename $Makefile\n" if -e $Makefile;
+	rename("$Makefile.new",$Makefile) || die "unable to rename $Makefile.new\n";
+	}
+else
+	{ unlink("$Makefile.new"); }
 
 print "CC            =$cc\n";
 print "CFLAG         =$cflags\n";
@@ -1985,9 +1995,13 @@ print OUT "#ifdef  __cplusplus\n";
 print OUT "}\n";
 print OUT "#endif\n";
 close(OUT);
-rename("crypto/opensslconf.h","crypto/opensslconf.h.bak") || die "unable to rename crypto/opensslconf.h\n" if -e "crypto/opensslconf.h";
-rename("crypto/opensslconf.h.new","crypto/opensslconf.h") || die "unable to rename crypto/opensslconf.h.new\n";
-
+if (compare("crypto/opensslconf.h.new","crypto/opensslconf.h"))
+	{
+	rename("crypto/opensslconf.h","crypto/opensslconf.h.bak") || die "unable to rename crypto/opensslconf.h\n" if -e "crypto/opensslconf.h";
+	rename("crypto/opensslconf.h.new","crypto/opensslconf.h") || die "unable to rename crypto/opensslconf.h.new\n";
+	}
+else
+	{ unlink("crypto/opensslconf.h.new"); }
 
 # Fix the date
 
@@ -2289,3 +2303,9 @@ sub test_sanity
 	print STDERR "No sanity errors detected!\n" if $errorcnt == 0;
 	return $errorcnt;
 	}
+
+sub file_newer
+	{
+	my ($file1, $file2) = @_;
+	return (stat($file1))[9] > (stat($file2))[9]
+	}

Index: src/crypto/external/bsd/openssl/dist/Makefile
diff -u src/crypto/external/bsd/openssl/dist/Makefile:1.13 src/crypto/external/bsd/openssl/dist/Makefile:1.14
--- src/crypto/external/bsd/openssl/dist/Makefile:1.13	Fri Oct 14 16:23:17 2016
+++ src/crypto/external/bsd/openssl/dist/Makefile	Fri Jan 27 23:16:20 2017
@@ -4,7 +4,7 @@
 ## Makefile for OpenSSL
 ##
 
-VERSION=1.0.2j
+VERSION=1.0.2k
 MAJOR=1
 MINOR=0.2
 SHLIB_VERSION_NUMBER=1.0.0
@@ -203,7 +203,8 @@ CLEARENV=	TOP= && unset TOP $${LIB+LIB} 
 		$${ASFLAGS+ASFLAGS} $${AFLAGS+AFLAGS}		\
 		$${LDCMD+LDCMD} $${LDFLAGS+LDFLAGS} $${SCRIPTS+SCRIPTS}	\
 		$${SHAREDCMD+SHAREDCMD} $${SHAREDFLAGS+SHAREDFLAGS}	\
-		$${SHARED_LIB+SHARED_LIB} $${LIBEXTRAS+LIBEXTRAS}
+		$${SHARED_LIB+SHARED_LIB} $${LIBEXTRAS+LIBEXTRAS}	\
+		$${APPS+APPS}
 
 # LC_ALL=C ensures that error [and other] messages are delivered in
 # same language for uniform treatment.

Index: src/crypto/external/bsd/openssl/dist/apps/ca.c
diff -u src/crypto/external/bsd/openssl/dist/apps/ca.c:1.12 src/crypto/external/bsd/openssl/dist/apps/ca.c:1.13
--- src/crypto/external/bsd/openssl/dist/apps/ca.c:1.12	Fri Oct 14 16:23:17 2016
+++ src/crypto/external/bsd/openssl/dist/apps/ca.c	Fri Jan 27 23:16:20 2017
@@ -319,9 +319,7 @@ int MAIN(int argc, char **argv)
 #define BSIZE 256
     MS_STATIC char buf[3][BSIZE];
     char *randfile = NULL;
-#ifndef OPENSSL_NO_ENGINE
     char *engine = NULL;
-#endif
     char *tofree = NULL;
     DB_ATTR db_attr;
 
@@ -595,9 +593,7 @@ int MAIN(int argc, char **argv)
     if (!load_config(bio_err, conf))
         goto err;
 
-#ifndef OPENSSL_NO_ENGINE
     e = setup_engine(bio_err, engine, 0);
-#endif
 
     /* Lets get the config section we are using */
     if (section == NULL) {
@@ -1485,6 +1481,7 @@ int MAIN(int argc, char **argv)
     X509_CRL_free(crl);
     NCONF_free(conf);
     NCONF_free(extconf);
+    release_engine(e);
     OBJ_cleanup();
     apps_shutdown();
     OPENSSL_EXIT(ret);
@@ -2227,7 +2224,6 @@ static int certify_spkac(X509 **xret, ch
     sk = CONF_get_section(parms, "default");
     if (sk_CONF_VALUE_num(sk) == 0) {
         BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
-        CONF_free(parms);
         goto err;
     }
 
Index: src/crypto/external/bsd/openssl/dist/apps/s_client.c
diff -u src/crypto/external/bsd/openssl/dist/apps/s_client.c:1.12 src/crypto/external/bsd/openssl/dist/apps/s_client.c:1.13
--- src/crypto/external/bsd/openssl/dist/apps/s_client.c:1.12	Fri Oct 14 16:23:17 2016
+++ src/crypto/external/bsd/openssl/dist/apps/s_client.c	Fri Jan 27 23:16:20 2017
@@ -695,12 +695,12 @@ int MAIN(int argc, char **argv)
     char *inrand = NULL;
     int mbuf_len = 0;
     struct timeval timeout, *timeoutp;
-#ifndef OPENSSL_NO_ENGINE
     char *engine_id = NULL;
+    ENGINE *e = NULL;
+#ifndef OPENSSL_NO_ENGINE
     char *ssl_client_engine_id = NULL;
     ENGINE *ssl_client_engine = NULL;
 #endif
-    ENGINE *e = NULL;
 #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
     struct timeval tv;
 # if defined(OPENSSL_SYS_BEOS_R5)
@@ -1187,8 +1187,8 @@ int MAIN(int argc, char **argv)
         next_proto.data = NULL;
 #endif
 
-#ifndef OPENSSL_NO_ENGINE
     e = setup_engine(bio_err, engine_id, 1);
+#ifndef OPENSSL_NO_ENGINE
     if (ssl_client_engine_id) {
         ssl_client_engine = ENGINE_by_id(ssl_client_engine_id);
         if (!ssl_client_engine) {
@@ -2134,6 +2134,7 @@ int MAIN(int argc, char **argv)
         OPENSSL_cleanse(mbuf, BUFSIZZ);
         OPENSSL_free(mbuf);
     }
+    release_engine(e);
     if (bio_c_out != NULL) {
         BIO_free(bio_c_out);
         bio_c_out = NULL;
Index: src/crypto/external/bsd/openssl/dist/apps/s_server.c
diff -u src/crypto/external/bsd/openssl/dist/apps/s_server.c:1.12 src/crypto/external/bsd/openssl/dist/apps/s_server.c:1.13
--- src/crypto/external/bsd/openssl/dist/apps/s_server.c:1.12	Fri Oct 14 16:23:17 2016
+++ src/crypto/external/bsd/openssl/dist/apps/s_server.c	Fri Jan 27 23:16:20 2017
@@ -328,9 +328,7 @@ static char *keymatexportlabel = NULL;
 static int keymatexportlen = 20;
 
 static int hack = 0;
-#ifndef OPENSSL_NO_ENGINE
 static char *engine_id = NULL;
-#endif
 static const char *session_id_prefix = NULL;
 
 static int enable_timeouts = 0;
@@ -484,9 +482,7 @@ static void s_server_init(void)
     s_quiet = 0;
     s_brief = 0;
     hack = 0;
-# ifndef OPENSSL_NO_ENGINE
     engine_id = NULL;
-# endif
 }
 #endif
 
@@ -1603,9 +1599,7 @@ int MAIN(int argc, char *argv[])
     SSL_load_error_strings();
     OpenSSL_add_ssl_algorithms();
 
-#ifndef OPENSSL_NO_ENGINE
     e = setup_engine(bio_err, engine_id, 1);
-#endif
 
     if (!app_passwd(bio_err, passarg, dpassarg, &pass, &dpass)) {
         BIO_printf(bio_err, "Error getting password\n");
@@ -2129,6 +2123,7 @@ int MAIN(int argc, char *argv[])
     if (jpake_secret && psk_key)
         OPENSSL_free(psk_key);
 #endif
+    release_engine(e);
     if (bio_s_out != NULL) {
         BIO_free(bio_s_out);
         bio_s_out = NULL;

Index: src/crypto/external/bsd/openssl/dist/apps/speed.c
diff -u src/crypto/external/bsd/openssl/dist/apps/speed.c:1.10 src/crypto/external/bsd/openssl/dist/apps/speed.c:1.11
--- src/crypto/external/bsd/openssl/dist/apps/speed.c:1.10	Fri Oct 14 16:23:17 2016
+++ src/crypto/external/bsd/openssl/dist/apps/speed.c	Fri Jan 27 23:16:21 2017
@@ -372,6 +372,7 @@ int MAIN(int, char **);
 
 int MAIN(int argc, char **argv)
 {
+    ENGINE *e = NULL;
     unsigned char *buf = NULL, *buf2 = NULL;
     int mret = 1;
     long count = 0, save_count = 0;
@@ -669,6 +670,10 @@ int MAIN(int argc, char **argv)
         ecdh_b[i] = NULL;
     }
 # endif
+# ifndef OPENSSL_NO_RSA
+    for (i = 0; i < RSA_NUM; i++)
+        rsa_key[i] = NULL;
+# endif
 
     if (bio_err == NULL)
         if ((bio_err = BIO_new(BIO_s_file())) != NULL)
@@ -677,12 +682,6 @@ int MAIN(int argc, char **argv)
     if (!load_config(bio_err, NULL))
         goto end;
 
-# ifndef OPENSSL_NO_RSA
-    memset(rsa_key, 0, sizeof(rsa_key));
-    for (i = 0; i < RSA_NUM; i++)
-        rsa_key[i] = NULL;
-# endif
-
     if ((buf = (unsigned char *)OPENSSL_malloc((int)BUFSIZE)) == NULL) {
         BIO_printf(bio_err, "out of memory\n");
         goto end;
@@ -749,7 +748,7 @@ int MAIN(int argc, char **argv)
                 BIO_printf(bio_err, "no engine given\n");
                 goto end;
             }
-            setup_engine(bio_err, *argv, 0);
+            e = setup_engine(bio_err, *argv, 0);
             /*
              * j will be increased again further down.  We just don't want
              * speed to confuse an engine with an algorithm, especially when
@@ -2526,6 +2525,7 @@ int MAIN(int argc, char **argv)
     }
 # endif
 
+    release_engine(e);
     apps_shutdown();
     OPENSSL_EXIT(mret);
 }

Index: src/crypto/external/bsd/openssl/dist/crypto/opensslv.h
diff -u src/crypto/external/bsd/openssl/dist/crypto/opensslv.h:1.21 src/crypto/external/bsd/openssl/dist/crypto/opensslv.h:1.22
--- src/crypto/external/bsd/openssl/dist/crypto/opensslv.h:1.21	Fri Oct 14 16:23:17 2016
+++ src/crypto/external/bsd/openssl/dist/crypto/opensslv.h	Fri Jan 27 23:16:21 2017
@@ -30,11 +30,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  0x100020afL
+# define OPENSSL_VERSION_NUMBER  0x100020bfL
 # ifdef OPENSSL_FIPS
-#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.0.2j-fips  26 Sep 2016"
+#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.0.2k-fips  26 Jan 2017"
 # else
-#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.0.2j  26 Sep 2016"
+#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.0.2k  26 Jan 2017"
 # endif
 # define OPENSSL_VERSION_PTEXT   " part of " OPENSSL_VERSION_TEXT
 

Index: src/crypto/external/bsd/openssl/dist/crypto/bn/bn_exp.c
diff -u src/crypto/external/bsd/openssl/dist/crypto/bn/bn_exp.c:1.12 src/crypto/external/bsd/openssl/dist/crypto/bn/bn_exp.c:1.13
--- src/crypto/external/bsd/openssl/dist/crypto/bn/bn_exp.c:1.12	Fri Oct 14 16:23:18 2016
+++ src/crypto/external/bsd/openssl/dist/crypto/bn/bn_exp.c	Fri Jan 27 23:16:21 2017
@@ -184,8 +184,9 @@ int BN_exp(BIGNUM *r, const BIGNUM *a, c
                 goto err;
         }
     }
-    if (r != rr)
-        BN_copy(r, rr);
+    if (r != rr && BN_copy(r, rr) == NULL)
+        goto err;
+
     ret = 1;
  err:
     BN_CTX_end(ctx);

Index: src/crypto/external/bsd/openssl/dist/crypto/ec/ec2_mult.c
diff -u src/crypto/external/bsd/openssl/dist/crypto/ec/ec2_mult.c:1.3 src/crypto/external/bsd/openssl/dist/crypto/ec/ec2_mult.c:1.4
--- src/crypto/external/bsd/openssl/dist/crypto/ec/ec2_mult.c:1.3	Mon Mar 23 10:22:47 2015
+++ src/crypto/external/bsd/openssl/dist/crypto/ec/ec2_mult.c	Fri Jan 27 23:16:21 2017
@@ -267,7 +267,7 @@ static int ec_GF2m_montgomery_point_mult
                                              BN_CTX *ctx)
 {
     BIGNUM *x1, *x2, *z1, *z2;
-    int ret = 0, i;
+    int ret = 0, i, group_top;
     BN_ULONG mask, word;
 
     if (r == point) {
@@ -297,10 +297,12 @@ static int ec_GF2m_montgomery_point_mult
     x2 = &r->X;
     z2 = &r->Y;
 
-    bn_wexpand(x1, group->field.top);
-    bn_wexpand(z1, group->field.top);
-    bn_wexpand(x2, group->field.top);
-    bn_wexpand(z2, group->field.top);
+    group_top = group->field.top;
+    if (bn_wexpand(x1, group_top) == NULL
+        || bn_wexpand(z1, group_top) == NULL
+        || bn_wexpand(x2, group_top) == NULL
+        || bn_wexpand(z2, group_top) == NULL)
+        goto err;
 
     if (!BN_GF2m_mod_arr(x1, &point->X, group->poly))
         goto err;               /* x1 = x */
@@ -329,14 +331,14 @@ static int ec_GF2m_montgomery_point_mult
     for (; i >= 0; i--) {
         word = scalar->d[i];
         while (mask) {
-            BN_consttime_swap(word & mask, x1, x2, group->field.top);
-            BN_consttime_swap(word & mask, z1, z2, group->field.top);
+            BN_consttime_swap(word & mask, x1, x2, group_top);
+            BN_consttime_swap(word & mask, z1, z2, group_top);
             if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx))
                 goto err;
             if (!gf2m_Mdouble(group, x1, z1, ctx))
                 goto err;
-            BN_consttime_swap(word & mask, x1, x2, group->field.top);
-            BN_consttime_swap(word & mask, z1, z2, group->field.top);
+            BN_consttime_swap(word & mask, x1, x2, group_top);
+            BN_consttime_swap(word & mask, z1, z2, group_top);
             mask >>= 1;
         }
         mask = BN_TBIT;

Index: src/crypto/external/bsd/openssl/dist/crypto/evp/e_aes.c
diff -u src/crypto/external/bsd/openssl/dist/crypto/evp/e_aes.c:1.10 src/crypto/external/bsd/openssl/dist/crypto/evp/e_aes.c:1.11
--- src/crypto/external/bsd/openssl/dist/crypto/evp/e_aes.c:1.10	Mon Oct 17 00:23:47 2016
+++ src/crypto/external/bsd/openssl/dist/crypto/evp/e_aes.c	Fri Jan 27 23:16:21 2017
@@ -155,10 +155,10 @@ void AES_ctr32_encrypt(const unsigned ch
                        const unsigned char ivec[AES_BLOCK_SIZE]);
 # endif
 # ifdef AES_XTS_ASM
-void AES_xts_encrypt(const char *inp, char *out, size_t len,
+void AES_xts_encrypt(const unsigned char *inp, unsigned char *out, size_t len,
                      const AES_KEY *key1, const AES_KEY *key2,
                      const unsigned char iv[16]);
-void AES_xts_decrypt(const char *inp, char *out, size_t len,
+void AES_xts_decrypt(const unsigned char *inp, unsigned char *out, size_t len,
                      const AES_KEY *key1, const AES_KEY *key2,
                      const unsigned char iv[16]);
 # endif

Index: src/crypto/external/bsd/openssl/dist/crypto/rsa/rsa_oaep.c
diff -u src/crypto/external/bsd/openssl/dist/crypto/rsa/rsa_oaep.c:1.4 src/crypto/external/bsd/openssl/dist/crypto/rsa/rsa_oaep.c:1.5
--- src/crypto/external/bsd/openssl/dist/crypto/rsa/rsa_oaep.c:1.4	Fri Oct 14 16:23:20 2016
+++ src/crypto/external/bsd/openssl/dist/crypto/rsa/rsa_oaep.c	Fri Jan 27 23:16:21 2017
@@ -89,17 +89,21 @@ int RSA_padding_add_PKCS1_OAEP_mgf1(unsi
     }
 
     if (PKCS1_MGF1(dbmask, emlen - mdlen, seed, mdlen, mgf1md) < 0)
-        return 0;
+        goto err;
     for (i = 0; i < emlen - mdlen; i++)
         db[i] ^= dbmask[i];
 
     if (PKCS1_MGF1(seedmask, mdlen, db, emlen - mdlen, mgf1md) < 0)
-        return 0;
+        goto err;
     for (i = 0; i < mdlen; i++)
         seed[i] ^= seedmask[i];
 
     OPENSSL_free(dbmask);
     return 1;
+
+ err:
+    OPENSSL_free(dbmask);
+    return 0;
 }
 
 int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,

Index: src/crypto/external/bsd/openssl/dist/crypto/ui/ui_lib.c
diff -u src/crypto/external/bsd/openssl/dist/crypto/ui/ui_lib.c:1.2 src/crypto/external/bsd/openssl/dist/crypto/ui/ui_lib.c:1.3
--- src/crypto/external/bsd/openssl/dist/crypto/ui/ui_lib.c:1.2	Fri Oct 14 16:23:21 2016
+++ src/crypto/external/bsd/openssl/dist/crypto/ui/ui_lib.c	Fri Jan 27 23:16:21 2017
@@ -164,7 +164,7 @@ static int general_allocate_string(UI *u
     UI_STRING *s = general_allocate_prompt(ui, prompt, prompt_freeable,
                                            type, input_flags, result_buf);
 
-    if (s) {
+    if (s != NULL) {
         if (allocate_string_stack(ui) >= 0) {
             s->_.string_data.result_minsize = minsize;
             s->_.string_data.result_maxsize = maxsize;
@@ -197,8 +197,8 @@ static int general_allocate_boolean(UI *
     } else if (cancel_chars == NULL) {
         UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN, ERR_R_PASSED_NULL_PARAMETER);
     } else {
-        for (p = ok_chars; *p; p++) {
-            if (strchr(cancel_chars, *p)) {
+        for (p = ok_chars; *p != '\0'; p++) {
+            if (strchr(cancel_chars, *p) != NULL) {
                 UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN,
                       UI_R_COMMON_OK_AND_CANCEL_CHARACTERS);
             }
@@ -207,7 +207,7 @@ static int general_allocate_boolean(UI *
         s = general_allocate_prompt(ui, prompt, prompt_freeable,
                                     type, input_flags, result_buf);
 
-        if (s) {
+        if (s != NULL) {
             if (allocate_string_stack(ui) >= 0) {
                 s->_.boolean_data.action_desc = action_desc;
                 s->_.boolean_data.ok_chars = ok_chars;
@@ -243,7 +243,7 @@ int UI_dup_input_string(UI *ui, const ch
 {
     char *prompt_copy = NULL;
 
-    if (prompt) {
+    if (prompt != NULL) {
         prompt_copy = BUF_strdup(prompt);
         if (prompt_copy == NULL) {
             UIerr(UI_F_UI_DUP_INPUT_STRING, ERR_R_MALLOC_FAILURE);
@@ -271,7 +271,7 @@ int UI_dup_verify_string(UI *ui, const c
 {
     char *prompt_copy = NULL;
 
-    if (prompt) {
+    if (prompt != NULL) {
         prompt_copy = BUF_strdup(prompt);
         if (prompt_copy == NULL) {
             UIerr(UI_F_UI_DUP_VERIFY_STRING, ERR_R_MALLOC_FAILURE);
@@ -302,7 +302,7 @@ int UI_dup_input_boolean(UI *ui, const c
     char *ok_chars_copy = NULL;
     char *cancel_chars_copy = NULL;
 
-    if (prompt) {
+    if (prompt != NULL) {
         prompt_copy = BUF_strdup(prompt);
         if (prompt_copy == NULL) {
             UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE);
@@ -310,7 +310,7 @@ int UI_dup_input_boolean(UI *ui, const c
         }
     }
 
-    if (action_desc) {
+    if (action_desc != NULL) {
         action_desc_copy = BUF_strdup(action_desc);
         if (action_desc_copy == NULL) {
             UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE);
@@ -318,7 +318,7 @@ int UI_dup_input_boolean(UI *ui, const c
         }
     }
 
-    if (ok_chars) {
+    if (ok_chars != NULL) {
         ok_chars_copy = BUF_strdup(ok_chars);
         if (ok_chars_copy == NULL) {
             UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE);
@@ -326,7 +326,7 @@ int UI_dup_input_boolean(UI *ui, const c
         }
     }
 
-    if (cancel_chars) {
+    if (cancel_chars != NULL) {
         cancel_chars_copy = BUF_strdup(cancel_chars);
         if (cancel_chars_copy == NULL) {
             UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE);
@@ -359,7 +359,7 @@ int UI_dup_info_string(UI *ui, const cha
 {
     char *text_copy = NULL;
 
-    if (text) {
+    if (text != NULL) {
         text_copy = BUF_strdup(text);
         if (text_copy == NULL) {
             UIerr(UI_F_UI_DUP_INFO_STRING, ERR_R_MALLOC_FAILURE);
@@ -381,7 +381,7 @@ int UI_dup_error_string(UI *ui, const ch
 {
     char *text_copy = NULL;
 
-    if (text) {
+    if (text != NULL) {
         text_copy = BUF_strdup(text);
         if (text_copy == NULL) {
             UIerr(UI_F_UI_DUP_ERROR_STRING, ERR_R_MALLOC_FAILURE);
@@ -397,7 +397,7 @@ char *UI_construct_prompt(UI *ui, const 
 {
     char *prompt = NULL;
 
-    if (ui->meth->ui_construct_prompt)
+    if (ui->meth->ui_construct_prompt != NULL)
         prompt = ui->meth->ui_construct_prompt(ui, object_desc, object_name);
     else {
         char prompt1[] = "Enter ";
@@ -408,7 +408,7 @@ char *UI_construct_prompt(UI *ui, const 
         if (object_desc == NULL)
             return NULL;
         len = sizeof(prompt1) - 1 + strlen(object_desc);
-        if (object_name)
+        if (object_name != NULL)
             len += sizeof(prompt2) - 1 + strlen(object_name);
         len += sizeof(prompt3) - 1;
 
@@ -417,7 +417,7 @@ char *UI_construct_prompt(UI *ui, const 
             return NULL;
         BUF_strlcpy(prompt, prompt1, len + 1);
         BUF_strlcat(prompt, object_desc, len + 1);
-        if (object_name) {
+        if (object_name != NULL) {
             BUF_strlcat(prompt, prompt2, len + 1);
             BUF_strlcat(prompt, object_name, len + 1);
         }
@@ -459,7 +459,8 @@ static int print_error(const char *str, 
     uis.type = UIT_ERROR;
     uis.out_string = str;
 
-    if (ui->meth->ui_write_string && !ui->meth->ui_write_string(ui, &uis))
+    if (ui->meth->ui_write_string != NULL
+        && ui->meth->ui_write_string(ui, &uis) <= 0)
         return -1;
     return 0;
 }
@@ -468,24 +469,28 @@ int UI_process(UI *ui)
 {
     int i, ok = 0;
 
-    if (ui->meth->ui_open_session && !ui->meth->ui_open_session(ui))
-        return -1;
+    if (ui->meth->ui_open_session != NULL
+        && ui->meth->ui_open_session(ui) <= 0) {
+        ok = -1;
+        goto err;
+    }
 
     if (ui->flags & UI_FLAG_PRINT_ERRORS)
         ERR_print_errors_cb((int (*)(const char *, size_t, void *))
                             print_error, (void *)ui);
 
     for (i = 0; i < sk_UI_STRING_num(ui->strings); i++) {
-        if (ui->meth->ui_write_string
-            && !ui->meth->ui_write_string(ui,
-                                          sk_UI_STRING_value(ui->strings, i)))
+        if (ui->meth->ui_write_string != NULL
+            && (ui->meth->ui_write_string(ui,
+                                          sk_UI_STRING_value(ui->strings, i))
+                <= 0))
         {
             ok = -1;
             goto err;
         }
     }
 
-    if (ui->meth->ui_flush)
+    if (ui->meth->ui_flush != NULL)
         switch (ui->meth->ui_flush(ui)) {
         case -1:               /* Interrupt/Cancel/something... */
             ok = -2;
@@ -499,7 +504,7 @@ int UI_process(UI *ui)
         }
 
     for (i = 0; i < sk_UI_STRING_num(ui->strings); i++) {
-        if (ui->meth->ui_read_string) {
+        if (ui->meth->ui_read_string != NULL) {
             switch (ui->meth->ui_read_string(ui,
                                              sk_UI_STRING_value(ui->strings,
                                                                 i))) {
@@ -516,7 +521,8 @@ int UI_process(UI *ui)
         }
     }
  err:
-    if (ui->meth->ui_close_session && !ui->meth->ui_close_session(ui))
+    if (ui->meth->ui_close_session != NULL
+        && ui->meth->ui_close_session(ui) <= 0)
         return -1;
     return ok;
 }
@@ -612,49 +618,49 @@ void UI_destroy_method(UI_METHOD *ui_met
 
 int UI_method_set_opener(UI_METHOD *method, int (*opener) (UI *ui))
 {
-    if (method) {
+    if (method != NULL) {
         method->ui_open_session = opener;
         return 0;
-    } else
-        return -1;
+    }
+    return -1;
 }
 
 int UI_method_set_writer(UI_METHOD *method,
                          int (*writer) (UI *ui, UI_STRING *uis))
 {
-    if (method) {
+    if (method != NULL) {
         method->ui_write_string = writer;
         return 0;
-    } else
-        return -1;
+    }
+    return -1;
 }
 
 int UI_method_set_flusher(UI_METHOD *method, int (*flusher) (UI *ui))
 {
-    if (method) {
+    if (method != NULL) {
         method->ui_flush = flusher;
         return 0;
-    } else
-        return -1;
+    }
+    return -1;
 }
 
 int UI_method_set_reader(UI_METHOD *method,
                          int (*reader) (UI *ui, UI_STRING *uis))
 {
-    if (method) {
+    if (method != NULL) {
         method->ui_read_string = reader;
         return 0;
-    } else
-        return -1;
+    }
+    return -1;
 }
 
 int UI_method_set_closer(UI_METHOD *method, int (*closer) (UI *ui))
 {
-    if (method) {
+    if (method != NULL) {
         method->ui_close_session = closer;
         return 0;
-    } else
-        return -1;
+    }
+    return -1;
 }
 
 int UI_method_set_prompt_constructor(UI_METHOD *method,
@@ -664,55 +670,55 @@ int UI_method_set_prompt_constructor(UI_
                                                                   const char
                                                                   *object_name))
 {
-    if (method) {
+    if (method != NULL) {
         method->ui_construct_prompt = prompt_constructor;
         return 0;
-    } else
-        return -1;
+    }
+    return -1;
 }
 
-int (*UI_method_get_opener(UI_METHOD *method)) (UI *) {
-    if (method)
+int (*UI_method_get_opener(UI_METHOD *method)) (UI *)
+{
+    if (method != NULL)
         return method->ui_open_session;
-    else
-        return NULL;
+    return NULL;
 }
 
-int (*UI_method_get_writer(UI_METHOD *method)) (UI *, UI_STRING *) {
-    if (method)
+int (*UI_method_get_writer(UI_METHOD *method)) (UI *, UI_STRING *)
+{
+    if (method != NULL)
         return method->ui_write_string;
-    else
-        return NULL;
+    return NULL;
 }
 
-int (*UI_method_get_flusher(UI_METHOD *method)) (UI *) {
-    if (method)
+int (*UI_method_get_flusher(UI_METHOD *method)) (UI *)
+{
+    if (method != NULL)
         return method->ui_flush;
-    else
-        return NULL;
+    return NULL;
 }
 
-int (*UI_method_get_reader(UI_METHOD *method)) (UI *, UI_STRING *) {
-    if (method)
+int (*UI_method_get_reader(UI_METHOD *method)) (UI *, UI_STRING *)
+{
+    if (method != NULL)
         return method->ui_read_string;
-    else
-        return NULL;
+    return NULL;
 }
 
-int (*UI_method_get_closer(UI_METHOD *method)) (UI *) {
-    if (method)
+int (*UI_method_get_closer(UI_METHOD *method)) (UI *)
+{
+    if (method != NULL)
         return method->ui_close_session;
-    else
-        return NULL;
+    return NULL;
 }
 
 char *(*UI_method_get_prompt_constructor(UI_METHOD *method)) (UI *,
                                                               const char *,
-                                                              const char *) {
-    if (method)
+                                                              const char *)
+{
+    if (method != NULL)
         return method->ui_construct_prompt;
-    else
-        return NULL;
+    return NULL;
 }
 
 enum UI_string_types UI_get_string_type(UI_STRING *uis)

Index: src/crypto/external/bsd/openssl/dist/crypto/ui/ui_openssl.c
diff -u src/crypto/external/bsd/openssl/dist/crypto/ui/ui_openssl.c:1.8 src/crypto/external/bsd/openssl/dist/crypto/ui/ui_openssl.c:1.9
--- src/crypto/external/bsd/openssl/dist/crypto/ui/ui_openssl.c:1.8	Fri Oct 14 16:23:21 2016
+++ src/crypto/external/bsd/openssl/dist/crypto/ui/ui_openssl.c	Fri Jan 27 23:16:21 2017
@@ -435,7 +435,7 @@ static int read_string_inner(UI *ui, UI_
 # else
     p = fgets(result, maxsize, tty_in);
 # endif
-    if (!p)
+    if (p == NULL)
         goto error;
     if (feof(tty_in))
         goto error;
@@ -504,18 +504,31 @@ static int open_console(UI *ui)
             is_a_tty = 0;
         else
 # endif
+# ifdef ENODEV
+            /*
+             * MacOS X returns ENODEV (Operation not supported by device),
+             * which seems appropriate.
+             */
+        if (errno == ENODEV)
+            is_a_tty = 0;
+        else
+# endif
             return 0;
     }
 #endif
 #ifdef OPENSSL_SYS_VMS
     status = sys$assign(&terminal, &channel, 0, 0);
+
+    /* if there isn't a TT device, something is very wrong */
     if (status != SS$_NORMAL)
         return 0;
-    status =
-        sys$qiow(0, channel, IO$_SENSEMODE, &iosb, 0, 0, tty_orig, 12, 0, 0,
-                 0, 0);
+
+    status = sys$qiow(0, channel, IO$_SENSEMODE, &iosb, 0, 0, tty_orig, 12,
+                      0, 0, 0, 0);
+
+    /* If IO$_SENSEMODE doesn't work, this is not a terminal device */
     if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
-        return 0;
+        is_a_tty = 0;
 #endif
     return 1;
 }
@@ -532,14 +545,15 @@ static int noecho_console(UI *ui)
         return 0;
 #endif
 #ifdef OPENSSL_SYS_VMS
-    tty_new[0] = tty_orig[0];
-    tty_new[1] = tty_orig[1] | TT$M_NOECHO;
-    tty_new[2] = tty_orig[2];
-    status =
-        sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12, 0, 0, 0,
-                 0);
-    if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
-        return 0;
+    if (is_a_tty) {
+        tty_new[0] = tty_orig[0];
+        tty_new[1] = tty_orig[1] | TT$M_NOECHO;
+        tty_new[2] = tty_orig[2];
+        status = sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12,
+                          0, 0, 0, 0);
+        if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
+            return 0;
+    }
 #endif
     return 1;
 }
@@ -556,14 +570,15 @@ static int echo_console(UI *ui)
         return 0;
 #endif
 #ifdef OPENSSL_SYS_VMS
-    tty_new[0] = tty_orig[0];
-    tty_new[1] = tty_orig[1] & ~TT$M_NOECHO;
-    tty_new[2] = tty_orig[2];
-    status =
-        sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12, 0, 0, 0,
-                 0);
-    if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
-        return 0;
+    if (is_a_tty) {
+        tty_new[0] = tty_orig[0];
+        tty_new[1] = tty_orig[1] & ~TT$M_NOECHO;
+        tty_new[2] = tty_orig[2];
+        status = sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12,
+                          0, 0, 0, 0);
+        if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
+            return 0;
+    }
 #endif
     return 1;
 }
@@ -576,6 +591,8 @@ static int close_console(UI *ui)
         fclose(tty_out);
 #ifdef OPENSSL_SYS_VMS
     status = sys$dassgn(channel);
+    if (status != SS$_NORMAL)
+        return 0;
 #endif
     CRYPTO_w_unlock(CRYPTO_LOCK_UI);
 

Index: src/crypto/external/bsd/openssl/dist/doc/crypto/EVP_DigestVerifyInit.pod
diff -u src/crypto/external/bsd/openssl/dist/doc/crypto/EVP_DigestVerifyInit.pod:1.4 src/crypto/external/bsd/openssl/dist/doc/crypto/EVP_DigestVerifyInit.pod:1.5
--- src/crypto/external/bsd/openssl/dist/doc/crypto/EVP_DigestVerifyInit.pod:1.4	Fri Oct 14 16:23:21 2016
+++ src/crypto/external/bsd/openssl/dist/doc/crypto/EVP_DigestVerifyInit.pod	Fri Jan 27 23:16:21 2017
@@ -10,7 +10,7 @@ EVP_DigestVerifyInit, EVP_DigestVerifyUp
 
  int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
 			const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey);
- int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt);
+ int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt);
  int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, size_t siglen);
 
 =head1 DESCRIPTION

Index: src/crypto/external/bsd/openssl/dist/ssl/s2_lib.c
diff -u src/crypto/external/bsd/openssl/dist/ssl/s2_lib.c:1.7 src/crypto/external/bsd/openssl/dist/ssl/s2_lib.c:1.8
--- src/crypto/external/bsd/openssl/dist/ssl/s2_lib.c:1.7	Fri Oct 14 16:23:22 2016
+++ src/crypto/external/bsd/openssl/dist/ssl/s2_lib.c	Fri Jan 27 23:16:21 2017
@@ -254,7 +254,7 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl2_cip
      SSL_3DES,
      SSL_MD5,
      SSL_SSLV2,
-     SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH,
+     SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM,
      0,
      112,
      168,

Index: src/crypto/external/bsd/openssl/dist/ssl/s3_clnt.c
diff -u src/crypto/external/bsd/openssl/dist/ssl/s3_clnt.c:1.19 src/crypto/external/bsd/openssl/dist/ssl/s3_clnt.c:1.20
--- src/crypto/external/bsd/openssl/dist/ssl/s3_clnt.c:1.19	Fri Oct 14 16:23:22 2016
+++ src/crypto/external/bsd/openssl/dist/ssl/s3_clnt.c	Fri Jan 27 23:16:21 2017
@@ -1710,12 +1710,6 @@ int ssl3_get_key_exchange(SSL *s)
         }
         p += i;
 
-        if (BN_is_zero(dh->p)) {
-            SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_P_VALUE);
-            goto f_err;
-        }
-
-
         if (2 > n - param_len) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
             goto f_err;
@@ -1736,11 +1730,6 @@ int ssl3_get_key_exchange(SSL *s)
         }
         p += i;
 
-        if (BN_is_zero(dh->g)) {
-            SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_VALUE);
-            goto f_err;
-        }
-
         if (2 > n - param_len) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
             goto f_err;
@@ -1767,6 +1756,39 @@ int ssl3_get_key_exchange(SSL *s)
             goto f_err;
         }
 
+        /*-
+         * Check that p and g are suitable enough
+         *
+         * p is odd
+         * 1 < g < p - 1
+         */
+        {
+            BIGNUM *tmp = NULL;
+
+            if (!BN_is_odd(dh->p)) {
+                SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_P_VALUE);
+                goto f_err;
+            }
+            if (BN_is_negative(dh->g) || BN_is_zero(dh->g)
+                || BN_is_one(dh->g)) {
+                SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_VALUE);
+                goto f_err;
+            }
+            if ((tmp = BN_new()) == NULL
+                || BN_copy(tmp, dh->p) == NULL
+                || !BN_sub_word(tmp, 1)) {
+                BN_free(tmp);
+                SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
+                goto err;
+            }
+            if (BN_cmp(dh->g, tmp) >= 0) {
+                BN_free(tmp);
+                SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_VALUE);
+                goto f_err;
+            }
+            BN_free(tmp);
+        }
+
 # ifndef OPENSSL_NO_RSA
         if (alg_a & SSL_aRSA)
             pkey =

Index: src/crypto/external/bsd/openssl/dist/ssl/s3_pkt.c
diff -u src/crypto/external/bsd/openssl/dist/ssl/s3_pkt.c:1.22 src/crypto/external/bsd/openssl/dist/ssl/s3_pkt.c:1.23
--- src/crypto/external/bsd/openssl/dist/ssl/s3_pkt.c:1.22	Fri Oct 14 16:23:22 2016
+++ src/crypto/external/bsd/openssl/dist/ssl/s3_pkt.c	Fri Jan 27 23:16:21 2017
@@ -136,6 +136,9 @@ static int do_ssl3_write(SSL *s, int typ
                          unsigned int len, int create_empty_fragment);
 static int ssl3_get_record(SSL *s);
 
+/*
+ * Return values are as per SSL_read()
+ */
 int ssl3_read_n(SSL *s, int n, int max, int extend)
 {
     /*
@@ -1086,7 +1089,10 @@ static int do_ssl3_write(SSL *s, int typ
     return -1;
 }
 
-/* if s->s3->wbuf.left != 0, we need to call this */
+/* if s->s3->wbuf.left != 0, we need to call this
+ *
+ * Return values are as per SSL_write(), i.e.
+ */
 int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
                        unsigned int len)
 {
@@ -1126,7 +1132,7 @@ int ssl3_write_pending(SSL *s, int type,
                  */
                 wb->left = 0;
             }
-            return (i);
+            return i;
         }
         wb->offset += i;
         wb->left -= i;
@@ -1597,16 +1603,13 @@ int ssl3_read_bytes(SSL *s, int type, un
 
     switch (rr->type) {
     default:
-#ifndef OPENSSL_NO_TLS
         /*
-         * TLS up to v1.1 just ignores unknown message types: TLS v1.2 give
-         * an unexpected message alert.
+         * TLS 1.0 and 1.1 say you SHOULD ignore unrecognised record types, but
+         * TLS 1.2 says you MUST send an unexpected message alert. We use the
+         * TLS 1.2 behaviour for all protocol versions to prevent issues where
+         * no progress is being made and the peer continually sends unrecognised
+         * record types, using up resources processing them.
          */
-        if (s->version >= TLS1_VERSION && s->version <= TLS1_1_VERSION) {
-            rr->length = 0;
-            goto start;
-        }
-#endif
         al = SSL_AD_UNEXPECTED_MESSAGE;
         SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNEXPECTED_RECORD);
         goto f_err;
Index: src/crypto/external/bsd/openssl/dist/ssl/t1_lib.c
diff -u src/crypto/external/bsd/openssl/dist/ssl/t1_lib.c:1.22 src/crypto/external/bsd/openssl/dist/ssl/t1_lib.c:1.23
--- src/crypto/external/bsd/openssl/dist/ssl/t1_lib.c:1.22	Fri Oct 14 16:23:22 2016
+++ src/crypto/external/bsd/openssl/dist/ssl/t1_lib.c	Fri Jan 27 23:16:21 2017
@@ -132,6 +132,9 @@ static int ssl_check_clienthello_tlsext_
 int ssl_check_serverhello_tlsext(SSL *s);
 #endif
 
+#define CHECKLEN(curr, val, limit) \
+    (((curr) >= (limit)) || (size_t)((limit) - (curr)) < (size_t)(val))
+
 SSL3_ENC_METHOD TLSv1_enc_data = {
     tls1_enc,
     tls1_mac,
@@ -1263,8 +1266,7 @@ unsigned char *ssl_add_clienthello_tlsex
 
     if (s->tlsext_hostname != NULL) {
         /* Add TLS extension servername to the Client Hello message */
-        unsigned long size_str;
-        long lenmax;
+        size_t size_str;
 
         /*-
          * check for enough space.
@@ -1274,10 +1276,8 @@ unsigned char *ssl_add_clienthello_tlsex
          * 2 for hostname length
          * + hostname length
          */
-
-        if ((lenmax = limit - ret - 9) < 0
-            || (size_str =
-                strlen(s->tlsext_hostname)) > (unsigned long)lenmax)
+        size_str = strlen(s->tlsext_hostname);
+        if (CHECKLEN(ret, 9 + size_str, limit))
             return NULL;
 
         /* extension type and length */
@@ -1321,7 +1321,7 @@ unsigned char *ssl_add_clienthello_tlsex
     if (s->srp_ctx.login != NULL) { /* Add TLS extension SRP username to the
                                      * Client Hello message */
 
-        int login_len = strlen(s->srp_ctx.login);
+        size_t login_len = strlen(s->srp_ctx.login);
         if (login_len > 255 || login_len == 0) {
             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
             return NULL;
@@ -1333,7 +1333,7 @@ unsigned char *ssl_add_clienthello_tlsex
          * 1 for the srp user identity
          * + srp user identity length
          */
-        if ((limit - ret - 5 - login_len) < 0)
+        if (CHECKLEN(ret, 5 + login_len, limit))
             return NULL;
 
         /* fill in the extension */
@@ -1350,20 +1350,23 @@ unsigned char *ssl_add_clienthello_tlsex
         /*
          * Add TLS extension ECPointFormats to the ClientHello message
          */
-        long lenmax;
         const unsigned char *pcurves, *pformats;
         size_t num_curves, num_formats, curves_list_len;
 
         tls1_get_formatlist(s, &pformats, &num_formats);
 
-        if ((lenmax = limit - ret - 5) < 0)
-            return NULL;
-        if (num_formats > (size_t)lenmax)
-            return NULL;
         if (num_formats > 255) {
             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
             return NULL;
         }
+        /*-
+         * check for enough space.
+         * 4 bytes for the ec point formats type and extension length
+         * 1 byte for the length of the formats
+         * + formats length
+         */
+        if (CHECKLEN(ret, 5 + num_formats, limit))
+            return NULL;
 
         s2n(TLSEXT_TYPE_ec_point_formats, ret);
         /* The point format list has 1-byte length. */
@@ -1379,15 +1382,20 @@ unsigned char *ssl_add_clienthello_tlsex
         if (!tls1_get_curvelist(s, 0, &pcurves, &num_curves))
             return NULL;
 
-        if ((lenmax = limit - ret - 6) < 0)
-            return NULL;
-        if (num_curves > (size_t)lenmax / 2)
-            return NULL;
         if (num_curves > 65532 / 2) {
             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
             return NULL;
         }
         curves_list_len = 2 * num_curves;
+        /*-
+         * check for enough space.
+         * 4 bytes for the ec curves type and extension length
+         * 2 bytes for the curve list length
+         * + curve list length
+         */
+        if (CHECKLEN(ret, 6 + curves_list_len, limit))
+            return NULL;
+
         s2n(TLSEXT_TYPE_elliptic_curves, ret);
         s2n(curves_list_len + 2, ret);
         s2n(curves_list_len, ret);
@@ -1397,7 +1405,7 @@ unsigned char *ssl_add_clienthello_tlsex
 # endif                         /* OPENSSL_NO_EC */
 
     if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) {
-        int ticklen;
+        size_t ticklen;
         if (!s->new_session && s->session && s->session->tlsext_tick)
             ticklen = s->session->tlsext_ticklen;
         else if (s->session && s->tlsext_session_ticket &&
@@ -1418,11 +1426,11 @@ unsigned char *ssl_add_clienthello_tlsex
          * Check for enough room 2 for extension type, 2 for len rest for
          * ticket
          */
-        if ((long)(limit - ret - 4 - ticklen) < 0)
+        if (CHECKLEN(ret, 4 + ticklen, limit))
             return NULL;
         s2n(TLSEXT_TYPE_session_ticket, ret);
         s2n(ticklen, ret);
-        if (ticklen) {
+        if (ticklen > 0) {
             memcpy(ret, s->session->tlsext_tick, ticklen);
             ret += ticklen;
         }
@@ -1433,7 +1441,14 @@ unsigned char *ssl_add_clienthello_tlsex
         size_t salglen;
         const unsigned char *salg;
         salglen = tls12_get_psigalgs(s, &salg);
-        if ((size_t)(limit - ret) < salglen + 6)
+
+        /*-
+         * check for enough space.
+         * 4 bytes for the sigalgs type and extension length
+         * 2 bytes for the sigalg list length
+         * + sigalg list length
+         */
+        if (CHECKLEN(ret, salglen + 6, limit))
             return NULL;
         s2n(TLSEXT_TYPE_signature_algorithms, ret);
         s2n(salglen + 2, ret);
@@ -1460,30 +1475,42 @@ unsigned char *ssl_add_clienthello_tlsex
 
     if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) {
         int i;
-        long extlen, idlen, itmp;
+        size_t extlen, idlen;
+        int lentmp;
         OCSP_RESPID *id;
 
         idlen = 0;
         for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) {
             id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
-            itmp = i2d_OCSP_RESPID(id, NULL);
-            if (itmp <= 0)
+            lentmp = i2d_OCSP_RESPID(id, NULL);
+            if (lentmp <= 0)
                 return NULL;
-            idlen += itmp + 2;
+            idlen += (size_t)lentmp + 2;
         }
 
         if (s->tlsext_ocsp_exts) {
-            extlen = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL);
-            if (extlen < 0)
+            lentmp = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL);
+            if (lentmp < 0)
                 return NULL;
+            extlen = (size_t)lentmp;
         } else
             extlen = 0;
 
-        if ((long)(limit - ret - 7 - extlen - idlen) < 0)
-            return NULL;
-        s2n(TLSEXT_TYPE_status_request, ret);
         if (extlen + idlen > 0xFFF0)
             return NULL;
+        /*
+         * 2 bytes for status request type
+         * 2 bytes for status request len
+         * 1 byte for OCSP request type
+         * 2 bytes for length of ids
+         * 2 bytes for length of extensions
+         * + length of ids
+         * + length of extensions
+         */
+        if (CHECKLEN(ret, 9 + idlen + extlen, limit))
+            return NULL;
+
+        s2n(TLSEXT_TYPE_status_request, ret);
         s2n(extlen + idlen + 5, ret);
         *(ret++) = TLSEXT_STATUSTYPE_ocsp;
         s2n(idlen, ret);
@@ -1493,9 +1520,9 @@ unsigned char *ssl_add_clienthello_tlsex
             id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
             /* skip over id len */
             ret += 2;
-            itmp = i2d_OCSP_RESPID(id, &ret);
+            lentmp = i2d_OCSP_RESPID(id, &ret);
             /* write id len */
-            s2n(itmp, q);
+            s2n(lentmp, q);
         }
         s2n(extlen, ret);
         if (extlen > 0)
@@ -1503,8 +1530,15 @@ unsigned char *ssl_add_clienthello_tlsex
     }
 # ifndef OPENSSL_NO_HEARTBEATS
     /* Add Heartbeat extension */
-    if ((limit - ret - 4 - 1) < 0)
+
+    /*-
+     * check for enough space.
+     * 4 bytes for the heartbeat ext type and extension length
+     * 1 byte for the mode
+     */
+    if (CHECKLEN(ret, 5, limit))
         return NULL;
+
     s2n(TLSEXT_TYPE_heartbeat, ret);
     s2n(1, ret);
     /*-
@@ -1524,7 +1558,12 @@ unsigned char *ssl_add_clienthello_tlsex
          * The client advertises an emtpy extension to indicate its support
          * for Next Protocol Negotiation
          */
-        if (limit - ret - 4 < 0)
+
+        /*-
+         * check for enough space.
+         * 4 bytes for the NPN ext type and extension length
+         */
+        if (CHECKLEN(ret, 4, limit))
             return NULL;
         s2n(TLSEXT_TYPE_next_proto_neg, ret);
         s2n(0, ret);
@@ -1532,7 +1571,13 @@ unsigned char *ssl_add_clienthello_tlsex
 # endif
 
     if (s->alpn_client_proto_list && !s->s3->tmp.finish_md_len) {
-        if ((size_t)(limit - ret) < 6 + s->alpn_client_proto_list_len)
+        /*-
+         * check for enough space.
+         * 4 bytes for the ALPN type and extension length
+         * 2 bytes for the ALPN protocol list length
+         * + ALPN protocol list length
+         */
+        if (CHECKLEN(ret, 6 + s->alpn_client_proto_list_len, limit))
             return NULL;
         s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret);
         s2n(2 + s->alpn_client_proto_list_len, ret);
@@ -1547,7 +1592,12 @@ unsigned char *ssl_add_clienthello_tlsex
 
         ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0);
 
-        if ((limit - ret - 4 - el) < 0)
+        /*-
+         * check for enough space.
+         * 4 bytes for the SRTP type and extension length
+         * + SRTP profiles length
+         */
+        if (CHECKLEN(ret, 4 + el, limit))
             return NULL;
 
         s2n(TLSEXT_TYPE_use_srtp, ret);
@@ -1587,6 +1637,17 @@ unsigned char *ssl_add_clienthello_tlsex
             else
                 hlen = 0;
 
+            /*-
+             * check for enough space. Strictly speaking we know we've already
+             * got enough space because to get here the message size is < 0x200,
+             * but we know that we've allocated far more than that in the buffer
+             * - but for consistency and robustness we're going to check anyway.
+             *
+             * 4 bytes for the padding type and extension length
+             * + padding length
+             */
+            if (CHECKLEN(ret, 4 + hlen, limit))
+                return NULL;
             s2n(TLSEXT_TYPE_padding, ret);
             s2n(hlen, ret);
             memset(ret, 0, hlen);
@@ -1644,7 +1705,12 @@ unsigned char *ssl_add_serverhello_tlsex
             return NULL;
         }
 
-        if ((limit - ret - 4 - el) < 0)
+        /*-
+         * check for enough space.
+         * 4 bytes for the reneg type and extension length
+         * + reneg data length
+         */
+        if (CHECKLEN(ret, 4 + el, limit))
             return NULL;
 
         s2n(TLSEXT_TYPE_renegotiate, ret);
@@ -1664,19 +1730,23 @@ unsigned char *ssl_add_serverhello_tlsex
         /*
          * Add TLS extension ECPointFormats to the ServerHello message
          */
-        long lenmax;
 
         tls1_get_formatlist(s, &plist, &plistlen);
 
-        if ((lenmax = limit - ret - 5) < 0)
-            return NULL;
-        if (plistlen > (size_t)lenmax)
-            return NULL;
         if (plistlen > 255) {
             SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
             return NULL;
         }
 
+        /*-
+         * check for enough space.
+         * 4 bytes for the ec points format type and extension length
+         * 1 byte for the points format list length
+         * + length of points format list
+         */
+        if (CHECKLEN(ret, 5 + plistlen, limit))
+            return NULL;
+
         s2n(TLSEXT_TYPE_ec_point_formats, ret);
         s2n(plistlen + 1, ret);
         *(ret++) = (unsigned char)plistlen;
@@ -1691,14 +1761,22 @@ unsigned char *ssl_add_serverhello_tlsex
 # endif                         /* OPENSSL_NO_EC */
 
     if (s->tlsext_ticket_expected && !(SSL_get_options(s) & SSL_OP_NO_TICKET)) {
-        if ((long)(limit - ret - 4) < 0)
+        /*-
+         * check for enough space.
+         * 4 bytes for the Ticket type and extension length
+         */
+        if (CHECKLEN(ret, 4, limit))
             return NULL;
         s2n(TLSEXT_TYPE_session_ticket, ret);
         s2n(0, ret);
     }
 
     if (s->tlsext_status_expected) {
-        if ((long)(limit - ret - 4) < 0)
+        /*-
+         * check for enough space.
+         * 4 bytes for the Status request type and extension length
+         */
+        if (CHECKLEN(ret, 4, limit))
             return NULL;
         s2n(TLSEXT_TYPE_status_request, ret);
         s2n(0, ret);
@@ -1726,7 +1804,12 @@ unsigned char *ssl_add_serverhello_tlsex
 
         ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0);
 
-        if ((limit - ret - 4 - el) < 0)
+        /*-
+         * check for enough space.
+         * 4 bytes for the SRTP profiles type and extension length
+         * + length of the SRTP profiles list
+         */
+        if (CHECKLEN(ret, 4 + el, limit))
             return NULL;
 
         s2n(TLSEXT_TYPE_use_srtp, ret);
@@ -1751,16 +1834,23 @@ unsigned char *ssl_add_serverhello_tlsex
             0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, 0x30, 0x08,
             0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17
         };
-        if (limit - ret < 36)
+
+        /* check for enough space. */
+        if (CHECKLEN(ret, sizeof(cryptopro_ext), limit))
             return NULL;
-        memcpy(ret, cryptopro_ext, 36);
-        ret += 36;
+        memcpy(ret, cryptopro_ext, sizeof(cryptopro_ext));
+        ret += sizeof(cryptopro_ext);
 
     }
 # ifndef OPENSSL_NO_HEARTBEATS
     /* Add Heartbeat extension if we've received one */
     if (s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) {
-        if ((limit - ret - 4 - 1) < 0)
+        /*-
+         * check for enough space.
+         * 4 bytes for the Heartbeat type and extension length
+         * 1 byte for the mode
+         */
+        if (CHECKLEN(ret, 5, limit))
             return NULL;
         s2n(TLSEXT_TYPE_heartbeat, ret);
         s2n(1, ret);
@@ -1789,7 +1879,12 @@ unsigned char *ssl_add_serverhello_tlsex
                                               s->
                                               ctx->next_protos_advertised_cb_arg);
         if (r == SSL_TLSEXT_ERR_OK) {
-            if ((long)(limit - ret - 4 - npalen) < 0)
+            /*-
+             * check for enough space.
+             * 4 bytes for the NPN type and extension length
+             * + length of protocols list
+             */
+            if (CHECKLEN(ret, 4 + npalen, limit))
                 return NULL;
             s2n(TLSEXT_TYPE_next_proto_neg, ret);
             s2n(npalen, ret);
@@ -1804,9 +1899,16 @@ unsigned char *ssl_add_serverhello_tlsex
 
     if (s->s3->alpn_selected) {
         const unsigned char *selected = s->s3->alpn_selected;
-        unsigned len = s->s3->alpn_selected_len;
+        size_t len = s->s3->alpn_selected_len;
 
-        if ((long)(limit - ret - 4 - 2 - 1 - len) < 0)
+        /*-
+         * check for enough space.
+         * 4 bytes for the ALPN type and extension length
+         * 2 bytes for ALPN data length
+         * 1 byte for selected protocol length
+         * + length of the selected protocol
+         */
+        if (CHECKLEN(ret, 7 + len, limit))
             return NULL;
         s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret);
         s2n(3 + len, ret);
@@ -1966,11 +2068,10 @@ static int tls1_alpn_handle_client_hello
 
 /*
  * Process the ALPN extension in a ClientHello.
- * ret: a pointer to the TLSEXT return value: SSL_TLSEXT_ERR_*
  * al: a pointer to the alert value to send in the event of a failure.
- * returns 1 on success, 0 on failure: al/ret set only on failure
+ * returns 1 on success, 0 on failure: al set only on failure
  */
-static int tls1_alpn_handle_client_hello_late(SSL *s, int *ret, int *al)
+static int tls1_alpn_handle_client_hello_late(SSL *s, int *al)
 {
     const unsigned char *selected = NULL;
     unsigned char selected_len = 0;
@@ -1986,7 +2087,6 @@ static int tls1_alpn_handle_client_hello
             s->s3->alpn_selected = OPENSSL_malloc(selected_len);
             if (s->s3->alpn_selected == NULL) {
                 *al = SSL_AD_INTERNAL_ERROR;
-                *ret = SSL_TLSEXT_ERR_ALERT_FATAL;
                 return 0;
             }
             memcpy(s->s3->alpn_selected, selected, selected_len);
@@ -3064,10 +3164,12 @@ int tls1_set_server_sigalgs(SSL *s)
     return 0;
 }
 
-int ssl_check_clienthello_tlsext_late(SSL *s)
+/*
+ * Upon success, returns 1.
+ * Upon failure, returns 0 and sets |al| to the appropriate fatal alert.
+ */
+int ssl_check_clienthello_tlsext_late(SSL *s, int *al)
 {
-    int ret = SSL_TLSEXT_ERR_OK;
-    int al;
 
     /*
      * If status request then ask callback what to do. Note: this must be
@@ -3076,58 +3178,41 @@ int ssl_check_clienthello_tlsext_late(SS
      * influence which certificate is sent
      */
     if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb) {
-        int r;
+        int ret;
         CERT_PKEY *certpkey;
         certpkey = ssl_get_server_send_pkey(s);
         /* If no certificate can't return certificate status */
-        if (certpkey == NULL) {
-            s->tlsext_status_expected = 0;
-            return 1;
-        }
-        /*
-         * Set current certificate to one we will use so SSL_get_certificate
-         * et al can pick it up.
-         */
-        s->cert->key = certpkey;
-        r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
-        switch (r) {
-            /* We don't want to send a status request response */
-        case SSL_TLSEXT_ERR_NOACK:
-            s->tlsext_status_expected = 0;
-            break;
-            /* status request response should be sent */
-        case SSL_TLSEXT_ERR_OK:
-            if (s->tlsext_ocsp_resp)
-                s->tlsext_status_expected = 1;
-            else
+        if (certpkey != NULL) {
+            /*
+             * Set current certificate to one we will use so SSL_get_certificate
+             * et al can pick it up.
+             */
+            s->cert->key = certpkey;
+            ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
+            switch (ret) {
+                /* We don't want to send a status request response */
+            case SSL_TLSEXT_ERR_NOACK:
                 s->tlsext_status_expected = 0;
-            break;
-            /* something bad happened */
-        case SSL_TLSEXT_ERR_ALERT_FATAL:
-            ret = SSL_TLSEXT_ERR_ALERT_FATAL;
-            al = SSL_AD_INTERNAL_ERROR;
-            goto err;
+                break;
+                /* status request response should be sent */
+            case SSL_TLSEXT_ERR_OK:
+                if (s->tlsext_ocsp_resp)
+                    s->tlsext_status_expected = 1;
+                break;
+                /* something bad happened */
+            case SSL_TLSEXT_ERR_ALERT_FATAL:
+            default:
+                *al = SSL_AD_INTERNAL_ERROR;
+                return 0;
+            }
         }
-    } else
-        s->tlsext_status_expected = 0;
-
-    if (!tls1_alpn_handle_client_hello_late(s, &ret, &al)) {
-        goto err;
     }
 
- err:
-    switch (ret) {
-    case SSL_TLSEXT_ERR_ALERT_FATAL:
-        ssl3_send_alert(s, SSL3_AL_FATAL, al);
-        return -1;
-
-    case SSL_TLSEXT_ERR_ALERT_WARNING:
-        ssl3_send_alert(s, SSL3_AL_WARNING, al);
-        return 1;
-
-    default:
-        return 1;
+    if (!tls1_alpn_handle_client_hello_late(s, al)) {
+        return 0;
     }
+
+    return 1;
 }
 
 int ssl_check_serverhello_tlsext(SSL *s)

Index: src/crypto/external/bsd/openssl/dist/ssl/s3_srvr.c
diff -u src/crypto/external/bsd/openssl/dist/ssl/s3_srvr.c:1.25 src/crypto/external/bsd/openssl/dist/ssl/s3_srvr.c:1.26
--- src/crypto/external/bsd/openssl/dist/ssl/s3_srvr.c:1.25	Fri Oct 14 16:23:22 2016
+++ src/crypto/external/bsd/openssl/dist/ssl/s3_srvr.c	Fri Jan 27 23:16:21 2017
@@ -506,7 +506,7 @@ int ssl3_accept(SSL *s)
                     * if SSL_VERIFY_CLIENT_ONCE is set, don't request cert
                     * during re-negotiation:
                     */
-                   ((s->session->peer != NULL) &&
+                   (s->s3->tmp.finish_md_len != 0 &&
                     (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) ||
                    /*
                     * never request cert in anonymous ciphersuites (see
@@ -1464,9 +1464,9 @@ int ssl3_get_client_hello(SSL *s)
 
     /* Handles TLS extensions that we couldn't check earlier */
     if (s->version >= SSL3_VERSION) {
-        if (ssl_check_clienthello_tlsext_late(s) <= 0) {
+        if (!ssl_check_clienthello_tlsext_late(s, &al)) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT);
-            goto err;
+            goto f_err;
         }
     }
 
@@ -1600,6 +1600,9 @@ int ssl3_send_server_key_exchange(SSL *s
     unsigned int u;
 #endif
 #ifndef OPENSSL_NO_DH
+# ifdef OPENSSL_NO_RSA
+    int j;
+# endif
     DH *dh = NULL, *dhp;
 #endif
 #ifndef OPENSSL_NO_ECDH
@@ -1861,6 +1864,16 @@ int ssl3_send_server_key_exchange(SSL *s
                 n += 1 + nr[i];
             else
 #endif
+#ifndef OPENSSL_NO_DH
+            /*
+             * for interoperability with some versions of the Microsoft TLS
+             * stack, we need to zero pad the DHE pub key to the same length
+             * as the prime, so use the length of the prime here
+             */
+            if ((i == 2) && (type & (SSL_kEDH)))
+                n += 2 + nr[0];
+            else
+#endif
                 n += 2 + nr[i];
         }
 
@@ -1895,6 +1908,20 @@ int ssl3_send_server_key_exchange(SSL *s
                 p++;
             } else
 #endif
+#ifndef OPENSSL_NO_DH
+            /*
+             * for interoperability with some versions of the Microsoft TLS
+             * stack, we need to zero pad the DHE pub key to the same length
+             * as the prime
+             */
+            if ((i == 2) && (type & (SSL_kEDH))) {
+                s2n(nr[0], p);
+                for (j = 0; j < (nr[0] - nr[2]); ++j) {
+                    *p = 0;
+                    ++p;
+                }
+            } else
+#endif
                 s2n(nr[i], p);
             BN_bn2bin(r[i], p);
             p += nr[i];

Index: src/crypto/external/bsd/openssl/dist/ssl/ssl_err.c
diff -u src/crypto/external/bsd/openssl/dist/ssl/ssl_err.c:1.11 src/crypto/external/bsd/openssl/dist/ssl/ssl_err.c:1.12
--- src/crypto/external/bsd/openssl/dist/ssl/ssl_err.c:1.11	Fri Oct 14 16:23:22 2016
+++ src/crypto/external/bsd/openssl/dist/ssl/ssl_err.c	Fri Jan 27 23:16:21 2017
@@ -753,6 +753,7 @@ static ERR_STRING_DATA SSL_str_reasons[]
      "tls illegal exporter label"},
     {ERR_REASON(SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST),
      "tls invalid ecpointformat list"},
+    {ERR_REASON(SSL_R_TOO_MANY_WARN_ALERTS), "too many warn alerts"},
     {ERR_REASON(SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST),
      "tls peer did not respond with certificate list"},
     {ERR_REASON(SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG),

Index: src/crypto/external/bsd/openssl/dist/ssl/ssl_lib.c
diff -u src/crypto/external/bsd/openssl/dist/ssl/ssl_lib.c:1.8 src/crypto/external/bsd/openssl/dist/ssl/ssl_lib.c:1.9
--- src/crypto/external/bsd/openssl/dist/ssl/ssl_lib.c:1.8	Fri Oct 14 16:23:22 2016
+++ src/crypto/external/bsd/openssl/dist/ssl/ssl_lib.c	Fri Jan 27 23:16:21 2017
@@ -2030,10 +2030,8 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *m
     ret->rbuf_freelist->len = 0;
     ret->rbuf_freelist->head = NULL;
     ret->wbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST));
-    if (!ret->wbuf_freelist) {
-        OPENSSL_free(ret->rbuf_freelist);
+    if (!ret->wbuf_freelist)
         goto err;
-    }
     ret->wbuf_freelist->chunklen = 0;
     ret->wbuf_freelist->len = 0;
     ret->wbuf_freelist->head = NULL;

Index: src/crypto/external/bsd/openssl/dist/ssl/ssl_locl.h
diff -u src/crypto/external/bsd/openssl/dist/ssl/ssl_locl.h:1.14 src/crypto/external/bsd/openssl/dist/ssl/ssl_locl.h:1.15
--- src/crypto/external/bsd/openssl/dist/ssl/ssl_locl.h:1.14	Fri Oct 14 16:23:22 2016
+++ src/crypto/external/bsd/openssl/dist/ssl/ssl_locl.h	Fri Jan 27 23:16:21 2017
@@ -1384,7 +1384,7 @@ unsigned char *ssl_add_serverhello_tlsex
 int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data,
                                  unsigned char *limit);
 int tls1_set_server_sigalgs(SSL *s);
-int ssl_check_clienthello_tlsext_late(SSL *s);
+int ssl_check_clienthello_tlsext_late(SSL *s, int *al);
 int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data,
                                  unsigned char *d, int n);
 int ssl_prepare_clienthello_tlsext(SSL *s);

Index: src/crypto/external/bsd/openssl/dist/ssl/ssl_sess.c
diff -u src/crypto/external/bsd/openssl/dist/ssl/ssl_sess.c:1.2 src/crypto/external/bsd/openssl/dist/ssl/ssl_sess.c:1.3
--- src/crypto/external/bsd/openssl/dist/ssl/ssl_sess.c:1.2	Fri Oct 14 16:23:22 2016
+++ src/crypto/external/bsd/openssl/dist/ssl/ssl_sess.c	Fri Jan 27 23:16:21 2017
@@ -769,6 +769,15 @@ int SSL_CTX_add_session(SSL_CTX *ctx, SS
          * obtain the same session from an external cache)
          */
         s = NULL;
+    } else if (s == NULL &&
+               lh_SSL_SESSION_retrieve(ctx->sessions, c) == NULL) {
+        /* s == NULL can also mean OOM error in lh_SSL_SESSION_insert ... */
+
+        /*
+         * ... so take back the extra reference and also don't add
+         * the session to the SSL_SESSION_list at this time
+         */
+        s = c;
     }
 
     /* Put at the head of the queue unless it is already in the cache */

Reply via email to